@astrale-os/cli 1.0.0-beta.32 → 1.0.0-beta.43
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/CHANGELOG.md +928 -0
- package/README.md +53 -43
- package/THIRD-PARTY-NOTICES.md +37 -1
- package/dist/astrale.js +349631 -83669
- package/dist/public/connect-core.js +16 -47
- package/dist/public/keys/index.js +1 -1
- package/dist/types/admin/contract.d.ts +11 -0
- package/dist/types/admin/graph/index.d.ts +1 -0
- package/dist/types/admin/graph/nodes.d.ts +12 -0
- package/dist/types/admin/instance/client.d.ts +2 -0
- package/dist/types/connection/lifetime.d.ts +1 -1
- package/dist/types/errors.d.ts +3 -0
- package/dist/types/lib/proc.d.ts +1 -0
- package/dist/types/lib/update.d.ts +15 -7
- package/package.json +8 -6
- package/studio/client/dist/assets/index-5C1uT6ML.css +2 -0
- package/studio/client/dist/assets/index-C4kNlvwF.js +80 -0
- package/studio/client/dist/assets/schema-studio-BR9d0faB.js +8 -0
- package/studio/client/dist/index.html +13 -2
- package/studio/package.json +2 -1
- package/studio/server/agent/ask.test.ts +7 -1
- package/studio/server/agent/bridge/grant.ts +15 -3
- package/studio/server/agent/prompts/system.test.ts +5 -0
- package/studio/server/agent/prompts/system.ts +19 -4
- package/studio/server/agent/routes.test.ts +39 -1
- package/studio/server/agent/routes.ts +3 -0
- package/studio/server/agent/run/coordinator.test.ts +7 -1
- package/studio/server/agent/run/preparation.ts +1 -0
- package/studio/server/agent/run/transcript.test.ts +47 -2
- package/studio/server/agent/run/transcript.ts +32 -3
- package/studio/server/api/documents.test.ts +31 -0
- package/studio/server/api/documents.ts +35 -1
- package/studio/server/api-agent-loadout.test.ts +7 -1
- package/studio/server/api.test.ts +7 -1
- package/studio/server/cache.ts +4 -4
- package/studio/server/detect.ts +9 -12
- package/studio/server/domain.test.ts +83 -3
- package/studio/server/domain.ts +205 -27
- package/studio/server/handoff/service.ts +1 -1
- package/studio/server/index.ts +5 -8
- package/studio/server/introspect/extractor.ts +111 -17
- package/studio/server/introspect/overlay-tsmorph.test.ts +9 -9
- package/studio/server/introspect/overlay.ts +1 -1
- package/studio/server/introspect/runtime.ts +9 -1
- package/studio/server/introspect/source-overlay/spans.ts +2 -5
- package/studio/server/lifecycle.ts +1 -1
- package/studio/server/state/baseline.test.ts +14 -0
- package/studio/server/state/baseline.ts +16 -2
- package/studio/server/watch.test.ts +2 -1
- package/studio/server/watch.ts +5 -2
- package/studio/server/workspace/create.ts +9 -8
- package/studio/server/workspace-state.ts +4 -6
- package/studio/server/workspace-watch.ts +33 -22
- package/studio/shared/contracts/agent.ts +3 -0
- package/viewer/dist/main.js +12 -12
- package/src/__tests__/fixtures/publication.ts +0 -20
- package/src/admin/.spec/api.d.ts +0 -3
- package/src/admin/.spec/architecture.md +0 -22
- package/src/admin/.spec/icon.svg +0 -3
- package/src/admin/.spec/layout.ts +0 -6
- package/src/admin/__tests__/fixture.ts +0 -25
- package/src/admin/catalog/.spec/api.d.ts +0 -63
- package/src/admin/catalog/.spec/architecture.md +0 -7
- package/src/admin/catalog/.spec/icon.svg +0 -3
- package/src/admin/catalog/.spec/layout.ts +0 -6
- package/src/admin/catalog/__tests__/client.test.ts +0 -245
- package/src/admin/catalog/client.ts +0 -195
- package/src/admin/catalog/index.ts +0 -13
- package/src/admin/catalog/model.ts +0 -41
- package/src/admin/catalog/tsconfig.json +0 -8
- package/src/admin/contract.ts +0 -47
- package/src/admin/graph/.spec/api.d.ts +0 -22
- package/src/admin/graph/.spec/architecture.md +0 -5
- package/src/admin/graph/.spec/icon.svg +0 -3
- package/src/admin/graph/.spec/layout.ts +0 -3
- package/src/admin/graph/index.ts +0 -6
- package/src/admin/graph/nodes.ts +0 -56
- package/src/admin/index.ts +0 -2
- package/src/admin/instance/.spec/api.d.ts +0 -62
- package/src/admin/instance/.spec/architecture.md +0 -10
- package/src/admin/instance/.spec/icon.svg +0 -3
- package/src/admin/instance/.spec/layout.ts +0 -6
- package/src/admin/instance/__tests__/client.test.ts +0 -273
- package/src/admin/instance/client.ts +0 -191
- package/src/admin/instance/index.ts +0 -15
- package/src/admin/instance/model.ts +0 -59
- package/src/admin/instance/tsconfig.json +0 -8
- package/src/commands/__tests__/admin-instance.test.ts +0 -91
- package/src/commands/__tests__/auth-login.test.ts +0 -231
- package/src/commands/__tests__/auth-token.test.ts +0 -223
- package/src/commands/__tests__/call-describe.test.ts +0 -80
- package/src/commands/__tests__/call.test.ts +0 -63
- package/src/commands/__tests__/domain-install-operation.test.ts +0 -145
- package/src/commands/__tests__/domain-install-owned.test.ts +0 -191
- package/src/commands/__tests__/domain-list.test.ts +0 -133
- package/src/commands/__tests__/domain-uninstall.test.ts +0 -53
- package/src/commands/__tests__/install-direct.test.ts +0 -128
- package/src/commands/__tests__/install-identity-override.test.ts +0 -76
- package/src/commands/__tests__/instance-bookmark.test.ts +0 -166
- package/src/commands/__tests__/instance-list-admin.test.ts +0 -26
- package/src/commands/__tests__/instance-list-rows.test.ts +0 -64
- package/src/commands/__tests__/instance-status.test.ts +0 -139
- package/src/commands/__tests__/instance-use.test.ts +0 -67
- package/src/commands/__tests__/introspect-parse.test.ts +0 -100
- package/src/commands/__tests__/logs.test.ts +0 -345
- package/src/commands/__tests__/read-commands.test.ts +0 -377
- package/src/commands/__tests__/setup-plan.test.ts +0 -61
- package/src/commands/__tests__/studio-descriptor.test.ts +0 -22
- package/src/commands/__tests__/token-ttl.test.ts +0 -66
- package/src/commands/__tests__/update.test.ts +0 -95
- package/src/commands/__tests__/view-build.test.ts +0 -58
- package/src/commands/__tests__/view.test.ts +0 -197
- package/src/commands/admin/status.ts +0 -61
- package/src/commands/admin/use.ts +0 -100
- package/src/commands/auth/login.ts +0 -82
- package/src/commands/auth/logout.ts +0 -53
- package/src/commands/auth/status.ts +0 -86
- package/src/commands/auth/token.ts +0 -174
- package/src/commands/browser.ts +0 -236
- package/src/commands/call-describe.ts +0 -123
- package/src/commands/call.ts +0 -230
- package/src/commands/domain/install.ts +0 -575
- package/src/commands/domain/list.ts +0 -155
- package/src/commands/domain/publish.ts +0 -136
- package/src/commands/domain/uninstall.ts +0 -128
- package/src/commands/get.ts +0 -69
- package/src/commands/identity/__tests__/register.test.ts +0 -93
- package/src/commands/identity/create.ts +0 -35
- package/src/commands/identity/delete.ts +0 -24
- package/src/commands/identity/export.ts +0 -46
- package/src/commands/identity/import.ts +0 -61
- package/src/commands/identity/list.ts +0 -56
- package/src/commands/identity/register.ts +0 -195
- package/src/commands/identity/sync.ts +0 -38
- package/src/commands/identity/unsync.ts +0 -34
- package/src/commands/identity/use.ts +0 -24
- package/src/commands/identity/whoami.ts +0 -34
- package/src/commands/idp/add.ts +0 -150
- package/src/commands/idp/list.ts +0 -57
- package/src/commands/idp/refresh.ts +0 -38
- package/src/commands/idp/remove.ts +0 -36
- package/src/commands/idp/show.ts +0 -29
- package/src/commands/instance/active.ts +0 -73
- package/src/commands/instance/bookmark.ts +0 -101
- package/src/commands/instance/create.ts +0 -61
- package/src/commands/instance/delete.ts +0 -69
- package/src/commands/instance/forget.ts +0 -26
- package/src/commands/instance/list.ts +0 -197
- package/src/commands/instance/status.ts +0 -92
- package/src/commands/instance/use.ts +0 -263
- package/src/commands/introspect.ts +0 -129
- package/src/commands/logs.ts +0 -371
- package/src/commands/mutate.ts +0 -122
- package/src/commands/query.ts +0 -142
- package/src/commands/session/analyze.ts +0 -72
- package/src/commands/session/list.ts +0 -36
- package/src/commands/setup.ts +0 -54
- package/src/commands/status.ts +0 -60
- package/src/commands/studio.ts +0 -434
- package/src/commands/token.ts +0 -121
- package/src/commands/ui/__tests__/commands.test.ts +0 -152
- package/src/commands/ui/add.ts +0 -51
- package/src/commands/ui/doctor.ts +0 -21
- package/src/commands/ui/init.ts +0 -38
- package/src/commands/ui/list.ts +0 -26
- package/src/commands/ui/preset-apply.ts +0 -19
- package/src/commands/ui/preset-list.ts +0 -12
- package/src/commands/ui/shared.ts +0 -25
- package/src/commands/update.ts +0 -356
- package/src/commands/use.ts +0 -86
- package/src/commands/view-serve.ts +0 -26
- package/src/commands/view.ts +0 -658
- package/src/connect-core.test.ts +0 -38
- package/src/connect-core.ts +0 -42
- package/src/connection/.spec/api.d.ts +0 -110
- package/src/connection/.spec/architecture.md +0 -58
- package/src/connection/.spec/capabilities/connection.ts +0 -13
- package/src/connection/.spec/examples/call.ts +0 -7
- package/src/connection/.spec/flows/command.ts +0 -20
- package/src/connection/.spec/flows/session.ts +0 -62
- package/src/connection/.spec/laws/connection.ts +0 -213
- package/src/connection/.spec/layout.ts +0 -22
- package/src/connection/__tests__/auth.test.ts +0 -129
- package/src/connection/__tests__/ca-fetch.test.ts +0 -60
- package/src/connection/__tests__/call.test.ts +0 -17
- package/src/connection/__tests__/credential.test.ts +0 -254
- package/src/connection/__tests__/errors.test.ts +0 -577
- package/src/connection/__tests__/exchange.test.ts +0 -404
- package/src/connection/__tests__/failure-fixtures.ts +0 -39
- package/src/connection/__tests__/failure-safety.test.ts +0 -75
- package/src/connection/__tests__/fixtures/localhost-cert.pem +0 -19
- package/src/connection/__tests__/fixtures/localhost-key.base64 +0 -1
- package/src/connection/__tests__/managed.test.ts +0 -39
- package/src/connection/__tests__/reasons.test.ts +0 -78
- package/src/connection/__tests__/self.test.ts +0 -71
- package/src/connection/__tests__/session.test.ts +0 -144
- package/src/connection/__tests__/target.test.ts +0 -95
- package/src/connection/auth.ts +0 -265
- package/src/connection/call.ts +0 -7
- package/src/connection/command.ts +0 -67
- package/src/connection/credential.ts +0 -138
- package/src/connection/errors.ts +0 -1
- package/src/connection/exchange.ts +0 -394
- package/src/connection/failure/classify.ts +0 -110
- package/src/connection/failure/index.ts +0 -18
- package/src/connection/failure/model.ts +0 -28
- package/src/connection/failure/render.ts +0 -116
- package/src/connection/index.ts +0 -8
- package/src/connection/lifetime.ts +0 -25
- package/src/connection/reasons.ts +0 -209
- package/src/connection/self.ts +0 -138
- package/src/connection/session.ts +0 -203
- package/src/connection/target.ts +0 -112
- package/src/connection/tsconfig.json +0 -6
- package/src/errors.ts +0 -66
- package/src/graph/.spec/api.d.ts +0 -41
- package/src/graph/.spec/laws/documents.ts +0 -24
- package/src/graph/.spec/laws/projection.ts +0 -13
- package/src/graph/.spec/layout.ts +0 -14
- package/src/graph/__tests__/mutation.test.ts +0 -51
- package/src/graph/__tests__/projection.test.ts +0 -22
- package/src/graph/__tests__/query.test.ts +0 -180
- package/src/graph/class.ts +0 -30
- package/src/graph/index.ts +0 -4
- package/src/graph/mutation.ts +0 -46
- package/src/graph/projection.ts +0 -21
- package/src/graph/query.ts +0 -95
- package/src/graph/tsconfig.json +0 -6
- package/src/identity/.history/ard/bootstrap-root-transfer.md +0 -57
- package/src/identity/.history/ard/domain-mediated-registration.md +0 -36
- package/src/identity/.spec/api.d.ts +0 -124
- package/src/identity/.spec/architecture.md +0 -33
- package/src/identity/.spec/capabilities/identity.ts +0 -7
- package/src/identity/.spec/flows/bootstrap-root.ts +0 -79
- package/src/identity/.spec/flows/domain-mediated-registration.ts +0 -51
- package/src/identity/.spec/flows/import.ts +0 -29
- package/src/identity/.spec/laws/identity.ts +0 -56
- package/src/identity/.spec/layout.ts +0 -13
- package/src/identity/__tests__/fixtures/registry-journey.ts +0 -65
- package/src/identity/__tests__/registration.test.ts +0 -64
- package/src/identity/__tests__/registry.test.ts +0 -74
- package/src/identity/__tests__/transfer.test.ts +0 -198
- package/src/identity/index.ts +0 -23
- package/src/identity/registration.ts +0 -72
- package/src/identity/registry.ts +0 -181
- package/src/identity/transfer.ts +0 -187
- package/src/identity/tsconfig.json +0 -6
- package/src/index.ts +0 -1
- package/src/keys/.spec/api.d.ts +0 -74
- package/src/keys/.spec/architecture.md +0 -13
- package/src/keys/.spec/laws/keys.ts +0 -43
- package/src/keys/.spec/layout.ts +0 -6
- package/src/keys/__tests__/algorithm.test.ts +0 -39
- package/src/keys/__tests__/keys.test.ts +0 -172
- package/src/keys/algorithm.ts +0 -33
- package/src/keys/credential.ts +0 -113
- package/src/keys/index.ts +0 -14
- package/src/keys/pair.ts +0 -219
- package/src/keys/tsconfig.json +0 -6
- package/src/lib/__tests__/admin-target.test.ts +0 -184
- package/src/lib/__tests__/binary.test.ts +0 -70
- package/src/lib/__tests__/browser-retention.test.ts +0 -212
- package/src/lib/__tests__/command-dx.test.ts +0 -102
- package/src/lib/__tests__/concurrency.test.ts +0 -62
- package/src/lib/__tests__/config.test.ts +0 -81
- package/src/lib/__tests__/design.test.ts +0 -99
- package/src/lib/__tests__/domain-publication.test.ts +0 -138
- package/src/lib/__tests__/format.test.ts +0 -22
- package/src/lib/__tests__/idp-session.driver.ts +0 -60
- package/src/lib/__tests__/idp-session.test.ts +0 -404
- package/src/lib/__tests__/idp.test.ts +0 -415
- package/src/lib/__tests__/instance-candidates.test.ts +0 -146
- package/src/lib/__tests__/instance-target.test.ts +0 -213
- package/src/lib/__tests__/instance.test.ts +0 -192
- package/src/lib/__tests__/local-status.test.ts +0 -202
- package/src/lib/__tests__/log-errors.test.ts +0 -64
- package/src/lib/__tests__/log.test.ts +0 -31
- package/src/lib/__tests__/meta.test.ts +0 -55
- package/src/lib/__tests__/output.test.ts +0 -162
- package/src/lib/__tests__/panel.test.ts +0 -40
- package/src/lib/__tests__/port.test.ts +0 -44
- package/src/lib/__tests__/prompt.test.ts +0 -25
- package/src/lib/__tests__/sdk-deps.test.ts +0 -68
- package/src/lib/__tests__/self.test.ts +0 -50
- package/src/lib/__tests__/skills.test.ts +0 -834
- package/src/lib/__tests__/studio-server-deps.test.ts +0 -111
- package/src/lib/__tests__/table.test.ts +0 -53
- package/src/lib/__tests__/update.test.ts +0 -511
- package/src/lib/__tests__/use-target.test.ts +0 -56
- package/src/lib/__tests__/validation.test.ts +0 -34
- package/src/lib/__tests__/view-assets.test.ts +0 -171
- package/src/lib/__tests__/view-external-open-intent.test.ts +0 -150
- package/src/lib/__tests__/view-external-open-origins.test.ts +0 -27
- package/src/lib/__tests__/view-open-intent.test.ts +0 -280
- package/src/lib/__tests__/view-port-allocation.test.ts +0 -82
- package/src/lib/__tests__/view-server.test.ts +0 -91
- package/src/lib/__tests__/view-session.test.ts +0 -100
- package/src/lib/__tests__/view-snapshot.test.ts +0 -77
- package/src/lib/admin-domain.ts +0 -43
- package/src/lib/admin-instance.ts +0 -56
- package/src/lib/admin-target.ts +0 -290
- package/src/lib/binary.ts +0 -127
- package/src/lib/browser-retention.ts +0 -210
- package/src/lib/browser.ts +0 -150
- package/src/lib/ca-fetch.ts +0 -133
- package/src/lib/command-dx.ts +0 -191
- package/src/lib/concurrency.ts +0 -31
- package/src/lib/config.ts +0 -57
- package/src/lib/credential-lifetime.ts +0 -24
- package/src/lib/domain-publication.ts +0 -104
- package/src/lib/failure-debug.ts +0 -26
- package/src/lib/format.ts +0 -4
- package/src/lib/idp-session.ts +0 -156
- package/src/lib/idp.ts +0 -926
- package/src/lib/instance-candidates.ts +0 -49
- package/src/lib/instance-target.ts +0 -197
- package/src/lib/instance.ts +0 -468
- package/src/lib/invocation.ts +0 -11
- package/src/lib/local-status.ts +0 -152
- package/src/lib/log.ts +0 -143
- package/src/lib/login-flow.ts +0 -201
- package/src/lib/meta.ts +0 -90
- package/src/lib/output.ts +0 -238
- package/src/lib/panel.ts +0 -61
- package/src/lib/port.ts +0 -41
- package/src/lib/proc.ts +0 -87
- package/src/lib/prompt.ts +0 -136
- package/src/lib/provision-instance.ts +0 -139
- package/src/lib/sdk-deps.ts +0 -104
- package/src/lib/self.ts +0 -22
- package/src/lib/skills/lock.ts +0 -117
- package/src/lib/skills/sync.ts +0 -878
- package/src/lib/skills.ts +0 -120
- package/src/lib/table.ts +0 -62
- package/src/lib/update.ts +0 -568
- package/src/lib/use-target.ts +0 -24
- package/src/lib/validation.ts +0 -59
- package/src/lib/view/assets.ts +0 -87
- package/src/lib/view/external-open-intent.ts +0 -41
- package/src/lib/view/external-open-origins.ts +0 -37
- package/src/lib/view/host-capabilities.ts +0 -17
- package/src/lib/view/open-intent.ts +0 -67
- package/src/lib/view/port-allocation.ts +0 -19
- package/src/lib/view/resolve.ts +0 -111
- package/src/lib/view/server.ts +0 -259
- package/src/lib/view/session.ts +0 -154
- package/src/lib/view/snapshot.ts +0 -101
- package/src/paths/.spec/api.d.ts +0 -13
- package/src/paths/.spec/architecture.md +0 -5
- package/src/paths/.spec/layout.ts +0 -3
- package/src/paths/index.ts +0 -13
- package/src/program/.spec/api.d.ts +0 -43
- package/src/program/.spec/architecture.md +0 -18
- package/src/program/.spec/laws/program.ts +0 -29
- package/src/program/.spec/layout.ts +0 -14
- package/src/program/__tests__/program.test.ts +0 -556
- package/src/program/argv.ts +0 -14
- package/src/program/build.ts +0 -205
- package/src/program/command.ts +0 -43
- package/src/program/index.ts +0 -3
- package/src/program/options.ts +0 -41
- package/src/program/registry.ts +0 -64
- package/src/program/tsconfig.json +0 -6
- package/src/setup/__tests__/instance-step.test.ts +0 -256
- package/src/setup/__tests__/util.test.ts +0 -29
- package/src/setup/engine.ts +0 -83
- package/src/setup/render.ts +0 -107
- package/src/setup/steps/admin.ts +0 -93
- package/src/setup/steps/agent-browser.ts +0 -81
- package/src/setup/steps/auth.ts +0 -54
- package/src/setup/steps/domain.ts +0 -68
- package/src/setup/steps/index.ts +0 -18
- package/src/setup/steps/instance.ts +0 -206
- package/src/setup/steps/skills-bridge.ts +0 -70
- package/src/setup/steps/skills.ts +0 -61
- package/src/setup/types.ts +0 -61
- package/src/setup/util.ts +0 -34
- package/src/state/.spec/api.d.ts +0 -152
- package/src/state/.spec/architecture.md +0 -45
- package/src/state/.spec/capabilities/state.ts +0 -7
- package/src/state/.spec/flows/identity-update.ts +0 -22
- package/src/state/.spec/laws/state.ts +0 -73
- package/src/state/.spec/layout.ts +0 -15
- package/src/state/__tests__/exchange-credentials.test.ts +0 -341
- package/src/state/__tests__/files.test.ts +0 -136
- package/src/state/__tests__/fixtures/identity-transition.ts +0 -37
- package/src/state/__tests__/fixtures/session-route-process.ts +0 -93
- package/src/state/__tests__/identities.test.ts +0 -142
- package/src/state/__tests__/paths.test.ts +0 -28
- package/src/state/__tests__/session-routes.test.ts +0 -138
- package/src/state/exchange-credentials.ts +0 -250
- package/src/state/files.ts +0 -170
- package/src/state/identities.ts +0 -229
- package/src/state/index.ts +0 -31
- package/src/state/paths.ts +0 -64
- package/src/state/session-routes.ts +0 -34
- package/src/state/tsconfig.json +0 -6
- package/src/telemetry/__tests__/analyze-log.test.ts +0 -38
- package/src/telemetry/__tests__/gate.test.ts +0 -63
- package/src/telemetry/__tests__/recorder.test.ts +0 -111
- package/src/telemetry/__tests__/redact.test.ts +0 -79
- package/src/telemetry/__tests__/retention.test.ts +0 -267
- package/src/telemetry/__tests__/session.test.ts +0 -166
- package/src/telemetry/__tests__/settings.test.ts +0 -102
- package/src/telemetry/__tests__/store-scan.test.ts +0 -128
- package/src/telemetry/__tests__/trigger.test.ts +0 -78
- package/src/telemetry/adapters/__tests__/claude-code.test.ts +0 -89
- package/src/telemetry/adapters/__tests__/codex.test.ts +0 -138
- package/src/telemetry/adapters/__tests__/index.test.ts +0 -88
- package/src/telemetry/adapters/claude-code.ts +0 -90
- package/src/telemetry/adapters/codex.ts +0 -160
- package/src/telemetry/adapters/index.ts +0 -45
- package/src/telemetry/adapters/types.ts +0 -21
- package/src/telemetry/analyze.ts +0 -249
- package/src/telemetry/gate.ts +0 -79
- package/src/telemetry/recorder.ts +0 -68
- package/src/telemetry/redact.ts +0 -53
- package/src/telemetry/retention.ts +0 -176
- package/src/telemetry/session.ts +0 -94
- package/src/telemetry/settings.ts +0 -79
- package/src/telemetry/store.ts +0 -174
- package/src/telemetry/trigger.ts +0 -107
- package/src/telemetry/types.ts +0 -64
- package/src/test-utils.ts +0 -18
- package/src/ui/.spec/api.d.ts +0 -14
- package/src/ui/.spec/architecture.md +0 -14
- package/src/ui/.spec/laws.ts +0 -50
- package/src/ui/.spec/layout.ts +0 -16
- package/src/ui/__tests__/ui.test.ts +0 -1742
- package/src/ui/index.ts +0 -13
- package/src/ui/lock.ts +0 -89
- package/src/ui/model.ts +0 -83
- package/src/ui/operations.ts +0 -1044
- package/src/ui/project.ts +0 -333
- package/src/ui/release.ts +0 -398
- package/src/ui/runner.ts +0 -18
- package/studio/client/dist/assets/index-BFVFs_8x.js +0 -81
- package/studio/client/dist/assets/index-DuB9iUdu.css +0 -2
- package/studio/client/dist/assets/schema-studio-DH6oEWME.js +0 -8
- package/studio/tsconfig.json +0 -24
- package/viewer/tsconfig.json +0 -13
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { ProvisionRequest } from '@astrale-os/sdk/auth'
|
|
2
|
-
import type { Call } from '@astrale-os/sdk/client'
|
|
3
|
-
import type { LocalBinding } from '@astrale-os/sdk/graph'
|
|
4
|
-
|
|
5
|
-
import { issuer } from '@astrale-os/sdk/auth'
|
|
6
|
-
import { call } from '@astrale-os/sdk/client'
|
|
7
|
-
import { NodeId } from '@astrale-os/sdk/graph/node'
|
|
8
|
-
import { Path } from '@astrale-os/sdk/graph/path'
|
|
9
|
-
|
|
10
|
-
export interface IdentityRegistrationResult {
|
|
11
|
-
readonly iss: string
|
|
12
|
-
readonly sub: string
|
|
13
|
-
readonly nodeId?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface IdentityProvisionSubmission {
|
|
17
|
-
readonly request: ProvisionRequest
|
|
18
|
-
readonly binding: LocalBinding
|
|
19
|
-
readonly via?: string
|
|
20
|
-
readonly direct: {
|
|
21
|
-
provision(request: ProvisionRequest): Promise<unknown>
|
|
22
|
-
}
|
|
23
|
-
readonly callable: {
|
|
24
|
-
call(call: Call): Promise<unknown>
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** Submit one prepared request either directly or through its explicit Domain authority owner. */
|
|
29
|
-
export async function submitIdentityProvision(
|
|
30
|
-
input: IdentityProvisionSubmission,
|
|
31
|
-
): Promise<IdentityRegistrationResult> {
|
|
32
|
-
const result =
|
|
33
|
-
input.via === undefined
|
|
34
|
-
? await input.direct.provision(input.request)
|
|
35
|
-
: await input.callable.call(
|
|
36
|
-
// Client admits the portable value before transport. ProvisionRequest is the
|
|
37
|
-
// stricter semantic type but does not declare the portable Object index signature.
|
|
38
|
-
call(Path.parse(input.via), input.request as unknown as Call['input']),
|
|
39
|
-
)
|
|
40
|
-
return acceptProvisionedIdentity(result, input.binding)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** Admit only the exact binding the CLI prepared; remote callables remain untrusted input. */
|
|
44
|
-
export function acceptProvisionedIdentity(
|
|
45
|
-
value: unknown,
|
|
46
|
-
binding: LocalBinding,
|
|
47
|
-
): IdentityRegistrationResult {
|
|
48
|
-
const result = record(value, 'Provision result')
|
|
49
|
-
const identities = record(result.identities, 'Provision result identities')
|
|
50
|
-
const identity = record(identities[binding], 'Provision result identity binding')
|
|
51
|
-
const createdNodes = record(result.createdNodes, 'Provision result created Nodes')
|
|
52
|
-
const node = createdNodes[binding]
|
|
53
|
-
return Object.freeze({
|
|
54
|
-
iss: issuer.accept(text(identity.issuer, 'Provisioned Identity issuer')),
|
|
55
|
-
sub: text(identity.subject, 'Provisioned Identity subject'),
|
|
56
|
-
...(node === undefined ? {} : { nodeId: NodeId(text(node, 'Provisioned Identity Node')) }),
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function record(value: unknown, label: string): Record<string, unknown> {
|
|
61
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
62
|
-
throw new TypeError(`${label} must be an object.`)
|
|
63
|
-
}
|
|
64
|
-
return value as Record<string, unknown>
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function text(value: unknown, label: string): string {
|
|
68
|
-
if (typeof value !== 'string' || value.length === 0) {
|
|
69
|
-
throw new TypeError(`${label} must be non-empty text.`)
|
|
70
|
-
}
|
|
71
|
-
return value
|
|
72
|
-
}
|
package/src/identity/registry.ts
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { AstraleError } from '../errors'
|
|
2
|
-
import { persistKeypair, removeKeypair } from '../keys/index'
|
|
3
|
-
import { deleteIdpSession } from '../lib/idp'
|
|
4
|
-
import { validateName } from '../lib/validation'
|
|
5
|
-
import {
|
|
6
|
-
readIdentityStore,
|
|
7
|
-
updateIdentityStore,
|
|
8
|
-
type Identity,
|
|
9
|
-
type IdentityMode,
|
|
10
|
-
type IdentityStore,
|
|
11
|
-
type Registration,
|
|
12
|
-
ExchangeCredentialCache,
|
|
13
|
-
SESSION_ROUTE_STORE,
|
|
14
|
-
} from '../state/index'
|
|
15
|
-
|
|
16
|
-
export type { Identity, IdentityStore, Registration } from '../state/index'
|
|
17
|
-
|
|
18
|
-
export async function readIdentities(): Promise<IdentityStore> {
|
|
19
|
-
return readIdentityStore()
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export async function createIdentity(
|
|
23
|
-
name: string,
|
|
24
|
-
options: {
|
|
25
|
-
readonly subject?: string
|
|
26
|
-
readonly mode?: IdentityMode
|
|
27
|
-
readonly issuer?: string
|
|
28
|
-
readonly kid?: string
|
|
29
|
-
} = {},
|
|
30
|
-
): Promise<Identity> {
|
|
31
|
-
validateName(name, 'Identity')
|
|
32
|
-
return updateIdentityStore(async (store) => {
|
|
33
|
-
if (store.identities[name]) throw new Error(`Identity "${name}" already exists`)
|
|
34
|
-
|
|
35
|
-
const subject = options.subject ?? name
|
|
36
|
-
const generated = await persistKeypair(subject, { kid: options.kid })
|
|
37
|
-
const identity: Identity = {
|
|
38
|
-
subject,
|
|
39
|
-
createdAt: new Date().toISOString(),
|
|
40
|
-
source: 'key',
|
|
41
|
-
mode: options.mode ?? 'local',
|
|
42
|
-
kid: generated.kid,
|
|
43
|
-
issuer: options.issuer,
|
|
44
|
-
}
|
|
45
|
-
const hasDefault = store.default !== '' && store.identities[store.default] !== undefined
|
|
46
|
-
return {
|
|
47
|
-
next: {
|
|
48
|
-
default: hasDefault ? store.default : name,
|
|
49
|
-
identities: { ...store.identities, [name]: identity },
|
|
50
|
-
},
|
|
51
|
-
value: identity,
|
|
52
|
-
}
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export async function deleteIdentity(name: string): Promise<void> {
|
|
57
|
-
await updateIdentityStore(async (store) => {
|
|
58
|
-
const entry = store.identities[name]
|
|
59
|
-
if (!entry) throw new Error(`Identity "${name}" not found`)
|
|
60
|
-
if (store.default === name) {
|
|
61
|
-
throw new Error(
|
|
62
|
-
`Cannot delete the default identity "${name}". Switch default first with: astrale identity use <other>`,
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
if ((entry.source ?? 'key') === 'idp') await deleteIdpSession(name)
|
|
66
|
-
else if (!hasAnotherKeyIdentity(store, name, entry.subject)) await removeKeypair(entry.subject)
|
|
67
|
-
|
|
68
|
-
const { [name]: _, ...identities } = store.identities
|
|
69
|
-
return { next: { ...store, identities }, value: undefined }
|
|
70
|
-
})
|
|
71
|
-
await new ExchangeCredentialCache().clear()
|
|
72
|
-
SESSION_ROUTE_STORE.clear()
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function hasAnotherKeyIdentity(store: IdentityStore, name: string, subject: string): boolean {
|
|
76
|
-
return Object.entries(store.identities).some(
|
|
77
|
-
([candidateName, candidate]) =>
|
|
78
|
-
candidateName !== name &&
|
|
79
|
-
(candidate.source ?? 'key') === 'key' &&
|
|
80
|
-
candidate.subject === subject,
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export async function setDefault(name: string): Promise<void> {
|
|
85
|
-
await updateIdentityStore((store) => {
|
|
86
|
-
if (!store.identities[name]) throw new Error(`Identity "${name}" not found`)
|
|
87
|
-
return { next: { ...store, default: name }, value: undefined }
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function getDefault(): Promise<Identity & { readonly name: string }> {
|
|
92
|
-
const store = await readIdentities()
|
|
93
|
-
if (store.default === '' || store.identities[store.default] === undefined) {
|
|
94
|
-
throw new AstraleError(
|
|
95
|
-
'NO_IDENTITY',
|
|
96
|
-
'No default identity.',
|
|
97
|
-
'Run: astrale identity create <name>',
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
const identity = store.identities[store.default]!
|
|
101
|
-
return { ...identity, name: store.default }
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export async function getIdentity(name: string): Promise<Identity> {
|
|
105
|
-
const store = await readIdentities()
|
|
106
|
-
const identity = store.identities[name]
|
|
107
|
-
if (!identity) {
|
|
108
|
-
throw new Error(`Identity "${name}" not found. Run: astrale identity create ${name}`)
|
|
109
|
-
}
|
|
110
|
-
return identity
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export async function upsertIdpIdentity(
|
|
114
|
-
name: string,
|
|
115
|
-
options: {
|
|
116
|
-
readonly subject: string
|
|
117
|
-
readonly idp: string
|
|
118
|
-
readonly issuer: string
|
|
119
|
-
readonly audience?: string
|
|
120
|
-
readonly claims?: Readonly<Record<string, unknown>>
|
|
121
|
-
readonly use?: boolean
|
|
122
|
-
},
|
|
123
|
-
): Promise<Identity> {
|
|
124
|
-
validateName(name, 'Identity')
|
|
125
|
-
validateName(options.idp, 'IdP')
|
|
126
|
-
return updateIdentityStore((store) => {
|
|
127
|
-
const existing = store.identities[name]
|
|
128
|
-
if (existing && (existing.source ?? 'key') !== 'idp') {
|
|
129
|
-
throw new Error(`Identity "${name}" already exists and is key-backed`)
|
|
130
|
-
}
|
|
131
|
-
const identity: Identity = {
|
|
132
|
-
subject: options.subject,
|
|
133
|
-
createdAt: existing?.createdAt ?? new Date().toISOString(),
|
|
134
|
-
source: 'idp',
|
|
135
|
-
mode: 'remote',
|
|
136
|
-
idp: options.idp,
|
|
137
|
-
issuer: options.issuer,
|
|
138
|
-
audience: options.audience,
|
|
139
|
-
claims: options.claims,
|
|
140
|
-
registrations: existing?.registrations,
|
|
141
|
-
}
|
|
142
|
-
return {
|
|
143
|
-
next: {
|
|
144
|
-
default: options.use === false ? store.default : name,
|
|
145
|
-
identities: { ...store.identities, [name]: identity },
|
|
146
|
-
},
|
|
147
|
-
value: identity,
|
|
148
|
-
}
|
|
149
|
-
})
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export async function setRegistration(
|
|
153
|
-
name: string,
|
|
154
|
-
instanceSlug: string,
|
|
155
|
-
registration: Registration,
|
|
156
|
-
): Promise<void> {
|
|
157
|
-
await updateIdentityStore((store) => {
|
|
158
|
-
const entry = store.identities[name]
|
|
159
|
-
if (!entry) throw new Error(`Identity "${name}" not found`)
|
|
160
|
-
const identity: Identity = {
|
|
161
|
-
...entry,
|
|
162
|
-
registrations: { ...entry.registrations, [instanceSlug]: registration },
|
|
163
|
-
}
|
|
164
|
-
return {
|
|
165
|
-
next: { ...store, identities: { ...store.identities, [name]: identity } },
|
|
166
|
-
value: undefined,
|
|
167
|
-
}
|
|
168
|
-
})
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export async function setIdentityMode(name: string, mode: IdentityMode): Promise<void> {
|
|
172
|
-
await updateIdentityStore((store) => {
|
|
173
|
-
const entry = store.identities[name]
|
|
174
|
-
if (!entry) throw new Error(`Identity "${name}" not found`)
|
|
175
|
-
const identity: Identity = { ...entry, mode }
|
|
176
|
-
return {
|
|
177
|
-
next: { ...store, identities: { ...store.identities, [name]: identity } },
|
|
178
|
-
value: undefined,
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
}
|
package/src/identity/transfer.ts
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import { compactDecrypt, CompactEncrypt, type JWK } from 'jose'
|
|
2
|
-
import { z } from 'zod'
|
|
3
|
-
|
|
4
|
-
import { AstraleError } from '../errors'
|
|
5
|
-
import { acceptKeypair, importKeypair, readKeypair } from '../keys/index'
|
|
6
|
-
import { validateName, validateUrl } from '../lib/validation'
|
|
7
|
-
import {
|
|
8
|
-
atomicWrite,
|
|
9
|
-
readIdentityStore,
|
|
10
|
-
updateIdentityStore,
|
|
11
|
-
type Identity,
|
|
12
|
-
type IdentityMode,
|
|
13
|
-
type IdentityStoreOptions,
|
|
14
|
-
} from '../state/index'
|
|
15
|
-
|
|
16
|
-
const IDENTITY_EXPORT_VERSION = 1 as const
|
|
17
|
-
const JwkSchema = z.record(z.string(), z.unknown())
|
|
18
|
-
const IdentityExportFields = {
|
|
19
|
-
subject: z.string().min(1),
|
|
20
|
-
mode: z.enum(['local', 'remote']).optional(),
|
|
21
|
-
kid: z.string().min(1).optional(),
|
|
22
|
-
issuer: z.string().url().optional(),
|
|
23
|
-
privateJwk: JwkSchema,
|
|
24
|
-
publicJwk: JwkSchema,
|
|
25
|
-
}
|
|
26
|
-
const LegacyIdentityExportSchema = z.object(IdentityExportFields).strict()
|
|
27
|
-
const IdentityExportV1Schema = z
|
|
28
|
-
.object({ version: z.literal(IDENTITY_EXPORT_VERSION), ...IdentityExportFields })
|
|
29
|
-
.strict()
|
|
30
|
-
|
|
31
|
-
export interface IdentityFileOptions {
|
|
32
|
-
readonly state?: IdentityStoreOptions
|
|
33
|
-
readonly keysDir?: string
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface IdentityExport {
|
|
37
|
-
readonly version: 1
|
|
38
|
-
readonly subject: string
|
|
39
|
-
readonly mode: IdentityMode
|
|
40
|
-
readonly kid?: string
|
|
41
|
-
readonly issuer?: string
|
|
42
|
-
readonly privateJwk: JWK
|
|
43
|
-
readonly publicJwk: JWK
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface IdentityImportOptions extends IdentityFileOptions {
|
|
47
|
-
readonly name?: string
|
|
48
|
-
readonly issuer?: string
|
|
49
|
-
readonly replace?: boolean
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function isEncryptedIdentityExport(raw: string): boolean {
|
|
53
|
-
const content = raw.trim()
|
|
54
|
-
return !content.startsWith('{') && content.split('.').length === 5
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export async function decodeIdentityExport(
|
|
58
|
-
raw: string,
|
|
59
|
-
passphrase?: string,
|
|
60
|
-
): Promise<IdentityExport> {
|
|
61
|
-
let json = raw
|
|
62
|
-
if (isEncryptedIdentityExport(raw)) {
|
|
63
|
-
if (passphrase === undefined) {
|
|
64
|
-
throw invalidExport('This encrypted identity export requires a passphrase.')
|
|
65
|
-
}
|
|
66
|
-
try {
|
|
67
|
-
const { plaintext } = await compactDecrypt(raw.trim(), new TextEncoder().encode(passphrase), {
|
|
68
|
-
keyManagementAlgorithms: ['PBES2-HS256+A128KW'],
|
|
69
|
-
contentEncryptionAlgorithms: ['A256GCM'],
|
|
70
|
-
})
|
|
71
|
-
json = new TextDecoder().decode(plaintext)
|
|
72
|
-
} catch {
|
|
73
|
-
throw invalidExport('Could not decrypt the identity export.')
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
let input: unknown
|
|
78
|
-
try {
|
|
79
|
-
input = JSON.parse(json)
|
|
80
|
-
} catch {
|
|
81
|
-
throw invalidExport('The identity export is not valid JSON.')
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
let decoded: z.infer<typeof LegacyIdentityExportSchema>
|
|
85
|
-
try {
|
|
86
|
-
decoded = hasVersion(input)
|
|
87
|
-
? IdentityExportV1Schema.parse(input)
|
|
88
|
-
: LegacyIdentityExportSchema.parse(input)
|
|
89
|
-
} catch {
|
|
90
|
-
throw invalidExport('The identity export has an invalid or unsupported shape.')
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const pair = await acceptKeypair({
|
|
94
|
-
privateJwk: decoded.privateJwk,
|
|
95
|
-
publicJwk: decoded.publicJwk,
|
|
96
|
-
})
|
|
97
|
-
if (decoded.kid && pair.kid && decoded.kid !== pair.kid) {
|
|
98
|
-
throw invalidExport('The envelope key ID differs from its JWK key ID.')
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
version: IDENTITY_EXPORT_VERSION,
|
|
103
|
-
subject: decoded.subject,
|
|
104
|
-
mode: decoded.mode ?? 'local',
|
|
105
|
-
kid: decoded.kid ?? pair.kid,
|
|
106
|
-
issuer: decoded.issuer,
|
|
107
|
-
privateJwk: pair.privateJwk,
|
|
108
|
-
publicJwk: pair.publicJwk,
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export async function encodeIdentityExport(
|
|
113
|
-
envelope: IdentityExport,
|
|
114
|
-
passphrase?: string,
|
|
115
|
-
): Promise<string> {
|
|
116
|
-
const plaintext = JSON.stringify(envelope, null, 2)
|
|
117
|
-
if (passphrase === undefined) return plaintext
|
|
118
|
-
return new CompactEncrypt(new TextEncoder().encode(plaintext))
|
|
119
|
-
.setProtectedHeader({ alg: 'PBES2-HS256+A128KW', enc: 'A256GCM' })
|
|
120
|
-
.encrypt(new TextEncoder().encode(passphrase))
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export async function exportIdentity(
|
|
124
|
-
name: string,
|
|
125
|
-
options: IdentityFileOptions = {},
|
|
126
|
-
): Promise<IdentityExport> {
|
|
127
|
-
const store = await readIdentityStore(options.state)
|
|
128
|
-
const identity = store.identities[name]
|
|
129
|
-
if (!identity)
|
|
130
|
-
throw new Error(`Identity "${name}" not found. Run: astrale identity create ${name}`)
|
|
131
|
-
if ((identity.source ?? 'key') !== 'key') {
|
|
132
|
-
throw new Error(`Identity "${name}" is IdP-backed and has no transferable local keypair`)
|
|
133
|
-
}
|
|
134
|
-
const pair = await readKeypair(identity.subject, options.keysDir)
|
|
135
|
-
return {
|
|
136
|
-
version: IDENTITY_EXPORT_VERSION,
|
|
137
|
-
subject: identity.subject,
|
|
138
|
-
mode: identity.mode ?? 'local',
|
|
139
|
-
kid: identity.kid ?? pair.kid,
|
|
140
|
-
issuer: identity.issuer,
|
|
141
|
-
privateJwk: pair.privateJwk,
|
|
142
|
-
publicJwk: pair.publicJwk,
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export async function importIdentity(
|
|
147
|
-
envelope: IdentityExport,
|
|
148
|
-
options: IdentityImportOptions = {},
|
|
149
|
-
): Promise<Identity> {
|
|
150
|
-
const name = options.name ?? envelope.subject
|
|
151
|
-
validateName(name, 'Identity')
|
|
152
|
-
if (options.issuer !== undefined) validateUrl(options.issuer)
|
|
153
|
-
|
|
154
|
-
return updateIdentityStore(async (store) => {
|
|
155
|
-
const existing = store.identities[name]
|
|
156
|
-
if (existing && !options.replace) throw new Error(`Identity "${name}" already exists`)
|
|
157
|
-
if (existing && (existing.source ?? 'key') !== 'key') {
|
|
158
|
-
throw new Error(`Identity "${name}" already exists and is IdP-backed`)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const pair = await importKeypair(envelope.subject, envelope, options.keysDir)
|
|
162
|
-
const identity: Identity = {
|
|
163
|
-
subject: envelope.subject,
|
|
164
|
-
createdAt: existing?.createdAt ?? (options.state?.now?.() ?? new Date()).toISOString(),
|
|
165
|
-
source: 'key',
|
|
166
|
-
mode: envelope.mode,
|
|
167
|
-
kid: envelope.kid ?? pair.kid,
|
|
168
|
-
issuer: options.issuer ?? envelope.issuer,
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
next: { ...store, identities: { ...store.identities, [name]: identity } },
|
|
172
|
-
value: identity,
|
|
173
|
-
}
|
|
174
|
-
}, options.state)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export async function writeIdentityExport(path: string, content: string): Promise<void> {
|
|
178
|
-
await atomicWrite(path, content)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function hasVersion(input: unknown): input is { readonly version: unknown } {
|
|
182
|
-
return typeof input === 'object' && input !== null && Object.hasOwn(input, 'version')
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function invalidExport(message: string): AstraleError {
|
|
186
|
-
return new AstraleError('INVALID_IDENTITY_EXPORT', message)
|
|
187
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {}
|
package/src/keys/.spec/api.d.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type { JWK } from 'jose'
|
|
2
|
-
|
|
3
|
-
type AuthOptions = {
|
|
4
|
-
readonly issuer?: string
|
|
5
|
-
readonly subject?: string
|
|
6
|
-
readonly kid?: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type AuthBinding = {
|
|
10
|
-
readonly credential: string
|
|
11
|
-
readonly publicKey: { readonly jwk: JWK }
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type KeypairPaths = {
|
|
15
|
-
readonly privatePath: string
|
|
16
|
-
readonly publicPath: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface Keypair {
|
|
20
|
-
readonly privateJwk: JWK
|
|
21
|
-
readonly publicJwk: JWK
|
|
22
|
-
readonly kid?: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface KeypairInput {
|
|
26
|
-
readonly privateJwk: unknown
|
|
27
|
-
readonly publicJwk: unknown
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function keypairPaths(subject: string, keysDir?: string): KeypairPaths
|
|
31
|
-
|
|
32
|
-
export function fileExists(path: string): Promise<boolean>
|
|
33
|
-
|
|
34
|
-
export function listIdentityKeys(keysDir?: string): Promise<string[]>
|
|
35
|
-
|
|
36
|
-
export function generateEd25519Jwk(
|
|
37
|
-
kid: string,
|
|
38
|
-
): Promise<{ readonly privateJwk: JWK; readonly publicJwk: JWK }>
|
|
39
|
-
|
|
40
|
-
export function persistKeypair(
|
|
41
|
-
subject: string,
|
|
42
|
-
opts?: { readonly keysDir?: string; readonly kid?: string },
|
|
43
|
-
): Promise<{ readonly publicJwk: JWK; readonly privateJwk: JWK; readonly kid: string }>
|
|
44
|
-
|
|
45
|
-
/** Admit supported private/public JWKs and prove that they form one pair. */
|
|
46
|
-
export function acceptKeypair(input: KeypairInput): Promise<Keypair>
|
|
47
|
-
|
|
48
|
-
/** Decode and cryptographically prove a persisted subject keypair. */
|
|
49
|
-
export function readKeypair(subject: string, keysDir?: string): Promise<Keypair>
|
|
50
|
-
|
|
51
|
-
/** Admit and atomically persist one externally supplied subject keypair. */
|
|
52
|
-
export function importKeypair(
|
|
53
|
-
subject: string,
|
|
54
|
-
input: KeypairInput,
|
|
55
|
-
keysDir?: string,
|
|
56
|
-
): Promise<Keypair>
|
|
57
|
-
|
|
58
|
-
export function removeKeypair(subject: string, keysDir?: string): Promise<void>
|
|
59
|
-
|
|
60
|
-
export function persistAuth(keysDir?: string, opts?: AuthOptions): Promise<AuthBinding>
|
|
61
|
-
|
|
62
|
-
export function loadAuth(keysDir?: string, opts?: AuthOptions): Promise<AuthBinding>
|
|
63
|
-
|
|
64
|
-
export function resolveAuth(keysDir?: string, opts?: AuthOptions): Promise<AuthBinding>
|
|
65
|
-
|
|
66
|
-
export function signAs(
|
|
67
|
-
subject: string,
|
|
68
|
-
keysDir?: string,
|
|
69
|
-
opts?: {
|
|
70
|
-
readonly issuer?: string
|
|
71
|
-
readonly audience?: string
|
|
72
|
-
readonly subject?: string
|
|
73
|
-
},
|
|
74
|
-
): Promise<string>
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# CLI key material
|
|
2
|
-
|
|
3
|
-
This Node-only module owns the retained `@astrale-os/cli/keys` subpath. Manager keys remain on their
|
|
4
|
-
legacy filenames; every other identity uses its own subject-named pair. Writes are private and
|
|
5
|
-
atomic through State. Signing admits the selected private JWK algorithm and never substitutes
|
|
6
|
-
manager material for a missing identity key.
|
|
7
|
-
|
|
8
|
-
Externally supplied or persisted pairs cross a proof-loss boundary here. Keys accepts only supported
|
|
9
|
-
algorithms, keeps paths inside the selected key directory, rejects private material in the public
|
|
10
|
-
file, and proves private/public correspondence before returning or replacing files.
|
|
11
|
-
|
|
12
|
-
The retained Node-only subpath contains the explicit raw-key operations required by import/export
|
|
13
|
-
and scaffold consumers. Ordinary connection code receives signed credentials or public material.
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { defineLaw } from '@astrale-os/spec/authoring'
|
|
2
|
-
|
|
3
|
-
export const CLI_KEYS_IDENTITY_ISOLATED = defineLaw({
|
|
4
|
-
id: 'CLI-KEYS-IDENTITY-ISOLATED',
|
|
5
|
-
statement:
|
|
6
|
-
'Each subject signs only with its own mode-0600 keypair; missing subject material fails even when manager keys exist.',
|
|
7
|
-
tests: [
|
|
8
|
-
{ file: '__tests__/keys.test.ts', id: 'TEST-CLI-KEYS-PRIVATE-MODE' },
|
|
9
|
-
{ file: '__tests__/keys.test.ts', id: 'TEST-CLI-KEYS-NO-MANAGER-FALLBACK' },
|
|
10
|
-
],
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
export const CLI_KEYS_LEGACY_READABLE = defineLaw({
|
|
14
|
-
id: 'CLI-KEYS-LEGACY-READABLE',
|
|
15
|
-
statement:
|
|
16
|
-
'Manager filenames and unstamped supported legacy algorithms remain readable without changing another identity key coordinate.',
|
|
17
|
-
tests: [
|
|
18
|
-
{ file: '__tests__/keys.test.ts', id: 'TEST-CLI-KEYS-LEGACY-FILENAMES' },
|
|
19
|
-
{ file: '__tests__/algorithm.test.ts', id: 'TEST-CLI-KEYS-INFERS-LEGACY-ALGORITHM' },
|
|
20
|
-
],
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
export const CLI_KEYS_PAIR_ADMITTED = defineLaw({
|
|
24
|
-
id: 'CLI-KEYS-PAIR-ADMITTED',
|
|
25
|
-
statement:
|
|
26
|
-
'A subject path remains inside the selected key directory, and imported or persisted material is returned only after supported-algorithm and private/public correspondence proof.',
|
|
27
|
-
tests: [
|
|
28
|
-
{ file: '__tests__/keys.test.ts', id: 'TEST-CLI-KEYS-PAIR-ADMISSION' },
|
|
29
|
-
{ file: '__tests__/keys.test.ts', id: 'TEST-CLI-KEYS-PATH-CONFINED' },
|
|
30
|
-
],
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
export const CLI_KEYS_CREDENTIAL_GRANT_PROFILE = defineLaw({
|
|
34
|
-
id: 'CLI-KEYS-CREDENTIAL-GRANT-PROFILE',
|
|
35
|
-
statement:
|
|
36
|
-
'A self-issued Kernel credential carries the effective subject as an already-resolved identity Grant, while an externally issued primary credential carries an identity-self Grant for Runtime resolution.',
|
|
37
|
-
tests: [
|
|
38
|
-
{
|
|
39
|
-
file: '__tests__/keys.test.ts',
|
|
40
|
-
id: 'TEST-CLI-KEYS-DISTINGUISHES-KERNEL-ROOT-GRANT',
|
|
41
|
-
},
|
|
42
|
-
],
|
|
43
|
-
})
|
package/src/keys/.spec/layout.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { AstraleError } from '../../errors'
|
|
4
|
-
import { inferAlg } from '../algorithm'
|
|
5
|
-
|
|
6
|
-
describe('inferAlg', () => {
|
|
7
|
-
test('returns explicit alg when present', () => {
|
|
8
|
-
expect(inferAlg({ alg: 'ES256' })).toBe('ES256')
|
|
9
|
-
expect(inferAlg({ alg: 'EdDSA' })).toBe('EdDSA')
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
/** @evidence TEST-CLI-KEYS-INFERS-LEGACY-ALGORITHM */
|
|
13
|
-
test('infers supported algorithms for legacy unstamped key files', () => {
|
|
14
|
-
expect(inferAlg({ kty: 'EC', crv: 'P-256' })).toBe('ES256')
|
|
15
|
-
expect(inferAlg({ kty: 'OKP', crv: 'Ed25519' })).toBe('EdDSA')
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
test('explicit alg wins over inferable shape (no second-guessing)', () => {
|
|
19
|
-
expect(inferAlg({ alg: 'ES256', kty: 'OKP', crv: 'Ed25519' })).toBe('ES256')
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
test('throws AstraleError with hint when no alg/crv/kty resolves', () => {
|
|
23
|
-
expect(() => inferAlg({})).toThrow(AstraleError)
|
|
24
|
-
expect(() => inferAlg({ kty: 'EC' })).toThrow(AstraleError)
|
|
25
|
-
expect(() => inferAlg({ kty: 'EC', crv: 'P-384' })).toThrow(AstraleError)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('error message includes keyPath when provided', () => {
|
|
29
|
-
expect(() => inferAlg({}, '/path/to/broken.jwk')).toThrow(/\/path\/to\/broken\.jwk/)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('treats empty-string alg as missing', () => {
|
|
33
|
-
expect(inferAlg({ alg: '', kty: 'EC', crv: 'P-256' })).toBe('ES256')
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
test('rejects unsupported explicit algorithms', () => {
|
|
37
|
-
expect(() => inferAlg({ alg: 'HS256', kty: 'oct' })).toThrow(/unsupported signing algorithm/)
|
|
38
|
-
})
|
|
39
|
-
})
|