@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
package/src/state/files.ts
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto'
|
|
2
|
-
import {
|
|
3
|
-
closeSync,
|
|
4
|
-
fsyncSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
openSync,
|
|
7
|
-
renameSync,
|
|
8
|
-
unlinkSync,
|
|
9
|
-
writeFileSync,
|
|
10
|
-
} from 'node:fs'
|
|
11
|
-
import { mkdir, open, readFile, rename, stat, unlink } from 'node:fs/promises'
|
|
12
|
-
import { dirname } from 'node:path'
|
|
13
|
-
|
|
14
|
-
/** Atomically publish one complete private state file through a same-directory temporary file. */
|
|
15
|
-
export async function atomicWrite(path: string, data: string): Promise<void> {
|
|
16
|
-
const directory = dirname(path)
|
|
17
|
-
const temporary = `${path}.${randomUUID()}.tmp`
|
|
18
|
-
await mkdir(directory, { recursive: true })
|
|
19
|
-
|
|
20
|
-
let handle: Awaited<ReturnType<typeof open>> | undefined
|
|
21
|
-
try {
|
|
22
|
-
handle = await open(temporary, 'wx', 0o600)
|
|
23
|
-
await handle.writeFile(data)
|
|
24
|
-
await handle.sync()
|
|
25
|
-
await handle.close()
|
|
26
|
-
handle = undefined
|
|
27
|
-
await rename(temporary, path)
|
|
28
|
-
|
|
29
|
-
const directoryHandle = await open(directory, 'r')
|
|
30
|
-
try {
|
|
31
|
-
await directoryHandle.sync()
|
|
32
|
-
} finally {
|
|
33
|
-
await directoryHandle.close()
|
|
34
|
-
}
|
|
35
|
-
} catch (error) {
|
|
36
|
-
await handle?.close().catch(() => undefined)
|
|
37
|
-
await unlink(temporary).catch(() => undefined)
|
|
38
|
-
throw error
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Atomically publish one complete private state file for synchronous consumer capabilities. */
|
|
43
|
-
export function atomicWriteSync(path: string, data: string): void {
|
|
44
|
-
const directory = dirname(path)
|
|
45
|
-
const temporary = `${path}.${randomUUID()}.tmp`
|
|
46
|
-
mkdirSync(directory, { recursive: true })
|
|
47
|
-
|
|
48
|
-
let descriptor: number | undefined
|
|
49
|
-
try {
|
|
50
|
-
descriptor = openSync(temporary, 'wx', 0o600)
|
|
51
|
-
writeFileSync(descriptor, data)
|
|
52
|
-
fsyncSync(descriptor)
|
|
53
|
-
closeSync(descriptor)
|
|
54
|
-
descriptor = undefined
|
|
55
|
-
renameSync(temporary, path)
|
|
56
|
-
|
|
57
|
-
const directoryDescriptor = openSync(directory, 'r')
|
|
58
|
-
try {
|
|
59
|
-
fsyncSync(directoryDescriptor)
|
|
60
|
-
} finally {
|
|
61
|
-
closeSync(directoryDescriptor)
|
|
62
|
-
}
|
|
63
|
-
} catch (error) {
|
|
64
|
-
if (descriptor !== undefined) closeSync(descriptor)
|
|
65
|
-
try {
|
|
66
|
-
unlinkSync(temporary)
|
|
67
|
-
} catch {
|
|
68
|
-
// The temporary file was either never created or was already renamed.
|
|
69
|
-
}
|
|
70
|
-
throw error
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface FileLockOptions {
|
|
75
|
-
readonly pollIntervalMs?: number
|
|
76
|
-
readonly staleAfterMs?: number
|
|
77
|
-
readonly timeoutMs?: number
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** Run one transition under a bounded cross-process create-exclusive lock. */
|
|
81
|
-
export async function withFileLock<Value>(
|
|
82
|
-
lockPath: string,
|
|
83
|
-
transition: () => Promise<Value>,
|
|
84
|
-
options: FileLockOptions = {},
|
|
85
|
-
): Promise<Value> {
|
|
86
|
-
const pollIntervalMs = options.pollIntervalMs ?? 100
|
|
87
|
-
const staleAfterMs = options.staleAfterMs ?? 30_000
|
|
88
|
-
const timeoutMs = options.timeoutMs ?? 60_000
|
|
89
|
-
const deadline = Date.now() + timeoutMs
|
|
90
|
-
|
|
91
|
-
for (;;) {
|
|
92
|
-
if (await tryAcquire(lockPath)) {
|
|
93
|
-
try {
|
|
94
|
-
return await transition()
|
|
95
|
-
} finally {
|
|
96
|
-
await unlink(lockPath).catch(() => undefined)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (await takeoverIfAbandoned(lockPath, staleAfterMs)) continue
|
|
100
|
-
if (Date.now() >= deadline) {
|
|
101
|
-
throw new Error(`Timed out after ${timeoutMs}ms waiting for lock ${lockPath}`)
|
|
102
|
-
}
|
|
103
|
-
await sleep(pollIntervalMs)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async function tryAcquire(lockPath: string): Promise<boolean> {
|
|
108
|
-
try {
|
|
109
|
-
const handle = await open(lockPath, 'wx', 0o600)
|
|
110
|
-
try {
|
|
111
|
-
await handle.writeFile(
|
|
112
|
-
JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString() }),
|
|
113
|
-
)
|
|
114
|
-
await handle.sync()
|
|
115
|
-
} finally {
|
|
116
|
-
await handle.close()
|
|
117
|
-
}
|
|
118
|
-
return true
|
|
119
|
-
} catch (error) {
|
|
120
|
-
const code = (error as { code?: string }).code
|
|
121
|
-
if (code === 'EEXIST') return false
|
|
122
|
-
if (code === 'ENOENT') {
|
|
123
|
-
await mkdir(dirname(lockPath), { recursive: true })
|
|
124
|
-
return tryAcquire(lockPath)
|
|
125
|
-
}
|
|
126
|
-
throw error
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async function takeoverIfAbandoned(lockPath: string, staleAfterMs: number): Promise<boolean> {
|
|
131
|
-
try {
|
|
132
|
-
const info = await stat(lockPath)
|
|
133
|
-
if (Date.now() - info.mtimeMs > staleAfterMs) {
|
|
134
|
-
await unlink(lockPath).catch(() => undefined)
|
|
135
|
-
return true
|
|
136
|
-
}
|
|
137
|
-
} catch (error) {
|
|
138
|
-
if ((error as { code?: string }).code === 'ENOENT') return true
|
|
139
|
-
throw error
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const pid = await readLockPid(lockPath)
|
|
143
|
-
if (pid !== undefined && pid !== process.pid && !isPidAlive(pid)) {
|
|
144
|
-
await unlink(lockPath).catch(() => undefined)
|
|
145
|
-
return true
|
|
146
|
-
}
|
|
147
|
-
return false
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async function readLockPid(lockPath: string): Promise<number | undefined> {
|
|
151
|
-
try {
|
|
152
|
-
const value = (JSON.parse(await readFile(lockPath, 'utf-8')) as { pid?: unknown }).pid
|
|
153
|
-
return typeof value === 'number' ? value : undefined
|
|
154
|
-
} catch {
|
|
155
|
-
return undefined
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function isPidAlive(pid: number): boolean {
|
|
160
|
-
try {
|
|
161
|
-
process.kill(pid, 0)
|
|
162
|
-
return true
|
|
163
|
-
} catch (error) {
|
|
164
|
-
return (error as { code?: string }).code === 'EPERM'
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function sleep(milliseconds: number): Promise<void> {
|
|
169
|
-
return new Promise((resolve) => setTimeout(resolve, milliseconds))
|
|
170
|
-
}
|
package/src/state/identities.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises'
|
|
2
|
-
import { z } from 'zod'
|
|
3
|
-
|
|
4
|
-
import type { FileLockOptions } from './files'
|
|
5
|
-
|
|
6
|
-
import { atomicWrite, withFileLock } from './files'
|
|
7
|
-
import { IDENTITIES_PATH } from './paths'
|
|
8
|
-
|
|
9
|
-
export type IdentitySource = 'key' | 'idp'
|
|
10
|
-
export type IdentityMode = 'local' | 'remote'
|
|
11
|
-
|
|
12
|
-
export interface Registration {
|
|
13
|
-
readonly iss: string
|
|
14
|
-
readonly sub: string
|
|
15
|
-
readonly registeredAt: string
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface Identity {
|
|
19
|
-
readonly subject: string
|
|
20
|
-
readonly createdAt: string
|
|
21
|
-
readonly source?: IdentitySource
|
|
22
|
-
readonly mode?: IdentityMode
|
|
23
|
-
readonly kid?: string
|
|
24
|
-
readonly idp?: string
|
|
25
|
-
readonly issuer?: string
|
|
26
|
-
readonly audience?: string
|
|
27
|
-
readonly claims?: Readonly<Record<string, unknown>>
|
|
28
|
-
readonly registrations?: Readonly<Record<string, Registration>>
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface IdentityStore {
|
|
32
|
-
readonly default: string
|
|
33
|
-
readonly identities: Readonly<Record<string, Identity>>
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const IDENTITY_STORE_VERSION = 1 as const
|
|
37
|
-
|
|
38
|
-
export type IdentityStateErrorCode =
|
|
39
|
-
| 'IDENTITY_STATE_INVALID'
|
|
40
|
-
| 'IDENTITY_STATE_VERSION_UNSUPPORTED'
|
|
41
|
-
| 'IDENTITY_STATE_UNREADABLE'
|
|
42
|
-
| 'IDENTITY_STATE_BACKUP_CONFLICT'
|
|
43
|
-
|
|
44
|
-
export class IdentityStateError extends Error {
|
|
45
|
-
readonly code: IdentityStateErrorCode
|
|
46
|
-
readonly path: string
|
|
47
|
-
|
|
48
|
-
constructor(code: IdentityStateErrorCode, path: string, message: string, cause?: unknown) {
|
|
49
|
-
super(message, { cause })
|
|
50
|
-
this.name = 'IdentityStateError'
|
|
51
|
-
this.code = code
|
|
52
|
-
this.path = path
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface IdentityStoreOptions {
|
|
57
|
-
readonly path?: string
|
|
58
|
-
readonly now?: () => Date
|
|
59
|
-
readonly lock?: FileLockOptions
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface IdentityUpdate<Value> {
|
|
63
|
-
readonly next: IdentityStore
|
|
64
|
-
readonly value: Value
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const RegistrationSchema: z.ZodType<Registration> = z
|
|
68
|
-
.object({
|
|
69
|
-
iss: z.string(),
|
|
70
|
-
sub: z.string(),
|
|
71
|
-
registeredAt: z.string(),
|
|
72
|
-
})
|
|
73
|
-
.strict()
|
|
74
|
-
|
|
75
|
-
const IdentitySchema: z.ZodType<Identity> = z
|
|
76
|
-
.object({
|
|
77
|
-
subject: z.string(),
|
|
78
|
-
createdAt: z.string(),
|
|
79
|
-
source: z.enum(['key', 'idp']).optional(),
|
|
80
|
-
mode: z.enum(['local', 'remote']).optional(),
|
|
81
|
-
kid: z.string().optional(),
|
|
82
|
-
idp: z.string().optional(),
|
|
83
|
-
issuer: z.string().url().optional(),
|
|
84
|
-
audience: z.string().optional(),
|
|
85
|
-
claims: z.record(z.string(), z.unknown()).optional(),
|
|
86
|
-
registrations: z.record(z.string(), RegistrationSchema).optional(),
|
|
87
|
-
})
|
|
88
|
-
.strict()
|
|
89
|
-
|
|
90
|
-
const IdentityStoreFields = {
|
|
91
|
-
default: z.string(),
|
|
92
|
-
identities: z.record(z.string(), IdentitySchema),
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const IdentityStoreSchema: z.ZodType<IdentityStore> = z.object(IdentityStoreFields).strict()
|
|
96
|
-
|
|
97
|
-
const IdentityFileV1Schema = z
|
|
98
|
-
.object({ version: z.literal(IDENTITY_STORE_VERSION), ...IdentityStoreFields })
|
|
99
|
-
.strict()
|
|
100
|
-
|
|
101
|
-
interface DecodedIdentityStore {
|
|
102
|
-
readonly store: IdentityStore
|
|
103
|
-
readonly legacyBytes?: string
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export async function readIdentityStore(
|
|
107
|
-
options: IdentityStoreOptions = {},
|
|
108
|
-
): Promise<IdentityStore> {
|
|
109
|
-
return (await readDecoded(options)).store
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export async function updateIdentityStore<Value>(
|
|
113
|
-
transition: (current: IdentityStore) => IdentityUpdate<Value> | Promise<IdentityUpdate<Value>>,
|
|
114
|
-
options: IdentityStoreOptions = {},
|
|
115
|
-
): Promise<Value> {
|
|
116
|
-
const path = options.path ?? IDENTITIES_PATH
|
|
117
|
-
return withFileLock(
|
|
118
|
-
`${path}.lock`,
|
|
119
|
-
async () => {
|
|
120
|
-
const current = await readDecoded(options)
|
|
121
|
-
const update = await transition(current.store)
|
|
122
|
-
if (current.legacyBytes !== undefined) {
|
|
123
|
-
await preserveLegacyBackup(path, current.legacyBytes)
|
|
124
|
-
}
|
|
125
|
-
await atomicWrite(path, encodeV1(update.next))
|
|
126
|
-
return update.value
|
|
127
|
-
},
|
|
128
|
-
options.lock,
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async function readDecoded(options: IdentityStoreOptions): Promise<DecodedIdentityStore> {
|
|
133
|
-
const path = options.path ?? IDENTITIES_PATH
|
|
134
|
-
let raw: string
|
|
135
|
-
try {
|
|
136
|
-
raw = await readFile(path, 'utf-8')
|
|
137
|
-
} catch (error) {
|
|
138
|
-
if ((error as { code?: string }).code === 'ENOENT') {
|
|
139
|
-
return { store: seed(options.now?.() ?? new Date()) }
|
|
140
|
-
}
|
|
141
|
-
throw new IdentityStateError(
|
|
142
|
-
'IDENTITY_STATE_UNREADABLE',
|
|
143
|
-
path,
|
|
144
|
-
`Could not read identity state at ${path}`,
|
|
145
|
-
error,
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
let input: unknown
|
|
150
|
-
try {
|
|
151
|
-
input = JSON.parse(raw)
|
|
152
|
-
} catch (error) {
|
|
153
|
-
throw invalidState(path, error)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (hasVersion(input)) {
|
|
157
|
-
if (typeof input.version !== 'number' || !Number.isInteger(input.version)) {
|
|
158
|
-
throw invalidState(path)
|
|
159
|
-
}
|
|
160
|
-
if (input.version !== IDENTITY_STORE_VERSION) {
|
|
161
|
-
throw new IdentityStateError(
|
|
162
|
-
'IDENTITY_STATE_VERSION_UNSUPPORTED',
|
|
163
|
-
path,
|
|
164
|
-
`Identity state at ${path} uses unsupported version ${input.version}`,
|
|
165
|
-
)
|
|
166
|
-
}
|
|
167
|
-
try {
|
|
168
|
-
const { version: _, ...store } = IdentityFileV1Schema.parse(input)
|
|
169
|
-
return { store }
|
|
170
|
-
} catch (error) {
|
|
171
|
-
throw invalidState(path, error)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
return { store: IdentityStoreSchema.parse(input), legacyBytes: raw }
|
|
177
|
-
} catch (error) {
|
|
178
|
-
throw invalidState(path, error)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function hasVersion(input: unknown): input is { readonly version: unknown } {
|
|
183
|
-
return typeof input === 'object' && input !== null && Object.hasOwn(input, 'version')
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function seed(_now: Date): IdentityStore {
|
|
187
|
-
return {
|
|
188
|
-
default: '',
|
|
189
|
-
identities: {},
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function encodeV1(store: IdentityStore): string {
|
|
194
|
-
return `${JSON.stringify({ version: IDENTITY_STORE_VERSION, ...store }, null, 2)}\n`
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async function preserveLegacyBackup(path: string, legacyBytes: string): Promise<void> {
|
|
198
|
-
const backupPath = `${path}.v0.bak`
|
|
199
|
-
try {
|
|
200
|
-
const existing = await readFile(backupPath, 'utf-8')
|
|
201
|
-
if (existing !== legacyBytes) {
|
|
202
|
-
throw new IdentityStateError(
|
|
203
|
-
'IDENTITY_STATE_BACKUP_CONFLICT',
|
|
204
|
-
backupPath,
|
|
205
|
-
`Legacy identity backup at ${backupPath} does not match the file being migrated`,
|
|
206
|
-
)
|
|
207
|
-
}
|
|
208
|
-
} catch (error) {
|
|
209
|
-
if (error instanceof IdentityStateError) throw error
|
|
210
|
-
if ((error as { code?: string }).code !== 'ENOENT') {
|
|
211
|
-
throw new IdentityStateError(
|
|
212
|
-
'IDENTITY_STATE_UNREADABLE',
|
|
213
|
-
backupPath,
|
|
214
|
-
`Could not read legacy identity backup at ${backupPath}`,
|
|
215
|
-
error,
|
|
216
|
-
)
|
|
217
|
-
}
|
|
218
|
-
await atomicWrite(backupPath, legacyBytes)
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function invalidState(path: string, cause?: unknown): IdentityStateError {
|
|
223
|
-
return new IdentityStateError(
|
|
224
|
-
'IDENTITY_STATE_INVALID',
|
|
225
|
-
path,
|
|
226
|
-
`Identity state at ${path} is malformed`,
|
|
227
|
-
cause,
|
|
228
|
-
)
|
|
229
|
-
}
|
package/src/state/index.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export { atomicWrite, atomicWriteSync, withFileLock } from './files'
|
|
2
|
-
export type { FileLockOptions } from './files'
|
|
3
|
-
export { ExchangeCredentialCache } from './exchange-credentials'
|
|
4
|
-
export type { exchange } from './exchange-credentials'
|
|
5
|
-
export { IDENTITY_STORE_VERSION, readIdentityStore, updateIdentityStore } from './identities'
|
|
6
|
-
export type {
|
|
7
|
-
Identity,
|
|
8
|
-
IdentityMode,
|
|
9
|
-
IdentitySource,
|
|
10
|
-
IdentityStore,
|
|
11
|
-
IdentityStoreOptions,
|
|
12
|
-
IdentityUpdate,
|
|
13
|
-
Registration,
|
|
14
|
-
} from './identities'
|
|
15
|
-
export {
|
|
16
|
-
ASTRALE_HOME,
|
|
17
|
-
CONFIG_PATH,
|
|
18
|
-
DATA_DIR,
|
|
19
|
-
IDENTITIES_PATH,
|
|
20
|
-
IDPS_PATH,
|
|
21
|
-
IDP_SESSIONS_DIR,
|
|
22
|
-
EXCHANGE_CREDENTIALS_PATH,
|
|
23
|
-
INSTALL_PATH,
|
|
24
|
-
INSTANCES_PATH,
|
|
25
|
-
KEYS_DIR,
|
|
26
|
-
SESSION_ROUTES_PATH,
|
|
27
|
-
createPaths,
|
|
28
|
-
paths,
|
|
29
|
-
} from './paths'
|
|
30
|
-
export type { PathEnvironment, Paths } from './paths'
|
|
31
|
-
export { FileSessionRouteStore, SESSION_ROUTE_STORE } from './session-routes'
|
package/src/state/paths.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { homedir } from 'node:os'
|
|
2
|
-
import { join } from 'node:path'
|
|
3
|
-
|
|
4
|
-
export interface PathEnvironment {
|
|
5
|
-
readonly ASTRALE_HOME?: string
|
|
6
|
-
readonly ASTRALE_KEYS_DIR?: string
|
|
7
|
-
readonly ASTRALE_DATA_DIR?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface Paths {
|
|
11
|
-
readonly home: string
|
|
12
|
-
readonly keys: string
|
|
13
|
-
readonly data: string
|
|
14
|
-
readonly config: string
|
|
15
|
-
readonly install: string
|
|
16
|
-
readonly identities: string
|
|
17
|
-
readonly instances: string
|
|
18
|
-
readonly idps: string
|
|
19
|
-
readonly idpSessionsDir: string
|
|
20
|
-
readonly exchangeCredentials: string
|
|
21
|
-
readonly sessionRoutes: string
|
|
22
|
-
idpDir(name: string): string
|
|
23
|
-
idpSession(identityName: string): string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Resolve every CLI state path once from explicit input and the captured environment. */
|
|
27
|
-
export function createPaths(home?: string, environment?: PathEnvironment): Paths {
|
|
28
|
-
const captured = environment ?? {
|
|
29
|
-
ASTRALE_HOME: process.env.ASTRALE_HOME,
|
|
30
|
-
ASTRALE_KEYS_DIR: process.env.ASTRALE_KEYS_DIR,
|
|
31
|
-
ASTRALE_DATA_DIR: process.env.ASTRALE_DATA_DIR,
|
|
32
|
-
}
|
|
33
|
-
const base = home ?? captured.ASTRALE_HOME ?? join(homedir(), '.astrale')
|
|
34
|
-
const idpsDir = join(base, 'idps')
|
|
35
|
-
const idpSessionsDir = join(base, 'idp-sessions')
|
|
36
|
-
return Object.freeze({
|
|
37
|
-
home: base,
|
|
38
|
-
keys: captured.ASTRALE_KEYS_DIR ?? join(base, 'keys'),
|
|
39
|
-
data: captured.ASTRALE_DATA_DIR ?? join(base, 'data'),
|
|
40
|
-
config: join(base, 'config.json'),
|
|
41
|
-
install: join(base, 'install.json'),
|
|
42
|
-
identities: join(base, 'identities.json'),
|
|
43
|
-
instances: join(base, 'instances.json'),
|
|
44
|
-
idps: join(idpsDir, 'index.json'),
|
|
45
|
-
idpSessionsDir,
|
|
46
|
-
exchangeCredentials: join(base, 'exchange', 'credentials.json'),
|
|
47
|
-
sessionRoutes: join(base, 'session', 'routes.json'),
|
|
48
|
-
idpDir: (name: string) => join(idpsDir, name),
|
|
49
|
-
idpSession: (identityName: string) => join(idpSessionsDir, `${identityName}.json`),
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export const paths: Paths = createPaths()
|
|
54
|
-
export const ASTRALE_HOME = paths.home
|
|
55
|
-
export const KEYS_DIR = paths.keys
|
|
56
|
-
export const DATA_DIR = paths.data
|
|
57
|
-
export const CONFIG_PATH = paths.config
|
|
58
|
-
export const INSTALL_PATH = paths.install
|
|
59
|
-
export const IDENTITIES_PATH = paths.identities
|
|
60
|
-
export const INSTANCES_PATH = paths.instances
|
|
61
|
-
export const IDPS_PATH = paths.idps
|
|
62
|
-
export const IDP_SESSIONS_DIR = paths.idpSessionsDir
|
|
63
|
-
export const EXCHANGE_CREDENTIALS_PATH = paths.exchangeCredentials
|
|
64
|
-
export const SESSION_ROUTES_PATH = paths.sessionRoutes
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { SessionRouteArtifact, SessionRouteStore } from '@astrale-os/sdk/client/session'
|
|
2
|
-
|
|
3
|
-
import { chmodSync, mkdirSync, readFileSync, unlinkSync } from 'node:fs'
|
|
4
|
-
import { dirname } from 'node:path'
|
|
5
|
-
|
|
6
|
-
import { atomicWriteSync } from './files'
|
|
7
|
-
import { SESSION_ROUTES_PATH } from './paths'
|
|
8
|
-
|
|
9
|
-
/** CLI filesystem representation for Kernel Client's admitted confidential route artifact. */
|
|
10
|
-
export class FileSessionRouteStore implements SessionRouteStore {
|
|
11
|
-
constructor(private readonly path = SESSION_ROUTES_PATH) {}
|
|
12
|
-
|
|
13
|
-
read(): unknown {
|
|
14
|
-
return JSON.parse(readFileSync(this.path, 'utf8')) as unknown
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
write(artifact: SessionRouteArtifact): void {
|
|
18
|
-
const directory = dirname(this.path)
|
|
19
|
-
mkdirSync(directory, { recursive: true, mode: 0o700 })
|
|
20
|
-
chmodSync(directory, 0o700)
|
|
21
|
-
atomicWriteSync(this.path, `${JSON.stringify(artifact)}\n`)
|
|
22
|
-
chmodSync(this.path, 0o600)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
clear(): void {
|
|
26
|
-
try {
|
|
27
|
-
unlinkSync(this.path)
|
|
28
|
-
} catch (error) {
|
|
29
|
-
if ((error as { readonly code?: unknown }).code !== 'ENOENT') throw error
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const SESSION_ROUTE_STORE = Object.freeze(new FileSessionRouteStore())
|
package/src/state/tsconfig.json
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { clampLog } from '../analyze'
|
|
4
|
-
|
|
5
|
-
describe('clampLog', () => {
|
|
6
|
-
test('short output is written through untouched', () => {
|
|
7
|
-
const json = '{"is_error":false,"num_turns":3}'
|
|
8
|
-
expect(clampLog(json)).toBe(json)
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
test('output at exactly the limit is not clamped', () => {
|
|
12
|
-
const text = 'x'.repeat(1000)
|
|
13
|
-
expect(clampLog(text, 1000)).toBe(text)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
test('oversized output keeps its head and its tail', () => {
|
|
17
|
-
// The JSON envelope opens at the top; a stack or error message closes at
|
|
18
|
-
// the bottom. Both must survive; the middle is what nobody reads.
|
|
19
|
-
const text = `HEAD${'x'.repeat(50_000)}TAIL`
|
|
20
|
-
const clamped = clampLog(text, 1000)
|
|
21
|
-
expect(clamped.startsWith('HEAD')).toBe(true)
|
|
22
|
-
expect(clamped.endsWith('TAIL')).toBe(true)
|
|
23
|
-
expect(clamped).toContain('bytes elided')
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
test('the result stays within a small constant of the limit', () => {
|
|
27
|
-
const clamped = clampLog('y'.repeat(10_000_000), 4096)
|
|
28
|
-
// head + tail + the elision marker, never the input.
|
|
29
|
-
expect(clamped.length).toBeLessThan(4096 + 128)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('the elision count reports what was actually dropped', () => {
|
|
33
|
-
const clamped = clampLog('z'.repeat(10_000), 1000)
|
|
34
|
-
const elided = Number(/… (\d+) bytes elided …/u.exec(clamped)?.[1])
|
|
35
|
-
const kept = clamped.length - `\n… ${elided} bytes elided …\n`.length
|
|
36
|
-
expect(elided + kept).toBe(10_000)
|
|
37
|
-
})
|
|
38
|
-
})
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import type { TelemetryEvent } from '../types'
|
|
4
|
-
|
|
5
|
-
import { commandHead, extractSignals, hasSignals } from '../gate'
|
|
6
|
-
|
|
7
|
-
function ev(argv: string[], exitCode: number, errorName?: string): TelemetryEvent {
|
|
8
|
-
return {
|
|
9
|
-
v: 1,
|
|
10
|
-
ts: '2026-07-10T10:00:00.000Z',
|
|
11
|
-
argv,
|
|
12
|
-
exitCode,
|
|
13
|
-
durationMs: 10,
|
|
14
|
-
errorName,
|
|
15
|
-
cwd: '/w',
|
|
16
|
-
root: '/w',
|
|
17
|
-
surface: 'cli',
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe('commandHead', () => {
|
|
22
|
-
test('keeps up to two leading command tokens, stops at flags/values', () => {
|
|
23
|
-
expect(commandHead(['get', '/path', '-i', 'x'])).toBe('get /path')
|
|
24
|
-
expect(commandHead(['domain', 'install', './foo'])).toBe('domain install')
|
|
25
|
-
expect(commandHead(['status'])).toBe('status')
|
|
26
|
-
expect(commandHead(['--help'])).toBe('(bare)')
|
|
27
|
-
expect(commandHead(['call', 'k=v'])).toBe('call')
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
describe('extractSignals / hasSignals', () => {
|
|
32
|
-
test('failures grouped by command with error names', () => {
|
|
33
|
-
const s = extractSignals([
|
|
34
|
-
ev(['domain', 'install'], 1, 'AUTH_ERROR'),
|
|
35
|
-
ev(['domain', 'install'], 1, 'AUTH_ERROR'),
|
|
36
|
-
ev(['status'], 0),
|
|
37
|
-
])
|
|
38
|
-
expect(s.failures).toEqual([
|
|
39
|
-
{ command: 'domain install', count: 2, errorNames: ['AUTH_ERROR'] },
|
|
40
|
-
])
|
|
41
|
-
expect(s.retries).toEqual([])
|
|
42
|
-
expect(hasSignals(s)).toBe(true)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test('3+ runs of one command is a retry smell even when green', () => {
|
|
46
|
-
const s = extractSignals([ev(['get', '/a'], 0), ev(['get', '/a'], 0), ev(['get', '/a'], 0)])
|
|
47
|
-
expect(s.retries).toEqual([{ command: 'get /a', count: 3 }])
|
|
48
|
-
expect(hasSignals(s)).toBe(true)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
test('quiet session has no signals until a transcript is attached', () => {
|
|
52
|
-
const s = extractSignals([ev(['status'], 0), ev(['query', '/'], 0)])
|
|
53
|
-
expect(hasSignals(s)).toBe(false)
|
|
54
|
-
s.harnessSessions = [
|
|
55
|
-
{
|
|
56
|
-
harness: 'claude-code',
|
|
57
|
-
transcriptPath: '/t.jsonl',
|
|
58
|
-
sizeBytes: 1,
|
|
59
|
-
},
|
|
60
|
-
]
|
|
61
|
-
expect(hasSignals(s)).toBe(true)
|
|
62
|
-
})
|
|
63
|
-
})
|