@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,155 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
|
|
3
|
-
import type { KernelCommandOpts } from '../../connection'
|
|
4
|
-
import type { ListProjection, RawOutputOpts } from '../../lib/output'
|
|
5
|
-
import type { CommandDefinition } from '../../program/index'
|
|
6
|
-
|
|
7
|
-
import { listAdminDomains, type DomainInfo } from '../../lib/admin-domain'
|
|
8
|
-
import { ADMIN_TARGET_OPTIONS, type AdminTargetCommandOpts } from '../../lib/admin-target'
|
|
9
|
-
import { fetchDomainPublication } from '../../lib/domain-publication'
|
|
10
|
-
import { fatal, withSpinner } from '../../lib/log'
|
|
11
|
-
import { isMachine, presentList } from '../../lib/output'
|
|
12
|
-
|
|
13
|
-
type ListOpts = KernelCommandOpts &
|
|
14
|
-
AdminTargetCommandOpts &
|
|
15
|
-
RawOutputOpts & {
|
|
16
|
-
check?: boolean
|
|
17
|
-
defaultOnly?: boolean
|
|
18
|
-
quiet?: boolean
|
|
19
|
-
count?: boolean
|
|
20
|
-
long?: boolean
|
|
21
|
-
format?: 'yaml' | 'json'
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** A catalog entry, optionally enriched with a live `--check` probe. */
|
|
25
|
-
export type DomainRow = DomainInfo & {
|
|
26
|
-
reachable?: boolean
|
|
27
|
-
schemaRevision?: string
|
|
28
|
-
checkError?: string | null
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Catalog rows for the human table. `paths` is the published URL (falling back
|
|
33
|
-
* to origin) so `astrale domain list -q | xargs -I{} astrale domain install {}`
|
|
34
|
-
* composes — install takes a URL. The STATUS column is dropped by `renderTable`
|
|
35
|
-
* unless `--check` filled it in.
|
|
36
|
-
*/
|
|
37
|
-
export function domainProjection(items: DomainRow[]): ListProjection {
|
|
38
|
-
return {
|
|
39
|
-
columns: [
|
|
40
|
-
{ key: 'name', header: 'NAME', color: chalk.bold },
|
|
41
|
-
{ key: 'origin', header: 'ORIGIN', color: chalk.cyan },
|
|
42
|
-
{ key: 'url', header: 'URL', color: chalk.dim },
|
|
43
|
-
{ key: 'default', header: 'DEFAULT' },
|
|
44
|
-
{ key: 'status', header: 'STATUS' },
|
|
45
|
-
],
|
|
46
|
-
rows: items.map((d) => ({
|
|
47
|
-
name: d.name,
|
|
48
|
-
origin: d.origin,
|
|
49
|
-
url: d.url ?? chalk.dim('(unpublished)'),
|
|
50
|
-
default: d.installByDefault ? chalk.green('default') : '',
|
|
51
|
-
status: statusCell(d),
|
|
52
|
-
})),
|
|
53
|
-
paths: items.map((d) => d.url ?? d.origin),
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function statusCell(d: DomainRow): string {
|
|
58
|
-
if (d.reachable === undefined) return ''
|
|
59
|
-
return d.reachable ? chalk.green('● live') : chalk.red(`○ ${d.checkError ?? 'unreachable'}`)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export default {
|
|
63
|
-
name: 'list',
|
|
64
|
-
description: 'List domains published in the admin catalog (DomainEntry.list)',
|
|
65
|
-
afterHelpText: `
|
|
66
|
-
Behavior:
|
|
67
|
-
Reads the admin catalog — every domain that has been \`publish\`ed
|
|
68
|
-
(origin → published worker URL). Listing only shows what is INSTALLABLE;
|
|
69
|
-
what is actually mounted where lives on each instance's own graph
|
|
70
|
-
(\`astrale query\` against that instance).
|
|
71
|
-
|
|
72
|
-
Default output is a NAME/ORIGIN/URL/DEFAULT table on a TTY, JSON when piped
|
|
73
|
-
or with --json/--raw (agent-friendly — full DomainInfo objects). -q prints
|
|
74
|
-
one install URL per line (pipeable into \`domain install\`); --count prints
|
|
75
|
-
only the number. --default-only keeps the install-by-default entries (what
|
|
76
|
-
every new instance receives during Admin-managed provisioning). --check probes each published URL's
|
|
77
|
-
canonical Publication and adds a live/unreachable STATUS column
|
|
78
|
-
(+ reachable/schemaRevision in machine output).
|
|
79
|
-
|
|
80
|
-
The admin kernel is selected like every admin op — the configured default,
|
|
81
|
-
or --admin <bookmark> / --admin-url <url>.
|
|
82
|
-
|
|
83
|
-
Examples:
|
|
84
|
-
$ astrale domain list
|
|
85
|
-
$ astrale domain list --check
|
|
86
|
-
$ astrale domain list --default-only -q
|
|
87
|
-
$ astrale domain list --json | jq -r '.[].url'
|
|
88
|
-
`,
|
|
89
|
-
options: [
|
|
90
|
-
...ADMIN_TARGET_OPTIONS,
|
|
91
|
-
{
|
|
92
|
-
flags: '--check',
|
|
93
|
-
description: "Probe each domain's canonical Publication + schema revision",
|
|
94
|
-
},
|
|
95
|
-
{ flags: '--default-only', description: 'Only show install-by-default domains' },
|
|
96
|
-
{ flags: '-q, --quiet', description: 'One install URL per line (unix-pipeable)' },
|
|
97
|
-
{ flags: '--count', description: 'Print only the number of published domains' },
|
|
98
|
-
{ flags: '-l, --long', description: 'Full catalog records in machine output' },
|
|
99
|
-
],
|
|
100
|
-
action: async (opts: ListOpts) => {
|
|
101
|
-
try {
|
|
102
|
-
const domains = await withSpinner(
|
|
103
|
-
'Fetching domains',
|
|
104
|
-
!isMachine(opts),
|
|
105
|
-
async (): Promise<DomainRow[]> => {
|
|
106
|
-
const list = await listAdminDomains(opts)
|
|
107
|
-
const filtered = opts.defaultOnly ? list.filter((d) => d.installByDefault) : list
|
|
108
|
-
filtered.sort(byDefaultThenName)
|
|
109
|
-
if (!opts.check) return filtered as DomainRow[]
|
|
110
|
-
// Reachability is a direct client-side Publication fetch per entry, in
|
|
111
|
-
// parallel — no admin round-trip, and version-independent of the
|
|
112
|
-
// admin worker (mirrors `domain install`'s probeDeclaredOrigin).
|
|
113
|
-
return Promise.all(filtered.map(probe))
|
|
114
|
-
},
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
presentList(
|
|
118
|
-
domains,
|
|
119
|
-
{ ...opts, quiet: opts.quiet, count: opts.count, long: opts.long },
|
|
120
|
-
domainProjection,
|
|
121
|
-
)
|
|
122
|
-
} catch (e) {
|
|
123
|
-
fatal(e)
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
} satisfies CommandDefinition
|
|
127
|
-
|
|
128
|
-
/** Install-by-default first, then alphabetical by origin — a stable display order. */
|
|
129
|
-
export function byDefaultThenName(a: DomainInfo, b: DomainInfo): number {
|
|
130
|
-
if (!!a.installByDefault !== !!b.installByDefault) return a.installByDefault ? -1 : 1
|
|
131
|
-
return a.origin.localeCompare(b.origin)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Enrich one entry with a reachability probe: fetch the published worker's
|
|
136
|
-
* canonical Publication and read its schema revision. A dead or missing URL is
|
|
137
|
-
* itself a result, not a throw.
|
|
138
|
-
*/
|
|
139
|
-
export async function probe(d: DomainInfo): Promise<DomainRow> {
|
|
140
|
-
if (!d.url) return { ...d, reachable: false, checkError: 'no url published' }
|
|
141
|
-
try {
|
|
142
|
-
const deployed = await fetchDomainPublication(d.url, AbortSignal.timeout(10_000))
|
|
143
|
-
if (deployed.origin !== d.origin) {
|
|
144
|
-
throw new Error(`Domain origin mismatch: deployed=${deployed.origin} expected=${d.origin}`)
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
...d,
|
|
148
|
-
reachable: true,
|
|
149
|
-
schemaRevision: deployed.schema.revision,
|
|
150
|
-
checkError: null,
|
|
151
|
-
}
|
|
152
|
-
} catch (err) {
|
|
153
|
-
return { ...d, reachable: false, checkError: err instanceof Error ? err.message : String(err) }
|
|
154
|
-
}
|
|
155
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
|
|
3
|
-
import type { KernelCommandOpts } from '../../connection'
|
|
4
|
-
import type { CommandDefinition } from '../../program/index'
|
|
5
|
-
|
|
6
|
-
import { formatKernelError } from '../../connection/errors'
|
|
7
|
-
import { publishAdminDomain } from '../../lib/admin-domain'
|
|
8
|
-
import { ADMIN_TARGET_OPTIONS, type AdminTargetCommandOpts } from '../../lib/admin-target'
|
|
9
|
-
import { domainPublicationUrl } from '../../lib/domain-publication'
|
|
10
|
-
import { withSpinner } from '../../lib/log'
|
|
11
|
-
import { isMachine, output } from '../../lib/output'
|
|
12
|
-
import { promptText } from '../../lib/prompt'
|
|
13
|
-
import { isHttpUrl, validateName, validateUrl } from '../../lib/validation'
|
|
14
|
-
|
|
15
|
-
type PublishOpts = KernelCommandOpts &
|
|
16
|
-
AdminTargetCommandOpts & {
|
|
17
|
-
origin?: string
|
|
18
|
-
name?: string
|
|
19
|
-
// `--public-url`, not `--url`: the global `--url` already means "target this
|
|
20
|
-
// kernel" (KERNEL_PASSTHROUGH_OPTIONS). This is the domain's own public
|
|
21
|
-
// address the kernel installs from — named for the role, not the substrate.
|
|
22
|
-
publicUrl?: string
|
|
23
|
-
description?: string
|
|
24
|
-
installByDefault?: boolean
|
|
25
|
-
// Global flags (program.ts) that force non-interactive — mirrors `instance use`.
|
|
26
|
-
ci?: boolean
|
|
27
|
-
noPrompt?: boolean
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Host of a URL (the natural `origin` default), or undefined if unparseable. */
|
|
31
|
-
function hostOf(url?: string): string | undefined {
|
|
32
|
-
if (!url) return undefined
|
|
33
|
-
try {
|
|
34
|
-
return new URL(url).host
|
|
35
|
-
} catch {
|
|
36
|
-
return undefined
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default {
|
|
41
|
-
name: 'publish',
|
|
42
|
-
description: 'Register a deployed domain in the admin catalog (DomainEntry.publish)',
|
|
43
|
-
afterHelpText: `
|
|
44
|
-
Behavior:
|
|
45
|
-
Upserts a catalog entry on the configured admin kernel: a domain's addressing
|
|
46
|
-
\`origin\`, registry \`name\`, and published \`url\` (no bytes, no version — the
|
|
47
|
-
author deploys the worker independently; publish just points the registry at
|
|
48
|
-
it). Idempotent: re-publishing the same name updates its url — and a publish
|
|
49
|
-
that would change nothing is reported as "already up to date" (no write).
|
|
50
|
-
|
|
51
|
-
Publishing only makes the domain INSTALLABLE. Mount it on an instance with
|
|
52
|
-
\`astrale domain install <url>\` (or rely on the admin's install-by-default
|
|
53
|
-
policy). Deployment and catalog publication are separate owners: run the
|
|
54
|
-
project's \`astrale-domain deploy <environment>\`, then publish its observed
|
|
55
|
-
public URL with this command.
|
|
56
|
-
|
|
57
|
-
Run in a terminal with flags omitted and it PROMPTS for origin / name /
|
|
58
|
-
public-url (origin defaults to the URL host, name to the origin's first
|
|
59
|
-
label). With no TTY — or \`--ci\` / \`--no-prompt\` — those three are required
|
|
60
|
-
up front, so piped / CI / agent runs fail fast instead of waiting on input.
|
|
61
|
-
|
|
62
|
-
Examples:
|
|
63
|
-
$ astrale domain publish --origin crm.acme.dev --name crm --public-url https://crm.acme.dev
|
|
64
|
-
`,
|
|
65
|
-
options: [
|
|
66
|
-
...ADMIN_TARGET_OPTIONS,
|
|
67
|
-
{ flags: '--origin <origin>', description: 'Domain addressing origin (e.g. crm.acme.dev)' },
|
|
68
|
-
{ flags: '--name <name>', description: 'Registry name / catalog slug (e.g. crm)' },
|
|
69
|
-
{ flags: '--public-url <url>', description: 'Public URL the kernel installs the domain from' },
|
|
70
|
-
{ flags: '--description <text>', description: 'Optional human description for the catalog' },
|
|
71
|
-
{
|
|
72
|
-
flags: '--install-by-default',
|
|
73
|
-
description: 'Mark the domain for install on every new instance',
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
// No positional arguments → Commander passes (opts, command); `opts` is first.
|
|
77
|
-
action: async (opts: PublishOpts) => {
|
|
78
|
-
try {
|
|
79
|
-
// Interactive fill (TTY only): a human running this by hand is prompted for
|
|
80
|
-
// any missing field. Automation passes every flag. No TTY / --ci /
|
|
81
|
-
// --no-prompt / CI env means no prompt: fall straight through to the
|
|
82
|
-
// required-flag error below so a piped or agent run fails fast.
|
|
83
|
-
const interactive = !!process.stdin.isTTY && !(opts.ci || opts.noPrompt || process.env.CI)
|
|
84
|
-
let { origin, name, publicUrl } = opts
|
|
85
|
-
if (interactive) {
|
|
86
|
-
if (!publicUrl)
|
|
87
|
-
publicUrl = await promptText('Public URL (https://…)', {
|
|
88
|
-
validate: (v) => isHttpUrl(v) || 'Enter a valid http(s) URL',
|
|
89
|
-
})
|
|
90
|
-
if (!origin)
|
|
91
|
-
origin = await promptText('Domain origin (e.g. crm.acme.dev)', {
|
|
92
|
-
default: hostOf(publicUrl),
|
|
93
|
-
})
|
|
94
|
-
if (!name) name = await promptText('Registry name', { default: origin?.split('.')[0] })
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (!origin || !name || !publicUrl) {
|
|
98
|
-
throw new Error(
|
|
99
|
-
'domain publish requires --origin, --name and --public-url, e.g.\n' +
|
|
100
|
-
' astrale domain publish --origin crm.acme.dev --name crm --public-url https://crm.acme.dev',
|
|
101
|
-
)
|
|
102
|
-
}
|
|
103
|
-
validateName(origin, 'origin')
|
|
104
|
-
validateName(name, 'domain')
|
|
105
|
-
validateUrl(publicUrl)
|
|
106
|
-
const discoveryUrl = domainPublicationUrl(publicUrl).href
|
|
107
|
-
|
|
108
|
-
const result = await withSpinner(
|
|
109
|
-
`Publishing ${name} → ${publicUrl}`,
|
|
110
|
-
!isMachine(opts),
|
|
111
|
-
() =>
|
|
112
|
-
publishAdminDomain(opts, {
|
|
113
|
-
origin,
|
|
114
|
-
name,
|
|
115
|
-
url: discoveryUrl,
|
|
116
|
-
...(opts.description ? { description: opts.description } : {}),
|
|
117
|
-
...(opts.installByDefault ? { installByDefault: true } : {}),
|
|
118
|
-
}),
|
|
119
|
-
{
|
|
120
|
-
success: ({ entry, changed, isNew }) =>
|
|
121
|
-
changed
|
|
122
|
-
? `${isNew ? 'Published' : 'Updated'}: ${entry.name} ${chalk.dim(`(${entry.origin} → ${entry.url})`)}`
|
|
123
|
-
: `Already up to date: ${entry.name} ${chalk.dim(`(${entry.origin} → ${entry.url} — no change, already latest)`)}`,
|
|
124
|
-
},
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
if (isMachine(opts)) {
|
|
128
|
-
output({ ...result.entry, changed: result.changed }, opts)
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
} catch (e) {
|
|
132
|
-
await formatKernelError(e, isMachine(opts), undefined, opts.debug)
|
|
133
|
-
process.exit(1)
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
} satisfies CommandDefinition
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { Path } from '@astrale-os/sdk/graph/path'
|
|
2
|
-
import { K } from '@astrale-os/sdk/schema'
|
|
3
|
-
import chalk from 'chalk'
|
|
4
|
-
|
|
5
|
-
import type { KernelCommandOpts } from '../../connection'
|
|
6
|
-
import type { CommandDefinition } from '../../program/index'
|
|
7
|
-
|
|
8
|
-
import { createPathCall, runKernelCommand } from '../../connection'
|
|
9
|
-
import { AstraleError } from '../../errors'
|
|
10
|
-
import { fatal, log } from '../../lib/log'
|
|
11
|
-
import { output } from '../../lib/output'
|
|
12
|
-
import { confirmWithInput } from '../../lib/prompt'
|
|
13
|
-
|
|
14
|
-
type UninstallOpts = KernelCommandOpts & {
|
|
15
|
-
readonly yes?: boolean
|
|
16
|
-
readonly ci?: boolean
|
|
17
|
-
readonly noPrompt?: boolean
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type UninstallResult = {
|
|
21
|
-
readonly operation: string
|
|
22
|
-
readonly transition: {
|
|
23
|
-
readonly intent: {
|
|
24
|
-
readonly origin: string
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** Public Kernel uninstall syscall input for one installed Domain origin. */
|
|
30
|
-
export function uninstallCallInput(
|
|
31
|
-
origin: string,
|
|
32
|
-
operation: string = crypto.randomUUID(),
|
|
33
|
-
): Readonly<{ operation: string; origin: string }> {
|
|
34
|
-
return Object.freeze({ operation, origin })
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export default {
|
|
38
|
-
name: 'uninstall',
|
|
39
|
-
description: 'Uninstall a domain from an instance through the public Kernel syscall',
|
|
40
|
-
afterHelpText: `
|
|
41
|
-
Behavior:
|
|
42
|
-
Removes one installed Domain origin from the target instance. The Kernel
|
|
43
|
-
refuses the operation while another installed Domain depends on it or while
|
|
44
|
-
business data still uses its schema. Uninstall never deletes business data.
|
|
45
|
-
Type the exact origin to confirm, or pass --yes in automation.
|
|
46
|
-
|
|
47
|
-
Use this before reinstalling only when an immutable Domain property (such as
|
|
48
|
-
its issuer) intentionally changed. Ordinary compatible upgrades should use
|
|
49
|
-
domain install directly and preserve the existing Domain identity.
|
|
50
|
-
|
|
51
|
-
Examples:
|
|
52
|
-
$ astrale domain uninstall grc.example -i staging
|
|
53
|
-
$ astrale domain uninstall grc.example -i staging --yes --json
|
|
54
|
-
`,
|
|
55
|
-
arguments: [
|
|
56
|
-
{
|
|
57
|
-
name: 'origin',
|
|
58
|
-
description: 'Installed Domain origin to remove',
|
|
59
|
-
required: true,
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
options: [
|
|
63
|
-
{
|
|
64
|
-
flags: '--yes',
|
|
65
|
-
description: 'Confirm Domain uninstall without prompting',
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
action: async (origin: string, opts: UninstallOpts) => {
|
|
69
|
-
try {
|
|
70
|
-
await confirmUninstall(origin, opts)
|
|
71
|
-
} catch (error) {
|
|
72
|
-
fatal(error, opts)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
await runKernelCommand<UninstallResult>({
|
|
76
|
-
opts,
|
|
77
|
-
label: `Uninstalling domain ${origin}`,
|
|
78
|
-
fn: async ({ session }) =>
|
|
79
|
-
(await session.call(
|
|
80
|
-
createPathCall(Path.project(K.functions.uninstall.ref).raw, uninstallCallInput(origin)),
|
|
81
|
-
)) as UninstallResult,
|
|
82
|
-
format: (result, formatOpts, machine) => {
|
|
83
|
-
if (machine) {
|
|
84
|
-
output(result, formatOpts)
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
log.success(`Domain uninstalled: ${result.transition.intent.origin}`)
|
|
88
|
-
log.dim(` operation: ${result.operation}`)
|
|
89
|
-
},
|
|
90
|
-
})
|
|
91
|
-
},
|
|
92
|
-
} satisfies CommandDefinition
|
|
93
|
-
|
|
94
|
-
async function confirmUninstall(origin: string, opts: UninstallOpts): Promise<void> {
|
|
95
|
-
if (opts.yes) return
|
|
96
|
-
|
|
97
|
-
const nonInteractive =
|
|
98
|
-
opts.ci ||
|
|
99
|
-
opts.noPrompt ||
|
|
100
|
-
process.env.CI ||
|
|
101
|
-
process.argv.includes('--ci') ||
|
|
102
|
-
process.argv.includes('--no-prompt') ||
|
|
103
|
-
!process.stdin.isTTY
|
|
104
|
-
if (nonInteractive) {
|
|
105
|
-
throw new AstraleError(
|
|
106
|
-
'CONFIRMATION_REQUIRED',
|
|
107
|
-
`Uninstalling Domain "${origin}" requires explicit confirmation.`,
|
|
108
|
-
`Re-run with --yes: astrale domain uninstall ${origin} --yes`,
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const warning =
|
|
113
|
-
chalk.red.bold('⚠ DANGER — DOMAIN UNINSTALL') +
|
|
114
|
-
'\n' +
|
|
115
|
-
chalk.dim('│') +
|
|
116
|
-
` origin ${chalk.bold(origin)}\n` +
|
|
117
|
-
chalk.dim('│') +
|
|
118
|
-
'\n' +
|
|
119
|
-
chalk.dim('│') +
|
|
120
|
-
' This removes the installed Domain from the target instance.\n' +
|
|
121
|
-
chalk.dim('│') +
|
|
122
|
-
' This command never deletes business data.\n' +
|
|
123
|
-
chalk.dim('│') +
|
|
124
|
-
' The Kernel refuses removal while dependents or business data remain.'
|
|
125
|
-
if (!(await confirmWithInput(warning, origin))) {
|
|
126
|
-
throw new AstraleError('UNINSTALL_CANCELLED', `Domain uninstall cancelled for "${origin}".`)
|
|
127
|
-
}
|
|
128
|
-
}
|
package/src/commands/get.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { Path } from '@astrale-os/sdk/graph/path'
|
|
2
|
-
|
|
3
|
-
import type { KernelCommandOpts } from '../connection'
|
|
4
|
-
import type { CommandDefinition } from '../program/index'
|
|
5
|
-
|
|
6
|
-
import { expandSelfInPath, runKernelCommand, withSelfHint } from '../connection'
|
|
7
|
-
import { AstraleError } from '../errors'
|
|
8
|
-
import { failInput, fatal } from '../lib/log'
|
|
9
|
-
import { denoise, output } from '../lib/output'
|
|
10
|
-
|
|
11
|
-
type GetOpts = KernelCommandOpts & { schema?: boolean }
|
|
12
|
-
|
|
13
|
-
/** Read one exact canonical Node. The caller's Path is not fabricated into the Node value. */
|
|
14
|
-
export async function getCommand(target: string, opts: GetOpts): Promise<void> {
|
|
15
|
-
let parsed
|
|
16
|
-
try {
|
|
17
|
-
parsed = Path.parse(target)
|
|
18
|
-
} catch (error) {
|
|
19
|
-
failInput(error, opts)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const last = parsed.ast.steps.at(-1)
|
|
23
|
-
if (last?.kind === 'method') {
|
|
24
|
-
const error = new AstraleError(
|
|
25
|
-
'NOT_A_NODE',
|
|
26
|
-
`${target} is a callable Path, not a Node.`,
|
|
27
|
-
`Use \`astrale call ${target}\` or \`astrale introspect ${target}\`.`,
|
|
28
|
-
)
|
|
29
|
-
fatal(error, opts)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
await runKernelCommand({
|
|
33
|
-
opts,
|
|
34
|
-
label: `Node ${target}`,
|
|
35
|
-
fn: async (context) => {
|
|
36
|
-
const { path, meta } = await expandSelfInPath(target, context)
|
|
37
|
-
const resolved = meta === undefined ? parsed : Path.parse(path)
|
|
38
|
-
return withSelfHint(() => context.graph.getOrThrow(resolved), meta)
|
|
39
|
-
},
|
|
40
|
-
format: (node, format) => output(opts.schema === true ? node : denoise(node), format),
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export default {
|
|
45
|
-
name: 'get',
|
|
46
|
-
description: 'Get one canonical node by Path or ID',
|
|
47
|
-
afterHelpText: `
|
|
48
|
-
Behavior:
|
|
49
|
-
Resolves one exact Kernel Path and prints the canonical Node
|
|
50
|
-
{ id, class, props }. Missing and authorization-masked nodes remain
|
|
51
|
-
intentionally indistinguishable. @self is expanded before dispatch.
|
|
52
|
-
|
|
53
|
-
A Node does not contain a synthetic path, labels, or backend class ID.
|
|
54
|
-
Method Paths are not Nodes — use call / introspect. Schema-valued
|
|
55
|
-
properties are omitted unless --schema is passed. Use query for
|
|
56
|
-
graph-shaped reads.
|
|
57
|
-
|
|
58
|
-
Examples:
|
|
59
|
-
$ astrale get /:notes.example.dev:class.Note
|
|
60
|
-
$ astrale get @abc123 --json
|
|
61
|
-
$ astrale get @self
|
|
62
|
-
$ astrale get /:kernel.astrale.ai --schema
|
|
63
|
-
`,
|
|
64
|
-
arguments: [{ name: 'target', description: 'Canonical Node Path or @id' }],
|
|
65
|
-
options: [{ flags: '--schema', description: 'Include schema-valued properties' }],
|
|
66
|
-
action: async (target, opts) => {
|
|
67
|
-
await getCommand(target as string, opts as GetOpts)
|
|
68
|
-
},
|
|
69
|
-
} satisfies CommandDefinition
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { issuer, jwk, provision } from '@astrale-os/sdk/auth'
|
|
2
|
-
import { normalizeProperties } from '@astrale-os/sdk/graph/properties'
|
|
3
|
-
import { expect, mock, test } from 'bun:test'
|
|
4
|
-
import { exportJWK, generateKeyPair, jwtVerify } from 'jose'
|
|
5
|
-
|
|
6
|
-
import { classKey } from '../../../graph'
|
|
7
|
-
import { formatIdentityRegistration, prepareIdentityProvision } from '../register'
|
|
8
|
-
|
|
9
|
-
/** @evidence TEST-CLI-IDENTITY-REGISTER-JSON-EXACT */
|
|
10
|
-
test('emits exactly one structured value for machine registration output', () => {
|
|
11
|
-
const writes: string[] = []
|
|
12
|
-
const logs: string[] = []
|
|
13
|
-
const originalWrite = process.stdout.write
|
|
14
|
-
const originalLog = console.log
|
|
15
|
-
process.stdout.write = mock((chunk: string | Uint8Array) => {
|
|
16
|
-
writes.push(typeof chunk === 'string' ? chunk : new TextDecoder().decode(chunk))
|
|
17
|
-
return true
|
|
18
|
-
}) as typeof process.stdout.write
|
|
19
|
-
console.log = mock((...values: unknown[]) => logs.push(values.map(String).join(' ')))
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
formatIdentityRegistration(
|
|
23
|
-
{ iss: 'https://identity.example', sub: 'self', nodeId: 'operator-node' },
|
|
24
|
-
{ json: true },
|
|
25
|
-
true,
|
|
26
|
-
)
|
|
27
|
-
} finally {
|
|
28
|
-
process.stdout.write = originalWrite
|
|
29
|
-
console.log = originalLog
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
expect(JSON.parse(writes.join(''))).toEqual({
|
|
33
|
-
iss: 'https://identity.example',
|
|
34
|
-
sub: 'self',
|
|
35
|
-
nodeId: 'operator-node',
|
|
36
|
-
})
|
|
37
|
-
expect(logs).toEqual([])
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
test('builds one exact Mutation V3 identity birth bound to a self proof', async () => {
|
|
41
|
-
const { privateKey, publicKey } = await generateKeyPair('ES256', { extractable: true })
|
|
42
|
-
const privateJwk = { ...(await exportJWK(privateKey)), alg: 'ES256', kid: 'alice-key' }
|
|
43
|
-
const publicJwk = jwk.acceptPublic({
|
|
44
|
-
...(await exportJWK(publicKey)),
|
|
45
|
-
alg: 'ES256',
|
|
46
|
-
kid: 'alice-key',
|
|
47
|
-
})
|
|
48
|
-
const kernelIssuer = issuer.accept('https://kernel.example')
|
|
49
|
-
const classPath = classKey('/:accounts.example:class.User', '--class')
|
|
50
|
-
const properties = normalizeProperties({
|
|
51
|
-
'accounts.example:class.User.property.name': 'Alice',
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
const prepared = await prepareIdentityProvision({
|
|
55
|
-
name: 'alice',
|
|
56
|
-
classPath,
|
|
57
|
-
properties,
|
|
58
|
-
privateKey: privateJwk,
|
|
59
|
-
publicKey: publicJwk,
|
|
60
|
-
kernelIssuer,
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
expect(String(prepared.binding)).toBe('identity')
|
|
64
|
-
expect(prepared.request.idempotencyKey).toBe('identity-register:alice')
|
|
65
|
-
expect(JSON.parse(JSON.stringify(prepared.request.mutation))).toEqual({
|
|
66
|
-
format: 'astrale.graph.mutation',
|
|
67
|
-
version: 'v3',
|
|
68
|
-
preconditions: [],
|
|
69
|
-
operations: [
|
|
70
|
-
{
|
|
71
|
-
op: 'node.create',
|
|
72
|
-
as: 'identity',
|
|
73
|
-
class: 'accounts.example:class.User',
|
|
74
|
-
props: { 'accounts.example:class.User.property.name': 'Alice' },
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
const credentials = prepared.request.identities[prepared.binding]?.credentials
|
|
80
|
-
expect(credentials?.publicKey).toEqual(publicJwk)
|
|
81
|
-
expect(typeof credentials?.proof).toBe('string')
|
|
82
|
-
if (typeof credentials?.proof !== 'string') throw new TypeError('Expected compact JWT proof')
|
|
83
|
-
|
|
84
|
-
const expectedFingerprint = await provision.fingerprint(prepared.request)
|
|
85
|
-
const expectedIssuer = await provision.selfIssuer(kernelIssuer, publicJwk)
|
|
86
|
-
const verified = await jwtVerify(credentials.proof, publicKey, {
|
|
87
|
-
algorithms: ['ES256'],
|
|
88
|
-
issuer: expectedIssuer,
|
|
89
|
-
subject: 'self',
|
|
90
|
-
audience: kernelIssuer,
|
|
91
|
-
})
|
|
92
|
-
expect(verified.payload.provision).toBe(expectedFingerprint)
|
|
93
|
-
})
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { CommandDefinition } from '../../program/index'
|
|
2
|
-
|
|
3
|
-
import { createIdentity } 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: 'create',
|
|
9
|
-
description: 'Create a new identity',
|
|
10
|
-
arguments: [{ name: 'name', description: 'Identity name', required: true }],
|
|
11
|
-
options: [
|
|
12
|
-
{ flags: '--subject <sub>', description: 'Custom subject (defaults to name)' },
|
|
13
|
-
{ flags: '--local', description: 'Local-only identity (default)' },
|
|
14
|
-
{ flags: '--remote', description: 'Remote (cloud-synced) identity — requires cloud login' },
|
|
15
|
-
...RAW_OUTPUT_OPTIONS,
|
|
16
|
-
],
|
|
17
|
-
action: async (
|
|
18
|
-
name: string,
|
|
19
|
-
opts: { subject?: string; local?: boolean; remote?: boolean } & RawOutputOpts,
|
|
20
|
-
) => {
|
|
21
|
-
try {
|
|
22
|
-
const mode = opts.remote ? 'remote' : 'local'
|
|
23
|
-
const identity = await createIdentity(name, { subject: opts.subject, mode })
|
|
24
|
-
if (isMachine(opts)) {
|
|
25
|
-
output({ name, ...identity }, opts)
|
|
26
|
-
return
|
|
27
|
-
}
|
|
28
|
-
log.success(
|
|
29
|
-
`Created identity "${name}" (subject: ${identity.subject}, mode: ${identity.mode})`,
|
|
30
|
-
)
|
|
31
|
-
} catch (e) {
|
|
32
|
-
fatal(e, opts)
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
} satisfies CommandDefinition
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { CommandDefinition } from '../../program/index'
|
|
2
|
-
|
|
3
|
-
import { deleteIdentity } 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: 'delete',
|
|
9
|
-
description: 'Delete an 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 deleteIdentity(name)
|
|
15
|
-
if (isMachine(opts)) {
|
|
16
|
-
output({ deleted: name }, opts)
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
log.success(`Deleted identity "${name}"`)
|
|
20
|
-
} catch (e) {
|
|
21
|
-
fatal(e, opts)
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
} satisfies CommandDefinition
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { CommandDefinition } from '../../program/index'
|
|
2
|
-
|
|
3
|
-
import { encodeIdentityExport, exportIdentity, writeIdentityExport } from '../../identity/index'
|
|
4
|
-
import { fatal, log } from '../../lib/log'
|
|
5
|
-
import { isMachine, output, RAW_OUTPUT_OPTIONS, type RawOutputOpts } from '../../lib/output'
|
|
6
|
-
import { readPassphrase } from '../../lib/prompt'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Export the per-identity keypair as a plaintext JWK envelope by default.
|
|
10
|
-
* With `--encrypt`, wrap it in a JOSE JWE (PBES2-HS256+A128KW / A256GCM)
|
|
11
|
-
* using a passphrase prompted from the TTY.
|
|
12
|
-
*/
|
|
13
|
-
export default {
|
|
14
|
-
name: 'export',
|
|
15
|
-
description: 'Export an identity keypair to disk (optional --encrypt)',
|
|
16
|
-
arguments: [
|
|
17
|
-
{ name: 'name', description: 'Identity name', required: true },
|
|
18
|
-
{ name: 'path', description: 'Output file path', required: true },
|
|
19
|
-
],
|
|
20
|
-
options: [
|
|
21
|
-
{ flags: '--encrypt', description: 'Encrypt the envelope with a passphrase (JOSE JWE)' },
|
|
22
|
-
...RAW_OUTPUT_OPTIONS,
|
|
23
|
-
],
|
|
24
|
-
action: async (name: string, path: string, opts: { encrypt?: boolean } & RawOutputOpts) => {
|
|
25
|
-
try {
|
|
26
|
-
const envelope = await exportIdentity(name)
|
|
27
|
-
const passphrase = opts.encrypt
|
|
28
|
-
? await readPassphrase('Passphrase (min 8 chars): ', { minLength: 8 })
|
|
29
|
-
: undefined
|
|
30
|
-
await writeIdentityExport(path, await encodeIdentityExport(envelope, passphrase))
|
|
31
|
-
|
|
32
|
-
if (isMachine(opts)) {
|
|
33
|
-
output({ name, path, encrypted: Boolean(opts.encrypt) }, opts)
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
log.success(`Exported identity "${name}" → ${path}${opts.encrypt ? ' (encrypted)' : ''}`)
|
|
37
|
-
if (!opts.encrypt) {
|
|
38
|
-
log.warn(
|
|
39
|
-
' Plaintext private JWK — keep this file secure. Use --encrypt for passphrase wrapping.',
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
} catch (e) {
|
|
43
|
-
fatal(e, opts)
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
} satisfies CommandDefinition
|