@cleocode/core 2026.9.26 → 2026.10.2
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/build-provenance.json +2 -2
- package/dist/cloud/journal.d.ts +9 -5
- package/dist/cloud/journal.d.ts.map +1 -1
- package/dist/cloud/journal.js +29 -8
- package/dist/cloud/journal.js.map +1 -1
- package/dist/cloud/manifest-check.d.ts +140 -4
- package/dist/cloud/manifest-check.d.ts.map +1 -1
- package/dist/cloud/manifest-check.js +309 -10
- package/dist/cloud/manifest-check.js.map +1 -1
- package/dist/cloud/nexus-attach.d.ts +119 -0
- package/dist/cloud/nexus-attach.d.ts.map +1 -0
- package/dist/cloud/nexus-attach.js +267 -0
- package/dist/cloud/nexus-attach.js.map +1 -0
- package/dist/cloud/nexus-auth.d.ts +15 -3
- package/dist/cloud/nexus-auth.d.ts.map +1 -1
- package/dist/cloud/nexus-auth.js +90 -6
- package/dist/cloud/nexus-auth.js.map +1 -1
- package/dist/cloud/nexus-cloud-activity.d.ts +37 -0
- package/dist/cloud/nexus-cloud-activity.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud-activity.js +79 -0
- package/dist/cloud/nexus-cloud-activity.js.map +1 -0
- package/dist/cloud/nexus-cloud-status.d.ts +132 -0
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud-status.js +476 -0
- package/dist/cloud/nexus-cloud-status.js.map +1 -0
- package/dist/cloud/nexus-cloud.d.ts +179 -0
- package/dist/cloud/nexus-cloud.d.ts.map +1 -0
- package/dist/cloud/nexus-cloud.js +296 -0
- package/dist/cloud/nexus-cloud.js.map +1 -0
- package/dist/cloud/nexus-device.d.ts +32 -7
- package/dist/cloud/nexus-device.d.ts.map +1 -1
- package/dist/cloud/nexus-device.js +54 -7
- package/dist/cloud/nexus-device.js.map +1 -1
- package/dist/cloud/nexus-enrol.d.ts +35 -4
- package/dist/cloud/nexus-enrol.d.ts.map +1 -1
- package/dist/cloud/nexus-enrol.js +192 -47
- package/dist/cloud/nexus-enrol.js.map +1 -1
- package/dist/cloud/nexus-home.d.ts +74 -0
- package/dist/cloud/nexus-home.d.ts.map +1 -0
- package/dist/cloud/nexus-home.js +97 -0
- package/dist/cloud/nexus-home.js.map +1 -0
- package/dist/cloud/nexus-link.d.ts +8 -1
- package/dist/cloud/nexus-link.d.ts.map +1 -1
- package/dist/cloud/nexus-link.js +138 -11
- package/dist/cloud/nexus-link.js.map +1 -1
- package/dist/cloud/nexus-logout.d.ts +114 -0
- package/dist/cloud/nexus-logout.d.ts.map +1 -0
- package/dist/cloud/nexus-logout.js +429 -0
- package/dist/cloud/nexus-logout.js.map +1 -0
- package/dist/cloud/nexus-vault-keys.d.ts +129 -0
- package/dist/cloud/nexus-vault-keys.d.ts.map +1 -0
- package/dist/cloud/nexus-vault-keys.js +277 -0
- package/dist/cloud/nexus-vault-keys.js.map +1 -0
- package/dist/cloud/nexus-vault-state.d.ts +121 -0
- package/dist/cloud/nexus-vault-state.d.ts.map +1 -0
- package/dist/cloud/nexus-vault-state.js +274 -0
- package/dist/cloud/nexus-vault-state.js.map +1 -0
- package/dist/cloud/nexus-vault.d.ts +160 -0
- package/dist/cloud/nexus-vault.d.ts.map +1 -0
- package/dist/cloud/nexus-vault.js +1733 -0
- package/dist/cloud/nexus-vault.js.map +1 -0
- package/dist/cloud/signing.d.ts +24 -8
- package/dist/cloud/signing.d.ts.map +1 -1
- package/dist/cloud/signing.js +61 -15
- package/dist/cloud/signing.js.map +1 -1
- package/dist/docs/export-document.js +8341 -3317
- package/dist/docs/export-document.js.map +3 -3
- package/dist/doctor/migrations.d.ts +75 -0
- package/dist/doctor/migrations.d.ts.map +1 -0
- package/dist/doctor/migrations.js +136 -0
- package/dist/doctor/migrations.js.map +1 -0
- package/dist/doctor/sync-sealer.d.ts +48 -0
- package/dist/doctor/sync-sealer.d.ts.map +1 -0
- package/dist/doctor/sync-sealer.js +109 -0
- package/dist/doctor/sync-sealer.js.map +1 -0
- package/dist/doctor/sync-triggers.d.ts +53 -0
- package/dist/doctor/sync-triggers.d.ts.map +1 -0
- package/dist/doctor/sync-triggers.js +157 -0
- package/dist/doctor/sync-triggers.js.map +1 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +5 -1
- package/dist/init.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/llm/plugin-facade.js +8668 -3644
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/nexus/projects-clean.d.ts +3 -0
- package/dist/nexus/projects-clean.d.ts.map +1 -1
- package/dist/nexus/projects-clean.js +9 -3
- package/dist/nexus/projects-clean.js.map +1 -1
- package/dist/nexus/registry-roots.d.ts +3 -1
- package/dist/nexus/registry-roots.d.ts.map +1 -1
- package/dist/nexus/registry-roots.js +5 -2
- package/dist/nexus/registry-roots.js.map +1 -1
- package/dist/nexus/registry.d.ts +8 -1
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +24 -10
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/workspace.d.ts +4 -1
- package/dist/nexus/workspace.d.ts.map +1 -1
- package/dist/nexus/workspace.js +10 -4
- package/dist/nexus/workspace.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +7 -2
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestrate/worker-verify.d.ts +121 -12
- package/dist/orchestrate/worker-verify.d.ts.map +1 -1
- package/dist/orchestrate/worker-verify.js +172 -21
- package/dist/orchestrate/worker-verify.js.map +1 -1
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +15 -9
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/release/ci-evidence.d.ts +9 -0
- package/dist/release/ci-evidence.d.ts.map +1 -1
- package/dist/release/ci-evidence.js +9 -2
- package/dist/release/ci-evidence.js.map +1 -1
- package/dist/resources/backend.d.ts +15 -3
- package/dist/resources/backend.d.ts.map +1 -1
- package/dist/resources/backend.js +7 -3
- package/dist/resources/backend.js.map +1 -1
- package/dist/resources/darwin-backend.d.ts +142 -0
- package/dist/resources/darwin-backend.d.ts.map +1 -0
- package/dist/resources/darwin-backend.js +288 -0
- package/dist/resources/darwin-backend.js.map +1 -0
- package/dist/resources/governor.d.ts +44 -1
- package/dist/resources/governor.d.ts.map +1 -1
- package/dist/resources/governor.js +100 -36
- package/dist/resources/governor.js.map +1 -1
- package/dist/resources/heavy-command.d.ts +132 -0
- package/dist/resources/heavy-command.d.ts.map +1 -0
- package/dist/resources/heavy-command.js +768 -0
- package/dist/resources/heavy-command.js.map +1 -0
- package/dist/resources/monitor.d.ts +50 -1
- package/dist/resources/monitor.d.ts.map +1 -1
- package/dist/resources/monitor.js +83 -1
- package/dist/resources/monitor.js.map +1 -1
- package/dist/resources/run-admission.d.ts +303 -0
- package/dist/resources/run-admission.d.ts.map +1 -0
- package/dist/resources/run-admission.js +648 -0
- package/dist/resources/run-admission.js.map +1 -0
- package/dist/resources/run-class.d.ts +111 -0
- package/dist/resources/run-class.d.ts.map +1 -0
- package/dist/resources/run-class.js +658 -0
- package/dist/resources/run-class.js.map +1 -0
- package/dist/resources/run-governed.d.ts +158 -0
- package/dist/resources/run-governed.d.ts.map +1 -0
- package/dist/resources/run-governed.js +406 -0
- package/dist/resources/run-governed.js.map +1 -0
- package/dist/resources/slot-holder.d.ts +267 -0
- package/dist/resources/slot-holder.d.ts.map +1 -0
- package/dist/resources/slot-holder.js +505 -0
- package/dist/resources/slot-holder.js.map +1 -0
- package/dist/resources/tool-groups.d.ts +74 -0
- package/dist/resources/tool-groups.d.ts.map +1 -0
- package/dist/resources/tool-groups.js +118 -0
- package/dist/resources/tool-groups.js.map +1 -0
- package/dist/routing/build-command-groups.d.ts.map +1 -1
- package/dist/routing/build-command-groups.js +1 -0
- package/dist/routing/build-command-groups.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +8676 -3652
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sentient/cross-project-hygiene.d.ts +3 -2
- package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
- package/dist/sentient/cross-project-hygiene.js +5 -2
- package/dist/sentient/cross-project-hygiene.js.map +1 -1
- package/dist/sentient/state.d.ts +7 -0
- package/dist/sentient/state.d.ts.map +1 -1
- package/dist/sentient/state.js.map +1 -1
- package/dist/sentient/tick.d.ts +14 -2
- package/dist/sentient/tick.d.ts.map +1 -1
- package/dist/sentient/tick.js +63 -4
- package/dist/sentient/tick.js.map +1 -1
- package/dist/setup/sections/nexus-account.d.ts +8 -6
- package/dist/setup/sections/nexus-account.d.ts.map +1 -1
- package/dist/setup/sections/nexus-account.js +53 -9
- package/dist/setup/sections/nexus-account.js.map +1 -1
- package/dist/store/backup-recover.d.ts.map +1 -1
- package/dist/store/backup-recover.js +5 -0
- package/dist/store/backup-recover.js.map +1 -1
- package/dist/store/data-accessor.d.ts +1 -0
- package/dist/store/data-accessor.d.ts.map +1 -1
- package/dist/store/data-accessor.js +7 -0
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +23 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +126 -36
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/recovery.d.ts.map +1 -1
- package/dist/store/exodus/recovery.js +15 -0
- package/dist/store/exodus/recovery.js.map +1 -1
- package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
- package/dist/store/legacy-tasks-lineage.js +5 -0
- package/dist/store/legacy-tasks-lineage.js.map +1 -1
- package/dist/store/lock.d.ts +8 -1
- package/dist/store/lock.d.ts.map +1 -1
- package/dist/store/lock.js +10 -2
- package/dist/store/lock.js.map +1 -1
- package/dist/store/migration-manager.d.ts +5 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +11 -0
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/migration-runner.d.ts +158 -0
- package/dist/store/migration-runner.d.ts.map +1 -0
- package/dist/store/migration-runner.js +493 -0
- package/dist/store/migration-runner.js.map +1 -0
- package/dist/store/portable-bundle-import.d.ts +15 -1
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +24 -4
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-relocate.d.ts +43 -0
- package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
- package/dist/store/portable-bundle-relocate.js +79 -5
- package/dist/store/portable-bundle-relocate.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts +20 -0
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +38 -3
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts +33 -0
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +34 -7
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/row-identity-registry.d.ts +137 -7
- package/dist/store/row-identity-registry.d.ts.map +1 -1
- package/dist/store/row-identity-registry.js +364 -9
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/row-identity.d.ts.map +1 -1
- package/dist/store/row-identity.js +9 -10
- package/dist/store/row-identity.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +10 -0
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.d.ts +31 -0
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +5 -1
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/sync/capture.d.ts +203 -0
- package/dist/store/sync/capture.d.ts.map +1 -0
- package/dist/store/sync/capture.js +562 -0
- package/dist/store/sync/capture.js.map +1 -0
- package/dist/store/sync/clock-store.d.ts.map +1 -1
- package/dist/store/sync/clock-store.js +2 -0
- package/dist/store/sync/clock-store.js.map +1 -1
- package/dist/store/sync/fk-orphans.d.ts +133 -0
- package/dist/store/sync/fk-orphans.d.ts.map +1 -0
- package/dist/store/sync/fk-orphans.js +265 -0
- package/dist/store/sync/fk-orphans.js.map +1 -0
- package/dist/store/sync/flags.d.ts +7 -0
- package/dist/store/sync/flags.d.ts.map +1 -1
- package/dist/store/sync/flags.js +16 -0
- package/dist/store/sync/flags.js.map +1 -1
- package/dist/store/sync/hlc.d.ts.map +1 -1
- package/dist/store/sync/hlc.js +4 -0
- package/dist/store/sync/hlc.js.map +1 -1
- package/dist/store/sync/identity-fill.d.ts +45 -0
- package/dist/store/sync/identity-fill.d.ts.map +1 -0
- package/dist/store/sync/identity-fill.js +85 -0
- package/dist/store/sync/identity-fill.js.map +1 -0
- package/dist/store/sync/machinery.d.ts +27 -0
- package/dist/store/sync/machinery.d.ts.map +1 -0
- package/dist/store/sync/machinery.js +44 -0
- package/dist/store/sync/machinery.js.map +1 -0
- package/dist/store/sync/netting.d.ts +120 -0
- package/dist/store/sync/netting.d.ts.map +1 -0
- package/dist/store/sync/netting.js +336 -0
- package/dist/store/sync/netting.js.map +1 -0
- package/dist/store/sync/replica.d.ts +59 -3
- package/dist/store/sync/replica.d.ts.map +1 -1
- package/dist/store/sync/replica.js +84 -3
- package/dist/store/sync/replica.js.map +1 -1
- package/dist/store/sync/schema.d.ts +18 -3
- package/dist/store/sync/schema.d.ts.map +1 -1
- package/dist/store/sync/schema.js +27 -3
- package/dist/store/sync/schema.js.map +1 -1
- package/dist/store/sync/seal-backlog.d.ts +21 -0
- package/dist/store/sync/seal-backlog.d.ts.map +1 -0
- package/dist/store/sync/seal-backlog.js +24 -0
- package/dist/store/sync/seal-backlog.js.map +1 -0
- package/dist/store/sync/sealer-values.d.ts +34 -0
- package/dist/store/sync/sealer-values.d.ts.map +1 -0
- package/dist/store/sync/sealer-values.js +53 -0
- package/dist/store/sync/sealer-values.js.map +1 -0
- package/dist/store/sync/sealer.d.ts +145 -0
- package/dist/store/sync/sealer.d.ts.map +1 -0
- package/dist/store/sync/sealer.js +906 -0
- package/dist/store/sync/sealer.js.map +1 -0
- package/dist/store/sync/structural.d.ts +63 -0
- package/dist/store/sync/structural.d.ts.map +1 -0
- package/dist/store/sync/structural.js +180 -0
- package/dist/store/sync/structural.js.map +1 -0
- package/dist/store/sync/timestamps.d.ts +92 -0
- package/dist/store/sync/timestamps.d.ts.map +1 -0
- package/dist/store/sync/timestamps.js +228 -0
- package/dist/store/sync/timestamps.js.map +1 -0
- package/dist/store/sync/tombstones.d.ts +75 -0
- package/dist/store/sync/tombstones.d.ts.map +1 -0
- package/dist/store/sync/tombstones.js +103 -0
- package/dist/store/sync/tombstones.js.map +1 -0
- package/dist/store/sync/trigger-classes.d.ts +221 -0
- package/dist/store/sync/trigger-classes.d.ts.map +1 -0
- package/dist/store/sync/trigger-classes.js +441 -0
- package/dist/store/sync/trigger-classes.js.map +1 -0
- package/dist/store/sync/trigger-suspend-at-path.d.ts +23 -0
- package/dist/store/sync/trigger-suspend-at-path.d.ts.map +1 -0
- package/dist/store/sync/trigger-suspend-at-path.js +44 -0
- package/dist/store/sync/trigger-suspend-at-path.js.map +1 -0
- package/dist/store/sync/writer-version.d.ts +43 -0
- package/dist/store/sync/writer-version.d.ts.map +1 -0
- package/dist/store/sync/writer-version.js +90 -0
- package/dist/store/sync/writer-version.js.map +1 -0
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +102 -0
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/trigger-suspend-schema.d.ts +44 -0
- package/dist/store/trigger-suspend-schema.d.ts.map +1 -0
- package/dist/store/trigger-suspend-schema.js +25 -0
- package/dist/store/trigger-suspend-schema.js.map +1 -0
- package/dist/store/vault-manifest.d.ts +365 -0
- package/dist/store/vault-manifest.d.ts.map +1 -0
- package/dist/store/vault-manifest.js +812 -0
- package/dist/store/vault-manifest.js.map +1 -0
- package/dist/store/writer-lease.d.ts +31 -0
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +65 -2
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +21 -0
- package/dist/system/health.js.map +1 -1
- package/dist/system/project-health.d.ts.map +1 -1
- package/dist/system/project-health.js +3 -1
- package/dist/system/project-health.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +58 -0
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +75 -6
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/affected-scope.d.ts +150 -23
- package/dist/tasks/affected-scope.d.ts.map +1 -1
- package/dist/tasks/affected-scope.js +320 -32
- package/dist/tasks/affected-scope.js.map +1 -1
- package/dist/tasks/change-set.d.ts +96 -0
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +169 -4
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/complete-ci.d.ts +115 -0
- package/dist/tasks/complete-ci.d.ts.map +1 -0
- package/dist/tasks/complete-ci.js +171 -0
- package/dist/tasks/complete-ci.js.map +1 -0
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +50 -17
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/compute-task-view.d.ts.map +1 -1
- package/dist/tasks/compute-task-view.js +7 -0
- package/dist/tasks/compute-task-view.js.map +1 -1
- package/dist/tasks/done-plan.d.ts.map +1 -1
- package/dist/tasks/done-plan.js +51 -30
- package/dist/tasks/done-plan.js.map +1 -1
- package/dist/tasks/done-record.d.ts +6 -0
- package/dist/tasks/done-record.d.ts.map +1 -1
- package/dist/tasks/done-record.js +9 -3
- package/dist/tasks/done-record.js.map +1 -1
- package/dist/tasks/evidence.d.ts +3 -2
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +143 -12
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/gate-notes.d.ts +22 -0
- package/dist/tasks/gate-notes.d.ts.map +1 -0
- package/dist/tasks/gate-notes.js +33 -0
- package/dist/tasks/gate-notes.js.map +1 -0
- package/dist/tasks/index.d.ts +2 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +2 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/test-run-binding.d.ts +117 -0
- package/dist/tasks/test-run-binding.d.ts.map +1 -0
- package/dist/tasks/test-run-binding.js +365 -0
- package/dist/tasks/test-run-binding.js.map +1 -0
- package/dist/tasks/tool-cache-env.d.ts +123 -0
- package/dist/tasks/tool-cache-env.d.ts.map +1 -0
- package/dist/tasks/tool-cache-env.js +287 -0
- package/dist/tasks/tool-cache-env.js.map +1 -0
- package/dist/tasks/tool-cache-failed-first.d.ts +155 -0
- package/dist/tasks/tool-cache-failed-first.d.ts.map +1 -0
- package/dist/tasks/tool-cache-failed-first.js +285 -0
- package/dist/tasks/tool-cache-failed-first.js.map +1 -0
- package/dist/tasks/tool-cache.d.ts +375 -55
- package/dist/tasks/tool-cache.d.ts.map +1 -1
- package/dist/tasks/tool-cache.js +912 -303
- package/dist/tasks/tool-cache.js.map +1 -1
- package/dist/tasks/tool-resolver.d.ts +4 -3
- package/dist/tasks/tool-resolver.d.ts.map +1 -1
- package/dist/tasks/tool-resolver.js +15 -4
- package/dist/tasks/tool-resolver.js.map +1 -1
- package/dist/tasks/tool-semaphore.d.ts +67 -7
- package/dist/tasks/tool-semaphore.d.ts.map +1 -1
- package/dist/tasks/tool-semaphore.js +134 -56
- package/dist/tasks/tool-semaphore.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +4 -0
- package/dist/upgrade.js.map +1 -1
- package/dist/validation/engine-ops.d.ts +6 -0
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +8 -0
- package/dist/validation/engine-ops.js.map +1 -1
- package/migrations/drizzle-cleo-project/20260930170000_t12819-trigger-suspend-clause/migration.sql +367 -0
- package/migrations/sync-journal/20260930120000_t12343-capture/migration.sql +47 -0
- package/migrations/sync-journal/20261001170000_t12984-sealer/migration.sql +101 -0
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +5 -5
- package/templates/CLEO-REFERENCE.md +8 -4
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleo Nexus device logout: `cleo logout nexus [--revoke]` with device
|
|
3
|
+
* credentials (cleo-nexus device contract §3.5, review M3, T12844).
|
|
4
|
+
*
|
|
5
|
+
* A logout never reports success while a credential may still be live:
|
|
6
|
+
*
|
|
7
|
+
* 1. Under the lock, the live credentials move into `pendingSignOut`
|
|
8
|
+
* (`--revoke`: `pendingRevoke`), newest first: `pending`, then `current`
|
|
9
|
+
* ({@link applyBeginSignOut}, {@link applyBeginRevoke}). From then on they
|
|
10
|
+
* are used for nothing but that request. The lock is released.
|
|
11
|
+
* 2. E9 (`POST /v1/devices/self/sign-out`) or E10 (`DELETE /v1/devices/self`)
|
|
12
|
+
* is sent with each credential in turn, newest first, with one attempt and
|
|
13
|
+
* a {@link NEXUS_REVOKE_TIMEOUT_MS} timeout.
|
|
14
|
+
* 3. Done means proved: 200, or a 401 whose reason proves the device state
|
|
15
|
+
* (`device-signed-out`, `device-revoked`, or `credential-revoked` with
|
|
16
|
+
* `revokedReason` `signed-out` / `revoked`). A revoke needs proof of a
|
|
17
|
+
* revoke; a signed-out device is not a revoked one. Any other 401 means
|
|
18
|
+
* that credential is dead, so the next one is tried. A network error,
|
|
19
|
+
* timeout, 429, 5xx or a route the server does not have yet stops the run:
|
|
20
|
+
* the slot is kept and every remaining request is left for the next run
|
|
21
|
+
* without another call.
|
|
22
|
+
* 4. The lock is re-taken and the slot is changed only if it still holds the
|
|
23
|
+
* credential that was answered (compare-and-swap):
|
|
24
|
+
* - a sign-out (confirmed, or every credential dead) clears
|
|
25
|
+
* `pendingSignOut` and keeps the device keys for the next login;
|
|
26
|
+
* - a revoke that ended (confirmed, found the device signed out, or every
|
|
27
|
+
* credential dead) forgets the device locally ({@link applyForgetDevice}),
|
|
28
|
+
* so no later login re-activates the id the user asked to burn. The
|
|
29
|
+
* entry is deleted, or kept stripped while `retired` requests of other
|
|
30
|
+
* devices remain; the store keeps the file while other entries remain.
|
|
31
|
+
* Only a confirmed request is reported `confirmed`; the others name the
|
|
32
|
+
* web remedy.
|
|
33
|
+
*
|
|
34
|
+
* Unsettled slots, and the `retired` requests of replaced devices, are
|
|
35
|
+
* retried by every later logout and, best effort with a shorter timeout, by
|
|
36
|
+
* `cleo login nexus` and `cleo project link` ({@link retryNexusDeviceEnds}).
|
|
37
|
+
* Retired requests are sent before the entry's own request.
|
|
38
|
+
*
|
|
39
|
+
* No function here logs, and no result or error carries a token.
|
|
40
|
+
*
|
|
41
|
+
* @task T12870
|
|
42
|
+
* @epic T12323
|
|
43
|
+
*/
|
|
44
|
+
import { z } from 'zod';
|
|
45
|
+
import { Http, NexusError } from './http.js';
|
|
46
|
+
import { logoutFromNexus, NEXUS_REVOKE_TIMEOUT_MS, resolveNexusApiUrl } from './nexus-auth.js';
|
|
47
|
+
import { FileNexusTokenStore, nexusOriginKey } from './nexus-credentials.js';
|
|
48
|
+
import { applyBeginRevoke, applyBeginSignOut, applyForgetDevice, applyRetiredSettled, applySignOutConfirmed, isForgottenDevice, NexusDeviceStore, UnreadableNexusDevice, } from './nexus-device.js';
|
|
49
|
+
/**
|
|
50
|
+
* Timeout of each E9/E10 call when a login or a link only retries on the way
|
|
51
|
+
* ({@link retryNexusDeviceEnds}); an explicit logout uses {@link NEXUS_REVOKE_TIMEOUT_MS}.
|
|
52
|
+
*/
|
|
53
|
+
export const NEXUS_END_RETRY_TIMEOUT_MS = 2_000;
|
|
54
|
+
function context(opts) {
|
|
55
|
+
const apiUrl = resolveNexusApiUrl(opts.apiUrl);
|
|
56
|
+
return {
|
|
57
|
+
apiUrl,
|
|
58
|
+
origin: nexusOriginKey(apiUrl),
|
|
59
|
+
fetch: opts.fetch ?? ((input, init) => globalThis.fetch(input, init)),
|
|
60
|
+
devices: opts.deviceStore ?? new NexusDeviceStore(),
|
|
61
|
+
now: opts.now ?? (() => new Date()),
|
|
62
|
+
timeoutMs: opts.timeoutMs ?? NEXUS_REVOKE_TIMEOUT_MS,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** E9 answers `{ deviceId, state }`; E10 answers `{ revoked }`. Only the status matters. */
|
|
66
|
+
const endAnswerSchema = z.looseObject({});
|
|
67
|
+
/**
|
|
68
|
+
* What a 401 proves about the device (§4.0.4): `revoked`, `signed-out`, or
|
|
69
|
+
* nothing (`null`: only this credential is dead).
|
|
70
|
+
*/
|
|
71
|
+
function provenState(details) {
|
|
72
|
+
const reason = details?.['reason'];
|
|
73
|
+
const revokedReason = details?.['revokedReason'];
|
|
74
|
+
if (reason === 'device-revoked')
|
|
75
|
+
return 'revoked';
|
|
76
|
+
if (reason === 'device-signed-out')
|
|
77
|
+
return 'signed-out';
|
|
78
|
+
if (reason === 'credential-revoked' && revokedReason === 'revoked')
|
|
79
|
+
return 'revoked';
|
|
80
|
+
if (reason === 'credential-revoked' && revokedReason === 'signed-out')
|
|
81
|
+
return 'signed-out';
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Send E9 or E10 with one credential: one attempt, a plain timeout, no lock held.
|
|
86
|
+
*
|
|
87
|
+
* @returns `done` for 200 or a 401 that proves the requested state,
|
|
88
|
+
* `signed-out` for a revoke that proves only a sign-out, `stale` for any
|
|
89
|
+
* other 401, `unanswered` for everything else, with the reason in `detail`.
|
|
90
|
+
*/
|
|
91
|
+
async function callEnd(ctx, action, token) {
|
|
92
|
+
const timed = (input, init) => ctx.fetch(input, { ...init, signal: AbortSignal.timeout(ctx.timeoutMs) });
|
|
93
|
+
const http = new Http({ baseUrl: ctx.apiUrl, token, fetch: timed, maxAttempts: 1 });
|
|
94
|
+
try {
|
|
95
|
+
if (action === 'sign-out') {
|
|
96
|
+
await http.request('POST', '/v1/devices/self/sign-out', endAnswerSchema, {});
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
await http.request('DELETE', '/v1/devices/self', endAnswerSchema);
|
|
100
|
+
}
|
|
101
|
+
return { answer: 'done', detail: 'HTTP 200' };
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
if (!(err instanceof NexusError)) {
|
|
105
|
+
return {
|
|
106
|
+
answer: 'unanswered',
|
|
107
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
108
|
+
transport: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (err.status === 401) {
|
|
112
|
+
const reason = err.details?.['reason'];
|
|
113
|
+
const detail = `HTTP 401 ${typeof reason === 'string' ? reason : err.code}`;
|
|
114
|
+
const state = provenState(err.details);
|
|
115
|
+
if (state === 'revoked' || (state === 'signed-out' && action === 'sign-out')) {
|
|
116
|
+
return { answer: 'done', detail };
|
|
117
|
+
}
|
|
118
|
+
if (state === 'signed-out')
|
|
119
|
+
return { answer: 'signed-out', detail };
|
|
120
|
+
// Only the Nexus API's own verdict on this credential counts as dead. A
|
|
121
|
+
// 401 without its envelope (a proxy or SSO gateway) or with reason
|
|
122
|
+
// `missing` (an Authorization header stripped on the way) proves
|
|
123
|
+
// nothing about the credential, so it is treated as no answer.
|
|
124
|
+
const dead = err.code === 'E_UNAUTHENTICATED' &&
|
|
125
|
+
(reason === 'invalid' ||
|
|
126
|
+
reason === 'credential-expired' ||
|
|
127
|
+
reason === 'credential-revoked');
|
|
128
|
+
return { answer: dead ? 'stale' : 'unanswered', detail };
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
answer: 'unanswered',
|
|
132
|
+
detail: err.code === 'E_NETWORK' ? 'no answer' : `HTTP ${err.status} ${err.code}`,
|
|
133
|
+
transport: err.code === 'E_NETWORK',
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** Every unsettled request of one entry: its `retired` items first, then its own slot. */
|
|
138
|
+
function requestsOf(userId, entry) {
|
|
139
|
+
const out = [];
|
|
140
|
+
for (const r of entry.retired ?? []) {
|
|
141
|
+
out.push({
|
|
142
|
+
userId,
|
|
143
|
+
deviceId: r.deviceId,
|
|
144
|
+
action: r.kind,
|
|
145
|
+
retired: true,
|
|
146
|
+
credentials: r.credentials,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const own = entry.pendingRevoke ?? entry.pendingSignOut;
|
|
150
|
+
if (own) {
|
|
151
|
+
out.push({
|
|
152
|
+
userId,
|
|
153
|
+
deviceId: entry.deviceId,
|
|
154
|
+
action: entry.pendingRevoke ? 'revoke' : 'sign-out',
|
|
155
|
+
retired: false,
|
|
156
|
+
credentials: own.credentials,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
/** The credentials a request's slot holds now, or `null` when the slot is gone. */
|
|
162
|
+
function slotNow(entry, req) {
|
|
163
|
+
if (entry === null)
|
|
164
|
+
return null;
|
|
165
|
+
if (req.retired) {
|
|
166
|
+
const item = (entry.retired ?? []).find((r) => r.deviceId === req.deviceId && r.kind === req.action);
|
|
167
|
+
return item ? item.credentials : null;
|
|
168
|
+
}
|
|
169
|
+
if (entry.deviceId !== req.deviceId)
|
|
170
|
+
return null;
|
|
171
|
+
const slot = req.action === 'revoke' ? entry.pendingRevoke : entry.pendingSignOut;
|
|
172
|
+
return slot ? slot.credentials : null;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* End a request under the lock, only if its slot still holds `token` (CAS):
|
|
176
|
+
* clear a sign-out slot, settle a retired item, or forget the device after a
|
|
177
|
+
* revoke. An entry left with nothing to keep is deleted.
|
|
178
|
+
*/
|
|
179
|
+
async function settleEnded(ctx, req, token) {
|
|
180
|
+
return ctx.devices.update((tx) => {
|
|
181
|
+
const entry = tx.get(ctx.apiUrl, req.userId);
|
|
182
|
+
const creds = slotNow(entry, req);
|
|
183
|
+
if (entry === null || creds === null || !creds.some((c) => c.token === token)) {
|
|
184
|
+
return { applied: false, removed: false };
|
|
185
|
+
}
|
|
186
|
+
const next = req.retired
|
|
187
|
+
? applyRetiredSettled(entry, req.deviceId, req.action)
|
|
188
|
+
: req.action === 'sign-out'
|
|
189
|
+
? applySignOutConfirmed(entry)
|
|
190
|
+
: applyForgetDevice(entry);
|
|
191
|
+
if (isForgottenDevice(next)) {
|
|
192
|
+
const removed = tx.delete(ctx.apiUrl, req.userId, {
|
|
193
|
+
deviceId: entry.deviceId,
|
|
194
|
+
credentialId: entry.current?.credentialId ?? null,
|
|
195
|
+
});
|
|
196
|
+
return { applied: true, removed };
|
|
197
|
+
}
|
|
198
|
+
tx.set(ctx.apiUrl, req.userId, next);
|
|
199
|
+
return { applied: true, removed: false };
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/** Try each credential of one request, newest first, and end it when it can be ended. */
|
|
203
|
+
async function settleRequest(ctx, req, warnings) {
|
|
204
|
+
const row = (outcome, removedLocally = false) => ({
|
|
205
|
+
userId: req.userId,
|
|
206
|
+
deviceId: req.deviceId,
|
|
207
|
+
action: req.action,
|
|
208
|
+
retired: req.retired,
|
|
209
|
+
outcome,
|
|
210
|
+
removedLocally,
|
|
211
|
+
});
|
|
212
|
+
const what = `${req.action === 'revoke' ? 'revoke' : 'sign-out'} of device ${req.deviceId}`;
|
|
213
|
+
const web = req.action === 'revoke'
|
|
214
|
+
? `revoke device ${req.deviceId} on cleocode.dev (Devices)`
|
|
215
|
+
: `sign out or revoke device ${req.deviceId} on cleocode.dev (Devices)`;
|
|
216
|
+
const end = async (token, outcome, note) => {
|
|
217
|
+
const settled = await settleEnded(ctx, req, token);
|
|
218
|
+
if (!settled.applied) {
|
|
219
|
+
warnings.push(`${what}: the local entry changed while the request was in flight (a login or another logout?); this machine may hold a newer credential. Run \`cleo logout nexus${req.action === 'revoke' ? ' --revoke' : ''}\` again`);
|
|
220
|
+
}
|
|
221
|
+
else if (note !== null) {
|
|
222
|
+
warnings.push(note);
|
|
223
|
+
}
|
|
224
|
+
return row(outcome, settled.removed);
|
|
225
|
+
};
|
|
226
|
+
for (const c of req.credentials) {
|
|
227
|
+
const { answer, detail, transport } = await callEnd(ctx, req.action, c.token);
|
|
228
|
+
if (answer === 'done')
|
|
229
|
+
return { row: await end(c.token, 'confirmed', null), unreachable: false };
|
|
230
|
+
if (answer === 'signed-out') {
|
|
231
|
+
const signedOut = await end(c.token, 'signed-out', `device ${req.deviceId} is signed out but not revoked, and a signed-out device's credentials cannot revoke it; this machine forgot the device, so the next login enrols a new one. To burn the old id, ${web}`);
|
|
232
|
+
return { row: signedOut, unreachable: false };
|
|
233
|
+
}
|
|
234
|
+
if (answer === 'unanswered') {
|
|
235
|
+
warnings.push(`${what} not confirmed (${detail}); it was kept and is retried by the next \`cleo logout nexus\`, \`cleo login nexus\` or \`cleo project link\``);
|
|
236
|
+
return { row: row('pending'), unreachable: transport === true };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Every credential is dead: retrying can never succeed, so the request ends here.
|
|
240
|
+
const first = req.credentials[0];
|
|
241
|
+
if (first === undefined)
|
|
242
|
+
return { row: row('unconfirmed'), unreachable: false };
|
|
243
|
+
const ended = await end(first.token, 'unconfirmed', `${what} not confirmed: the server refused every credential this machine held for it as no longer valid, so none is live and none was kept${req.action === 'revoke' && !req.retired ? '; this machine forgot the device' : ''}. To make sure, ${web}`);
|
|
244
|
+
return { row: ended, unreachable: false };
|
|
245
|
+
}
|
|
246
|
+
/** Every unsettled request on the origin, plus a warning per entry this machine cannot open. */
|
|
247
|
+
async function unsettled(ctx, warnings, warnUnreadable) {
|
|
248
|
+
const out = [];
|
|
249
|
+
for (const d of await ctx.devices.list()) {
|
|
250
|
+
if (d.origin !== ctx.origin)
|
|
251
|
+
continue;
|
|
252
|
+
if (d instanceof UnreadableNexusDevice) {
|
|
253
|
+
if (!warnUnreadable)
|
|
254
|
+
continue;
|
|
255
|
+
warnings.push(`the device entry for user ${d.userId}${d.deviceId ? ` (device ${d.deviceId})` : ''} cannot be opened on this machine (${d.reason}); sign it out or revoke it on cleocode.dev`);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
out.push(...requestsOf(d.userId, d.unseal()));
|
|
259
|
+
}
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
262
|
+
/** Sort rows by user, then device, for a stable envelope. */
|
|
263
|
+
function byUserThenDevice(a, b) {
|
|
264
|
+
return a.userId.localeCompare(b.userId) || a.deviceId.localeCompare(b.deviceId);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Retry every unsettled sign-out and revoke on the origin (contract §3.5,
|
|
268
|
+
* L2): each entry's `pendingSignOut` or `pendingRevoke`, and the `retired`
|
|
269
|
+
* requests of devices it replaced. Never throws for a server that cannot be
|
|
270
|
+
* reached; the rows and warnings say what is still open.
|
|
271
|
+
*
|
|
272
|
+
* @param opts - API URL, stores and test overrides.
|
|
273
|
+
* @returns One row per request tried, and the warnings.
|
|
274
|
+
*/
|
|
275
|
+
export async function settleNexusDeviceEnds(opts = {}) {
|
|
276
|
+
const ctx = context(opts);
|
|
277
|
+
const warnings = [];
|
|
278
|
+
const devices = [];
|
|
279
|
+
let unreachable = false;
|
|
280
|
+
let skipped = 0;
|
|
281
|
+
for (const req of await unsettled(ctx, warnings, opts.warnUnreadable ?? true)) {
|
|
282
|
+
if (unreachable) {
|
|
283
|
+
skipped += 1;
|
|
284
|
+
// The server already failed to answer in this run: leave the rest for
|
|
285
|
+
// the next run rather than wait out one timeout per request.
|
|
286
|
+
devices.push({
|
|
287
|
+
userId: req.userId,
|
|
288
|
+
deviceId: req.deviceId,
|
|
289
|
+
action: req.action,
|
|
290
|
+
retired: req.retired,
|
|
291
|
+
outcome: 'pending',
|
|
292
|
+
removedLocally: false,
|
|
293
|
+
});
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
const r = await settleRequest(ctx, req, warnings);
|
|
298
|
+
// Only a transport failure (no answer at all) stops the run: an HTTP
|
|
299
|
+
// error on one request (a 404, 5xx or 429 for an old device) never
|
|
300
|
+
// keeps the entry's own sign-out or revoke from being sent.
|
|
301
|
+
if (r.unreachable)
|
|
302
|
+
unreachable = true;
|
|
303
|
+
devices.push(r.row);
|
|
304
|
+
}
|
|
305
|
+
catch (err) {
|
|
306
|
+
// A store failure on one request keeps every row collected so far.
|
|
307
|
+
warnings.push(`${req.action} of device ${req.deviceId} could not be settled locally (${err instanceof Error ? err.message : String(err)}); it is retried next time`);
|
|
308
|
+
devices.push({
|
|
309
|
+
userId: req.userId,
|
|
310
|
+
deviceId: req.deviceId,
|
|
311
|
+
action: req.action,
|
|
312
|
+
retired: req.retired,
|
|
313
|
+
outcome: 'pending',
|
|
314
|
+
removedLocally: false,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (skipped > 0) {
|
|
319
|
+
warnings.push(`${skipped} more unsettled sign-out or revoke request(s) were not sent because Cleo Nexus did not answer; they are retried next time`);
|
|
320
|
+
}
|
|
321
|
+
return { devices: devices.sort(byUserThenDevice), warnings };
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Best-effort {@link settleNexusDeviceEnds} for flows that only retry on the
|
|
325
|
+
* way (login, commands that need a credential): a store or network failure
|
|
326
|
+
* becomes a warning and never fails the caller.
|
|
327
|
+
*
|
|
328
|
+
* @param opts - API URL, stores and test overrides.
|
|
329
|
+
* @param warnings - Receives the warnings.
|
|
330
|
+
*/
|
|
331
|
+
export async function retryNexusDeviceEnds(opts, warnings) {
|
|
332
|
+
try {
|
|
333
|
+
const settled = await settleNexusDeviceEnds({
|
|
334
|
+
timeoutMs: NEXUS_END_RETRY_TIMEOUT_MS,
|
|
335
|
+
...opts,
|
|
336
|
+
warnUnreadable: false,
|
|
337
|
+
});
|
|
338
|
+
warnings.push(...settled.warnings);
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
warnings.push(`could not retry an unsettled Cleo Nexus sign-out (${err instanceof Error ? err.message : String(err)}); \`cleo logout nexus\` retries it`);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Under the lock, move every readable entry on the origin into its
|
|
346
|
+
* sign-out or revoke slot. A revoke of an entry with no credential left
|
|
347
|
+
* (already signed out) cannot be sent, so the device is forgotten locally
|
|
348
|
+
* and the web remedy is returned.
|
|
349
|
+
*
|
|
350
|
+
* @returns Warnings for the result envelope.
|
|
351
|
+
*/
|
|
352
|
+
async function beginEnds(ctx, action) {
|
|
353
|
+
const begin = action === 'revoke' ? applyBeginRevoke : applyBeginSignOut;
|
|
354
|
+
return ctx.devices.update((tx) => {
|
|
355
|
+
const notes = [];
|
|
356
|
+
for (const k of tx.keys()) {
|
|
357
|
+
if (k.origin !== ctx.origin || !k.readable)
|
|
358
|
+
continue;
|
|
359
|
+
const entry = tx.get(ctx.apiUrl, k.userId);
|
|
360
|
+
if (entry === null)
|
|
361
|
+
continue;
|
|
362
|
+
const next = begin(entry, ctx.now());
|
|
363
|
+
if (action === 'revoke' && next.pendingRevoke === null && next.keys !== null) {
|
|
364
|
+
const forgotten = applyForgetDevice(next);
|
|
365
|
+
if (isForgottenDevice(forgotten)) {
|
|
366
|
+
tx.delete(ctx.apiUrl, k.userId, { deviceId: entry.deviceId, credentialId: null });
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
tx.set(ctx.apiUrl, k.userId, forgotten);
|
|
370
|
+
}
|
|
371
|
+
notes.push(`device ${next.deviceId} holds no credential (it is signed out), so it cannot be revoked from here; this machine forgot it, so the next login enrols a new device. To burn the old id, revoke device ${next.deviceId} on cleocode.dev (Devices)`);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
tx.set(ctx.apiUrl, k.userId, next);
|
|
375
|
+
}
|
|
376
|
+
return [...tx.warnings, ...notes];
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* `cleo logout nexus [--revoke]` with device credentials (contract §3.5, M3).
|
|
381
|
+
*
|
|
382
|
+
* Every readable entry on the origin is moved to `pendingSignOut` (or
|
|
383
|
+
* `pendingRevoke`), then every unsettled request on the origin is sent,
|
|
384
|
+
* including ones left by earlier runs. A leftover 9.24 session for the origin
|
|
385
|
+
* is signed out too. The device keys stay after a sign-out, so a later login
|
|
386
|
+
* reuses the device id; a confirmed revoke removes the entry.
|
|
387
|
+
*
|
|
388
|
+
* @param opts - API URL, `revoke`, stores and test overrides.
|
|
389
|
+
* @returns The per-device outcomes. A row that is not `confirmed` is also
|
|
390
|
+
* named in `warnings`; the result never claims a sign-out the server did
|
|
391
|
+
* not confirm.
|
|
392
|
+
* A device file that cannot be read or locked is reported as a warning, and
|
|
393
|
+
* the 9.24 session is still signed out.
|
|
394
|
+
*/
|
|
395
|
+
export async function logoutNexusDevice(opts = {}) {
|
|
396
|
+
const ctx = context(opts);
|
|
397
|
+
const action = opts.revoke === true ? 'revoke' : 'sign-out';
|
|
398
|
+
const warnings = [];
|
|
399
|
+
let devices = [];
|
|
400
|
+
try {
|
|
401
|
+
warnings.push(...(await beginEnds(ctx, action)));
|
|
402
|
+
const settled = await settleNexusDeviceEnds({
|
|
403
|
+
...opts,
|
|
404
|
+
apiUrl: ctx.apiUrl,
|
|
405
|
+
deviceStore: ctx.devices,
|
|
406
|
+
});
|
|
407
|
+
devices = settled.devices;
|
|
408
|
+
warnings.push(...settled.warnings);
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
// A broken device file must not stop the 9.24 session sign-out below.
|
|
412
|
+
warnings.push(`the device credentials could not be signed out (${err instanceof Error ? err.message : String(err)}); fix the device file and run \`cleo logout nexus\` again`);
|
|
413
|
+
}
|
|
414
|
+
let session = null;
|
|
415
|
+
const sessions = opts.store ?? new FileNexusTokenStore();
|
|
416
|
+
if ((await sessions.get(ctx.apiUrl)) !== null) {
|
|
417
|
+
session = await logoutFromNexus({
|
|
418
|
+
apiUrl: ctx.apiUrl,
|
|
419
|
+
store: sessions,
|
|
420
|
+
...(opts.fetch ? { fetch: opts.fetch } : {}),
|
|
421
|
+
});
|
|
422
|
+
warnings.push(...session.warnings);
|
|
423
|
+
}
|
|
424
|
+
if (action === 'revoke' && devices.length === 0 && session !== null) {
|
|
425
|
+
warnings.push(`no device credential is stored for ${ctx.apiUrl}, so nothing was revoked; the 9.24 session was signed out`);
|
|
426
|
+
}
|
|
427
|
+
return { apiUrl: ctx.apiUrl, action, devices, session, warnings };
|
|
428
|
+
}
|
|
429
|
+
//# sourceMappingURL=nexus-logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nexus-logout.js","sourceRoot":"","sources":["../../src/cloud/nexus-logout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vault's connection and keys: a read-write device connection, the
|
|
3
|
+
* account master key, this device's certificate, and the stream data keys.
|
|
4
|
+
*
|
|
5
|
+
* Owner decision (2026-10-01): adding a device needs only `cleo login` and
|
|
6
|
+
* the one-time browser approval; that approval also hands the device the
|
|
7
|
+
* encryption key. So the account master key (MK) is escrowed on Cleo Nexus:
|
|
8
|
+
*
|
|
9
|
+
* 1. `GET /v1/account/keys/escrow` returns MK sealed to this device's X25519
|
|
10
|
+
* key (`sealTo`), released only to an approved, active device. The client
|
|
11
|
+
* opens it with the device's private key and checks it against the
|
|
12
|
+
* escrow's verifier.
|
|
13
|
+
* 2. No escrow and no account keys: this is the account's first vault use.
|
|
14
|
+
* The client mints MK and escrows it (`PUT`, insert-only). A concurrent
|
|
15
|
+
* first device loses the insert with 409 and reads the winner's key.
|
|
16
|
+
* 3. The device certifies itself under MK (a self-grant, `PUT
|
|
17
|
+
* /v1/devices/:id/key`), so other devices can verify its snapshots.
|
|
18
|
+
* 4. Signer trust comes from `certifiedSigners` over `GET /v1/devices/trust`,
|
|
19
|
+
* with the trust state persisted in {@link NexusVaultState}.
|
|
20
|
+
*
|
|
21
|
+
* Threat model (cleo-nexus T082): the escrow `PUT` sends MK to the server
|
|
22
|
+
* over TLS, and the server stores it encrypted under a server-held key
|
|
23
|
+
* (`KEY_ESCROW_SECRET`). Snapshots are therefore encrypted at rest with keys
|
|
24
|
+
* Cleo Nexus can recover: this is server-escrowed encryption, not
|
|
25
|
+
* zero-knowledge end-to-end encryption. What the escrow does guarantee is
|
|
26
|
+
* that MK is released only to an approved, active device of the account,
|
|
27
|
+
* sealed to that device's key.
|
|
28
|
+
*
|
|
29
|
+
* A project's data key (PDK) is minted by its first pusher and stored
|
|
30
|
+
* wrapped by MK (`PUT /v1/projects/:id/keys/:userId`); the home stream key
|
|
31
|
+
* is derived from MK.
|
|
32
|
+
*
|
|
33
|
+
* No function here logs a key, and no error carries one.
|
|
34
|
+
*
|
|
35
|
+
* @task T12336
|
|
36
|
+
* @epic T12322
|
|
37
|
+
*/
|
|
38
|
+
import type { CloudWarning } from '@cleocode/contracts';
|
|
39
|
+
import { type KeyPair } from './crypto.js';
|
|
40
|
+
import { type FetchLike, Http, type ResponseSchema } from './http.js';
|
|
41
|
+
import { type TrustedSigners } from './keys.js';
|
|
42
|
+
import { resolveNexusApiUrl } from './nexus-auth.js';
|
|
43
|
+
import { type NexusCloudOptions } from './nexus-cloud.js';
|
|
44
|
+
import type { SealedNexusDevice } from './nexus-device.js';
|
|
45
|
+
import { NexusVaultState } from './nexus-vault-state.js';
|
|
46
|
+
/** Timeout of a snapshot blob upload or download. */
|
|
47
|
+
export declare const NEXUS_VAULT_BLOB_TIMEOUT_MS: number;
|
|
48
|
+
/** The sealed-box context of an escrow release (must match the server, cleo-nexus T082). */
|
|
49
|
+
export declare const escrowContext: (userId: string, deviceId: string) => string;
|
|
50
|
+
/** Options of every vault command. */
|
|
51
|
+
export interface NexusVaultOptions extends NexusCloudOptions {
|
|
52
|
+
/** Vault state store (tests). */
|
|
53
|
+
vaultState?: NexusVaultState;
|
|
54
|
+
/** Timeout of a blob transfer; default {@link NEXUS_VAULT_BLOB_TIMEOUT_MS}. */
|
|
55
|
+
blobTimeoutMs?: number;
|
|
56
|
+
}
|
|
57
|
+
/** A read-write connection with this machine's device credential and keys. */
|
|
58
|
+
export interface NexusVaultConnection {
|
|
59
|
+
readonly apiUrl: string;
|
|
60
|
+
readonly userId: string;
|
|
61
|
+
readonly deviceId: string;
|
|
62
|
+
readonly device: SealedNexusDevice;
|
|
63
|
+
/** Device keys: X25519 for sealed boxes, Ed25519 for signatures. */
|
|
64
|
+
readonly keys: {
|
|
65
|
+
encryption: KeyPair;
|
|
66
|
+
signing: KeyPair;
|
|
67
|
+
};
|
|
68
|
+
/** The authenticated client (sends `X-Cleo-Device-Id`). For the journal. */
|
|
69
|
+
readonly http: Http;
|
|
70
|
+
/** `fetch` for presigned blob transfers (long timeout, no credential). */
|
|
71
|
+
readonly blobFetch: FetchLike;
|
|
72
|
+
readonly state: NexusVaultState;
|
|
73
|
+
readonly warnings: CloudWarning[];
|
|
74
|
+
/** A request whose failure stays a raw {@link NexusError} (callers handle server codes). */
|
|
75
|
+
raw<T>(method: string, path: string, schema: ResponseSchema<T>, body?: unknown): Promise<T>;
|
|
76
|
+
/** {@link NexusVaultConnection.raw}, with failures mapped to {@link NexusAccountError}. */
|
|
77
|
+
call<T>(method: string, path: string, schema: ResponseSchema<T>, body?: unknown): Promise<T>;
|
|
78
|
+
/** `GET`, mapped; a 404 answers `null`. */
|
|
79
|
+
find<T>(path: string, schema: ResponseSchema<T>): Promise<T | null>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Open a read-write vault connection with this machine's device credential.
|
|
83
|
+
*
|
|
84
|
+
* @param opts - API URL, account, stores and test overrides.
|
|
85
|
+
* @returns The connection.
|
|
86
|
+
* @throws {NexusAccountError} Not signed in, device mode off, or no device keys.
|
|
87
|
+
*/
|
|
88
|
+
export declare function connectNexusVault(opts?: NexusVaultOptions): Promise<NexusVaultConnection>;
|
|
89
|
+
/** The unlocked account key and the signers this device trusts. */
|
|
90
|
+
export interface NexusAccountKey {
|
|
91
|
+
masterKey: Buffer;
|
|
92
|
+
keyVersion: number;
|
|
93
|
+
signers: TrustedSigners;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get the account master key for this device, minting and escrowing it on
|
|
97
|
+
* the account's first vault use, and certify this device under it.
|
|
98
|
+
*
|
|
99
|
+
* @param conn - A vault connection.
|
|
100
|
+
* @param opts - `readOnly`: never mint, escrow or certify (GET only); a missing escrow is
|
|
101
|
+
* `E_NEXUS_VAULT_EMPTY`.
|
|
102
|
+
* @returns The key, its version and the trusted signers.
|
|
103
|
+
* @throws {NexusAccountError} `E_NEXUS_VAULT_KEY_UNAVAILABLE` when the key
|
|
104
|
+
* cannot be obtained or verified; a mapped API error otherwise.
|
|
105
|
+
*/
|
|
106
|
+
export declare function unlockNexusAccountKey(conn: NexusVaultConnection, opts?: {
|
|
107
|
+
readOnly?: boolean;
|
|
108
|
+
}): Promise<NexusAccountKey>;
|
|
109
|
+
/**
|
|
110
|
+
* The data key of a project stream: unwrap the newest wrapped key, or mint
|
|
111
|
+
* and store one when the project has none yet (its first push).
|
|
112
|
+
*
|
|
113
|
+
* @param conn - A vault connection.
|
|
114
|
+
* @param mk - The unlocked master key.
|
|
115
|
+
* @param projectId - The server's project id.
|
|
116
|
+
* @param mint - Whether a missing key may be created (push: yes; restore: no).
|
|
117
|
+
* @returns The project data key, or `null` when none exists and `mint` is false.
|
|
118
|
+
*/
|
|
119
|
+
export declare function nexusProjectDataKey(conn: NexusVaultConnection, mk: Buffer, projectId: string, mint: boolean): Promise<Buffer | null>;
|
|
120
|
+
/**
|
|
121
|
+
* The data key of the account's `home:` stream (derived from MK, never stored).
|
|
122
|
+
*
|
|
123
|
+
* @param mk - The unlocked master key.
|
|
124
|
+
* @returns The home stream key.
|
|
125
|
+
*/
|
|
126
|
+
export declare function nexusHomeDataKey(mk: Buffer): Buffer;
|
|
127
|
+
/** Re-export for callers that only need the URL resolver. */
|
|
128
|
+
export { resolveNexusApiUrl };
|
|
129
|
+
//# sourceMappingURL=nexus-vault-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nexus-vault-keys.d.ts","sourceRoot":"","sources":["../../src/cloud/nexus-vault-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASxD,OAAO,EAAE,KAAK,OAAO,EAAyB,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,KAAK,SAAS,EAAE,IAAI,EAAc,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAClF,OAAO,EAML,KAAK,cAAc,EAGpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAqB,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qDAAqD;AACrD,eAAO,MAAM,2BAA2B,QAAc,CAAC;AAEvD,4FAA4F;AAC5F,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,WAChB,CAAC;AAE/C,sCAAsC;AACtC,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,iCAAiC;IACjC,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,8EAA8E;AAC9E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACzD,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC;IAClC,4FAA4F;IAC5F,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5F,2FAA2F;IAC3F,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7F,2CAA2C;IAC3C,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;CACrE;AAQD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CA8D/B;AAED,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;CACzB;AA8FD;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,oBAAoB,EAC1B,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,eAAe,CAAC,CAoC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,oBAAoB,EAC1B,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2BxB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,6DAA6D;AAC7D,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|