@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,111 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import { readFileSync, readdirSync, statSync } from 'node:fs'
|
|
3
|
-
import { join, relative } from 'node:path'
|
|
4
|
-
import { Project } from 'ts-morph'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* The Domain Studio SERVER ships as raw source inside the published CLI package
|
|
8
|
-
* (package.json `files`: studio/server, studio/shared) and runs UNBUNDLED under
|
|
9
|
-
* Bun — unlike the CLI itself, which is bundled into dist/astrale.js with all its
|
|
10
|
-
* deps inlined. So at `astrale studio` runtime, the server can only resolve the
|
|
11
|
-
* third-party packages that the CLI declares in its own `dependencies` (the
|
|
12
|
-
* studio's package.json deps are NOT installed for an `npm i -g @astrale-os/cli`
|
|
13
|
-
* consumer — they're client/build-only, inlined into studio/client/dist).
|
|
14
|
-
*
|
|
15
|
-
* This test enforces that invariant. If it fails, either add the package to the
|
|
16
|
-
* CLI's `dependencies` or drop the import — do NOT add it to studio/package.json
|
|
17
|
-
* (that won't ship to npm consumers).
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const CLI_ROOT = new URL('../../../', import.meta.url).pathname
|
|
21
|
-
|
|
22
|
-
interface PackageManifest {
|
|
23
|
-
dependencies?: Record<string, string>
|
|
24
|
-
scripts?: Record<string, string>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const cliPackage = JSON.parse(
|
|
28
|
-
readFileSync(join(CLI_ROOT, 'package.json'), 'utf8'),
|
|
29
|
-
) as PackageManifest
|
|
30
|
-
const studioPackage = JSON.parse(
|
|
31
|
-
readFileSync(join(CLI_ROOT, 'studio/package.json'), 'utf8'),
|
|
32
|
-
) as PackageManifest
|
|
33
|
-
|
|
34
|
-
/** Base package of a bare specifier: `@scope/pkg/sub` → `@scope/pkg`, `pkg/sub` → `pkg`. */
|
|
35
|
-
function basePackage(spec: string): string {
|
|
36
|
-
const parts = spec.split('/')
|
|
37
|
-
return spec.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]!
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function isBuiltin(spec: string): boolean {
|
|
41
|
-
return spec.startsWith('node:') || spec === 'bun' || spec.startsWith('bun:')
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function runtimeFiles(directory: string): string[] {
|
|
45
|
-
return readdirSync(directory).flatMap((entry) => {
|
|
46
|
-
const path = join(directory, entry)
|
|
47
|
-
if (statSync(path).isDirectory()) return runtimeFiles(path)
|
|
48
|
-
return /\.(?:ts|tsx)$/.test(path) && !/\.test\.(?:ts|tsx)$/.test(path) ? [path] : []
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const studioPath = (path: string) => relative(CLI_ROOT, path).replaceAll('\\', '/')
|
|
53
|
-
|
|
54
|
-
describe('studio server runtime deps', () => {
|
|
55
|
-
const deps = new Set(Object.keys(cliPackage.dependencies ?? {}))
|
|
56
|
-
|
|
57
|
-
const project = new Project({ skipAddingFilesFromTsConfig: true })
|
|
58
|
-
project.addSourceFilesAtPaths([
|
|
59
|
-
join(CLI_ROOT, 'studio/server/**/*.ts'),
|
|
60
|
-
join(CLI_ROOT, 'studio/server/**/*.tsx'),
|
|
61
|
-
join(CLI_ROOT, 'studio/shared/**/*.ts'),
|
|
62
|
-
join(CLI_ROOT, 'studio/shared/**/*.tsx'),
|
|
63
|
-
])
|
|
64
|
-
const runtimeSourceFiles = project
|
|
65
|
-
.getSourceFiles()
|
|
66
|
-
.filter((sourceFile) => !/\.test\.(?:ts|tsx)$/.test(sourceFile.getBaseName()))
|
|
67
|
-
|
|
68
|
-
// getImportStringLiterals covers static imports, re-exports, and dynamic import().
|
|
69
|
-
const offenders: Record<string, string[]> = {}
|
|
70
|
-
for (const sf of runtimeSourceFiles) {
|
|
71
|
-
const specs = sf.getImportStringLiterals().map((l) => l.getLiteralValue())
|
|
72
|
-
for (const spec of specs) {
|
|
73
|
-
if (spec.startsWith('.') || spec.startsWith('/') || isBuiltin(spec)) continue
|
|
74
|
-
const pkg = basePackage(spec)
|
|
75
|
-
if (!deps.has(pkg)) (offenders[pkg] ??= []).push(sf.getFilePath().replace(CLI_ROOT, ''))
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
test('only import Node/Bun builtins or packages in the CLI dependencies', () => {
|
|
80
|
-
expect(
|
|
81
|
-
offenders,
|
|
82
|
-
`studio server imports packages NOT in the CLI's package.json dependencies — ` +
|
|
83
|
-
`they won't be installed for an \`npm i -g @astrale-os/cli\` consumer:\n` +
|
|
84
|
-
JSON.stringify(offenders, null, 2),
|
|
85
|
-
).toEqual({})
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
test('parses every shipped Studio server and shared runtime source', () => {
|
|
89
|
-
const expected = [
|
|
90
|
-
...runtimeFiles(join(CLI_ROOT, 'studio/server')),
|
|
91
|
-
...runtimeFiles(join(CLI_ROOT, 'studio/shared')),
|
|
92
|
-
]
|
|
93
|
-
.map(studioPath)
|
|
94
|
-
.sort()
|
|
95
|
-
const parsed = runtimeSourceFiles
|
|
96
|
-
.map((sourceFile) => studioPath(sourceFile.getFilePath()))
|
|
97
|
-
.sort()
|
|
98
|
-
|
|
99
|
-
expect(parsed).toEqual(expected)
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
describe('studio test gate', () => {
|
|
104
|
-
test('the root and Studio suites include all client, server, and shared tests', () => {
|
|
105
|
-
expect(cliPackage.scripts?.test).toBe(
|
|
106
|
-
'node scripts/qualification/source-boundary.mjs --target && bun test src studio/client/src studio/server studio/shared && node --test scripts/*.test.mjs',
|
|
107
|
-
)
|
|
108
|
-
expect(cliPackage.scripts?.['test:studio']).toBe('pnpm --dir studio test')
|
|
109
|
-
expect(studioPackage.scripts?.test).toBe('bun test client/src server shared')
|
|
110
|
-
})
|
|
111
|
-
})
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { renderTable } from '../table'
|
|
4
|
-
|
|
5
|
-
const ESC = String.fromCharCode(27)
|
|
6
|
-
const strip = (s: string): string => s.replace(new RegExp(`${ESC}\\[[0-9;]*m`, 'g'), '')
|
|
7
|
-
|
|
8
|
-
const COLS = [
|
|
9
|
-
{ key: 'name', header: 'NAME' },
|
|
10
|
-
{ key: 'kind', header: 'KIND' },
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
describe('renderTable', () => {
|
|
14
|
-
test('aligns the KIND column across rows of different name widths', () => {
|
|
15
|
-
const out = strip(
|
|
16
|
-
renderTable(
|
|
17
|
-
[
|
|
18
|
-
{ name: 'example.astrale.ai', kind: 'Domain' },
|
|
19
|
-
{ name: 'workspace', kind: 'Folder' },
|
|
20
|
-
],
|
|
21
|
-
{ columns: COLS },
|
|
22
|
-
),
|
|
23
|
-
)
|
|
24
|
-
const [a, b] = out.split('\n')
|
|
25
|
-
expect(a.indexOf('Domain')).toBe(b.indexOf('Folder'))
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('empty rows render as (empty)', () => {
|
|
29
|
-
expect(strip(renderTable([], { columns: COLS }))).toContain('(empty)')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('drops a column that is empty across every row (with header)', () => {
|
|
33
|
-
const out = strip(renderTable([{ name: 'a', kind: '' }], { columns: COLS, showHeader: true }))
|
|
34
|
-
expect(out).toContain('NAME')
|
|
35
|
-
expect(out).not.toContain('KIND')
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('computes width on visible length, ignoring ANSI in cells', () => {
|
|
39
|
-
const colored = `${ESC}[32mok${ESC}[39m`
|
|
40
|
-
const out = strip(
|
|
41
|
-
renderTable(
|
|
42
|
-
[
|
|
43
|
-
{ name: colored, kind: 'x' },
|
|
44
|
-
{ name: 'wider-name', kind: 'y' },
|
|
45
|
-
],
|
|
46
|
-
{ columns: COLS },
|
|
47
|
-
),
|
|
48
|
-
)
|
|
49
|
-
const [a, b] = out.split('\n')
|
|
50
|
-
// KIND aligns despite the ANSI codes that were in row 0's name cell.
|
|
51
|
-
expect(a.indexOf('x')).toBe(b.indexOf('y'))
|
|
52
|
-
})
|
|
53
|
-
})
|
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import { chmod, mkdir, mkdtemp, readFile, rename, rm, symlink, writeFile } from 'node:fs/promises'
|
|
3
|
-
import { tmpdir } from 'node:os'
|
|
4
|
-
import { dirname, join } from 'node:path'
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
admitScriptInstall,
|
|
8
|
-
classifyUpdateExecution,
|
|
9
|
-
DEFAULT_UPDATE_CHANNEL,
|
|
10
|
-
InstallMetadataSchema,
|
|
11
|
-
readInstallMetadata,
|
|
12
|
-
releaseBase,
|
|
13
|
-
replaceStandaloneCohort,
|
|
14
|
-
shouldUpdate,
|
|
15
|
-
updateAstrale,
|
|
16
|
-
writeInstallMetadata,
|
|
17
|
-
type InstallMetadata,
|
|
18
|
-
type UpdateExecution,
|
|
19
|
-
} from '../update'
|
|
20
|
-
|
|
21
|
-
async function makeFakeRelease(
|
|
22
|
-
root: string,
|
|
23
|
-
version: string,
|
|
24
|
-
options: { binaryVersion?: string; legacyManifest?: boolean; omitViewerIndex?: boolean } = {},
|
|
25
|
-
): Promise<string> {
|
|
26
|
-
const release = join(root, 'release')
|
|
27
|
-
const payload = join(root, 'payload')
|
|
28
|
-
const binaryVersion = options.binaryVersion ?? version
|
|
29
|
-
await mkdir(release, { recursive: true })
|
|
30
|
-
await mkdir(payload, { recursive: true })
|
|
31
|
-
await writeFile(
|
|
32
|
-
join(payload, 'astrale'),
|
|
33
|
-
`#!/usr/bin/env sh\nif [ "$1" = "--version" ]; then echo "${binaryVersion}"; exit 0; fi\necho astrale\n`,
|
|
34
|
-
)
|
|
35
|
-
await chmod(join(payload, 'astrale'), 0o755)
|
|
36
|
-
await mkdir(join(payload, 'viewer', 'dist'), { recursive: true })
|
|
37
|
-
await writeFile(join(payload, 'viewer', 'dist', 'main.js'), 'viewer main\n')
|
|
38
|
-
if (!options.omitViewerIndex) {
|
|
39
|
-
await writeFile(join(payload, 'viewer', 'dist', 'index.html'), '<!doctype html>\n')
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const asset = join(release, 'astrale-darwin-arm64.tar.gz')
|
|
43
|
-
const tar = Bun.spawn(['tar', '-C', payload, '-czf', asset, 'astrale', 'viewer'])
|
|
44
|
-
expect(await tar.exited).toBe(0)
|
|
45
|
-
const shaProc = Bun.spawn(['shasum', '-a', '256', asset], { stdout: 'pipe' })
|
|
46
|
-
const sha = (await new Response(shaProc.stdout).text()).trim().split(/\s+/)[0]
|
|
47
|
-
expect(await shaProc.exited).toBe(0)
|
|
48
|
-
await writeFile(join(release, 'sha256sums.txt'), `${sha} astrale-darwin-arm64.tar.gz\n`)
|
|
49
|
-
await writeFile(
|
|
50
|
-
join(release, 'manifest.json'),
|
|
51
|
-
JSON.stringify(
|
|
52
|
-
{
|
|
53
|
-
version,
|
|
54
|
-
binaryVersion: options.binaryVersion,
|
|
55
|
-
channel: 'alpha',
|
|
56
|
-
repo: 'astrale-os/cli',
|
|
57
|
-
assets: options.legacyManifest
|
|
58
|
-
? {
|
|
59
|
-
'darwin-arm64': 'astrale-darwin-arm64.tar.gz',
|
|
60
|
-
}
|
|
61
|
-
: {
|
|
62
|
-
'darwin-arm64': {
|
|
63
|
-
name: 'astrale-darwin-arm64.tar.gz',
|
|
64
|
-
sha256: sha,
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
null,
|
|
69
|
-
2,
|
|
70
|
-
),
|
|
71
|
-
)
|
|
72
|
-
return release
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function makeInstall(
|
|
76
|
-
root: string,
|
|
77
|
-
version: string,
|
|
78
|
-
): Promise<{ meta: InstallMetadata; path: string; execution: UpdateExecution }> {
|
|
79
|
-
const bin = join(root, 'bin', 'astrale')
|
|
80
|
-
await mkdir(join(root, 'bin'), { recursive: true })
|
|
81
|
-
await writeFile(
|
|
82
|
-
bin,
|
|
83
|
-
`#!/usr/bin/env sh\nif [ "$1" = "--version" ]; then echo "${version}"; exit 0; fi\necho old\n`,
|
|
84
|
-
)
|
|
85
|
-
await chmod(bin, 0o755)
|
|
86
|
-
await mkdir(join(root, 'bin', 'viewer', 'dist'), { recursive: true })
|
|
87
|
-
await writeFile(join(root, 'bin', 'viewer', 'dist', 'main.js'), 'old viewer main\n')
|
|
88
|
-
await writeFile(join(root, 'bin', 'viewer', 'dist', 'index.html'), 'old viewer html\n')
|
|
89
|
-
const path = join(root, 'home', 'install.json')
|
|
90
|
-
const meta: InstallMetadata = {
|
|
91
|
-
method: 'script',
|
|
92
|
-
channel: 'alpha',
|
|
93
|
-
version,
|
|
94
|
-
repo: 'astrale-os/cli',
|
|
95
|
-
bin,
|
|
96
|
-
}
|
|
97
|
-
await writeInstallMetadata(meta, path)
|
|
98
|
-
return { meta, path, execution: { kind: 'standalone', executable: bin } }
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
describe('update helpers', () => {
|
|
102
|
-
test('classifies only a Bun-compiled executable as standalone', () => {
|
|
103
|
-
expect(
|
|
104
|
-
classifyUpdateExecution({
|
|
105
|
-
bunVersion: '1.3.14',
|
|
106
|
-
executable: '/tmp/astrale',
|
|
107
|
-
entry: '/$bunfs/root/astrale',
|
|
108
|
-
}),
|
|
109
|
-
).toEqual({ kind: 'standalone', executable: '/tmp/astrale' })
|
|
110
|
-
expect(
|
|
111
|
-
classifyUpdateExecution({
|
|
112
|
-
bunVersion: '1.3.14',
|
|
113
|
-
executable: '/opt/homebrew/bin/bun',
|
|
114
|
-
entry: '/tmp/astrale.ts',
|
|
115
|
-
}),
|
|
116
|
-
).toEqual({ kind: 'package-managed', executable: '/opt/homebrew/bin/bun' })
|
|
117
|
-
expect(
|
|
118
|
-
classifyUpdateExecution({
|
|
119
|
-
executable: '/opt/homebrew/bin/node',
|
|
120
|
-
entry: '/tmp/astrale.js',
|
|
121
|
-
}),
|
|
122
|
-
).toEqual({ kind: 'package-managed', executable: '/opt/homebrew/bin/node' })
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
test('defaults missing install metadata to the beta channel', () => {
|
|
126
|
-
expect(DEFAULT_UPDATE_CHANNEL).toBe('beta')
|
|
127
|
-
expect(
|
|
128
|
-
InstallMetadataSchema.parse({
|
|
129
|
-
method: 'script',
|
|
130
|
-
bin: '/tmp/astrale',
|
|
131
|
-
}).channel,
|
|
132
|
-
).toBe('beta')
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
test('releaseBase resolves exact versions and channels', () => {
|
|
136
|
-
const meta: InstallMetadata = {
|
|
137
|
-
method: 'script',
|
|
138
|
-
channel: 'alpha',
|
|
139
|
-
repo: 'astrale-os/cli',
|
|
140
|
-
bin: '/tmp/astrale',
|
|
141
|
-
}
|
|
142
|
-
expect(releaseBase(meta, {})).toBe('https://github.com/astrale-os/cli/releases/download/alpha')
|
|
143
|
-
expect(releaseBase(meta, { channel: 'canary' })).toBe(
|
|
144
|
-
'https://github.com/astrale-os/cli/releases/download/canary',
|
|
145
|
-
)
|
|
146
|
-
expect(releaseBase(meta, { version: '0.4.1' })).toBe(
|
|
147
|
-
'https://github.com/astrale-os/cli/releases/download/cli/v0.4.1',
|
|
148
|
-
)
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
test('shouldUpdate is exact and predictable', () => {
|
|
152
|
-
expect(shouldUpdate('0.4.0', '0.4.0')).toBe(false)
|
|
153
|
-
expect(shouldUpdate('0.4.0', '0.4.1')).toBe(true)
|
|
154
|
-
})
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
describe('script install admission', () => {
|
|
158
|
-
test('a metadata commit failure restores the exact previous file', async () => {
|
|
159
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
160
|
-
const path = join(root, 'install.json')
|
|
161
|
-
const original = '{"exact":"previous metadata"}\n'
|
|
162
|
-
await writeFile(path, original)
|
|
163
|
-
|
|
164
|
-
await expect(
|
|
165
|
-
writeInstallMetadata(
|
|
166
|
-
{
|
|
167
|
-
method: 'script',
|
|
168
|
-
channel: 'beta',
|
|
169
|
-
version: '1.1.0',
|
|
170
|
-
repo: 'astrale-os/cli',
|
|
171
|
-
bin: '/tmp/astrale',
|
|
172
|
-
},
|
|
173
|
-
path,
|
|
174
|
-
{
|
|
175
|
-
mkdir,
|
|
176
|
-
rm,
|
|
177
|
-
writeFile,
|
|
178
|
-
rename: async (from, to) => {
|
|
179
|
-
if (String(from).endsWith('.next')) throw new Error('injected metadata commit failure')
|
|
180
|
-
await rename(from, to)
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
),
|
|
184
|
-
).rejects.toThrow('injected metadata commit failure')
|
|
185
|
-
|
|
186
|
-
expect(await readFile(path, 'utf8')).toBe(original)
|
|
187
|
-
await expect(readFile(`${path}.next`, 'utf8')).rejects.toMatchObject({ code: 'ENOENT' })
|
|
188
|
-
await expect(readFile(`${path}.previous`, 'utf8')).rejects.toMatchObject({ code: 'ENOENT' })
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
test('rejects malformed JSON with the stable metadata error', async () => {
|
|
192
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
193
|
-
const path = join(root, 'install.json')
|
|
194
|
-
await writeFile(path, '{')
|
|
195
|
-
|
|
196
|
-
await expect(readInstallMetadata(path)).rejects.toMatchObject({
|
|
197
|
-
code: 'UPDATE_BAD_INSTALL_METADATA',
|
|
198
|
-
})
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
test('admits a symlink only when it resolves to the recorded binary', async () => {
|
|
202
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
203
|
-
const { meta } = await makeInstall(root, '1.0.0')
|
|
204
|
-
const alias = join(root, 'astrale-alias')
|
|
205
|
-
await symlink(meta.bin, alias)
|
|
206
|
-
|
|
207
|
-
const admitted = await admitScriptInstall(meta, {
|
|
208
|
-
kind: 'standalone',
|
|
209
|
-
executable: alias,
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
expect(admitted.metadata).toEqual(meta)
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
test('rejects a standalone binary that does not own the recorded target', async () => {
|
|
216
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
217
|
-
const { meta } = await makeInstall(root, '1.0.0')
|
|
218
|
-
const other = join(root, 'other-astrale')
|
|
219
|
-
await writeFile(other, '#!/bin/sh\n')
|
|
220
|
-
|
|
221
|
-
await expect(
|
|
222
|
-
admitScriptInstall(meta, { kind: 'standalone', executable: other }),
|
|
223
|
-
).rejects.toMatchObject({ code: 'UPDATE_INSTALL_MISMATCH' })
|
|
224
|
-
})
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
describe('updateAstrale', () => {
|
|
228
|
-
test('a package-managed process never consults or mutates a coexisting script install', async () => {
|
|
229
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
230
|
-
const { path, meta } = await makeInstall(root, '1.0.0')
|
|
231
|
-
const before = await readFile(meta.bin, 'utf8')
|
|
232
|
-
process.env.ASTRALE_UPDATE_BASE = 'file:///definitely-not-a-release'
|
|
233
|
-
try {
|
|
234
|
-
const result = await updateAstrale({
|
|
235
|
-
currentVersion: '2.0.0',
|
|
236
|
-
installPath: path,
|
|
237
|
-
execution: { kind: 'package-managed', executable: '/opt/homebrew/bin/node' },
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
expect(result).toEqual({
|
|
241
|
-
status: 'managed',
|
|
242
|
-
currentVersion: '2.0.0',
|
|
243
|
-
executable: '/opt/homebrew/bin/node',
|
|
244
|
-
})
|
|
245
|
-
expect(await readFile(meta.bin, 'utf8')).toBe(before)
|
|
246
|
-
} finally {
|
|
247
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
248
|
-
}
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
test('check compares the installed release identity from metadata', async () => {
|
|
252
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
253
|
-
const { path, execution } = await makeInstall(root, 'main-abc123')
|
|
254
|
-
const release = await makeFakeRelease(root, 'main-abc123', { binaryVersion: '1.0.0' })
|
|
255
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
256
|
-
try {
|
|
257
|
-
const result = await updateAstrale({
|
|
258
|
-
check: true,
|
|
259
|
-
currentVersion: '1.0.0',
|
|
260
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
261
|
-
installPath: path,
|
|
262
|
-
execution,
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
expect(result).toMatchObject({
|
|
266
|
-
status: 'up-to-date',
|
|
267
|
-
currentVersion: 'main-abc123',
|
|
268
|
-
latestVersion: 'main-abc123',
|
|
269
|
-
})
|
|
270
|
-
} finally {
|
|
271
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
272
|
-
}
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
test('check reports available update without replacing the binary', async () => {
|
|
276
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
277
|
-
const { path, meta, execution } = await makeInstall(root, '1.0.0')
|
|
278
|
-
const release = await makeFakeRelease(root, '1.1.0')
|
|
279
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
280
|
-
try {
|
|
281
|
-
const result = await updateAstrale({
|
|
282
|
-
check: true,
|
|
283
|
-
currentVersion: '1.0.0',
|
|
284
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
285
|
-
installPath: path,
|
|
286
|
-
execution,
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
expect(result).toMatchObject({
|
|
290
|
-
status: 'available',
|
|
291
|
-
currentVersion: '1.0.0',
|
|
292
|
-
latestVersion: '1.1.0',
|
|
293
|
-
})
|
|
294
|
-
expect(await readFile(meta.bin, 'utf8')).toContain('echo old')
|
|
295
|
-
} finally {
|
|
296
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
297
|
-
}
|
|
298
|
-
})
|
|
299
|
-
|
|
300
|
-
test('supports legacy string asset manifests', async () => {
|
|
301
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
302
|
-
const { path, meta, execution } = await makeInstall(root, '1.0.0')
|
|
303
|
-
const release = await makeFakeRelease(root, '1.1.0', { legacyManifest: true })
|
|
304
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
305
|
-
try {
|
|
306
|
-
const check = await updateAstrale({
|
|
307
|
-
check: true,
|
|
308
|
-
currentVersion: '1.0.0',
|
|
309
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
310
|
-
installPath: path,
|
|
311
|
-
execution,
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
expect(check).toMatchObject({
|
|
315
|
-
status: 'available',
|
|
316
|
-
latestVersion: '1.1.0',
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
const result = await updateAstrale({
|
|
320
|
-
currentVersion: '1.0.0',
|
|
321
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
322
|
-
installPath: path,
|
|
323
|
-
execution,
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
expect(result).toMatchObject({
|
|
327
|
-
status: 'updated',
|
|
328
|
-
currentVersion: '1.1.0',
|
|
329
|
-
})
|
|
330
|
-
const versionProc = Bun.spawn([meta.bin, '--version'], { stdout: 'pipe' })
|
|
331
|
-
expect(await new Response(versionProc.stdout).text()).toBe('1.1.0\n')
|
|
332
|
-
expect(await versionProc.exited).toBe(0)
|
|
333
|
-
} finally {
|
|
334
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
335
|
-
}
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
test('updates the binary and install metadata', async () => {
|
|
339
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
340
|
-
const { path, meta, execution } = await makeInstall(root, '1.0.0')
|
|
341
|
-
const release = await makeFakeRelease(root, '1.1.0')
|
|
342
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
343
|
-
try {
|
|
344
|
-
const result = await updateAstrale({
|
|
345
|
-
currentVersion: '1.0.0',
|
|
346
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
347
|
-
installPath: path,
|
|
348
|
-
execution,
|
|
349
|
-
})
|
|
350
|
-
|
|
351
|
-
expect(result).toMatchObject({
|
|
352
|
-
status: 'updated',
|
|
353
|
-
previousVersion: '1.0.0',
|
|
354
|
-
currentVersion: '1.1.0',
|
|
355
|
-
})
|
|
356
|
-
const versionProc = Bun.spawn([meta.bin, '--version'], { stdout: 'pipe' })
|
|
357
|
-
expect(await new Response(versionProc.stdout).text()).toBe('1.1.0\n')
|
|
358
|
-
expect(await versionProc.exited).toBe(0)
|
|
359
|
-
const updatedMeta = JSON.parse(await readFile(path, 'utf8')) as InstallMetadata
|
|
360
|
-
expect(updatedMeta.version).toBe('1.1.0')
|
|
361
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'main.js'), 'utf8')).toBe(
|
|
362
|
-
'viewer main\n',
|
|
363
|
-
)
|
|
364
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'index.html'), 'utf8')).toBe(
|
|
365
|
-
'<!doctype html>\n',
|
|
366
|
-
)
|
|
367
|
-
} finally {
|
|
368
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
369
|
-
}
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
test('a partial Viewer archive leaves the installed cohort and metadata unchanged', async () => {
|
|
373
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
374
|
-
const { path, meta, execution } = await makeInstall(root, '1.0.0')
|
|
375
|
-
const release = await makeFakeRelease(root, '1.1.0', { omitViewerIndex: true })
|
|
376
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
377
|
-
const beforeBinary = await readFile(meta.bin, 'utf8')
|
|
378
|
-
const beforeMetadata = await readFile(path, 'utf8')
|
|
379
|
-
try {
|
|
380
|
-
await expect(
|
|
381
|
-
updateAstrale({
|
|
382
|
-
currentVersion: '1.0.0',
|
|
383
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
384
|
-
installPath: path,
|
|
385
|
-
execution,
|
|
386
|
-
}),
|
|
387
|
-
).rejects.toThrow()
|
|
388
|
-
|
|
389
|
-
expect(await readFile(meta.bin, 'utf8')).toBe(beforeBinary)
|
|
390
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'main.js'), 'utf8')).toBe(
|
|
391
|
-
'old viewer main\n',
|
|
392
|
-
)
|
|
393
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'index.html'), 'utf8')).toBe(
|
|
394
|
-
'old viewer html\n',
|
|
395
|
-
)
|
|
396
|
-
expect(await readFile(path, 'utf8')).toBe(beforeMetadata)
|
|
397
|
-
} finally {
|
|
398
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
399
|
-
}
|
|
400
|
-
})
|
|
401
|
-
|
|
402
|
-
test('a Viewer commit failure rolls back binary, Viewer, and metadata', async () => {
|
|
403
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
404
|
-
const { path, meta, execution } = await makeInstall(root, '1.0.0')
|
|
405
|
-
const release = await makeFakeRelease(root, '1.1.0')
|
|
406
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
407
|
-
const beforeBinary = await readFile(meta.bin, 'utf8')
|
|
408
|
-
const beforeMetadata = await readFile(path, 'utf8')
|
|
409
|
-
try {
|
|
410
|
-
await expect(
|
|
411
|
-
updateAstrale(
|
|
412
|
-
{
|
|
413
|
-
currentVersion: '1.0.0',
|
|
414
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
415
|
-
installPath: path,
|
|
416
|
-
execution,
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
replaceStandaloneCohort: (installed, next, viewer) =>
|
|
420
|
-
replaceStandaloneCohort(installed, next, viewer, {
|
|
421
|
-
rename: async (from, to) => {
|
|
422
|
-
if (String(from).endsWith('viewer.next')) {
|
|
423
|
-
throw Object.assign(new Error('injected Viewer commit failure'), {
|
|
424
|
-
code: 'EIO',
|
|
425
|
-
})
|
|
426
|
-
}
|
|
427
|
-
await rename(from, to)
|
|
428
|
-
},
|
|
429
|
-
}),
|
|
430
|
-
},
|
|
431
|
-
),
|
|
432
|
-
).rejects.toThrow('injected Viewer commit failure')
|
|
433
|
-
|
|
434
|
-
expect(await readFile(meta.bin, 'utf8')).toBe(beforeBinary)
|
|
435
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'main.js'), 'utf8')).toBe(
|
|
436
|
-
'old viewer main\n',
|
|
437
|
-
)
|
|
438
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'index.html'), 'utf8')).toBe(
|
|
439
|
-
'old viewer html\n',
|
|
440
|
-
)
|
|
441
|
-
expect(await readFile(path, 'utf8')).toBe(beforeMetadata)
|
|
442
|
-
} finally {
|
|
443
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
444
|
-
}
|
|
445
|
-
})
|
|
446
|
-
|
|
447
|
-
test('a metadata failure after cohort commit restores binary, Viewer, and metadata', async () => {
|
|
448
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
449
|
-
const { path, meta, execution } = await makeInstall(root, '1.0.0')
|
|
450
|
-
const release = await makeFakeRelease(root, '1.1.0')
|
|
451
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
452
|
-
const beforeBinary = await readFile(meta.bin, 'utf8')
|
|
453
|
-
const beforeMetadata = await readFile(path, 'utf8')
|
|
454
|
-
try {
|
|
455
|
-
await expect(
|
|
456
|
-
updateAstrale(
|
|
457
|
-
{
|
|
458
|
-
currentVersion: '1.0.0',
|
|
459
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
460
|
-
installPath: path,
|
|
461
|
-
execution,
|
|
462
|
-
},
|
|
463
|
-
{
|
|
464
|
-
writeInstallMetadata: async () => {
|
|
465
|
-
throw new Error('injected metadata write failure')
|
|
466
|
-
},
|
|
467
|
-
},
|
|
468
|
-
),
|
|
469
|
-
).rejects.toThrow('injected metadata write failure')
|
|
470
|
-
|
|
471
|
-
expect(await readFile(meta.bin, 'utf8')).toBe(beforeBinary)
|
|
472
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'main.js'), 'utf8')).toBe(
|
|
473
|
-
'old viewer main\n',
|
|
474
|
-
)
|
|
475
|
-
expect(await readFile(join(dirname(meta.bin), 'viewer', 'dist', 'index.html'), 'utf8')).toBe(
|
|
476
|
-
'old viewer html\n',
|
|
477
|
-
)
|
|
478
|
-
expect(await readFile(path, 'utf8')).toBe(beforeMetadata)
|
|
479
|
-
} finally {
|
|
480
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
481
|
-
}
|
|
482
|
-
})
|
|
483
|
-
|
|
484
|
-
test('updates canary-style releases whose binary reports the package version', async () => {
|
|
485
|
-
const root = await mkdtemp(join(tmpdir(), 'astrale-update-test-'))
|
|
486
|
-
const { path, meta, execution } = await makeInstall(root, 'main-old123')
|
|
487
|
-
const release = await makeFakeRelease(root, 'main-new456', { binaryVersion: '1.0.0' })
|
|
488
|
-
process.env.ASTRALE_UPDATE_BASE = `file://${release}`
|
|
489
|
-
try {
|
|
490
|
-
const result = await updateAstrale({
|
|
491
|
-
currentVersion: '1.0.0',
|
|
492
|
-
platform: { os: 'darwin', arch: 'arm64' },
|
|
493
|
-
installPath: path,
|
|
494
|
-
execution,
|
|
495
|
-
})
|
|
496
|
-
|
|
497
|
-
expect(result).toMatchObject({
|
|
498
|
-
status: 'updated',
|
|
499
|
-
previousVersion: 'main-old123',
|
|
500
|
-
currentVersion: 'main-new456',
|
|
501
|
-
})
|
|
502
|
-
const versionProc = Bun.spawn([meta.bin, '--version'], { stdout: 'pipe' })
|
|
503
|
-
expect(await new Response(versionProc.stdout).text()).toBe('1.0.0\n')
|
|
504
|
-
expect(await versionProc.exited).toBe(0)
|
|
505
|
-
const updatedMeta = JSON.parse(await readFile(path, 'utf8')) as InstallMetadata
|
|
506
|
-
expect(updatedMeta.version).toBe('main-new456')
|
|
507
|
-
} finally {
|
|
508
|
-
delete process.env.ASTRALE_UPDATE_BASE
|
|
509
|
-
}
|
|
510
|
-
})
|
|
511
|
-
})
|