@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,61 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises'
|
|
2
|
-
|
|
3
|
-
import type { CommandDefinition } from '../../program/index'
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
decodeIdentityExport,
|
|
7
|
-
importIdentity,
|
|
8
|
-
isEncryptedIdentityExport,
|
|
9
|
-
} from '../../identity/index'
|
|
10
|
-
import { fatal, log } from '../../lib/log'
|
|
11
|
-
import { isMachine, output, RAW_OUTPUT_OPTIONS, type RawOutputOpts } from '../../lib/output'
|
|
12
|
-
import { readPassphrase } from '../../lib/prompt'
|
|
13
|
-
|
|
14
|
-
export default {
|
|
15
|
-
name: 'import',
|
|
16
|
-
description: 'Import an identity keypair envelope (auto-detects JWE)',
|
|
17
|
-
arguments: [{ name: 'path', description: 'Envelope file path', required: true }],
|
|
18
|
-
options: [
|
|
19
|
-
{
|
|
20
|
-
flags: '--name <name>',
|
|
21
|
-
description: 'Override identity name (defaults to envelope subject)',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
flags: '--issuer <url>',
|
|
25
|
-
description: 'Default issuer for credentials signed with this imported key',
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
flags: '--replace',
|
|
29
|
-
description: 'Replace an existing key-backed identity with the imported keypair',
|
|
30
|
-
},
|
|
31
|
-
...RAW_OUTPUT_OPTIONS,
|
|
32
|
-
],
|
|
33
|
-
action: async (
|
|
34
|
-
path: string,
|
|
35
|
-
opts: { name?: string; issuer?: string; replace?: boolean } & RawOutputOpts,
|
|
36
|
-
) => {
|
|
37
|
-
try {
|
|
38
|
-
const raw = await readFile(path, 'utf-8')
|
|
39
|
-
const passphrase = isEncryptedIdentityExport(raw)
|
|
40
|
-
? await readPassphrase('Passphrase: ')
|
|
41
|
-
: undefined
|
|
42
|
-
const envelope = await decodeIdentityExport(raw, passphrase)
|
|
43
|
-
const name = opts.name ?? envelope.subject
|
|
44
|
-
const identity = await importIdentity(envelope, {
|
|
45
|
-
name,
|
|
46
|
-
issuer: opts.issuer,
|
|
47
|
-
replace: opts.replace,
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
if (isMachine(opts)) {
|
|
51
|
-
output({ name, ...identity }, opts)
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
log.success(
|
|
55
|
-
`Imported identity "${name}" (subject=${identity.subject}, kid=${identity.kid ?? '?'})`,
|
|
56
|
-
)
|
|
57
|
-
} catch (e) {
|
|
58
|
-
fatal(e, opts)
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
} satisfies CommandDefinition
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
|
|
3
|
-
import type { ListOpts, ListProjection } from '../../lib/output'
|
|
4
|
-
import type { CommandDefinition } from '../../program/index'
|
|
5
|
-
|
|
6
|
-
import { readIdentities } from '../../identity/index'
|
|
7
|
-
import { log } from '../../lib/log'
|
|
8
|
-
import { isMachine, presentList, RAW_OUTPUT_OPTIONS } from '../../lib/output'
|
|
9
|
-
|
|
10
|
-
type IdentityRow = {
|
|
11
|
-
name: string
|
|
12
|
-
subject: string
|
|
13
|
-
source: string
|
|
14
|
-
idp?: string
|
|
15
|
-
default: boolean
|
|
16
|
-
createdAt?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function projection(items: IdentityRow[]): ListProjection {
|
|
20
|
-
return {
|
|
21
|
-
columns: [
|
|
22
|
-
{ key: 'name', header: 'NAME', color: chalk.bold },
|
|
23
|
-
{ key: 'subject', header: 'SUBJECT', color: chalk.dim },
|
|
24
|
-
{ key: 'source', header: 'SOURCE', color: chalk.dim },
|
|
25
|
-
],
|
|
26
|
-
rows: items.map((i) => ({
|
|
27
|
-
name: i.default ? `${i.name} ${chalk.green('*')}` : i.name,
|
|
28
|
-
subject: i.subject !== i.name ? i.subject : '',
|
|
29
|
-
source: i.source === 'idp' ? `idp:${i.idp ?? '?'}` : 'key',
|
|
30
|
-
})),
|
|
31
|
-
paths: items.map((i) => i.name),
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export default {
|
|
36
|
-
name: 'list',
|
|
37
|
-
description: 'List all identities',
|
|
38
|
-
options: [...RAW_OUTPUT_OPTIONS],
|
|
39
|
-
action: async (opts: ListOpts) => {
|
|
40
|
-
const store = await readIdentities()
|
|
41
|
-
const items: IdentityRow[] = Object.entries(store.identities).map(([name, id]) => ({
|
|
42
|
-
name,
|
|
43
|
-
subject: id.subject,
|
|
44
|
-
source: id.source ?? 'key',
|
|
45
|
-
idp: id.idp,
|
|
46
|
-
default: name === store.default,
|
|
47
|
-
createdAt: id.createdAt,
|
|
48
|
-
}))
|
|
49
|
-
|
|
50
|
-
if (items.length === 0 && !isMachine(opts)) {
|
|
51
|
-
log.dim(' No identities. Run: astrale identity create <name>')
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
presentList(items, opts, projection)
|
|
55
|
-
},
|
|
56
|
-
} satisfies CommandDefinition
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import type { IssuerId, JsonWebKey, ProvisionRequest } from '@astrale-os/sdk/auth'
|
|
2
|
-
import type { ClassKey as ClassKeyValue } from '@astrale-os/sdk/graph/class'
|
|
3
|
-
import type { JWK } from 'jose'
|
|
4
|
-
|
|
5
|
-
import { provision, jwk } from '@astrale-os/sdk/auth'
|
|
6
|
-
import { LocalBinding } from '@astrale-os/sdk/graph'
|
|
7
|
-
import { normalizeProperties } from '@astrale-os/sdk/graph/properties'
|
|
8
|
-
import { MutationAST } from '@astrale-os/sdk/mutation'
|
|
9
|
-
import { importJWK, SignJWT } from 'jose'
|
|
10
|
-
import { readFile } from 'node:fs/promises'
|
|
11
|
-
|
|
12
|
-
import type { KernelCommandOpts } from '../../connection'
|
|
13
|
-
import type { IdentityRegistrationResult } from '../../identity/index'
|
|
14
|
-
import type { CommandDefinition } from '../../program/index'
|
|
15
|
-
|
|
16
|
-
import { registrationKeyForTarget, runKernelCommand } from '../../connection'
|
|
17
|
-
import { classKey } from '../../graph'
|
|
18
|
-
import { getIdentity, setRegistration, submitIdentityProvision } from '../../identity/index'
|
|
19
|
-
import { fileExists, keypairPaths } from '../../keys/index'
|
|
20
|
-
import { fatal, log } from '../../lib/log'
|
|
21
|
-
import { output } from '../../lib/output'
|
|
22
|
-
|
|
23
|
-
type RegisterOpts = KernelCommandOpts & {
|
|
24
|
-
class?: string
|
|
25
|
-
props?: string
|
|
26
|
-
via?: string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async function readJwk(path: string): Promise<JWK> {
|
|
30
|
-
return JSON.parse(await readFile(path, 'utf8')) as JWK
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default {
|
|
34
|
-
name: 'register',
|
|
35
|
-
description: 'Atomically provision a local key identity and its V2 graph Node',
|
|
36
|
-
afterHelpText: `
|
|
37
|
-
Behavior:
|
|
38
|
-
Creates one Node through Mutation V3 and designates it as a self-proven
|
|
39
|
-
Identity in the same atomic Auth.provision request. --class is required;
|
|
40
|
-
--props must use fully-qualified Property keys owned by that Class.
|
|
41
|
-
|
|
42
|
-
By default the authenticated caller submits the request directly to Kernel
|
|
43
|
-
Auth.provision. Use --via for an application-owned identity Class: the CLI
|
|
44
|
-
sends the exact self-proven request through that Domain callable, then admits
|
|
45
|
-
its result and stores the same target-bound registration. The callable owns
|
|
46
|
-
authorization; the CLI never receives installed Domain authority.
|
|
47
|
-
|
|
48
|
-
The Kernel assigns each Node ID; callers do not choose a storage path. The
|
|
49
|
-
CLI binds the key proof to the exact provision fingerprint and target Kernel
|
|
50
|
-
audience, then caches the returned (issuer, subject) for subsequent calls.
|
|
51
|
-
|
|
52
|
-
Example:
|
|
53
|
-
$ astrale identity register alice --class /:accounts.example:class.User \
|
|
54
|
-
--props '{"accounts.example:class.User.property.name":"Alice"}' -i staging
|
|
55
|
-
$ astrale identity register responder --class /:ops.example:class.Operator \
|
|
56
|
-
--via /:ops.example:function.provisionOperator -i staging
|
|
57
|
-
`,
|
|
58
|
-
arguments: [{ name: 'name', description: 'Local identity name', required: true }],
|
|
59
|
-
options: [
|
|
60
|
-
{
|
|
61
|
-
flags: '--class <classPath>',
|
|
62
|
-
description: 'Exact Class of the identity-bearing Node (required)',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
flags: '--props <json>',
|
|
66
|
-
description: 'Fully-qualified canonical properties for the new Node',
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
flags: '--via <callablePath>',
|
|
70
|
-
description: 'Submit the self-proven request through an authorizing Domain callable',
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
action: async (name: string, opts: RegisterOpts) => {
|
|
74
|
-
try {
|
|
75
|
-
if (!opts.class) throw new TypeError('Missing required flag: --class <classPath>')
|
|
76
|
-
const identity = await getIdentity(name)
|
|
77
|
-
const { privatePath, publicPath } = keypairPaths(identity.subject)
|
|
78
|
-
if (!(await fileExists(privatePath)) || !(await fileExists(publicPath))) {
|
|
79
|
-
throw new Error(
|
|
80
|
-
`No keypair on disk for "${name}" (expected ${privatePath}). Recreate it with \`astrale identity create ${name}\`.`,
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const privateKey = await readJwk(privatePath)
|
|
85
|
-
const publicKey = jwk.acceptPublic(await readJwk(publicPath))
|
|
86
|
-
const classPath = classKey(opts.class, '--class')
|
|
87
|
-
const properties = normalizeProperties(opts.props ? JSON.parse(opts.props) : {})
|
|
88
|
-
|
|
89
|
-
await runKernelCommand<IdentityRegistrationResult>({
|
|
90
|
-
opts,
|
|
91
|
-
label: `Register "${name}"`,
|
|
92
|
-
fn: async ({ auth, session, target }) => {
|
|
93
|
-
const registrationKey = registrationKeyForTarget(target)
|
|
94
|
-
const existing = identity.registrations?.[registrationKey]
|
|
95
|
-
if (existing) {
|
|
96
|
-
log.warn(`"${name}" is already registered on "${registrationKey}"`)
|
|
97
|
-
return existing
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const prepared = await prepareIdentityProvision({
|
|
101
|
-
name,
|
|
102
|
-
classPath,
|
|
103
|
-
properties,
|
|
104
|
-
privateKey,
|
|
105
|
-
publicKey,
|
|
106
|
-
kernelIssuer: target.kernelIssuer,
|
|
107
|
-
})
|
|
108
|
-
const registered = await submitIdentityProvision({
|
|
109
|
-
request: prepared.request,
|
|
110
|
-
binding: prepared.binding,
|
|
111
|
-
...(opts.via === undefined ? {} : { via: opts.via }),
|
|
112
|
-
direct: auth,
|
|
113
|
-
callable: session,
|
|
114
|
-
})
|
|
115
|
-
await setRegistration(name, registrationKey, {
|
|
116
|
-
iss: registered.iss,
|
|
117
|
-
sub: registered.sub,
|
|
118
|
-
registeredAt: new Date().toISOString(),
|
|
119
|
-
})
|
|
120
|
-
return registered
|
|
121
|
-
},
|
|
122
|
-
format: formatIdentityRegistration,
|
|
123
|
-
})
|
|
124
|
-
} catch (error) {
|
|
125
|
-
fatal(error, opts)
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
} satisfies CommandDefinition
|
|
129
|
-
|
|
130
|
-
/** Preserve one structured stdout value while retaining useful detail in the human view. */
|
|
131
|
-
export function formatIdentityRegistration(
|
|
132
|
-
result: IdentityRegistrationResult,
|
|
133
|
-
format: KernelCommandOpts,
|
|
134
|
-
machine: boolean,
|
|
135
|
-
): void {
|
|
136
|
-
output(result, format)
|
|
137
|
-
if (machine) return
|
|
138
|
-
log.dim(` iss=${result.iss}`)
|
|
139
|
-
log.dim(` sub=${result.sub}`)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/** Build and self-prove one exact canonical provision request for the target Kernel. */
|
|
143
|
-
export async function prepareIdentityProvision(input: {
|
|
144
|
-
readonly name: string
|
|
145
|
-
readonly classPath: ClassKeyValue
|
|
146
|
-
readonly properties: ReturnType<typeof normalizeProperties>
|
|
147
|
-
readonly privateKey: JWK
|
|
148
|
-
readonly publicKey: JsonWebKey
|
|
149
|
-
readonly kernelIssuer: IssuerId
|
|
150
|
-
}): Promise<{
|
|
151
|
-
readonly binding: ReturnType<typeof LocalBinding>
|
|
152
|
-
readonly request: ProvisionRequest
|
|
153
|
-
}> {
|
|
154
|
-
const binding = LocalBinding('identity')
|
|
155
|
-
const mutation = MutationAST.build((builder) => {
|
|
156
|
-
builder.createNode({ as: binding, class: input.classPath, props: input.properties })
|
|
157
|
-
return undefined
|
|
158
|
-
})
|
|
159
|
-
const idempotencyKey = `identity-register:${input.name}`
|
|
160
|
-
const unsigned = provision.accept({
|
|
161
|
-
idempotencyKey,
|
|
162
|
-
mutation,
|
|
163
|
-
identities: {
|
|
164
|
-
[binding]: { credentials: { publicKey: input.publicKey, proof: 'pending-proof' } },
|
|
165
|
-
},
|
|
166
|
-
})
|
|
167
|
-
const fingerprint = await provision.fingerprint(unsigned)
|
|
168
|
-
const issuer = await provision.selfIssuer(input.kernelIssuer, input.publicKey)
|
|
169
|
-
const proof = await mintProvisionProof(input.privateKey, issuer, input.kernelIssuer, fingerprint)
|
|
170
|
-
return {
|
|
171
|
-
binding,
|
|
172
|
-
request: provision.accept({
|
|
173
|
-
idempotencyKey,
|
|
174
|
-
mutation,
|
|
175
|
-
identities: { [binding]: { credentials: { publicKey: input.publicKey, proof } } },
|
|
176
|
-
}),
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
async function mintProvisionProof(
|
|
181
|
-
privateKey: JWK,
|
|
182
|
-
issuer: string,
|
|
183
|
-
audience: string,
|
|
184
|
-
fingerprint: string,
|
|
185
|
-
): Promise<string> {
|
|
186
|
-
const key = await importJWK(privateKey, 'ES256')
|
|
187
|
-
return new SignJWT({ provision: fingerprint })
|
|
188
|
-
.setProtectedHeader({ alg: 'ES256', ...(privateKey.kid ? { kid: privateKey.kid } : {}) })
|
|
189
|
-
.setIssuer(issuer)
|
|
190
|
-
.setSubject('self')
|
|
191
|
-
.setAudience(audience)
|
|
192
|
-
.setIssuedAt()
|
|
193
|
-
.setExpirationTime('5m')
|
|
194
|
-
.sign(key)
|
|
195
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { CommandDefinition } from '../../program/index'
|
|
2
|
-
|
|
3
|
-
import { getIdentity, setIdentityMode } from '../../identity/index'
|
|
4
|
-
import { fatal, fatalNotImplemented, log } from '../../lib/log'
|
|
5
|
-
import { isMachine, output, RAW_OUTPUT_OPTIONS, type RawOutputOpts } from '../../lib/output'
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
name: 'sync',
|
|
9
|
-
description: 'Migrate an identity local → remote (astrale cloud)',
|
|
10
|
-
arguments: [{ name: 'name', description: 'Identity name', required: true }],
|
|
11
|
-
options: [
|
|
12
|
-
{
|
|
13
|
-
flags: '--force',
|
|
14
|
-
description: 'Tag as remote in the local registry even without cloud login',
|
|
15
|
-
},
|
|
16
|
-
...RAW_OUTPUT_OPTIONS,
|
|
17
|
-
],
|
|
18
|
-
action: async (name: string, opts: { force?: boolean } & RawOutputOpts) => {
|
|
19
|
-
try {
|
|
20
|
-
const identity = await getIdentity(name)
|
|
21
|
-
if (!opts.force) {
|
|
22
|
-
fatalNotImplemented(
|
|
23
|
-
'identity sync (remote)',
|
|
24
|
-
'Cloud adapter is stubbed in v1. Use --force to pre-tag the identity locally.',
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
await setIdentityMode(name, 'remote')
|
|
28
|
-
if (isMachine(opts)) {
|
|
29
|
-
output({ name, mode: 'remote', subject: identity.subject }, opts)
|
|
30
|
-
return
|
|
31
|
-
}
|
|
32
|
-
log.warn(`Tagged "${name}" as remote locally (cloud sync stubbed in v1)`)
|
|
33
|
-
log.dim(` subject=${identity.subject}`)
|
|
34
|
-
} catch (e) {
|
|
35
|
-
fatal(e, opts)
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
} satisfies CommandDefinition
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { CommandDefinition } from '../../program/index'
|
|
2
|
-
|
|
3
|
-
import { getIdentity, setIdentityMode } from '../../identity/index'
|
|
4
|
-
import { fatal, log } from '../../lib/log'
|
|
5
|
-
import { isMachine, output, RAW_OUTPUT_OPTIONS, type RawOutputOpts } from '../../lib/output'
|
|
6
|
-
|
|
7
|
-
/** Metadata-only flip remote → local until cloud sync ships (§2.7). */
|
|
8
|
-
export default {
|
|
9
|
-
name: 'unsync',
|
|
10
|
-
description: 'Migrate an identity remote → local',
|
|
11
|
-
arguments: [{ name: 'name', description: 'Identity name', required: true }],
|
|
12
|
-
options: [...RAW_OUTPUT_OPTIONS],
|
|
13
|
-
action: async (name: string, opts: RawOutputOpts) => {
|
|
14
|
-
try {
|
|
15
|
-
const identity = await getIdentity(name)
|
|
16
|
-
if (identity.mode !== 'remote') {
|
|
17
|
-
if (isMachine(opts)) {
|
|
18
|
-
output({ name, mode: identity.mode ?? 'local', unchanged: true }, opts)
|
|
19
|
-
return
|
|
20
|
-
}
|
|
21
|
-
log.warn(`Identity "${name}" is already ${identity.mode ?? 'local'}`)
|
|
22
|
-
return
|
|
23
|
-
}
|
|
24
|
-
await setIdentityMode(name, 'local')
|
|
25
|
-
if (isMachine(opts)) {
|
|
26
|
-
output({ name, mode: 'local' }, opts)
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
log.success(`Identity "${name}" → local`)
|
|
30
|
-
} catch (e) {
|
|
31
|
-
fatal(e, opts)
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
} satisfies CommandDefinition
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { CommandDefinition } from '../../program/index'
|
|
2
|
-
|
|
3
|
-
import { setDefault } from '../../identity/index'
|
|
4
|
-
import { fatal, log } from '../../lib/log'
|
|
5
|
-
import { isMachine, output, RAW_OUTPUT_OPTIONS, type RawOutputOpts } from '../../lib/output'
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
name: 'use',
|
|
9
|
-
description: 'Set the active CLI identity',
|
|
10
|
-
arguments: [{ name: 'name', description: 'Identity name', required: true }],
|
|
11
|
-
options: [...RAW_OUTPUT_OPTIONS],
|
|
12
|
-
action: async (name: string, opts: RawOutputOpts) => {
|
|
13
|
-
try {
|
|
14
|
-
await setDefault(name)
|
|
15
|
-
if (isMachine(opts)) {
|
|
16
|
-
output({ default: name }, opts)
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
log.success(`Active identity set to "${name}"`)
|
|
20
|
-
} catch (e) {
|
|
21
|
-
fatal(e, opts)
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
} satisfies CommandDefinition
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
|
|
3
|
-
import type { CommandDefinition } from '../../program/index'
|
|
4
|
-
|
|
5
|
-
import { getDefault } from '../../identity/index'
|
|
6
|
-
import { fatal } from '../../lib/log'
|
|
7
|
-
import { isMachine, output, RAW_OUTPUT_OPTIONS, type RawOutputOpts } from '../../lib/output'
|
|
8
|
-
|
|
9
|
-
type WhoamiResult = {
|
|
10
|
-
name: string
|
|
11
|
-
subject: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default {
|
|
15
|
-
name: 'whoami',
|
|
16
|
-
description: 'Show the current default identity',
|
|
17
|
-
options: [...RAW_OUTPUT_OPTIONS],
|
|
18
|
-
action: async (opts: RawOutputOpts) => {
|
|
19
|
-
try {
|
|
20
|
-
const identity = await getDefault()
|
|
21
|
-
const result: WhoamiResult = {
|
|
22
|
-
name: identity.name,
|
|
23
|
-
subject: identity.subject,
|
|
24
|
-
}
|
|
25
|
-
if (isMachine(opts)) {
|
|
26
|
-
output(result, opts)
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
console.log(`${chalk.bold(result.name)} (subject: ${result.subject})`)
|
|
30
|
-
} catch (e) {
|
|
31
|
-
fatal(e, opts)
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
} satisfies CommandDefinition
|
package/src/commands/idp/add.ts
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises'
|
|
2
|
-
|
|
3
|
-
import type { CommandDefinition } from '../../program/index'
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
fetchOidcMetadata,
|
|
7
|
-
fetchWorkosApplication,
|
|
8
|
-
OidcMetadataSchema,
|
|
9
|
-
type IdpClientConfig,
|
|
10
|
-
upsertIdpConfig,
|
|
11
|
-
workosAuthKitMetadata,
|
|
12
|
-
} from '../../lib/idp'
|
|
13
|
-
import { log } from '../../lib/log'
|
|
14
|
-
import { isMachine, output, RAW_OUTPUT_OPTIONS } from '../../lib/output'
|
|
15
|
-
import { validateName, validateUrl } from '../../lib/validation'
|
|
16
|
-
|
|
17
|
-
type AddOpts = {
|
|
18
|
-
issuer?: string
|
|
19
|
-
metadata?: string
|
|
20
|
-
clientId?: string
|
|
21
|
-
clientSecretEnv?: string
|
|
22
|
-
redirectUri?: string
|
|
23
|
-
scope?: string
|
|
24
|
-
public?: boolean
|
|
25
|
-
workosApiKeyEnv?: string
|
|
26
|
-
workosApp?: string
|
|
27
|
-
workosAuthkit?: boolean
|
|
28
|
-
workosApiHostname?: string
|
|
29
|
-
raw?: boolean
|
|
30
|
-
json?: boolean
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default {
|
|
34
|
-
name: 'add',
|
|
35
|
-
description: 'Add or update an OpenID Connect identity provider',
|
|
36
|
-
arguments: [{ name: 'name', description: 'Local IdP registry name' }],
|
|
37
|
-
options: [
|
|
38
|
-
{ flags: '--issuer <url>', description: 'OIDC issuer URL' },
|
|
39
|
-
{ flags: '--metadata <path>', description: 'Read discovery metadata from a local JSON file' },
|
|
40
|
-
{ flags: '--client-id <id>', description: 'OAuth/OIDC client ID' },
|
|
41
|
-
{ flags: '--client-secret-env <name>', description: 'Env var containing the client secret' },
|
|
42
|
-
{ flags: '--redirect-uri <url>', description: 'Redirect URI for authorization-code login' },
|
|
43
|
-
{ flags: '--scope <scope>', description: 'Default OAuth scope string' },
|
|
44
|
-
{ flags: '--public', description: 'Mark the client as public/PKCE-capable' },
|
|
45
|
-
{
|
|
46
|
-
flags: '--workos-api-key-env <name>',
|
|
47
|
-
description: 'Env var containing the WorkOS API key',
|
|
48
|
-
default: 'WORKOS_API_KEY',
|
|
49
|
-
},
|
|
50
|
-
{ flags: '--workos-app <id>', description: 'Fetch WorkOS Connect application metadata' },
|
|
51
|
-
{
|
|
52
|
-
flags: '--workos-authkit',
|
|
53
|
-
description: 'Configure WorkOS AuthKit CLI Auth using client_id only',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
flags: '--workos-api-hostname <url>',
|
|
57
|
-
description: 'WorkOS API host for AuthKit CLI Auth',
|
|
58
|
-
default: 'https://api.workos.com',
|
|
59
|
-
},
|
|
60
|
-
...RAW_OUTPUT_OPTIONS,
|
|
61
|
-
],
|
|
62
|
-
afterHelpText: `
|
|
63
|
-
Examples:
|
|
64
|
-
$ astrale idp add workos --workos-authkit --client-id client_...
|
|
65
|
-
$ astrale idp add workos-connect --issuer https://example.authkit.app \\
|
|
66
|
-
--client-id client_... --scope "openid profile email offline_access"
|
|
67
|
-
$ astrale idp add workos-connect --issuer https://example.authkit.app \\
|
|
68
|
-
--workos-app app_... --workos-api-key-env WORKOS_API_KEY
|
|
69
|
-
|
|
70
|
-
Security:
|
|
71
|
-
Client secrets and WorkOS API keys are never stored by the CLI. Store only
|
|
72
|
-
the env var name with --client-secret-env / --workos-api-key-env.
|
|
73
|
-
`,
|
|
74
|
-
action: async (name: string, opts: AddOpts) => {
|
|
75
|
-
validateName(name, 'IdP')
|
|
76
|
-
if (!opts.issuer && !opts.metadata && !opts.workosAuthkit) {
|
|
77
|
-
throw new Error('Either --issuer, --metadata, or --workos-authkit is required')
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
let metadata = opts.workosAuthkit
|
|
81
|
-
? workosAuthKitMetadata(opts.workosApiHostname, opts.clientId)
|
|
82
|
-
: opts.metadata
|
|
83
|
-
? OidcMetadataSchema.parse(JSON.parse(await readFile(opts.metadata, 'utf-8')))
|
|
84
|
-
: await fetchOidcMetadata(opts.issuer!)
|
|
85
|
-
|
|
86
|
-
if (opts.issuer) {
|
|
87
|
-
validateUrl(opts.issuer)
|
|
88
|
-
if (normalizeIssuer(metadata.issuer) !== normalizeIssuer(opts.issuer)) {
|
|
89
|
-
throw new Error(
|
|
90
|
-
`OIDC issuer mismatch: metadata has ${metadata.issuer}, expected ${opts.issuer}`,
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let client: IdpClientConfig = {
|
|
96
|
-
client_id: opts.clientId,
|
|
97
|
-
client_secret_env: opts.clientSecretEnv,
|
|
98
|
-
redirect_uris: opts.redirectUri ? [opts.redirectUri] : undefined,
|
|
99
|
-
scope: opts.scope,
|
|
100
|
-
public: opts.public,
|
|
101
|
-
token_response: opts.workosAuthkit ? 'workos-authkit' : undefined,
|
|
102
|
-
token_request_format: opts.workosAuthkit ? 'json' : undefined,
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (opts.workosApp) {
|
|
106
|
-
const app = await fetchWorkosApplication({
|
|
107
|
-
app: opts.workosApp,
|
|
108
|
-
apiKeyEnv: opts.workosApiKeyEnv ?? 'WORKOS_API_KEY',
|
|
109
|
-
})
|
|
110
|
-
client = {
|
|
111
|
-
...client,
|
|
112
|
-
client_id: client.client_id ?? app.client_id,
|
|
113
|
-
redirect_uris:
|
|
114
|
-
client.redirect_uris ?? app.redirect_uris?.map((uri) => uri.uri).filter(isString),
|
|
115
|
-
scope: client.scope ?? app.scopes?.join(' '),
|
|
116
|
-
public: client.public ?? app.uses_pkce,
|
|
117
|
-
workos_application_id: app.id,
|
|
118
|
-
workos_application_type: app.application_type,
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (opts.workosAuthkit && client.client_id) {
|
|
123
|
-
metadata = workosAuthKitMetadata(opts.workosApiHostname, client.client_id)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const idp = await upsertIdpConfig({ name, metadata, client })
|
|
127
|
-
if (isMachine(opts)) {
|
|
128
|
-
output(redact(idp), opts)
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
log.success(`IdP "${name}" saved`)
|
|
133
|
-
log.dim(` issuer: ${idp.metadata.issuer}`)
|
|
134
|
-
if (idp.client.client_id) log.dim(` client_id: ${idp.client.client_id}`)
|
|
135
|
-
if (idp.client.client_secret_env)
|
|
136
|
-
log.dim(` client_secret_env: ${idp.client.client_secret_env}`)
|
|
137
|
-
},
|
|
138
|
-
} satisfies CommandDefinition
|
|
139
|
-
|
|
140
|
-
function isString(value: unknown): value is string {
|
|
141
|
-
return typeof value === 'string'
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function redact<T extends { client: IdpClientConfig }>(value: T): T {
|
|
145
|
-
return value
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function normalizeIssuer(value: string): string {
|
|
149
|
-
return value.replace(/\/+$/, '')
|
|
150
|
-
}
|
package/src/commands/idp/list.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
|
|
3
|
-
import type { ListOpts, ListProjection } from '../../lib/output'
|
|
4
|
-
import type { CommandDefinition } from '../../program/index'
|
|
5
|
-
|
|
6
|
-
import { listIdpConfigs } from '../../lib/idp'
|
|
7
|
-
import { log } from '../../lib/log'
|
|
8
|
-
import { isMachine, presentList, RAW_OUTPUT_OPTIONS } from '../../lib/output'
|
|
9
|
-
|
|
10
|
-
type IdpRow = {
|
|
11
|
-
name: string
|
|
12
|
-
issuer: string
|
|
13
|
-
clientId?: string
|
|
14
|
-
scope?: string
|
|
15
|
-
builtIn: boolean
|
|
16
|
-
updatedAt?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function projection(items: IdpRow[]): ListProjection {
|
|
20
|
-
return {
|
|
21
|
-
columns: [
|
|
22
|
-
{ key: 'name', header: 'NAME', color: chalk.bold },
|
|
23
|
-
{ key: 'type', header: 'TYPE', color: chalk.dim },
|
|
24
|
-
{ key: 'issuer', header: 'ISSUER', color: chalk.dim },
|
|
25
|
-
{ key: 'clientId', header: 'CLIENT_ID', color: chalk.dim },
|
|
26
|
-
],
|
|
27
|
-
rows: items.map((i) => ({
|
|
28
|
-
name: i.name,
|
|
29
|
-
type: i.builtIn ? 'built-in' : 'custom',
|
|
30
|
-
issuer: i.issuer ?? '',
|
|
31
|
-
clientId: i.clientId ?? '',
|
|
32
|
-
})),
|
|
33
|
-
paths: items.map((i) => i.name),
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export default {
|
|
38
|
-
name: 'list',
|
|
39
|
-
description: 'List configured identity providers',
|
|
40
|
-
options: [...RAW_OUTPUT_OPTIONS],
|
|
41
|
-
action: async (opts: ListOpts) => {
|
|
42
|
-
const items: IdpRow[] = (await listIdpConfigs()).map((config) => ({
|
|
43
|
-
name: config.name,
|
|
44
|
-
issuer: config.entry.issuer,
|
|
45
|
-
clientId: config.client.client_id,
|
|
46
|
-
scope: config.client.scope,
|
|
47
|
-
builtIn: !!config.entry.builtIn,
|
|
48
|
-
updatedAt: config.entry.updatedAt,
|
|
49
|
-
}))
|
|
50
|
-
|
|
51
|
-
if (items.length === 0 && !isMachine(opts)) {
|
|
52
|
-
log.dim(' No IdPs. Run: astrale idp add <name> --issuer <url>')
|
|
53
|
-
return
|
|
54
|
-
}
|
|
55
|
-
presentList(items, opts, projection)
|
|
56
|
-
},
|
|
57
|
-
} satisfies CommandDefinition
|