@cortexkit/opencode-antigravity-auth 3.0.5 → 3.0.6
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/README.md +38 -352
- package/dist/cli.js +9199 -8799
- package/dist/cli.js.map +4 -4
- package/dist/cli.meta.json +1286 -1064
- package/dist/index.js +13641 -14559
- package/dist/index.js.map +4 -4
- package/dist/index.meta.json +1333 -1342
- package/dist/server.js +10618 -11080
- package/dist/server.js.map +4 -4
- package/dist/server.meta.json +1 -1
- package/dist/src/auth-method-labels.d.ts +3 -0
- package/dist/src/auth-method-labels.d.ts.map +1 -0
- package/dist/src/auth-method-labels.js +5 -0
- package/dist/src/auth-method-labels.js.map +1 -0
- package/dist/src/cli.d.ts +3 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +98 -12
- package/dist/src/cli.js.map +1 -1
- package/dist/src/common-auth-embedded/claustrum/consumer.d.ts +33 -3
- package/dist/src/common-auth-embedded/claustrum/consumer.js +96 -1
- package/dist/src/common-auth-embedded/claustrum/custody.d.ts +4 -1
- package/dist/src/common-auth-embedded/claustrum/enrollment.d.ts +6 -1
- package/dist/src/common-auth-embedded/claustrum/enrollment.js +6 -1
- package/dist/src/common-auth-embedded/claustrum/index.d.ts +2 -1
- package/dist/src/common-auth-embedded/claustrum/index.js +5 -3
- package/dist/src/common-auth-embedded/claustrum/insula.d.ts +69 -0
- package/dist/src/common-auth-embedded/claustrum/insula.js +152 -0
- package/dist/src/common-auth-embedded/claustrum/roster.d.ts +13 -0
- package/dist/src/common-auth-embedded/claustrum/roster.js +33 -3
- package/dist/src/common-auth-embedded/fs/refresh-file-lock.js +20 -11
- package/dist/src/common-auth-embedded/quota/codec.d.ts +2 -0
- package/dist/src/common-auth-embedded/quota/codec.js +2 -1
- package/dist/src/common-auth-embedded/quota/format.d.ts +26 -0
- package/dist/src/common-auth-embedded/quota/format.js +78 -42
- package/dist/src/common-auth-embedded/quota/index.d.ts +4 -4
- package/dist/src/common-auth-embedded/quota/index.js +2 -2
- package/dist/src/common-auth-embedded/quota/map.d.ts +11 -0
- package/dist/src/common-auth-embedded/quota/map.js +36 -1
- package/dist/src/common-auth-embedded/quota/merge.d.ts +3 -1
- package/dist/src/common-auth-embedded/quota/merge.js +21 -5
- package/dist/src/common-auth-embedded/quota/projection.d.ts +2 -1
- package/dist/src/common-auth-embedded/quota/projection.js +3 -1
- package/dist/src/common-auth-embedded/setup/command-runner.js +49 -0
- package/dist/src/common-auth-embedded/setup/command.d.ts +3 -0
- package/dist/src/common-auth-embedded/setup/command.js +215 -0
- package/dist/src/common-auth-embedded/setup/config-write.js +60 -0
- package/dist/src/common-auth-embedded/setup/detect.d.ts +6 -0
- package/dist/src/common-auth-embedded/setup/detect.js +224 -0
- package/dist/src/common-auth-embedded/setup/enroll.js +70 -0
- package/dist/src/common-auth-embedded/setup/index.d.ts +5 -0
- package/dist/src/common-auth-embedded/setup/index.js +4 -0
- package/dist/src/common-auth-embedded/setup/paths.js +33 -0
- package/dist/src/common-auth-embedded/setup/process-fence.d.ts +43 -0
- package/dist/src/common-auth-embedded/setup/process-fence.js +270 -0
- package/dist/src/common-auth-embedded/setup/prompts.js +26 -0
- package/dist/src/common-auth-embedded/setup/register.d.ts +11 -0
- package/dist/src/common-auth-embedded/setup/register.js +130 -0
- package/dist/src/common-auth-embedded/setup/types.d.ts +136 -0
- package/dist/src/common-auth-embedded/source-output.json +228 -80
- package/dist/src/common-auth-embedded/store/schema.d.ts +2 -0
- package/dist/src/common-auth-embedded/store/schema.js +3 -2
- package/dist/src/ga/rpc/protocol.d.ts +4 -7
- package/dist/src/ga/rpc/protocol.d.ts.map +1 -1
- package/dist/src/ga/rpc/protocol.js +5 -13
- package/dist/src/ga/rpc/protocol.js.map +1 -1
- package/dist/src/ga/server/auth.d.ts +8 -3
- package/dist/src/ga/server/auth.d.ts.map +1 -1
- package/dist/src/ga/server/auth.js +25 -9
- package/dist/src/ga/server/auth.js.map +1 -1
- package/dist/src/ga/server/index.d.ts +39 -12
- package/dist/src/ga/server/index.d.ts.map +1 -1
- package/dist/src/ga/server/index.js +214 -53
- package/dist/src/ga/server/index.js.map +1 -1
- package/dist/src/ga/server/pool-login.d.ts +22 -0
- package/dist/src/ga/server/pool-login.d.ts.map +1 -0
- package/dist/src/ga/server/pool-login.js +150 -0
- package/dist/src/ga/server/pool-login.js.map +1 -0
- package/dist/src/ga/tui/host-ga.d.ts +2 -5
- package/dist/src/ga/tui/host-ga.d.ts.map +1 -1
- package/dist/src/ga/tui/host-ga.js +17 -49
- package/dist/src/ga/tui/host-ga.js.map +1 -1
- package/dist/src/plugin/accounts.d.ts +1 -1
- package/dist/src/plugin/accounts.d.ts.map +1 -1
- package/dist/src/plugin/accounts.js +1 -0
- package/dist/src/plugin/accounts.js.map +1 -1
- package/dist/src/plugin/background-vault-quota-refresh.d.ts +2 -0
- package/dist/src/plugin/background-vault-quota-refresh.d.ts.map +1 -1
- package/dist/src/plugin/background-vault-quota-refresh.js +125 -10
- package/dist/src/plugin/background-vault-quota-refresh.js.map +1 -1
- package/dist/src/plugin/command-apply.d.ts +2 -2
- package/dist/src/plugin/command-apply.d.ts.map +1 -1
- package/dist/src/plugin/command-apply.js +3 -10
- package/dist/src/plugin/command-apply.js.map +1 -1
- package/dist/src/plugin/commands.d.ts +1 -0
- package/dist/src/plugin/commands.d.ts.map +1 -1
- package/dist/src/plugin/commands.js +2 -2
- package/dist/src/plugin/commands.js.map +1 -1
- package/dist/src/plugin/config/operator-settings-schema.d.ts +0 -4
- package/dist/src/plugin/config/operator-settings-schema.d.ts.map +1 -1
- package/dist/src/plugin/config/operator-settings-schema.js +0 -5
- package/dist/src/plugin/config/operator-settings-schema.js.map +1 -1
- package/dist/src/plugin/config/schema.d.ts +0 -7
- package/dist/src/plugin/config/schema.d.ts.map +1 -1
- package/dist/src/plugin/config/schema.js +0 -43
- package/dist/src/plugin/config/schema.js.map +1 -1
- package/dist/src/plugin/config/writer.d.ts +1 -1
- package/dist/src/plugin/config/writer.js +1 -1
- package/dist/src/plugin/fetch/retry-state.d.ts +19 -3
- package/dist/src/plugin/fetch/retry-state.d.ts.map +1 -1
- package/dist/src/plugin/fetch/retry-state.js +0 -6
- package/dist/src/plugin/fetch/retry-state.js.map +1 -1
- package/dist/src/plugin/fetch-interceptor.d.ts.map +1 -1
- package/dist/src/plugin/fetch-interceptor.js +0 -3
- package/dist/src/plugin/fetch-interceptor.js.map +1 -1
- package/dist/src/plugin/fetch-routing.d.ts +0 -16
- package/dist/src/plugin/fetch-routing.d.ts.map +1 -1
- package/dist/src/plugin/fetch-routing.js +0 -49
- package/dist/src/plugin/fetch-routing.js.map +1 -1
- package/dist/src/plugin/ga-location-services.d.ts +14 -9
- package/dist/src/plugin/ga-location-services.d.ts.map +1 -1
- package/dist/src/plugin/ga-location-services.js +120 -40
- package/dist/src/plugin/ga-location-services.js.map +1 -1
- package/dist/src/plugin/google-origin.d.ts +7 -0
- package/dist/src/plugin/google-origin.d.ts.map +1 -0
- package/dist/src/plugin/google-origin.js +14 -0
- package/dist/src/plugin/google-origin.js.map +1 -0
- package/dist/src/plugin/index.d.ts.map +1 -1
- package/dist/src/plugin/index.js +15 -4
- package/dist/src/plugin/index.js.map +1 -1
- package/dist/src/plugin/oauth-methods.d.ts.map +1 -1
- package/dist/src/plugin/oauth-methods.js +0 -33
- package/dist/src/plugin/oauth-methods.js.map +1 -1
- package/dist/src/plugin/operator-settings.d.ts +1 -1
- package/dist/src/plugin/operator-settings.d.ts.map +1 -1
- package/dist/src/plugin/operator-settings.js +1 -8
- package/dist/src/plugin/operator-settings.js.map +1 -1
- package/dist/src/plugin/quota.d.ts +11 -7
- package/dist/src/plugin/quota.d.ts.map +1 -1
- package/dist/src/plugin/quota.js +128 -102
- package/dist/src/plugin/quota.js.map +1 -1
- package/dist/src/plugin/request.d.ts +5 -3
- package/dist/src/plugin/request.d.ts.map +1 -1
- package/dist/src/plugin/request.js +87 -168
- package/dist/src/plugin/request.js.map +1 -1
- package/dist/src/plugin/server.d.ts.map +1 -1
- package/dist/src/plugin/server.js +60 -53
- package/dist/src/plugin/server.js.map +1 -1
- package/dist/src/plugin/shared/advisory-repository.d.ts +20 -0
- package/dist/src/plugin/shared/advisory-repository.d.ts.map +1 -0
- package/dist/src/plugin/shared/advisory-repository.js +91 -0
- package/dist/src/plugin/shared/advisory-repository.js.map +1 -0
- package/dist/src/plugin/shared/request-services.d.ts +19 -25
- package/dist/src/plugin/shared/request-services.d.ts.map +1 -1
- package/dist/src/plugin/shared/request-services.js +105 -188
- package/dist/src/plugin/shared/request-services.js.map +1 -1
- package/dist/src/plugin/shared/runtime.js +4 -2
- package/dist/src/plugin/shared/runtime.js.map +1 -1
- package/dist/src/plugin/shared/vault-request-credentials.d.ts +4 -1
- package/dist/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
- package/dist/src/plugin/shared/vault-request-credentials.js +41 -7
- package/dist/src/plugin/shared/vault-request-credentials.js.map +1 -1
- package/dist/src/plugin/storage.d.ts +2 -2
- package/dist/src/plugin/storage.d.ts.map +1 -1
- package/dist/src/plugin/storage.js.map +1 -1
- package/dist/src/plugin/vault-custody.d.ts.map +1 -1
- package/dist/src/plugin/vault-custody.js +147 -35
- package/dist/src/plugin/vault-custody.js.map +1 -1
- package/dist/src/plugin/vault-quota-outcome.d.ts +19 -0
- package/dist/src/plugin/vault-quota-outcome.d.ts.map +1 -0
- package/dist/src/plugin/vault-quota-outcome.js +47 -0
- package/dist/src/plugin/vault-quota-outcome.js.map +1 -0
- package/dist/src/quota-presentation.d.ts +29 -1
- package/dist/src/quota-presentation.d.ts.map +1 -1
- package/dist/src/quota-presentation.js +52 -17
- package/dist/src/quota-presentation.js.map +1 -1
- package/dist/src/setup.d.ts +15 -0
- package/dist/src/setup.d.ts.map +1 -0
- package/dist/src/setup.js +320 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/sidebar-projection.d.ts +1 -1
- package/dist/src/sidebar-projection.d.ts.map +1 -1
- package/dist/src/sidebar-state.d.ts +1 -1
- package/dist/src/sidebar-state.d.ts.map +1 -1
- package/dist/src/sidebar-state.js +19 -1
- package/dist/src/sidebar-state.js.map +1 -1
- package/dist/src/tui.d.ts.map +1 -1
- package/dist/src/tui.js +205 -110
- package/dist/src/tui.js.map +1 -1
- package/dist/tui-build-map.json +37 -37
- package/dist/tui-ga-build-map.json +33 -33
- package/dist/types/src/auth-method-labels.d.ts +3 -0
- package/dist/types/src/auth-method-labels.d.ts.map +1 -0
- package/dist/types/src/cli.d.ts +3 -1
- package/dist/types/src/cli.d.ts.map +1 -1
- package/dist/types/src/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
- package/dist/types/src/common-auth-embedded/claustrum/consumer.d.ts +132 -0
- package/dist/types/src/common-auth-embedded/claustrum/custody.d.ts +178 -0
- package/dist/types/src/common-auth-embedded/claustrum/enrollment.d.ts +164 -0
- package/dist/types/src/common-auth-embedded/claustrum/errors.d.ts +16 -0
- package/dist/types/src/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
- package/dist/types/src/common-auth-embedded/claustrum/index.d.ts +19 -0
- package/dist/types/src/common-auth-embedded/claustrum/insula.d.ts +69 -0
- package/dist/types/src/common-auth-embedded/claustrum/interlock.d.ts +27 -0
- package/dist/types/src/common-auth-embedded/claustrum/roster.d.ts +221 -0
- package/dist/types/src/common-auth-embedded/opencode2/errors.d.ts +25 -0
- package/dist/types/src/common-auth-embedded/opencode2/index.d.ts +8 -0
- package/dist/types/src/common-auth-embedded/opencode2/install.d.ts +55 -0
- package/dist/types/src/common-auth-embedded/opencode2/integration.d.ts +112 -0
- package/dist/types/src/common-auth-embedded/opencode2/sse.d.ts +12 -0
- package/dist/types/src/common-auth-embedded/opencode2/types.d.ts +413 -0
- package/dist/types/src/common-auth-embedded/quota/codec.d.ts +2 -0
- package/dist/types/src/common-auth-embedded/quota/format.d.ts +26 -0
- package/dist/types/src/common-auth-embedded/quota/index.d.ts +4 -4
- package/dist/types/src/common-auth-embedded/quota/map.d.ts +11 -0
- package/dist/types/src/common-auth-embedded/quota/merge.d.ts +3 -1
- package/dist/types/src/common-auth-embedded/quota/projection.d.ts +2 -1
- package/dist/types/src/common-auth-embedded/routing/admission.d.ts +93 -0
- package/dist/types/src/common-auth-embedded/routing/index.d.ts +8 -0
- package/dist/types/src/common-auth-embedded/routing/ordered.d.ts +47 -0
- package/dist/types/src/common-auth-embedded/routing/pins.d.ts +22 -0
- package/dist/types/src/common-auth-embedded/routing/sticky.d.ts +158 -0
- package/dist/types/src/common-auth-embedded/setup/command.d.ts +3 -0
- package/dist/types/src/common-auth-embedded/setup/detect.d.ts +6 -0
- package/dist/types/src/common-auth-embedded/setup/index.d.ts +5 -0
- package/dist/types/src/common-auth-embedded/setup/process-fence.d.ts +43 -0
- package/dist/types/src/common-auth-embedded/setup/register.d.ts +11 -0
- package/dist/types/src/common-auth-embedded/setup/types.d.ts +136 -0
- package/dist/types/src/common-auth-embedded/store/schema.d.ts +2 -0
- package/dist/types/src/ga/rpc/protocol.d.ts +4 -7
- package/dist/types/src/ga/rpc/protocol.d.ts.map +1 -1
- package/dist/types/src/ga/server/auth.d.ts +8 -3
- package/dist/types/src/ga/server/auth.d.ts.map +1 -1
- package/dist/types/src/ga/server/index.d.ts +39 -12
- package/dist/types/src/ga/server/index.d.ts.map +1 -1
- package/dist/types/src/ga/server/pool-login.d.ts +22 -0
- package/dist/types/src/ga/server/pool-login.d.ts.map +1 -0
- package/dist/types/src/plugin/accounts.d.ts +1 -1
- package/dist/types/src/plugin/accounts.d.ts.map +1 -1
- package/dist/types/src/plugin/background-vault-quota-refresh.d.ts +2 -0
- package/dist/types/src/plugin/background-vault-quota-refresh.d.ts.map +1 -1
- package/dist/types/src/plugin/command-apply.d.ts +2 -2
- package/dist/types/src/plugin/command-apply.d.ts.map +1 -1
- package/dist/types/src/plugin/commands.d.ts +1 -0
- package/dist/types/src/plugin/commands.d.ts.map +1 -1
- package/dist/types/src/plugin/config/operator-settings-schema.d.ts +0 -4
- package/dist/types/src/plugin/config/operator-settings-schema.d.ts.map +1 -1
- package/dist/types/src/plugin/config/schema.d.ts +0 -7
- package/dist/types/src/plugin/config/schema.d.ts.map +1 -1
- package/dist/types/src/plugin/config/writer.d.ts +1 -1
- package/dist/types/src/plugin/fetch/retry-state.d.ts +19 -3
- package/dist/types/src/plugin/fetch/retry-state.d.ts.map +1 -1
- package/dist/types/src/plugin/fetch-interceptor.d.ts.map +1 -1
- package/dist/types/src/plugin/fetch-routing.d.ts +0 -16
- package/dist/types/src/plugin/fetch-routing.d.ts.map +1 -1
- package/dist/types/src/plugin/ga-location-services.d.ts +14 -9
- package/dist/types/src/plugin/ga-location-services.d.ts.map +1 -1
- package/dist/types/src/plugin/google-origin.d.ts +7 -0
- package/dist/types/src/plugin/google-origin.d.ts.map +1 -0
- package/dist/types/src/plugin/index.d.ts.map +1 -1
- package/dist/types/src/plugin/oauth-methods.d.ts.map +1 -1
- package/dist/types/src/plugin/operator-settings.d.ts +1 -1
- package/dist/types/src/plugin/operator-settings.d.ts.map +1 -1
- package/dist/types/src/plugin/quota.d.ts +11 -7
- package/dist/types/src/plugin/quota.d.ts.map +1 -1
- package/dist/types/src/plugin/request.d.ts +5 -3
- package/dist/types/src/plugin/request.d.ts.map +1 -1
- package/dist/types/src/plugin/server.d.ts.map +1 -1
- package/dist/types/src/plugin/shared/advisory-repository.d.ts +20 -0
- package/dist/types/src/plugin/shared/advisory-repository.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/request-services.d.ts +19 -25
- package/dist/types/src/plugin/shared/request-services.d.ts.map +1 -1
- package/dist/types/src/plugin/shared/vault-request-credentials.d.ts +4 -1
- package/dist/types/src/plugin/shared/vault-request-credentials.d.ts.map +1 -1
- package/dist/types/src/plugin/storage.d.ts +2 -2
- package/dist/types/src/plugin/storage.d.ts.map +1 -1
- package/dist/types/src/plugin/vault-custody.d.ts.map +1 -1
- package/dist/types/src/plugin/vault-quota-outcome.d.ts +19 -0
- package/dist/types/src/plugin/vault-quota-outcome.d.ts.map +1 -0
- package/dist/types/src/setup.d.ts +15 -0
- package/dist/types/src/setup.d.ts.map +1 -0
- package/dist/types/src/sidebar-state.d.ts +1 -1
- package/dist/types/src/sidebar-state.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/common-auth-embedded/claustrum/consumer.d.ts +33 -3
- package/src/common-auth-embedded/claustrum/consumer.js +96 -1
- package/src/common-auth-embedded/claustrum/custody.d.ts +4 -1
- package/src/common-auth-embedded/claustrum/enrollment.d.ts +6 -1
- package/src/common-auth-embedded/claustrum/enrollment.js +6 -1
- package/src/common-auth-embedded/claustrum/index.d.ts +2 -1
- package/src/common-auth-embedded/claustrum/index.js +5 -3
- package/src/common-auth-embedded/claustrum/insula.d.ts +69 -0
- package/src/common-auth-embedded/claustrum/insula.js +152 -0
- package/src/common-auth-embedded/claustrum/roster.d.ts +13 -0
- package/src/common-auth-embedded/claustrum/roster.js +33 -3
- package/src/common-auth-embedded/fs/refresh-file-lock.js +20 -11
- package/src/common-auth-embedded/quota/codec.d.ts +2 -0
- package/src/common-auth-embedded/quota/codec.js +2 -1
- package/src/common-auth-embedded/quota/format.d.ts +26 -0
- package/src/common-auth-embedded/quota/format.js +78 -42
- package/src/common-auth-embedded/quota/index.d.ts +4 -4
- package/src/common-auth-embedded/quota/index.js +2 -2
- package/src/common-auth-embedded/quota/map.d.ts +11 -0
- package/src/common-auth-embedded/quota/map.js +36 -1
- package/src/common-auth-embedded/quota/merge.d.ts +3 -1
- package/src/common-auth-embedded/quota/merge.js +21 -5
- package/src/common-auth-embedded/quota/projection.d.ts +2 -1
- package/src/common-auth-embedded/quota/projection.js +3 -1
- package/src/common-auth-embedded/setup/command-runner.js +49 -0
- package/src/common-auth-embedded/setup/command.d.ts +3 -0
- package/src/common-auth-embedded/setup/command.js +215 -0
- package/src/common-auth-embedded/setup/config-write.js +60 -0
- package/src/common-auth-embedded/setup/detect.d.ts +6 -0
- package/src/common-auth-embedded/setup/detect.js +224 -0
- package/src/common-auth-embedded/setup/enroll.js +70 -0
- package/src/common-auth-embedded/setup/index.d.ts +5 -0
- package/src/common-auth-embedded/setup/index.js +4 -0
- package/src/common-auth-embedded/setup/paths.js +33 -0
- package/src/common-auth-embedded/setup/process-fence.d.ts +43 -0
- package/src/common-auth-embedded/setup/process-fence.js +270 -0
- package/src/common-auth-embedded/setup/prompts.js +26 -0
- package/src/common-auth-embedded/setup/register.d.ts +11 -0
- package/src/common-auth-embedded/setup/register.js +130 -0
- package/src/common-auth-embedded/setup/types.d.ts +136 -0
- package/src/common-auth-embedded/source-output.json +228 -80
- package/src/common-auth-embedded/store/schema.d.ts +2 -0
- package/src/common-auth-embedded/store/schema.js +3 -2
- package/src/sidebar-state.ts +19 -2
- package/src/tui-compiled/common-auth-embedded/quota/codec.js +2 -1
- package/src/tui-compiled/common-auth-embedded/quota/format.js +78 -42
- package/src/tui-compiled/common-auth-embedded/quota/index.js +2 -2
- package/src/tui-compiled/common-auth-embedded/quota/map.js +36 -1
- package/src/tui-compiled/common-auth-embedded/quota/merge.js +21 -5
- package/src/tui-compiled/common-auth-embedded/quota/projection.js +3 -1
- package/src/tui-compiled/quota-presentation.js +42 -9
- package/src/tui-compiled/sidebar-state.js +15 -1
- package/src/tui-compiled/tui.js +516 -334
- package/src/tui-ga-compiled/host-ga.js +11 -38
- package/src/tui-ga-compiled/shared/1ff34afa7c42d196-projection.js +3 -1
- package/src/tui-ga-compiled/shared/77138df80c7ae006-map.js +36 -1
- package/src/tui-ga-compiled/shared/98cc0c186c46c42d-quota-presentation.js +42 -9
- package/src/tui-ga-compiled/shared/aef2402f8fc342f0-format.js +78 -42
- package/src/tui-ga-compiled/shared/bf17cbee28e58197-index.js +2 -2
- package/src/tui-ga-compiled/shared/ca21dc417b36dc5d-codec.js +2 -1
- package/src/tui-ga-compiled/shared/ecc214300932dfb6-merge.js +21 -5
- package/src/tui-ga-raw/host-ga.tsx +31 -62
- package/src/tui-ga-raw/shared/1ff34afa7c42d196-projection.js +3 -1
- package/src/tui-ga-raw/shared/77138df80c7ae006-map.js +36 -1
- package/src/tui-ga-raw/shared/98cc0c186c46c42d-quota-presentation.js +42 -9
- package/src/tui-ga-raw/shared/aef2402f8fc342f0-format.js +78 -42
- package/src/tui-ga-raw/shared/bf17cbee28e58197-index.js +2 -2
- package/src/tui-ga-raw/shared/ca21dc417b36dc5d-codec.js +2 -1
- package/src/tui-ga-raw/shared/ecc214300932dfb6-merge.js +21 -5
- package/src/tui-raw/common-auth-embedded/quota/codec.js +2 -1
- package/src/tui-raw/common-auth-embedded/quota/format.js +78 -42
- package/src/tui-raw/common-auth-embedded/quota/index.js +2 -2
- package/src/tui-raw/common-auth-embedded/quota/map.js +36 -1
- package/src/tui-raw/common-auth-embedded/quota/merge.js +21 -5
- package/src/tui-raw/common-auth-embedded/quota/projection.js +3 -1
- package/src/tui-raw/quota-presentation.js +42 -9
- package/src/tui-raw/sidebar-state.js +15 -1
- package/src/tui-raw/tui.tsx +423 -218
- package/src/tui.tsx +423 -218
- package/dist/src/tui/vault-setup.d.ts +0 -98
- package/dist/src/tui/vault-setup.d.ts.map +0 -1
- package/dist/src/tui/vault-setup.js +0 -198
- package/dist/src/tui/vault-setup.js.map +0 -1
- package/dist/types/src/plugin/transform/model-resolver.d.ts +0 -2
- package/dist/types/src/plugin/transform/model-resolver.d.ts.map +0 -1
- package/dist/types/src/quota-presentation.d.ts +0 -18
- package/dist/types/src/quota-presentation.d.ts.map +0 -1
|
@@ -83,6 +83,40 @@ export function isCreditBudgetEntry(value) {
|
|
|
83
83
|
optional(value, 'remaining', isFiniteNumber) &&
|
|
84
84
|
optional(value, 'unit', isString));
|
|
85
85
|
}
|
|
86
|
+
function isQuotaCounter(value) {
|
|
87
|
+
return (isRecord(value) &&
|
|
88
|
+
isFiniteNumber(value.value) &&
|
|
89
|
+
Number.isInteger(value.value) &&
|
|
90
|
+
value.value >= 0 &&
|
|
91
|
+
isFiniteNumber(value.checkedAt));
|
|
92
|
+
}
|
|
93
|
+
export function isQuotaCounters(value) {
|
|
94
|
+
return isRecord(value) && Object.values(value).every(isQuotaCounter);
|
|
95
|
+
}
|
|
96
|
+
/** Keep usable counters without letting one malformed count hide a quota map. */
|
|
97
|
+
export function readQuotaCounters(value) {
|
|
98
|
+
if (!isRecord(value))
|
|
99
|
+
return undefined;
|
|
100
|
+
const entries = Object.entries(value).filter(([, entry]) => isQuotaCounter(entry));
|
|
101
|
+
return entries.length === 0
|
|
102
|
+
? undefined
|
|
103
|
+
: Object.fromEntries(entries);
|
|
104
|
+
}
|
|
105
|
+
/** Decode persisted quota, dropping malformed counters but not limit evidence. */
|
|
106
|
+
export function decodeQuotaMap(value) {
|
|
107
|
+
// A valid map is returned as the same object, so stored quota keeps the
|
|
108
|
+
// identity it had before counters existed; only a map with a malformed
|
|
109
|
+
// counter is copied without it.
|
|
110
|
+
if (isQuotaMap(value))
|
|
111
|
+
return value;
|
|
112
|
+
if (!isRecord(value))
|
|
113
|
+
return undefined;
|
|
114
|
+
const { counters: rawCounters, ...rest } = value;
|
|
115
|
+
if (!isQuotaMap(rest))
|
|
116
|
+
return undefined;
|
|
117
|
+
const counters = readQuotaCounters(rawCounters);
|
|
118
|
+
return { ...rest, ...(counters === undefined ? {} : { counters }) };
|
|
119
|
+
}
|
|
86
120
|
/**
|
|
87
121
|
* True when `value` is a well-formed quota map. Unrecognised top-level keys
|
|
88
122
|
* are tolerated (and preserved by merge) so a newer writer's additions
|
|
@@ -101,5 +135,6 @@ export function isQuotaMap(value) {
|
|
|
101
135
|
return false;
|
|
102
136
|
seen.add(key);
|
|
103
137
|
}
|
|
104
|
-
return optional(value, 'budget', isCreditBudgetEntry)
|
|
138
|
+
return (optional(value, 'budget', isCreditBudgetEntry) &&
|
|
139
|
+
optional(value, 'counters', isQuotaCounters));
|
|
105
140
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type QuotaMap } from './map.js';
|
|
1
|
+
import { type QuotaCounter, type QuotaMap } from './map.js';
|
|
2
2
|
export interface ObservedReading {
|
|
3
3
|
/** Defaults to `all`. */
|
|
4
4
|
scope?: string;
|
|
@@ -32,6 +32,8 @@ export interface QuotaObservation {
|
|
|
32
32
|
coverage?: ObservedPair[];
|
|
33
33
|
/** Absent means the observation says nothing about the budget. */
|
|
34
34
|
budget?: ObservedBudget;
|
|
35
|
+
/** Each named count uses its own time, independently of limits and budget. */
|
|
36
|
+
counters?: Record<string, QuotaCounter>;
|
|
35
37
|
}
|
|
36
38
|
/** Thrown by `mergeQuotaObservation` when either argument is malformed. */
|
|
37
39
|
export declare class QuotaCodecError extends TypeError {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// no entry gets an absence record. A pair outside the coverage is never
|
|
12
12
|
// touched, so a header-shaped partial observation (which covers only what it
|
|
13
13
|
// carries) cannot erase a family limit or the budget.
|
|
14
|
-
import { ALL_SCOPE, entryTime,
|
|
14
|
+
import { ALL_SCOPE, decodeQuotaMap, entryTime, isQuotaCounters, limitKey, } from './map.js';
|
|
15
15
|
/** Thrown by `mergeQuotaObservation` when either argument is malformed. */
|
|
16
16
|
export class QuotaCodecError extends TypeError {
|
|
17
17
|
constructor(message) {
|
|
@@ -83,7 +83,8 @@ export function isQuotaObservation(value) {
|
|
|
83
83
|
}
|
|
84
84
|
if (!coverage.every(isObservedPair))
|
|
85
85
|
return false;
|
|
86
|
-
return value.budget === undefined || isObservedBudget(value.budget)
|
|
86
|
+
return ((value.budget === undefined || isObservedBudget(value.budget)) &&
|
|
87
|
+
(value.counters === undefined || isQuotaCounters(value.counters)));
|
|
87
88
|
}
|
|
88
89
|
function compareEntries(left, right) {
|
|
89
90
|
if (left.scope !== right.scope)
|
|
@@ -99,6 +100,16 @@ function mergeBudget(stored, observed, checkedAt) {
|
|
|
99
100
|
return stored;
|
|
100
101
|
return { ...observed, checkedAt };
|
|
101
102
|
}
|
|
103
|
+
function mergeCounters(stored, observed) {
|
|
104
|
+
const counters = new Map(Object.entries(stored ?? {}));
|
|
105
|
+
for (const [name, counter] of Object.entries(observed ?? {})) {
|
|
106
|
+
const existing = counters.get(name);
|
|
107
|
+
if (existing === undefined || counter.checkedAt >= existing.checkedAt) {
|
|
108
|
+
counters.set(name, counter);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return counters.size === 0 ? undefined : Object.fromEntries(counters);
|
|
112
|
+
}
|
|
102
113
|
/**
|
|
103
114
|
* Applies `observation` to `stored` (undefined for a row with no map yet) and
|
|
104
115
|
* returns the new map. Pure: neither argument is modified. Throws
|
|
@@ -106,13 +117,16 @@ function mergeBudget(stored, observed, checkedAt) {
|
|
|
106
117
|
* write rather than persisting a map it could not read back.
|
|
107
118
|
*/
|
|
108
119
|
export function mergeQuotaObservation(stored, observation) {
|
|
109
|
-
|
|
120
|
+
// Decode the stored map the way reads do, so a malformed counter that reads
|
|
121
|
+
// already hide is dropped here too instead of refusing every later write.
|
|
122
|
+
const decoded = stored === undefined ? undefined : decodeQuotaMap(stored);
|
|
123
|
+
if (stored !== undefined && decoded === undefined) {
|
|
110
124
|
throw new QuotaCodecError('stored quota map is malformed');
|
|
111
125
|
}
|
|
112
126
|
if (!isQuotaObservation(observation)) {
|
|
113
127
|
throw new QuotaCodecError('quota observation is malformed');
|
|
114
128
|
}
|
|
115
|
-
const base =
|
|
129
|
+
const base = decoded ?? { limits: [] };
|
|
116
130
|
const at = observation.checkedAt;
|
|
117
131
|
const entries = new Map();
|
|
118
132
|
for (const entry of base.limits) {
|
|
@@ -152,11 +166,13 @@ export function mergeQuotaObservation(stored, observation) {
|
|
|
152
166
|
: { scope, label: pair.label, kind: 'retired', retiredAt: at });
|
|
153
167
|
}
|
|
154
168
|
// Keys this module does not recognise are carried over untouched.
|
|
155
|
-
const { limits: _limits, budget: _budget, ...unknownKeys } = base;
|
|
169
|
+
const { limits: _limits, budget: _budget, counters: _counters, ...unknownKeys } = base;
|
|
156
170
|
const budget = mergeBudget(base.budget, observation.budget, at);
|
|
171
|
+
const counters = mergeCounters(base.counters, observation.counters);
|
|
157
172
|
return {
|
|
158
173
|
...unknownKeys,
|
|
159
174
|
limits: [...entries.values()].sort(compareEntries),
|
|
160
175
|
...(budget === undefined ? {} : { budget }),
|
|
176
|
+
...(counters === undefined ? {} : { counters }),
|
|
161
177
|
};
|
|
162
178
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type QuotaMap } from './map.js';
|
|
1
|
+
import { type QuotaCounter, type QuotaMap } from './map.js';
|
|
2
2
|
export interface ProjectedLimit {
|
|
3
3
|
scope: string;
|
|
4
4
|
label: string;
|
|
@@ -30,6 +30,7 @@ export interface ProjectedQuota {
|
|
|
30
30
|
checkedAt?: number;
|
|
31
31
|
/** Present only when the stored budget is a reading, not cleared. */
|
|
32
32
|
budget?: ProjectedBudget;
|
|
33
|
+
counters?: Record<string, QuotaCounter>;
|
|
33
34
|
}
|
|
34
35
|
/**
|
|
35
36
|
* Resolves `map` for a request in `scope` (`all` or a model family). A family
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// scope, orders the result the way the primitives expect, and carries each
|
|
7
7
|
// entry's (scope, label) so a decision names the limit it judged rather than
|
|
8
8
|
// the position it occupied.
|
|
9
|
-
import { ALL_SCOPE, } from './map.js';
|
|
9
|
+
import { ALL_SCOPE, readQuotaCounters, } from './map.js';
|
|
10
10
|
function project(entry) {
|
|
11
11
|
if (entry.kind === 'retired') {
|
|
12
12
|
return {
|
|
@@ -94,11 +94,13 @@ export function projectQuota(map, scope = ALL_SCOPE) {
|
|
|
94
94
|
? Math.min(...stamped.map((limit) => limit.checkedAt))
|
|
95
95
|
: undefined;
|
|
96
96
|
const budget = map?.budget?.kind === 'reading' ? projectBudget(map.budget) : undefined;
|
|
97
|
+
const counters = readQuotaCounters(map?.counters);
|
|
97
98
|
return {
|
|
98
99
|
scope,
|
|
99
100
|
limits,
|
|
100
101
|
...(checkedAt === undefined ? {} : { checkedAt }),
|
|
101
102
|
...(budget === undefined ? {} : { budget }),
|
|
103
|
+
...(counters === undefined ? {} : { counters }),
|
|
102
104
|
};
|
|
103
105
|
}
|
|
104
106
|
/**
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
export const defaultCommandRunner = {
|
|
3
|
+
run(file, args, options = {}) {
|
|
4
|
+
return new Promise((resolve) => {
|
|
5
|
+
const started = performance.now();
|
|
6
|
+
const timeoutMs = options.timeoutMs ?? 15_000;
|
|
7
|
+
execFile(file, [...args], {
|
|
8
|
+
env: options.env ?? process.env,
|
|
9
|
+
timeout: timeoutMs,
|
|
10
|
+
windowsHide: true,
|
|
11
|
+
windowsVerbatimArguments: options.windowsVerbatimArguments,
|
|
12
|
+
maxBuffer: 1024 * 1024,
|
|
13
|
+
}, (error, stdout, stderr) => {
|
|
14
|
+
const durationMs = performance.now() - started;
|
|
15
|
+
resolve({
|
|
16
|
+
exitCode: error
|
|
17
|
+
? typeof error.code === 'number'
|
|
18
|
+
? error.code
|
|
19
|
+
: 1
|
|
20
|
+
: 0,
|
|
21
|
+
stdout: String(stdout ?? ''),
|
|
22
|
+
stderr: String(stderr ?? ''),
|
|
23
|
+
signal: error?.signal ?? null,
|
|
24
|
+
// Buffer-limit and spawn errors have string codes, not timeout kills.
|
|
25
|
+
timedOut: error?.killed === true &&
|
|
26
|
+
typeof error.code !== 'string' &&
|
|
27
|
+
error.signal === 'SIGTERM' &&
|
|
28
|
+
durationMs >= timeoutMs &&
|
|
29
|
+
timeoutMs > 0,
|
|
30
|
+
durationMs,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
/** Batch launchers need cmd.exe; no free-form user text is accepted as shell arguments. */
|
|
37
|
+
export function runResolvedCommand(runner, platform, file, args, env, timeoutMs = 15_000) {
|
|
38
|
+
if (platform === 'win32' && /\.(cmd|bat)$/i.test(file)) {
|
|
39
|
+
if (/["%!\r\n]/.test(file) ||
|
|
40
|
+
args.some((arg) => !/^[a-zA-Z0-9@:/._+-]+$/.test(arg)))
|
|
41
|
+
throw new Error('Unsafe batch launcher or argument; use an executable instead.');
|
|
42
|
+
return runner.run('cmd.exe', ['/d', '/s', '/c', `""${file}" ${args.join(' ')}"`], {
|
|
43
|
+
env,
|
|
44
|
+
timeoutMs,
|
|
45
|
+
windowsVerbatimArguments: true,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return runner.run(file, args, { env, timeoutMs });
|
|
49
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { SetupIO, SetupPlugin, SetupResult } from './types.js';
|
|
2
|
+
export declare const AMBIGUOUS_OPENCODE_MESSAGE = "Multiple OpenCode generations found. Choose --opencode=1|2|both before running noninteractive setup.";
|
|
3
|
+
export declare function runSetup(plugin: SetupPlugin, argv?: readonly string[], io?: SetupIO): Promise<SetupResult>;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { select } from '../auth-menu/select.js';
|
|
2
|
+
import { isInteractive, printLine, processTerminal, } from '../auth-menu/terminal.js';
|
|
3
|
+
import { hostEnrollmentPaths } from '../claustrum/enrollment.js';
|
|
4
|
+
import { defaultCommandRunner } from './command-runner.js';
|
|
5
|
+
import { detectHosts } from './detect.js';
|
|
6
|
+
import { connectSetupHost } from './enroll.js';
|
|
7
|
+
import { setupPaths } from './paths.js';
|
|
8
|
+
import { assertHostsStopped, createProcessFence, ProcessFenceViolationError, ProcessInspectionError, } from './process-fence.js';
|
|
9
|
+
import { selectSetupHosts } from './prompts.js';
|
|
10
|
+
import { planOpenCodeRegistration, registerOpenCode, registerPi, } from './register.js';
|
|
11
|
+
export const AMBIGUOUS_OPENCODE_MESSAGE = 'Multiple OpenCode generations found. Choose --opencode=1|2|both before running noninteractive setup.';
|
|
12
|
+
function flags(argv) {
|
|
13
|
+
const result = {
|
|
14
|
+
yes: false,
|
|
15
|
+
dryRun: false,
|
|
16
|
+
claustrum: false,
|
|
17
|
+
noClaustrum: false,
|
|
18
|
+
login: false,
|
|
19
|
+
opencode: undefined,
|
|
20
|
+
};
|
|
21
|
+
for (const arg of argv) {
|
|
22
|
+
if (arg === '--yes')
|
|
23
|
+
result.yes = true;
|
|
24
|
+
else if (arg === '--dry-run')
|
|
25
|
+
result.dryRun = true;
|
|
26
|
+
else if (arg === '--claustrum')
|
|
27
|
+
result.claustrum = true;
|
|
28
|
+
else if (arg === '--no-claustrum')
|
|
29
|
+
result.noClaustrum = true;
|
|
30
|
+
else if (arg === '--login')
|
|
31
|
+
result.login = true;
|
|
32
|
+
else if (/^--opencode=(1|2|both)$/.test(arg))
|
|
33
|
+
result.opencode = arg.slice('--opencode='.length);
|
|
34
|
+
else
|
|
35
|
+
throw new Error(`Unknown setup argument: ${arg}`);
|
|
36
|
+
}
|
|
37
|
+
if (result.claustrum && result.noClaustrum)
|
|
38
|
+
throw new Error('--claustrum and --no-claustrum cannot be used together.');
|
|
39
|
+
if (result.login && result.claustrum)
|
|
40
|
+
throw new Error('--login and --claustrum cannot be used together.');
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function validatePlugin(plugin) {
|
|
44
|
+
for (const pkg of Object.values(plugin.packages)) {
|
|
45
|
+
if (!/^(?:@[a-z0-9._-]+\/)?[a-z0-9._-]+$/.test(pkg))
|
|
46
|
+
throw new Error('Setup requires npm package names.');
|
|
47
|
+
}
|
|
48
|
+
if (!/^\d+\.\d+\.\d+(?:-[a-zA-Z0-9.-]+)?(?:\+[a-zA-Z0-9.-]+)?$/.test(plugin.version))
|
|
49
|
+
throw new Error('Setup requires a concrete package version.');
|
|
50
|
+
for (const host of Object.values(plugin.vault.hosts)) {
|
|
51
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(host.name))
|
|
52
|
+
throw new Error('Setup requires lowercase vault names containing only letters, digits and dashes.');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function runSetup(plugin, argv = [], io = {}) {
|
|
56
|
+
const options = flags(argv);
|
|
57
|
+
validatePlugin(plugin);
|
|
58
|
+
const terminal = io.terminal ?? processTerminal();
|
|
59
|
+
const detection = await detectHosts(plugin, io);
|
|
60
|
+
printLine(terminal, `${plugin.displayName} setup`);
|
|
61
|
+
for (const [label, host] of [
|
|
62
|
+
['OpenCode', detection.opencode],
|
|
63
|
+
['Pi', detection.pi],
|
|
64
|
+
]) {
|
|
65
|
+
printLine(terminal, `${label}: ${host.installed ? `found (version ${host.version ?? 'unknown'})` : 'not found'} — ${host.directory}`);
|
|
66
|
+
}
|
|
67
|
+
printLine(terminal, `Claustrum: ${detection.claustrum.available ? 'available' : 'not available'}`);
|
|
68
|
+
// Pi is registered by running its CLI, so a leftover Pi folder without the
|
|
69
|
+
// CLI cannot be set up. Leave it out instead of failing the whole run, so it
|
|
70
|
+
// never blocks setting up OpenCode.
|
|
71
|
+
const piWithoutCli = detection.pi.installed && !detection.pi.executable;
|
|
72
|
+
if (piWithoutCli)
|
|
73
|
+
printLine(terminal, 'Pi: skipped, because its folder exists but pi is not on PATH. Install the Pi CLI and rerun setup to add it.');
|
|
74
|
+
const found = ['opencode', 'pi'].filter((host) => detection[host].installed && !(host === 'pi' && piWithoutCli));
|
|
75
|
+
// A dry run changes nothing, so without a terminal it plans the --yes path
|
|
76
|
+
// instead of refusing; scripts and CI can preview setup with --dry-run alone.
|
|
77
|
+
const assumeYes = options.yes || (options.dryRun && !isInteractive(terminal));
|
|
78
|
+
if (!assumeYes && !isInteractive(terminal))
|
|
79
|
+
throw new Error('Setup requires a TTY or --yes.');
|
|
80
|
+
const hosts = assumeYes
|
|
81
|
+
? found
|
|
82
|
+
: ((await selectSetupHosts(terminal, found)) ?? []);
|
|
83
|
+
let generation = options.opencode ??
|
|
84
|
+
(detection.opencode.generation === 'ambiguous'
|
|
85
|
+
? '1'
|
|
86
|
+
: detection.opencode.generation);
|
|
87
|
+
if (hosts.includes('opencode') &&
|
|
88
|
+
!options.opencode &&
|
|
89
|
+
detection.opencode.generation === 'ambiguous') {
|
|
90
|
+
if (assumeYes || !isInteractive(terminal))
|
|
91
|
+
throw new Error(AMBIGUOUS_OPENCODE_MESSAGE);
|
|
92
|
+
const choice = await select(terminal, [
|
|
93
|
+
{ value: '1', label: 'OpenCode 1' },
|
|
94
|
+
{ value: '2', label: 'OpenCode 2' },
|
|
95
|
+
{ value: 'both', label: 'Both (one compatible registration)' },
|
|
96
|
+
], { message: 'Which OpenCode generation should be registered?' });
|
|
97
|
+
if (choice === null)
|
|
98
|
+
return { hosts: [], dryRun: options.dryRun, mode: 'local', detection };
|
|
99
|
+
generation = choice;
|
|
100
|
+
}
|
|
101
|
+
if (!hosts.length) {
|
|
102
|
+
printLine(terminal, 'No hosts selected. Install OpenCode or Pi and rerun setup.');
|
|
103
|
+
return { hosts, dryRun: options.dryRun, mode: 'local', detection };
|
|
104
|
+
}
|
|
105
|
+
const { env, platform } = setupPaths(io);
|
|
106
|
+
const fence = io.fence ??
|
|
107
|
+
createProcessFence(io.runner ?? defaultCommandRunner, { platform });
|
|
108
|
+
const stopped = async () => {
|
|
109
|
+
try {
|
|
110
|
+
await assertHostsStopped(fence, env);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (error instanceof ProcessInspectionError)
|
|
114
|
+
printLine(terminal, error.refusalText);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
printLine(terminal, 'Checking that OpenCode and Pi are not running…');
|
|
119
|
+
if (options.dryRun) {
|
|
120
|
+
try {
|
|
121
|
+
const preview = fence.previewRunningHosts
|
|
122
|
+
? await fence.previewRunningHosts(env)
|
|
123
|
+
: { hosts: await fence.listRunningHosts(env), uncheckedRuntimes: 0 };
|
|
124
|
+
const active = preview.hosts;
|
|
125
|
+
if (preview.uncheckedRuntimes > 0)
|
|
126
|
+
printLine(terminal, 'Node or Bun programs are running; a real run checks whether any of them is OpenCode or Pi.');
|
|
127
|
+
const names = new Set(new ProcessFenceViolationError(active).activeHosts.map((host) => host.command.toLowerCase() === 'pi' ? 'Pi' : 'OpenCode'));
|
|
128
|
+
for (const name of names)
|
|
129
|
+
printLine(terminal, `${name} is running; setup will ask you to quit it.`);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
printLine(terminal, 'Process inspection failed; real setup will require successful inspection and stopped OpenCode/Pi hosts.');
|
|
133
|
+
if (error instanceof ProcessInspectionError)
|
|
134
|
+
printLine(terminal, error.refusalText);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else
|
|
138
|
+
await stopped();
|
|
139
|
+
if (options.claustrum && !detection.claustrum.available)
|
|
140
|
+
throw new Error('Claustrum is not available. Start ck or use --no-claustrum for local sign-in.');
|
|
141
|
+
let useVault = Boolean(options.claustrum);
|
|
142
|
+
if (!useVault &&
|
|
143
|
+
!options.login &&
|
|
144
|
+
!options.noClaustrum &&
|
|
145
|
+
!assumeYes &&
|
|
146
|
+
detection.claustrum.available &&
|
|
147
|
+
isInteractive(terminal)) {
|
|
148
|
+
// Not `confirm`: it reads Escape and Ctrl-C as "No", and "No" here means
|
|
149
|
+
// a local sign-in. Cancelling must stop setup before anything changes.
|
|
150
|
+
const choice = await select(terminal, [
|
|
151
|
+
{ label: 'No', value: false },
|
|
152
|
+
{ label: 'Yes', value: true },
|
|
153
|
+
], { message: 'Connect these hosts to the Claustrum vault?' });
|
|
154
|
+
if (choice === null) {
|
|
155
|
+
printLine(terminal, 'Setup cancelled. Nothing was changed.');
|
|
156
|
+
return { hosts: [], dryRun: options.dryRun, mode: 'local', detection };
|
|
157
|
+
}
|
|
158
|
+
useVault = choice === true;
|
|
159
|
+
}
|
|
160
|
+
const mode = useVault ? 'claustrum' : 'local';
|
|
161
|
+
// Validate every config before login or enrollment can change credential state.
|
|
162
|
+
const writes = hosts.includes('opencode')
|
|
163
|
+
? planOpenCodeRegistration(plugin, generation, io)
|
|
164
|
+
: [];
|
|
165
|
+
if (options.dryRun) {
|
|
166
|
+
printLine(terminal, 'Dry run: no registrations, enrollment, sign-in or migration will be performed.');
|
|
167
|
+
for (const host of hosts) {
|
|
168
|
+
if (plugin.beforeSignIn)
|
|
169
|
+
printLine(terminal, `Would run beforeSignIn(${host}, ${mode}).`);
|
|
170
|
+
if (useVault) {
|
|
171
|
+
const paths = hostEnrollmentPaths(plugin.vault.hosts[host].paths);
|
|
172
|
+
printLine(terminal, `Would Connect ${host}: write ${paths.statePath} and ${paths.tokenPath}; wait for ck auth enroll approve.`);
|
|
173
|
+
}
|
|
174
|
+
else
|
|
175
|
+
printLine(terminal, `Would sign in locally for ${host}.`);
|
|
176
|
+
if (plugin.beforeRegister)
|
|
177
|
+
printLine(terminal, `Would run beforeRegister(${host}, ${mode}).`);
|
|
178
|
+
}
|
|
179
|
+
for (const write of writes)
|
|
180
|
+
printLine(terminal, `${write.changed ? 'Would write' : 'Unchanged'} ${write.path}:\n${write.content}`);
|
|
181
|
+
if (hosts.includes('pi'))
|
|
182
|
+
printLine(terminal, `Would run ${detection.pi.executable} install npm:${plugin.packages.pi}@${plugin.version}`);
|
|
183
|
+
for (const host of hosts)
|
|
184
|
+
printLine(terminal, `Would migrate ${host} using the plugin callback (provider-specific writes).`);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const context = {
|
|
188
|
+
opencodeGeneration: generation,
|
|
189
|
+
mode,
|
|
190
|
+
hosts: Object.freeze([...hosts]),
|
|
191
|
+
piAgentDir: detection.pi.directory,
|
|
192
|
+
};
|
|
193
|
+
for (const host of hosts) {
|
|
194
|
+
await stopped();
|
|
195
|
+
await plugin.beforeSignIn?.(host, context);
|
|
196
|
+
await stopped();
|
|
197
|
+
if (useVault)
|
|
198
|
+
await connectSetupHost(plugin, host, io, terminal, stopped);
|
|
199
|
+
else
|
|
200
|
+
await plugin.signInLocal(host, context);
|
|
201
|
+
await stopped();
|
|
202
|
+
await plugin.beforeRegister?.(host, mode, context);
|
|
203
|
+
await stopped();
|
|
204
|
+
if (host === 'opencode')
|
|
205
|
+
await registerOpenCode(writes, stopped);
|
|
206
|
+
else
|
|
207
|
+
await registerPi(plugin, detection.pi.executable, io);
|
|
208
|
+
await stopped();
|
|
209
|
+
await plugin.migrate(host, context);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
printLine(terminal, `${options.dryRun ? 'Planned' : 'Configured'} ${plugin.displayName} for ${hosts.join(', ')} (${mode}).`);
|
|
213
|
+
printLine(terminal, `Next: ${hosts.includes('opencode') ? 'start OpenCode' : 'start Pi'} and run ${plugin.slashCommand}.`);
|
|
214
|
+
return { hosts, dryRun: options.dryRun, mode, detection };
|
|
215
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, open, rename, stat, unlink } from 'node:fs/promises';
|
|
3
|
+
import { basename, dirname, join } from 'node:path';
|
|
4
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
5
|
+
/** Ordinary host config inherits Windows ACLs and preserves an existing POSIX mode. */
|
|
6
|
+
export async function writeHostConfigAtomic(file, content, options = {}) {
|
|
7
|
+
const windows = (options.platform ?? process.platform) === 'win32';
|
|
8
|
+
const parent = dirname(file);
|
|
9
|
+
await mkdir(parent, { recursive: true });
|
|
10
|
+
let mode;
|
|
11
|
+
if (!windows) {
|
|
12
|
+
try {
|
|
13
|
+
mode = (await stat(file)).mode & 0o7777;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error.code !== 'ENOENT')
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const stage = join(parent, `.${basename(file)}.${(options.stageName ?? randomUUID)()}.tmp`);
|
|
21
|
+
let created = false;
|
|
22
|
+
try {
|
|
23
|
+
const handle = await open(stage, 'wx', mode ?? 0o666);
|
|
24
|
+
created = true;
|
|
25
|
+
try {
|
|
26
|
+
await handle.writeFile(content, 'utf8');
|
|
27
|
+
// An existing mode is deliberate; restore bits masked by the current umask.
|
|
28
|
+
if (mode !== undefined)
|
|
29
|
+
await handle.chmod(mode);
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await handle.close();
|
|
33
|
+
}
|
|
34
|
+
const now = options.now ?? (() => performance.now());
|
|
35
|
+
const started = now();
|
|
36
|
+
for (let attempt = 0;; attempt++) {
|
|
37
|
+
await options.beforeRename?.();
|
|
38
|
+
try {
|
|
39
|
+
await (options.rename ?? rename)(stage, file);
|
|
40
|
+
created = false;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const code = error.code;
|
|
45
|
+
const remaining = 2000 - (now() - started);
|
|
46
|
+
if (!windows ||
|
|
47
|
+
!['EPERM', 'EBUSY', 'EACCES'].includes(code ?? '') ||
|
|
48
|
+
remaining <= 0 ||
|
|
49
|
+
attempt >= 40)
|
|
50
|
+
throw new Error(`Unable to replace host config ${file}. Close editors or other programs using the file, then rerun setup.`);
|
|
51
|
+
await (options.wait ?? delay)(Math.min(remaining, 25 * 2 ** Math.min(attempt, 2)));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
// Never remove a colliding stage that this call did not create.
|
|
57
|
+
if (created)
|
|
58
|
+
await unlink(stage).catch(() => { });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SetupDetection, SetupFileSystem, SetupIO, SetupPlugin } from './types.js';
|
|
2
|
+
export declare const defaultSetupFileSystem: SetupFileSystem;
|
|
3
|
+
export declare function findExecutableOnPath(name: string, io?: SetupIO): string | null;
|
|
4
|
+
export declare function openCodeDesktopMarkers(io?: SetupIO): string[];
|
|
5
|
+
export declare function detectOpenCodeGeneration(io?: SetupIO): '1' | '2' | 'ambiguous';
|
|
6
|
+
export declare function detectHosts(plugin: SetupPlugin, io?: SetupIO): Promise<SetupDetection>;
|