@cleocode/core 2026.9.23 → 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 +2 -2
- 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/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 +35 -1
- package/dist/decide/client.d.ts.map +1 -1
- package/dist/decide/client.js +124 -30
- package/dist/decide/client.js.map +1 -1
- package/dist/decide/credentials.d.ts +177 -17
- package/dist/decide/credentials.d.ts.map +1 -1
- package/dist/decide/credentials.js +505 -41
- package/dist/decide/credentials.js.map +1 -1
- package/dist/decide/index.d.ts +8 -8
- package/dist/decide/index.d.ts.map +1 -1
- package/dist/decide/index.js +8 -8
- package/dist/decide/index.js.map +1 -1
- package/dist/decide/jev-wire.d.ts +25 -19
- package/dist/decide/jev-wire.d.ts.map +1 -1
- package/dist/decide/jev-wire.js +56 -31
- package/dist/decide/jev-wire.js.map +1 -1
- package/dist/decide/operations.d.ts +63 -12
- package/dist/decide/operations.d.ts.map +1 -1
- package/dist/decide/operations.js +116 -58
- package/dist/decide/operations.js.map +1 -1
- package/dist/decide/provider-state.d.ts +85 -12
- package/dist/decide/provider-state.d.ts.map +1 -1
- package/dist/decide/provider-state.js +154 -21
- package/dist/decide/provider-state.js.map +1 -1
- package/dist/decide/provider.d.ts +5 -0
- package/dist/decide/provider.d.ts.map +1 -1
- package/dist/decide/provider.js.map +1 -1
- package/dist/decide/providers.d.ts +15 -2
- package/dist/decide/providers.d.ts.map +1 -1
- package/dist/decide/providers.js +22 -6
- package/dist/decide/providers.js.map +1 -1
- package/dist/decide/sites/registry.d.ts +22 -0
- package/dist/decide/sites/registry.d.ts.map +1 -1
- package/dist/decide/sites/registry.js +23 -0
- package/dist/decide/sites/registry.js.map +1 -1
- package/dist/decide/wizard.d.ts +12 -4
- package/dist/decide/wizard.d.ts.map +1 -1
- package/dist/decide/wizard.js +79 -26
- package/dist/decide/wizard.js.map +1 -1
- 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-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 +2928 -1053
- 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 +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.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 +5 -4
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +6 -4
- 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 +3017 -1142
- 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/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/learnings.d.ts +6 -6
- package/dist/memory/patterns.d.ts +4 -4
- 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/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/orchestrate/pivot.d.ts +4 -0
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +75 -12
- package/dist/orchestrate/pivot.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 +6 -3
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/spawn-prompt.js +1 -1
- package/dist/orchestration/spawn-prompt.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 +70 -3
- package/dist/project-scope.d.ts.map +1 -1
- package/dist/project-scope.js +154 -15
- package/dist/project-scope.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/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 +3027 -1152
- 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 +10 -10
- 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 +103 -26
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +166 -37
- 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.map +1 -1
- package/dist/setup/config-json-merge.js +1 -0
- package/dist/setup/config-json-merge.js.map +1 -1
- package/dist/setup/index.d.ts +4 -2
- package/dist/setup/index.d.ts.map +1 -1
- package/dist/setup/index.js +6 -2
- package/dist/setup/index.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/wizard.d.ts +1 -1
- package/dist/setup/wizard.d.ts.map +1 -1
- 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/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/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-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/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/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 +73 -18
- package/dist/store/credential-transfer.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/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/migration-manager.d.ts +61 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +102 -4
- package/dist/store/migration-manager.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/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 +10 -0
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +1 -0
- 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/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/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +245 -47
- package/dist/store/sqlite-data-accessor.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 +52 -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 +13 -4
- package/dist/store/worktree-build-guard.d.ts.map +1 -1
- package/dist/store/worktree-build-guard.js +21 -10
- package/dist/store/worktree-build-guard.js.map +1 -1
- package/dist/store/worktree-isolation-guard.d.ts +121 -10
- package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
- package/dist/store/worktree-isolation-guard.js +155 -34
- package/dist/store/worktree-isolation-guard.js.map +1 -1
- package/dist/system/backup.d.ts +7 -0
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +5 -0
- 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 +1 -1
- package/dist/task-tools/index.d.ts.map +1 -1
- package/dist/task-tools/index.js +1 -1
- package/dist/task-tools/index.js.map +1 -1
- package/dist/task-tools/score-task-priority.d.ts +38 -0
- package/dist/task-tools/score-task-priority.d.ts.map +1 -1
- package/dist/task-tools/score-task-priority.js +51 -0
- 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/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +3 -4
- package/dist/tasks/analyze.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 +59 -3
- package/dist/tasks/change-set.js.map +1 -1
- 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 +560 -59
- package/dist/tasks/component-pr.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 +20 -1
- package/dist/tasks/duplicate-detector.d.ts.map +1 -1
- package/dist/tasks/duplicate-detector.js +10 -2
- package/dist/tasks/duplicate-detector.js.map +1 -1
- package/dist/tasks/engine-wrap-ops.d.ts +19 -10
- package/dist/tasks/engine-wrap-ops.d.ts.map +1 -1
- package/dist/tasks/engine-wrap-ops.js +38 -10
- package/dist/tasks/engine-wrap-ops.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/plan.d.ts.map +1 -1
- package/dist/tasks/plan.js +16 -60
- package/dist/tasks/plan.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 +25 -2
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +32 -13
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +7 -5
- package/dist/tasks/update.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 +51 -8
- 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 +23 -13
- package/schemas/project-info.schema.json +10 -4
- package/templates/CLEO-INJECTION.md +1 -1
- package/templates/CLEO-REFERENCE.md +3 -3
- package/templates/cleo-gitignore +11 -0
- package/templates/workflows/release-prepare.yml.tmpl +156 -10
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleo Nexus session-token store.
|
|
3
|
+
*
|
|
4
|
+
* Stored at `<cleoHome>/nexus-credentials.json` (resolved through
|
|
5
|
+
* `@cleocode/paths`, arch gate 2) with 0600 permissions, one session per API
|
|
6
|
+
* origin. Modelled on `../decide/credentials.ts`:
|
|
7
|
+
*
|
|
8
|
+
* - Writes go through `withLock` and `writeJsonFileAtomic({ mode: 0o600 })`,
|
|
9
|
+
* so neither the live file, the temp file nor a rotated backup is ever
|
|
10
|
+
* looser than owner-only. Deleting a session also purges the rotated
|
|
11
|
+
* backups, which would otherwise keep a copy of the token.
|
|
12
|
+
* - Reads return a {@link SealedNexusSession}: the token sits in a private
|
|
13
|
+
* field, so `JSON.stringify`, `util.inspect` and template strings of the
|
|
14
|
+
* handle show a masked preview only. {@link SealedNexusSession.bearer} is the
|
|
15
|
+
* one accessor, called where the HTTP request is built.
|
|
16
|
+
*
|
|
17
|
+
* Everything goes through the {@link NexusTokenStore} interface, so an OS
|
|
18
|
+
* keychain store can replace the file later without touching the callers.
|
|
19
|
+
*
|
|
20
|
+
* @task T12712
|
|
21
|
+
* @epic T12322
|
|
22
|
+
*/
|
|
23
|
+
import { closeSync, constants as fsConstants, lstatSync, mkdirSync, openSync, readdirSync, readFileSync, statSync, unlinkSync, writeSync, } from 'node:fs';
|
|
24
|
+
import { basename, dirname, join } from 'node:path';
|
|
25
|
+
import { inspect } from 'node:util';
|
|
26
|
+
import { nexusAccountOrganizationSchema, nexusAccountUserSchema, } from '@cleocode/contracts';
|
|
27
|
+
import { getCleoHome } from '@cleocode/paths';
|
|
28
|
+
import { z } from 'zod';
|
|
29
|
+
import { withLock } from '../store/file-utils.js';
|
|
30
|
+
/** File name of the store, directly under the CLEO home. */
|
|
31
|
+
export const NEXUS_CREDENTIALS_FILE = 'nexus-credentials.json';
|
|
32
|
+
const sessionSchema = z.object({
|
|
33
|
+
token: z.string().min(1),
|
|
34
|
+
tokenType: z.string(),
|
|
35
|
+
expiresAt: z.string().nullable(),
|
|
36
|
+
user: nexusAccountUserSchema.nullable(),
|
|
37
|
+
organization: nexusAccountOrganizationSchema.nullable(),
|
|
38
|
+
createdAt: z.string(),
|
|
39
|
+
});
|
|
40
|
+
const storeSchema = z.object({
|
|
41
|
+
version: z.literal(1),
|
|
42
|
+
sessions: z.record(z.string(), sessionSchema),
|
|
43
|
+
});
|
|
44
|
+
const EMPTY_STORE = { version: 1, sessions: {} };
|
|
45
|
+
/** `O_NOFOLLOW` where the platform has it (not on Windows). */
|
|
46
|
+
const NO_FOLLOW = fsConstants.O_NOFOLLOW ?? 0;
|
|
47
|
+
/**
|
|
48
|
+
* Mask a token down to a short, non-reversible preview.
|
|
49
|
+
*
|
|
50
|
+
* @param token - Plaintext token (read transiently, not retained).
|
|
51
|
+
* @returns `…` plus at most the last 4 characters.
|
|
52
|
+
*/
|
|
53
|
+
export function maskNexusToken(token) {
|
|
54
|
+
return token.length > 12 ? `…${token.slice(-4)}` : '…';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Opaque handle to a stored session. The token is held in a private field;
|
|
58
|
+
* serialising or inspecting the handle yields the masked preview only.
|
|
59
|
+
*/
|
|
60
|
+
export class SealedNexusSession {
|
|
61
|
+
/** API origin the session belongs to. */
|
|
62
|
+
apiUrl;
|
|
63
|
+
/** Token type (`Bearer`). */
|
|
64
|
+
tokenType;
|
|
65
|
+
/** ISO expiry, when known. */
|
|
66
|
+
expiresAt;
|
|
67
|
+
/** Signed-in user, when known. */
|
|
68
|
+
user;
|
|
69
|
+
/** Primary organization, when known. */
|
|
70
|
+
organization;
|
|
71
|
+
/** ISO time the session was stored. */
|
|
72
|
+
createdAt;
|
|
73
|
+
/** Masked token preview. */
|
|
74
|
+
tokenPreview;
|
|
75
|
+
#token;
|
|
76
|
+
/**
|
|
77
|
+
* @param apiUrl - API origin.
|
|
78
|
+
* @param record - Stored record; the token is captured privately.
|
|
79
|
+
*/
|
|
80
|
+
constructor(apiUrl, record) {
|
|
81
|
+
this.apiUrl = apiUrl;
|
|
82
|
+
this.tokenType = record.tokenType;
|
|
83
|
+
this.expiresAt = record.expiresAt;
|
|
84
|
+
this.user = record.user;
|
|
85
|
+
this.organization = record.organization;
|
|
86
|
+
this.createdAt = record.createdAt;
|
|
87
|
+
this.#token = record.token;
|
|
88
|
+
this.tokenPreview = maskNexusToken(record.token);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The plaintext token. Call only where the `Authorization` header is built.
|
|
92
|
+
*
|
|
93
|
+
* @returns The bearer token.
|
|
94
|
+
*/
|
|
95
|
+
bearer() {
|
|
96
|
+
return this.#token;
|
|
97
|
+
}
|
|
98
|
+
/** Secret-free JSON form. */
|
|
99
|
+
toJSON() {
|
|
100
|
+
return {
|
|
101
|
+
apiUrl: this.apiUrl,
|
|
102
|
+
tokenType: this.tokenType,
|
|
103
|
+
expiresAt: this.expiresAt,
|
|
104
|
+
user: this.user,
|
|
105
|
+
organization: this.organization,
|
|
106
|
+
createdAt: this.createdAt,
|
|
107
|
+
tokenPreview: this.tokenPreview,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Secret-free string form. */
|
|
111
|
+
toString() {
|
|
112
|
+
return `SealedNexusSession(${this.apiUrl}, token ${this.tokenPreview})`;
|
|
113
|
+
}
|
|
114
|
+
/** Secret-free `util.inspect` form. */
|
|
115
|
+
[inspect.custom]() {
|
|
116
|
+
return this.toString();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Thrown when the store cannot be written safely. */
|
|
120
|
+
export class NexusCredentialsError extends Error {
|
|
121
|
+
constructor(message) {
|
|
122
|
+
super(message);
|
|
123
|
+
this.name = 'NexusCredentialsError';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The storage key for an API URL: its origin (scheme, host and port).
|
|
128
|
+
*
|
|
129
|
+
* @param apiUrl - Any URL on the API host.
|
|
130
|
+
* @returns The origin, e.g. `https://api.cleocode.dev`.
|
|
131
|
+
*/
|
|
132
|
+
export function nexusOriginKey(apiUrl) {
|
|
133
|
+
return new URL(apiUrl).origin;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Absolute path of the default file store.
|
|
137
|
+
*
|
|
138
|
+
* @returns `<cleoHome>/nexus-credentials.json`.
|
|
139
|
+
*/
|
|
140
|
+
export function nexusCredentialsPath() {
|
|
141
|
+
return join(getCleoHome(), NEXUS_CREDENTIALS_FILE);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* File-backed {@link NexusTokenStore}: `<cleoHome>/nexus-credentials.json`,
|
|
145
|
+
* mode 0600, one entry per API origin.
|
|
146
|
+
*/
|
|
147
|
+
export class FileNexusTokenStore {
|
|
148
|
+
/** Absolute path of the store file. */
|
|
149
|
+
location;
|
|
150
|
+
/** @param path - Store path; defaults to {@link nexusCredentialsPath}. */
|
|
151
|
+
constructor(path = nexusCredentialsPath()) {
|
|
152
|
+
this.location = path;
|
|
153
|
+
}
|
|
154
|
+
async get(apiUrl) {
|
|
155
|
+
const key = nexusOriginKey(apiUrl);
|
|
156
|
+
const record = this.read().sessions[key];
|
|
157
|
+
return record ? new SealedNexusSession(key, record) : null;
|
|
158
|
+
}
|
|
159
|
+
async put(apiUrl, session) {
|
|
160
|
+
const key = nexusOriginKey(apiUrl);
|
|
161
|
+
const record = sessionSchema.parse({
|
|
162
|
+
token: session.token,
|
|
163
|
+
tokenType: session.tokenType,
|
|
164
|
+
expiresAt: session.expiresAt,
|
|
165
|
+
user: session.user,
|
|
166
|
+
organization: session.organization,
|
|
167
|
+
createdAt: new Date().toISOString(),
|
|
168
|
+
});
|
|
169
|
+
await this.write((current) => ({
|
|
170
|
+
version: 1,
|
|
171
|
+
sessions: { ...current.sessions, [key]: record },
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
async delete(apiUrl, expected) {
|
|
175
|
+
const key = nexusOriginKey(apiUrl);
|
|
176
|
+
let deleted = false;
|
|
177
|
+
if (key in this.read().sessions) {
|
|
178
|
+
await this.write((current) => {
|
|
179
|
+
const stored = current.sessions[key];
|
|
180
|
+
if (!stored || (expected !== undefined && stored.token !== expected.bearer())) {
|
|
181
|
+
return current;
|
|
182
|
+
}
|
|
183
|
+
deleted = true;
|
|
184
|
+
const sessions = { ...current.sessions };
|
|
185
|
+
delete sessions[key];
|
|
186
|
+
return { version: 1, sessions };
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// Rotated backups hold earlier copies of the file, and so of the token.
|
|
190
|
+
this.purgeBackups();
|
|
191
|
+
return deleted;
|
|
192
|
+
}
|
|
193
|
+
async list() {
|
|
194
|
+
return Object.entries(this.read().sessions)
|
|
195
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
196
|
+
.map(([key, record]) => new SealedNexusSession(key, record));
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Read and validate the file; a missing or malformed file reads as empty. A
|
|
200
|
+
* file readable or writable by group/others, or owned by another user, is
|
|
201
|
+
* refused: its token may already be exposed or planted.
|
|
202
|
+
*/
|
|
203
|
+
read() {
|
|
204
|
+
this.assertPrivate();
|
|
205
|
+
let raw;
|
|
206
|
+
try {
|
|
207
|
+
raw = readFileSync(this.location, 'utf-8');
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return EMPTY_STORE;
|
|
211
|
+
}
|
|
212
|
+
if (!raw.trim())
|
|
213
|
+
return EMPTY_STORE;
|
|
214
|
+
try {
|
|
215
|
+
const parsed = storeSchema.safeParse(JSON.parse(raw));
|
|
216
|
+
return parsed.success ? parsed.data : EMPTY_STORE;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return EMPTY_STORE;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/** Locked, atomic, owner-only read-modify-write. */
|
|
223
|
+
async write(transform) {
|
|
224
|
+
this.assertNoSymlinks();
|
|
225
|
+
this.seed();
|
|
226
|
+
await withLock(this.location, (current) => {
|
|
227
|
+
const parsed = storeSchema.safeParse(current);
|
|
228
|
+
return transform(parsed.success ? parsed.data : EMPTY_STORE);
|
|
229
|
+
}, { mode: 0o600 });
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Create the store file owner-only if it does not exist. `O_EXCL` plus
|
|
233
|
+
* `O_NOFOLLOW` close the window between the symlink check and the create: a
|
|
234
|
+
* symlink planted meanwhile makes the open fail instead of being followed.
|
|
235
|
+
* On `EEXIST` the existing entry is re-opened with `O_NOFOLLOW`, which fails
|
|
236
|
+
* (`ELOOP`) on a symlink, so a planted link is refused before the locked
|
|
237
|
+
* write can touch it.
|
|
238
|
+
*/
|
|
239
|
+
seed() {
|
|
240
|
+
mkdirSync(dirname(this.location), { recursive: true, mode: 0o700 });
|
|
241
|
+
let fd;
|
|
242
|
+
try {
|
|
243
|
+
fd = openSync(this.location, fsConstants.O_CREAT | fsConstants.O_EXCL | fsConstants.O_WRONLY | NO_FOLLOW, 0o600);
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
if (!(err instanceof Error && 'code' in err && err.code === 'EEXIST'))
|
|
247
|
+
throw err;
|
|
248
|
+
try {
|
|
249
|
+
closeSync(openSync(this.location, fsConstants.O_RDONLY | NO_FOLLOW));
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
throw new NexusCredentialsError(`refusing to write Nexus credentials through a symlink: ${this.location}`);
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
writeSync(fd, `${JSON.stringify(EMPTY_STORE)}\n`);
|
|
258
|
+
}
|
|
259
|
+
finally {
|
|
260
|
+
closeSync(fd);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Throw when the store exists with a mode wider than 0600 or another owner.
|
|
265
|
+
* Skipped on Windows, where Node reports every file as 0o666 and uids do not
|
|
266
|
+
* apply; the file lives in the user's profile, protected by its ACL.
|
|
267
|
+
*/
|
|
268
|
+
assertPrivate() {
|
|
269
|
+
if (process.platform === 'win32')
|
|
270
|
+
return;
|
|
271
|
+
let st;
|
|
272
|
+
try {
|
|
273
|
+
st = statSync(this.location);
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return; // absent: created 0600 on first write
|
|
277
|
+
}
|
|
278
|
+
const uid = typeof process.getuid === 'function' ? process.getuid() : null;
|
|
279
|
+
if ((st.mode & 0o077) !== 0 || (uid !== null && st.uid !== uid)) {
|
|
280
|
+
throw new NexusCredentialsError(`refusing to read ${this.location}: it must be owned by you with mode 0600 (it is ${(st.mode & 0o777).toString(8)}). Run: chmod 600 ${this.location}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/** Refuse to write a token through a symlink (it could point anywhere). */
|
|
284
|
+
assertNoSymlinks() {
|
|
285
|
+
for (const candidate of [this.location, ...this.backupFiles()]) {
|
|
286
|
+
let isLink = false;
|
|
287
|
+
try {
|
|
288
|
+
isLink = lstatSync(candidate).isSymbolicLink();
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (isLink) {
|
|
294
|
+
throw new NexusCredentialsError(`refusing to write Nexus credentials through a symlink: ${candidate}`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/** Rotated backups of the store file. */
|
|
299
|
+
backupFiles() {
|
|
300
|
+
const backupDir = join(dirname(this.location), '.backups');
|
|
301
|
+
const prefix = `${basename(this.location)}.`;
|
|
302
|
+
try {
|
|
303
|
+
return readdirSync(backupDir)
|
|
304
|
+
.filter((entry) => entry.startsWith(prefix))
|
|
305
|
+
.map((entry) => join(backupDir, entry));
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
return [];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/** Delete every rotated backup (best effort). */
|
|
312
|
+
purgeBackups() {
|
|
313
|
+
for (const file of this.backupFiles()) {
|
|
314
|
+
try {
|
|
315
|
+
unlinkSync(file);
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
/* best effort */
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=nexus-credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nexus-credentials.js","sourceRoot":"","sources":["../../src/cloud/nexus-credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cleo project link`: register the current project with Cleo Nexus and bind
|
|
3
|
+
* the remote project to the local one.
|
|
4
|
+
*
|
|
5
|
+
* ## What is sent
|
|
6
|
+
*
|
|
7
|
+
* `POST /v1/projects` with `{ projectId, label }` only:
|
|
8
|
+
*
|
|
9
|
+
* - `projectId` is the tracked, immutable `.cleo/project-id`
|
|
10
|
+
* (`readDeclaredProjectIdentity`), the key the server stores projects under,
|
|
11
|
+
* so the remote id IS the local id.
|
|
12
|
+
* - `label` is the project's display name in plaintext
|
|
13
|
+
* ({@link getProjectDisplayName}), or `--label`. It must not look like a path.
|
|
14
|
+
*
|
|
15
|
+
* No filesystem path, git remote or directory layout is ever sent.
|
|
16
|
+
*
|
|
17
|
+
* ## Idempotency
|
|
18
|
+
*
|
|
19
|
+
* Registering the same id again answers 200 (201 on first registration) and
|
|
20
|
+
* sets the server label to the one sent, so re-linking after a rename updates
|
|
21
|
+
* the label. Linking twice is safe.
|
|
22
|
+
*
|
|
23
|
+
* ## Where the binding lives
|
|
24
|
+
*
|
|
25
|
+
* `<project>/.cleo/nexus-link.json`, keyed by API origin. It is machine-local:
|
|
26
|
+
* `.cleo/.gitignore` denies everything not allow-listed, so the binding (which
|
|
27
|
+
* names an account's organization) is never committed. It is not
|
|
28
|
+
* `project-context.json`, which is tracked in git and regenerated by
|
|
29
|
+
* `cleo upgrade`, and not the project `cleo.db`, so linking never opens or
|
|
30
|
+
* migrates the task store. Each clone links itself, the same way each machine
|
|
31
|
+
* signs itself in.
|
|
32
|
+
*
|
|
33
|
+
* @task T12712
|
|
34
|
+
* @epic T12322
|
|
35
|
+
*/
|
|
36
|
+
import type { NexusProjectLink, NexusProjectLinkResult } from '@cleocode/contracts';
|
|
37
|
+
import { type NexusFlowOptions } from './nexus-auth.js';
|
|
38
|
+
/** File name of the binding, inside the project's `.cleo/` directory. */
|
|
39
|
+
export declare const NEXUS_LINK_FILE = "nexus-link.json";
|
|
40
|
+
/** Longest label the server accepts (`RegisterProjectRequest.label`). */
|
|
41
|
+
export declare const NEXUS_LABEL_MAX = 120;
|
|
42
|
+
/** Options for {@link linkProjectToNexus}. */
|
|
43
|
+
export interface NexusLinkOptions extends NexusFlowOptions {
|
|
44
|
+
/** Project root; defaults to the resolved current project. */
|
|
45
|
+
projectRoot?: string;
|
|
46
|
+
/** Label to register (`--label`); defaults to {@link getProjectDisplayName}. */
|
|
47
|
+
label?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validate a project label: 1-120 characters; no path separator or look-alike
|
|
51
|
+
* slash, no drive letter (`C:`), no leading `~`, no control characters; and
|
|
52
|
+
* not the OS username, which would leak the account name. A label is a name,
|
|
53
|
+
* never a path.
|
|
54
|
+
*
|
|
55
|
+
* @param raw - Candidate label.
|
|
56
|
+
* @returns The trimmed label.
|
|
57
|
+
* @throws {NexusAccountError} `E_NEXUS_INVALID_LABEL`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function validateNexusProjectLabel(raw: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Path of the binding file for a project.
|
|
62
|
+
*
|
|
63
|
+
* @param projectRoot - Project root.
|
|
64
|
+
* @returns `<project>/.cleo/nexus-link.json`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function nexusLinkPath(projectRoot: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* The stored binding for a project and origin, if any.
|
|
69
|
+
*
|
|
70
|
+
* @param projectRoot - Project root.
|
|
71
|
+
* @param apiUrl - API URL (any URL on the origin).
|
|
72
|
+
* @returns The binding, or `null`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function readNexusProjectLink(projectRoot: string, apiUrl: string): NexusProjectLink | null;
|
|
75
|
+
/**
|
|
76
|
+
* Register the project with Nexus (label only, never a path) and persist the
|
|
77
|
+
* binding in `.cleo/nexus-link.json`. Idempotent.
|
|
78
|
+
*
|
|
79
|
+
* @param opts - Project root, label, API URL, store and test overrides.
|
|
80
|
+
* @returns The binding and whether it already existed.
|
|
81
|
+
* @throws {NexusAccountError} Not signed in, expired session, invalid label,
|
|
82
|
+
* not a CLEO project, or an API refusal (e.g. the id belongs to another account).
|
|
83
|
+
*/
|
|
84
|
+
export declare function linkProjectToNexus(opts?: NexusLinkOptions): Promise<NexusProjectLinkResult>;
|
|
85
|
+
//# sourceMappingURL=nexus-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nexus-link.d.ts","sourceRoot":"","sources":["../../src/cloud/nexus-link.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAOpF,OAAO,EAEL,KAAK,gBAAgB,EAGtB,MAAM,iBAAiB,CAAC;AAIzB,yEAAyE;AACzE,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD,yEAAyE;AACzE,eAAO,MAAM,eAAe,MAAM,CAAC;AAmBnC,8CAA8C;AAC9C,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmBD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAmB7D;AAmBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEzD;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAEjG;AAkBD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,sBAAsB,CAAC,CAmEjC"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cleo project link`: register the current project with Cleo Nexus and bind
|
|
3
|
+
* the remote project to the local one.
|
|
4
|
+
*
|
|
5
|
+
* ## What is sent
|
|
6
|
+
*
|
|
7
|
+
* `POST /v1/projects` with `{ projectId, label }` only:
|
|
8
|
+
*
|
|
9
|
+
* - `projectId` is the tracked, immutable `.cleo/project-id`
|
|
10
|
+
* (`readDeclaredProjectIdentity`), the key the server stores projects under,
|
|
11
|
+
* so the remote id IS the local id.
|
|
12
|
+
* - `label` is the project's display name in plaintext
|
|
13
|
+
* ({@link getProjectDisplayName}), or `--label`. It must not look like a path.
|
|
14
|
+
*
|
|
15
|
+
* No filesystem path, git remote or directory layout is ever sent.
|
|
16
|
+
*
|
|
17
|
+
* ## Idempotency
|
|
18
|
+
*
|
|
19
|
+
* Registering the same id again answers 200 (201 on first registration) and
|
|
20
|
+
* sets the server label to the one sent, so re-linking after a rename updates
|
|
21
|
+
* the label. Linking twice is safe.
|
|
22
|
+
*
|
|
23
|
+
* ## Where the binding lives
|
|
24
|
+
*
|
|
25
|
+
* `<project>/.cleo/nexus-link.json`, keyed by API origin. It is machine-local:
|
|
26
|
+
* `.cleo/.gitignore` denies everything not allow-listed, so the binding (which
|
|
27
|
+
* names an account's organization) is never committed. It is not
|
|
28
|
+
* `project-context.json`, which is tracked in git and regenerated by
|
|
29
|
+
* `cleo upgrade`, and not the project `cleo.db`, so linking never opens or
|
|
30
|
+
* migrates the task store. Each clone links itself, the same way each machine
|
|
31
|
+
* signs itself in.
|
|
32
|
+
*
|
|
33
|
+
* @task T12712
|
|
34
|
+
* @epic T12322
|
|
35
|
+
*/
|
|
36
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
37
|
+
import { homedir, userInfo } from 'node:os';
|
|
38
|
+
import { join, resolve } from 'node:path';
|
|
39
|
+
import { readDeclaredProjectIdentity } from '@cleocode/paths';
|
|
40
|
+
import { z } from 'zod';
|
|
41
|
+
import { getCleoDirAbsolute, resolveOrCwd } from '../paths.js';
|
|
42
|
+
import { getProjectDisplayName } from '../project-info.js';
|
|
43
|
+
import { withLock } from '../store/file-utils.js';
|
|
44
|
+
import { Http, NexusError } from './http.js';
|
|
45
|
+
import { NexusAccountError, requireNexusSession, resolveNexusApiUrl, } from './nexus-auth.js';
|
|
46
|
+
import { FileNexusTokenStore } from './nexus-credentials.js';
|
|
47
|
+
import { registerProject } from './projects.js';
|
|
48
|
+
/** File name of the binding, inside the project's `.cleo/` directory. */
|
|
49
|
+
export const NEXUS_LINK_FILE = 'nexus-link.json';
|
|
50
|
+
/** Longest label the server accepts (`RegisterProjectRequest.label`). */
|
|
51
|
+
export const NEXUS_LABEL_MAX = 120;
|
|
52
|
+
const linkSchema = z.object({
|
|
53
|
+
apiUrl: z.string(),
|
|
54
|
+
localProjectId: z.string(),
|
|
55
|
+
remoteProjectId: z.string(),
|
|
56
|
+
organizationId: z.string(),
|
|
57
|
+
label: z.string().nullable(),
|
|
58
|
+
streamId: z.string(),
|
|
59
|
+
linkedAt: z.string(),
|
|
60
|
+
});
|
|
61
|
+
const linkFileSchema = z.object({
|
|
62
|
+
version: z.literal(1),
|
|
63
|
+
links: z.record(z.string(), linkSchema),
|
|
64
|
+
});
|
|
65
|
+
/**
|
|
66
|
+
* Path separators and their look-alikes: `/`, `\`, fullwidth / \, division
|
|
67
|
+
* slash ∕, set minus ∖, fraction slash ⁄, big solidi ⧸ ⧹, small reverse
|
|
68
|
+
* solidus ﹨. Plus C0/C1 control characters.
|
|
69
|
+
*/
|
|
70
|
+
const LABEL_FORBIDDEN = /[/\\\uFF0F\uFF3C\u2215\u2216\u2044\u29F8\u29F9\uFE68\u0000-\u001f\u007f-\u009f]/;
|
|
71
|
+
/** The OS account name, or `null` when the platform cannot say. */
|
|
72
|
+
function osUsername() {
|
|
73
|
+
try {
|
|
74
|
+
return userInfo().username || null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validate a project label: 1-120 characters; no path separator or look-alike
|
|
82
|
+
* slash, no drive letter (`C:`), no leading `~`, no control characters; and
|
|
83
|
+
* not the OS username, which would leak the account name. A label is a name,
|
|
84
|
+
* never a path.
|
|
85
|
+
*
|
|
86
|
+
* @param raw - Candidate label.
|
|
87
|
+
* @returns The trimmed label.
|
|
88
|
+
* @throws {NexusAccountError} `E_NEXUS_INVALID_LABEL`.
|
|
89
|
+
*/
|
|
90
|
+
export function validateNexusProjectLabel(raw) {
|
|
91
|
+
const label = raw.trim();
|
|
92
|
+
const pathLike = LABEL_FORBIDDEN.test(label) || label.startsWith('~') || /^[A-Za-z]:/.test(label);
|
|
93
|
+
if (!label || label.length > NEXUS_LABEL_MAX || pathLike) {
|
|
94
|
+
throw new NexusAccountError('E_NEXUS_INVALID_LABEL', `invalid project label "${label}": use 1-${NEXUS_LABEL_MAX} characters with no slash or backslash (or look-alike), drive letter or leading "~" (a name, not a path)`, 'pass `--label <name>`');
|
|
95
|
+
}
|
|
96
|
+
const username = osUsername();
|
|
97
|
+
if (username !== null && label.toLowerCase() === username.toLowerCase()) {
|
|
98
|
+
throw new NexusAccountError('E_NEXUS_INVALID_LABEL', 'the project label equals your OS username, which would reveal it to the server', 'pass `--label <name>` with a different name');
|
|
99
|
+
}
|
|
100
|
+
return label;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The label to send: `--label`, else the project's display name. A project
|
|
104
|
+
* rooted at the home directory has no meaningful name (its basename is the
|
|
105
|
+
* account name), so it must be labelled explicitly.
|
|
106
|
+
*/
|
|
107
|
+
function resolveLinkLabel(projectRoot, explicit) {
|
|
108
|
+
if (explicit !== undefined)
|
|
109
|
+
return validateNexusProjectLabel(explicit);
|
|
110
|
+
if (resolve(projectRoot) === resolve(homedir())) {
|
|
111
|
+
throw new NexusAccountError('E_NEXUS_INVALID_LABEL', 'this project is your home directory; its name would reveal your account name', 'pass `--label <name>`');
|
|
112
|
+
}
|
|
113
|
+
return validateNexusProjectLabel(getProjectDisplayName(projectRoot));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Path of the binding file for a project.
|
|
117
|
+
*
|
|
118
|
+
* @param projectRoot - Project root.
|
|
119
|
+
* @returns `<project>/.cleo/nexus-link.json`.
|
|
120
|
+
*/
|
|
121
|
+
export function nexusLinkPath(projectRoot) {
|
|
122
|
+
return join(getCleoDirAbsolute(projectRoot), NEXUS_LINK_FILE);
|
|
123
|
+
}
|
|
124
|
+
/** Read the binding file; missing or malformed reads as empty. */
|
|
125
|
+
function readLinkFile(path) {
|
|
126
|
+
try {
|
|
127
|
+
const parsed = linkFileSchema.safeParse(JSON.parse(readFileSync(path, 'utf-8')));
|
|
128
|
+
if (parsed.success)
|
|
129
|
+
return parsed.data;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
/* missing or unreadable */
|
|
133
|
+
}
|
|
134
|
+
return { version: 1, links: {} };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The stored binding for a project and origin, if any.
|
|
138
|
+
*
|
|
139
|
+
* @param projectRoot - Project root.
|
|
140
|
+
* @param apiUrl - API URL (any URL on the origin).
|
|
141
|
+
* @returns The binding, or `null`.
|
|
142
|
+
*/
|
|
143
|
+
export function readNexusProjectLink(projectRoot, apiUrl) {
|
|
144
|
+
return readLinkFile(nexusLinkPath(projectRoot)).links[new URL(apiUrl).origin] ?? null;
|
|
145
|
+
}
|
|
146
|
+
/** Map an API failure to a Nexus error; a 401 means the session expired. */
|
|
147
|
+
function toLinkError(err) {
|
|
148
|
+
if (err instanceof NexusError) {
|
|
149
|
+
if (err.status === 401) {
|
|
150
|
+
return new NexusAccountError('E_NEXUS_SESSION_EXPIRED', 'the Nexus session expired or was revoked', 'run `cleo login nexus` again');
|
|
151
|
+
}
|
|
152
|
+
const remedy = typeof err.details?.['remedy'] === 'string' ? err.details['remedy'] : undefined;
|
|
153
|
+
return new NexusAccountError('E_NEXUS_REQUEST_FAILED', err.message, remedy);
|
|
154
|
+
}
|
|
155
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Register the project with Nexus (label only, never a path) and persist the
|
|
159
|
+
* binding in `.cleo/nexus-link.json`. Idempotent.
|
|
160
|
+
*
|
|
161
|
+
* @param opts - Project root, label, API URL, store and test overrides.
|
|
162
|
+
* @returns The binding and whether it already existed.
|
|
163
|
+
* @throws {NexusAccountError} Not signed in, expired session, invalid label,
|
|
164
|
+
* not a CLEO project, or an API refusal (e.g. the id belongs to another account).
|
|
165
|
+
*/
|
|
166
|
+
export async function linkProjectToNexus(opts = {}) {
|
|
167
|
+
const apiUrl = resolveNexusApiUrl(opts.apiUrl);
|
|
168
|
+
const store = opts.store ?? new FileNexusTokenStore();
|
|
169
|
+
const session = await requireNexusSession(apiUrl, store);
|
|
170
|
+
let projectRoot;
|
|
171
|
+
try {
|
|
172
|
+
projectRoot = resolveOrCwd(opts.projectRoot);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
throw new NexusAccountError('E_NEXUS_NOT_A_PROJECT', 'not inside a CLEO project', 'run `cleo init` first');
|
|
176
|
+
}
|
|
177
|
+
const identity = readDeclaredProjectIdentity(projectRoot);
|
|
178
|
+
if (!identity) {
|
|
179
|
+
throw new NexusAccountError('E_NEXUS_NOT_A_PROJECT', 'this project has no project id (.cleo/project-id)', 'run `cleo init` or `cleo upgrade` to assign one');
|
|
180
|
+
}
|
|
181
|
+
const projectId = identity.projectId;
|
|
182
|
+
const label = resolveLinkLabel(projectRoot, opts.label);
|
|
183
|
+
const http = new Http({
|
|
184
|
+
baseUrl: apiUrl,
|
|
185
|
+
token: session.bearer(),
|
|
186
|
+
...(opts.fetch ? { fetch: opts.fetch } : {}),
|
|
187
|
+
});
|
|
188
|
+
let registered;
|
|
189
|
+
try {
|
|
190
|
+
registered = await registerProject(http, { projectId, label });
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
throw toLinkError(err);
|
|
194
|
+
}
|
|
195
|
+
const linkPath = nexusLinkPath(projectRoot);
|
|
196
|
+
const link = {
|
|
197
|
+
apiUrl,
|
|
198
|
+
localProjectId: projectId,
|
|
199
|
+
remoteProjectId: registered.project.projectId,
|
|
200
|
+
organizationId: registered.project.organizationId,
|
|
201
|
+
label: registered.project.label,
|
|
202
|
+
streamId: registered.streamId,
|
|
203
|
+
linkedAt: new Date().toISOString(),
|
|
204
|
+
};
|
|
205
|
+
// Locked read-modify-write: concurrent links (other origins, other shells)
|
|
206
|
+
// never drop each other's entries. withLock needs a parseable file to read,
|
|
207
|
+
// so seed an empty one exclusively ('wx') when there is none.
|
|
208
|
+
try {
|
|
209
|
+
writeFileSync(linkPath, `${JSON.stringify({ version: 1, links: {} })}\n`, { flag: 'wx' });
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
if (!(err instanceof Error && 'code' in err && err.code === 'EEXIST'))
|
|
213
|
+
throw err;
|
|
214
|
+
}
|
|
215
|
+
await withLock(linkPath, (current) => {
|
|
216
|
+
const parsed = linkFileSchema.safeParse(current);
|
|
217
|
+
const links = parsed.success ? parsed.data.links : {};
|
|
218
|
+
return { version: 1, links: { ...links, [apiUrl]: link } };
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
link,
|
|
222
|
+
alreadyLinked: !registered.created,
|
|
223
|
+
linkPath,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=nexus-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nexus-link.js","sourceRoot":"","sources":["../../src/cloud/nexus-link.ts"],"names":[],"mappings":"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"}
|