@cortexkit/opencode-antigravity-auth 2.2.0 → 3.0.0
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 +95 -89
- package/dist/cli.js +18469 -810
- package/dist/cli.js.map +4 -4
- package/dist/cli.meta.json +4079 -0
- package/dist/index.js +40923 -16450
- package/dist/index.js.map +4 -4
- package/dist/index.meta.json +6949 -0
- package/dist/server.js +50948 -0
- package/dist/server.js.map +7 -0
- package/dist/server.meta.json +7284 -0
- package/dist/src/cli.d.ts +46 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +207 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/common-auth-embedded/NOTICE.txt +21 -0
- package/dist/src/common-auth-embedded/auth-menu/accounts.d.ts +97 -0
- package/dist/src/common-auth-embedded/auth-menu/accounts.js +387 -0
- package/dist/src/common-auth-embedded/auth-menu/ansi.d.ts +26 -0
- package/dist/src/common-auth-embedded/auth-menu/ansi.js +98 -0
- package/dist/src/common-auth-embedded/auth-menu/confirm.d.ts +7 -0
- package/dist/src/common-auth-embedded/auth-menu/confirm.js +21 -0
- package/dist/src/common-auth-embedded/auth-menu/doctor.d.ts +52 -0
- package/dist/src/common-auth-embedded/auth-menu/doctor.js +81 -0
- package/dist/src/common-auth-embedded/auth-menu/index.d.ts +17 -0
- package/dist/src/common-auth-embedded/auth-menu/index.js +12 -0
- package/dist/src/common-auth-embedded/auth-menu/login.d.ts +55 -0
- package/dist/src/common-auth-embedded/auth-menu/login.js +83 -0
- package/dist/src/common-auth-embedded/auth-menu/menu.d.ts +59 -0
- package/dist/src/common-auth-embedded/auth-menu/menu.js +73 -0
- package/dist/src/common-auth-embedded/auth-menu/opencode-v1.d.ts +49 -0
- package/dist/src/common-auth-embedded/auth-menu/opencode-v1.js +47 -0
- package/dist/src/common-auth-embedded/auth-menu/select.d.ts +21 -0
- package/dist/src/common-auth-embedded/auth-menu/select.js +159 -0
- package/dist/src/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
- package/dist/src/common-auth-embedded/auth-menu/terminal.js +19 -0
- package/dist/src/common-auth-embedded/claustrum/consumer.d.ts +102 -0
- package/dist/src/common-auth-embedded/claustrum/consumer.js +298 -0
- package/dist/src/common-auth-embedded/claustrum/custody.d.ts +175 -0
- package/dist/src/common-auth-embedded/claustrum/custody.js +354 -0
- package/dist/src/common-auth-embedded/claustrum/enrollment.d.ts +158 -0
- package/dist/src/common-auth-embedded/claustrum/enrollment.js +759 -0
- package/dist/src/common-auth-embedded/claustrum/errors.d.ts +16 -0
- package/dist/src/common-auth-embedded/claustrum/errors.js +8 -0
- package/dist/src/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
- package/dist/src/common-auth-embedded/claustrum/host-slot.js +72 -0
- package/dist/src/common-auth-embedded/claustrum/index.d.ts +18 -0
- package/dist/src/common-auth-embedded/claustrum/index.js +22 -0
- package/dist/src/common-auth-embedded/claustrum/interlock.d.ts +27 -0
- package/dist/src/common-auth-embedded/claustrum/interlock.js +29 -0
- package/dist/src/common-auth-embedded/claustrum/roster.d.ts +208 -0
- package/dist/src/common-auth-embedded/claustrum/roster.js +536 -0
- package/dist/src/common-auth-embedded/commands/builtins.d.ts +71 -0
- package/dist/src/common-auth-embedded/commands/builtins.js +534 -0
- package/dist/src/common-auth-embedded/commands/index.d.ts +10 -0
- package/dist/src/common-auth-embedded/commands/index.js +5 -0
- package/dist/src/common-auth-embedded/commands/menu.d.ts +61 -0
- package/dist/src/common-auth-embedded/commands/menu.js +300 -0
- package/dist/src/common-auth-embedded/commands/model.d.ts +238 -0
- package/dist/src/common-auth-embedded/commands/model.js +16 -0
- package/dist/src/common-auth-embedded/commands/pi.d.ts +23 -0
- package/dist/src/common-auth-embedded/commands/pi.js +206 -0
- package/dist/src/common-auth-embedded/commands/seam.d.ts +72 -0
- package/dist/src/common-auth-embedded/commands/seam.js +301 -0
- package/dist/src/common-auth-embedded/fs/atomic-write.d.ts +20 -0
- package/dist/src/common-auth-embedded/fs/atomic-write.js +80 -0
- package/dist/src/common-auth-embedded/fs/index.d.ts +7 -0
- package/dist/src/common-auth-embedded/fs/index.js +6 -0
- package/dist/src/common-auth-embedded/fs/lock-constants.d.ts +14 -0
- package/dist/src/common-auth-embedded/fs/lock-constants.js +14 -0
- package/dist/src/common-auth-embedded/fs/refresh-file-lock.d.ts +33 -0
- package/dist/src/common-auth-embedded/fs/refresh-file-lock.js +501 -0
- package/dist/src/common-auth-embedded/fs/with-lock.d.ts +33 -0
- package/dist/src/common-auth-embedded/fs/with-lock.js +48 -0
- package/dist/src/common-auth-embedded/logger/capture-sink.d.ts +14 -0
- package/dist/src/common-auth-embedded/logger/capture-sink.js +13 -0
- package/dist/src/common-auth-embedded/logger/engine.d.ts +100 -0
- package/dist/src/common-auth-embedded/logger/engine.js +246 -0
- package/dist/src/common-auth-embedded/logger/index.d.ts +6 -0
- package/dist/src/common-auth-embedded/logger/index.js +3 -0
- package/dist/src/common-auth-embedded/logger/redact.d.ts +11 -0
- package/dist/src/common-auth-embedded/logger/redact.js +83 -0
- package/dist/src/common-auth-embedded/opencode2/errors.d.ts +25 -0
- package/dist/src/common-auth-embedded/opencode2/errors.js +15 -0
- package/dist/src/common-auth-embedded/opencode2/index.d.ts +8 -0
- package/dist/src/common-auth-embedded/opencode2/index.js +4 -0
- package/dist/src/common-auth-embedded/opencode2/install.d.ts +55 -0
- package/dist/src/common-auth-embedded/opencode2/install.js +886 -0
- package/dist/src/common-auth-embedded/opencode2/integration.d.ts +112 -0
- package/dist/src/common-auth-embedded/opencode2/integration.js +143 -0
- package/dist/src/common-auth-embedded/opencode2/sse.d.ts +12 -0
- package/dist/src/common-auth-embedded/opencode2/sse.js +60 -0
- package/dist/src/common-auth-embedded/opencode2/types.d.ts +413 -0
- package/dist/src/common-auth-embedded/pi-slot/index.d.ts +3 -0
- package/dist/src/common-auth-embedded/pi-slot/index.js +2 -0
- package/dist/src/common-auth-embedded/pi-slot/lock.js +212 -0
- package/dist/src/common-auth-embedded/pi-slot/slot.d.ts +49 -0
- package/dist/src/common-auth-embedded/pi-slot/slot.js +383 -0
- package/dist/src/common-auth-embedded/quota/codec.d.ts +11 -0
- package/dist/src/common-auth-embedded/quota/codec.js +12 -0
- package/dist/src/common-auth-embedded/quota/format.d.ts +46 -0
- package/dist/src/common-auth-embedded/quota/format.js +138 -0
- package/dist/src/common-auth-embedded/quota/index.d.ts +10 -0
- package/dist/src/common-auth-embedded/quota/index.js +5 -0
- package/dist/src/common-auth-embedded/quota/map.d.ts +63 -0
- package/dist/src/common-auth-embedded/quota/map.js +105 -0
- package/dist/src/common-auth-embedded/quota/merge.d.ts +48 -0
- package/dist/src/common-auth-embedded/quota/merge.js +162 -0
- package/dist/src/common-auth-embedded/quota/projection.d.ts +64 -0
- package/dist/src/common-auth-embedded/quota/projection.js +134 -0
- package/dist/src/common-auth-embedded/routing/admission.d.ts +93 -0
- package/dist/src/common-auth-embedded/routing/admission.js +142 -0
- package/dist/src/common-auth-embedded/routing/index.d.ts +8 -0
- package/dist/src/common-auth-embedded/routing/index.js +4 -0
- package/dist/src/common-auth-embedded/routing/ordered.d.ts +47 -0
- package/dist/src/common-auth-embedded/routing/ordered.js +58 -0
- package/dist/src/common-auth-embedded/routing/pins.d.ts +22 -0
- package/dist/src/common-auth-embedded/routing/pins.js +34 -0
- package/dist/src/common-auth-embedded/routing/sticky.d.ts +158 -0
- package/dist/src/common-auth-embedded/routing/sticky.js +339 -0
- package/dist/src/common-auth-embedded/rpc/client.d.ts +3 -0
- package/dist/src/common-auth-embedded/rpc/client.js +2 -0
- package/dist/src/common-auth-embedded/rpc/index.d.ts +10 -0
- package/dist/src/common-auth-embedded/rpc/index.js +5 -0
- package/dist/src/common-auth-embedded/rpc/notifications.d.ts +73 -0
- package/dist/src/common-auth-embedded/rpc/notifications.js +100 -0
- package/dist/src/common-auth-embedded/rpc/port-file.d.ts +33 -0
- package/dist/src/common-auth-embedded/rpc/port-file.js +217 -0
- package/dist/src/common-auth-embedded/rpc/rpc-client.d.ts +30 -0
- package/dist/src/common-auth-embedded/rpc/rpc-client.js +253 -0
- package/dist/src/common-auth-embedded/rpc/rpc-server.d.ts +58 -0
- package/dist/src/common-auth-embedded/rpc/rpc-server.js +311 -0
- package/dist/src/common-auth-embedded/rpc/server-registry.d.ts +11 -0
- package/dist/src/common-auth-embedded/rpc/server-registry.js +47 -0
- package/dist/src/common-auth-embedded/source-output.json +1326 -0
- package/dist/src/common-auth-embedded/store/attribution.d.ts +28 -0
- package/dist/src/common-auth-embedded/store/attribution.js +60 -0
- package/dist/src/common-auth-embedded/store/errors.d.ts +55 -0
- package/dist/src/common-auth-embedded/store/errors.js +38 -0
- package/dist/src/common-auth-embedded/store/hooks.d.ts +12 -0
- package/dist/src/common-auth-embedded/store/hooks.js +34 -0
- package/dist/src/common-auth-embedded/store/identity.d.ts +39 -0
- package/dist/src/common-auth-embedded/store/identity.js +79 -0
- package/dist/src/common-auth-embedded/store/index.d.ts +21 -0
- package/dist/src/common-auth-embedded/store/index.js +7 -0
- package/dist/src/common-auth-embedded/store/mutate.d.ts +189 -0
- package/dist/src/common-auth-embedded/store/mutate.js +500 -0
- package/dist/src/common-auth-embedded/store/pool.d.ts +196 -0
- package/dist/src/common-auth-embedded/store/pool.js +120 -0
- package/dist/src/common-auth-embedded/store/provider-state.d.ts +131 -0
- package/dist/src/common-auth-embedded/store/provider-state.js +226 -0
- package/dist/src/common-auth-embedded/store/publication.d.ts +47 -0
- package/dist/src/common-auth-embedded/store/publication.js +304 -0
- package/dist/src/common-auth-embedded/store/pull.d.ts +36 -0
- package/dist/src/common-auth-embedded/store/pull.js +143 -0
- package/dist/src/common-auth-embedded/store/refresh-lock.d.ts +63 -0
- package/dist/src/common-auth-embedded/store/refresh-lock.js +136 -0
- package/dist/src/common-auth-embedded/store/refresh.d.ts +72 -0
- package/dist/src/common-auth-embedded/store/refresh.js +225 -0
- package/dist/src/common-auth-embedded/store/reserved.js +13 -0
- package/dist/src/common-auth-embedded/store/rows.d.ts +313 -0
- package/dist/src/common-auth-embedded/store/rows.js +1258 -0
- package/dist/src/common-auth-embedded/store/runtime.d.ts +36 -0
- package/dist/src/common-auth-embedded/store/runtime.js +68 -0
- package/dist/src/common-auth-embedded/store/schema.d.ts +443 -0
- package/dist/src/common-auth-embedded/store/schema.js +754 -0
- package/dist/src/common-auth-embedded/store/settings.d.ts +63 -0
- package/dist/src/common-auth-embedded/store/settings.js +120 -0
- package/dist/src/common-auth-embedded/store/torn.d.ts +78 -0
- package/dist/src/common-auth-embedded/store/torn.js +294 -0
- package/dist/src/common-auth-embedded/tui/index.d.ts +8 -0
- package/dist/src/common-auth-embedded/tui/index.js +21 -0
- package/dist/src/common-auth-embedded/util/any-signal.js +42 -0
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +4 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/ga/proxy-guard.d.ts +120 -0
- package/dist/src/ga/proxy-guard.d.ts.map +1 -0
- package/dist/src/ga/proxy-guard.js +269 -0
- package/dist/src/ga/proxy-guard.js.map +1 -0
- package/dist/src/ga/rpc/protocol.d.ts +504 -0
- package/dist/src/ga/rpc/protocol.d.ts.map +1 -0
- package/dist/src/ga/rpc/protocol.js +1278 -0
- package/dist/src/ga/rpc/protocol.js.map +1 -0
- package/dist/src/ga/server/auth.d.ts +9 -0
- package/dist/src/ga/server/auth.d.ts.map +1 -0
- package/dist/src/ga/server/auth.js +37 -0
- package/dist/src/ga/server/auth.js.map +1 -0
- package/dist/src/ga/server/index.d.ts +576 -0
- package/dist/src/ga/server/index.d.ts.map +1 -0
- package/dist/src/ga/server/index.js +1012 -0
- package/dist/src/ga/server/index.js.map +1 -0
- package/dist/src/ga/tui/host-ga.d.ts +350 -0
- package/dist/src/ga/tui/host-ga.d.ts.map +1 -0
- package/dist/src/ga/tui/host-ga.js +1242 -0
- package/dist/src/ga/tui/host-ga.js.map +1 -0
- package/dist/src/logging/provider-key-policy.d.ts +9 -0
- package/dist/src/logging/provider-key-policy.d.ts.map +1 -0
- package/dist/src/logging/provider-key-policy.js +11 -0
- package/dist/src/logging/provider-key-policy.js.map +1 -0
- package/dist/src/plugin/account-access.d.ts +130 -15
- package/dist/src/plugin/account-access.d.ts.map +1 -1
- package/dist/src/plugin/account-access.js +331 -129
- package/dist/src/plugin/account-access.js.map +1 -1
- package/dist/src/plugin/account-blocks.d.ts +102 -0
- package/dist/src/plugin/account-blocks.d.ts.map +1 -0
- package/dist/src/plugin/account-blocks.js +196 -0
- package/dist/src/plugin/account-blocks.js.map +1 -0
- package/dist/src/plugin/accounts.d.ts +85 -1
- package/dist/src/plugin/accounts.d.ts.map +1 -1
- package/dist/src/plugin/accounts.js +127 -3
- package/dist/src/plugin/accounts.js.map +1 -1
- package/dist/src/plugin/auth-loader.d.ts +69 -5
- package/dist/src/plugin/auth-loader.d.ts.map +1 -1
- package/dist/src/plugin/auth-loader.js +355 -52
- package/dist/src/plugin/auth-loader.js.map +1 -1
- package/dist/src/plugin/background-quota-refresh.d.ts +54 -8
- package/dist/src/plugin/background-quota-refresh.d.ts.map +1 -1
- package/dist/src/plugin/background-quota-refresh.js +81 -24
- package/dist/src/plugin/background-quota-refresh.js.map +1 -1
- package/dist/src/plugin/cache/index.d.ts +1 -1
- package/dist/src/plugin/cache/index.d.ts.map +1 -1
- package/dist/src/plugin/cache/index.js +1 -1
- package/dist/src/plugin/cache/index.js.map +1 -1
- package/dist/src/plugin/cache/signature-cache.d.ts +55 -10
- package/dist/src/plugin/cache/signature-cache.d.ts.map +1 -1
- package/dist/src/plugin/cache/signature-cache.js +100 -41
- package/dist/src/plugin/cache/signature-cache.js.map +1 -1
- package/dist/src/plugin/cache.d.ts +80 -16
- package/dist/src/plugin/cache.d.ts.map +1 -1
- package/dist/src/plugin/cache.js +339 -200
- package/dist/src/plugin/cache.js.map +1 -1
- package/dist/src/plugin/catalog.d.ts +4 -18
- package/dist/src/plugin/catalog.d.ts.map +1 -1
- package/dist/src/plugin/catalog.js +11 -41
- package/dist/src/plugin/catalog.js.map +1 -1
- package/dist/src/plugin/command-apply.d.ts +58 -0
- package/dist/src/plugin/command-apply.d.ts.map +1 -0
- package/dist/src/plugin/command-apply.js +168 -0
- package/dist/src/plugin/command-apply.js.map +1 -0
- package/dist/src/plugin/command-data.d.ts +1 -0
- package/dist/src/plugin/command-data.d.ts.map +1 -1
- package/dist/src/plugin/command-data.js +2 -0
- package/dist/src/plugin/command-data.js.map +1 -1
- package/dist/src/plugin/commands.d.ts +142 -132
- package/dist/src/plugin/commands.d.ts.map +1 -1
- package/dist/src/plugin/commands.js +214 -686
- package/dist/src/plugin/commands.js.map +1 -1
- package/dist/src/plugin/config/index.d.ts +1 -1
- package/dist/src/plugin/config/index.d.ts.map +1 -1
- package/dist/src/plugin/config/index.js +1 -1
- package/dist/src/plugin/config/index.js.map +1 -1
- package/dist/src/plugin/config/loader.d.ts +37 -1
- package/dist/src/plugin/config/loader.d.ts.map +1 -1
- package/dist/src/plugin/config/loader.js +64 -9
- package/dist/src/plugin/config/loader.js.map +1 -1
- package/dist/src/plugin/config/operator-settings-schema.d.ts +2 -2
- package/dist/src/plugin/config/schema.d.ts +2 -2
- package/dist/src/plugin/config/writer.d.ts +7 -0
- package/dist/src/plugin/config/writer.d.ts.map +1 -1
- package/dist/src/plugin/config/writer.js +10 -1
- package/dist/src/plugin/config/writer.js.map +1 -1
- package/dist/src/plugin/debug.d.ts +72 -29
- package/dist/src/plugin/debug.d.ts.map +1 -1
- package/dist/src/plugin/debug.js +353 -239
- package/dist/src/plugin/debug.js.map +1 -1
- package/dist/src/plugin/fetch/retry-state.d.ts +1 -1
- package/dist/src/plugin/fetch/retry-state.d.ts.map +1 -1
- package/dist/src/plugin/fetch/retry-state.js.map +1 -1
- package/dist/src/plugin/fetch-interceptor.d.ts +66 -11
- package/dist/src/plugin/fetch-interceptor.d.ts.map +1 -1
- package/dist/src/plugin/fetch-interceptor.js +228 -1347
- package/dist/src/plugin/fetch-interceptor.js.map +1 -1
- package/dist/src/plugin/fetch-routing.d.ts +7 -2
- package/dist/src/plugin/fetch-routing.d.ts.map +1 -1
- package/dist/src/plugin/fetch-routing.js +7 -4
- package/dist/src/plugin/fetch-routing.js.map +1 -1
- package/dist/src/plugin/ga-location-services.d.ts +389 -0
- package/dist/src/plugin/ga-location-services.d.ts.map +1 -0
- package/dist/src/plugin/ga-location-services.js +1838 -0
- package/dist/src/plugin/ga-location-services.js.map +1 -0
- package/dist/src/plugin/gemini-dump.d.ts +37 -12
- package/dist/src/plugin/gemini-dump.d.ts.map +1 -1
- package/dist/src/plugin/gemini-dump.js +42 -21
- package/dist/src/plugin/gemini-dump.js.map +1 -1
- package/dist/src/plugin/google-search-tool.d.ts +2 -1
- package/dist/src/plugin/google-search-tool.d.ts.map +1 -1
- package/dist/src/plugin/google-search-tool.js +4 -1
- package/dist/src/plugin/google-search-tool.js.map +1 -1
- package/dist/src/plugin/index.d.ts.map +1 -1
- package/dist/src/plugin/index.js +505 -141
- package/dist/src/plugin/index.js.map +1 -1
- package/dist/src/plugin/killswitch.d.ts +1 -2
- package/dist/src/plugin/killswitch.d.ts.map +1 -1
- package/dist/src/plugin/lifecycle.d.ts +24 -1
- package/dist/src/plugin/lifecycle.d.ts.map +1 -1
- package/dist/src/plugin/lifecycle.js +95 -8
- package/dist/src/plugin/lifecycle.js.map +1 -1
- package/dist/src/plugin/logger.d.ts +61 -10
- package/dist/src/plugin/logger.d.ts.map +1 -1
- package/dist/src/plugin/logger.js +134 -63
- package/dist/src/plugin/logger.js.map +1 -1
- package/dist/src/plugin/neutral-types.d.ts +42 -0
- package/dist/src/plugin/neutral-types.d.ts.map +1 -0
- package/dist/src/plugin/neutral-types.js +12 -0
- package/dist/src/plugin/neutral-types.js.map +1 -0
- package/dist/src/plugin/oauth-methods.d.ts +2 -1
- package/dist/src/plugin/oauth-methods.d.ts.map +1 -1
- package/dist/src/plugin/oauth-methods.js +173 -88
- package/dist/src/plugin/oauth-methods.js.map +1 -1
- package/dist/src/plugin/operator-settings.d.ts +34 -0
- package/dist/src/plugin/operator-settings.d.ts.map +1 -1
- package/dist/src/plugin/operator-settings.js +105 -2
- package/dist/src/plugin/operator-settings.js.map +1 -1
- package/dist/src/plugin/persist-account-pool.d.ts +63 -2
- package/dist/src/plugin/persist-account-pool.d.ts.map +1 -1
- package/dist/src/plugin/persist-account-pool.js +125 -2
- package/dist/src/plugin/persist-account-pool.js.map +1 -1
- package/dist/src/plugin/quota.d.ts +335 -35
- package/dist/src/plugin/quota.d.ts.map +1 -1
- package/dist/src/plugin/quota.js +825 -95
- package/dist/src/plugin/quota.js.map +1 -1
- package/dist/src/plugin/refresh-queue.d.ts +35 -5
- package/dist/src/plugin/refresh-queue.d.ts.map +1 -1
- package/dist/src/plugin/refresh-queue.js +50 -16
- package/dist/src/plugin/refresh-queue.js.map +1 -1
- package/dist/src/plugin/request-helpers.d.ts +30 -5
- package/dist/src/plugin/request-helpers.d.ts.map +1 -1
- package/dist/src/plugin/request-helpers.js +82 -17
- package/dist/src/plugin/request-helpers.js.map +1 -1
- package/dist/src/plugin/request.d.ts +63 -15
- package/dist/src/plugin/request.d.ts.map +1 -1
- package/dist/src/plugin/request.js +190 -60
- package/dist/src/plugin/request.js.map +1 -1
- package/dist/src/plugin/session-context.d.ts.map +1 -1
- package/dist/src/plugin/session-context.js +5 -2
- package/dist/src/plugin/session-context.js.map +1 -1
- package/dist/src/plugin/shared/local-grant.d.ts +26 -0
- package/dist/src/plugin/shared/local-grant.d.ts.map +1 -0
- package/dist/src/plugin/shared/local-grant.js +19 -0
- package/dist/src/plugin/shared/local-grant.js.map +1 -0
- package/dist/src/plugin/shared/request-cancellation.d.ts +12 -0
- package/dist/src/plugin/shared/request-cancellation.d.ts.map +1 -0
- package/dist/src/plugin/shared/request-cancellation.js +118 -0
- package/dist/src/plugin/shared/request-cancellation.js.map +1 -0
- package/dist/src/plugin/shared/request-services.d.ts +375 -0
- package/dist/src/plugin/shared/request-services.d.ts.map +1 -0
- package/dist/src/plugin/shared/request-services.js +1743 -0
- package/dist/src/plugin/shared/request-services.js.map +1 -0
- package/dist/src/plugin/shared/runtime.d.ts +217 -0
- package/dist/src/plugin/shared/runtime.d.ts.map +1 -0
- package/dist/src/plugin/shared/runtime.js +345 -0
- package/dist/src/plugin/shared/runtime.js.map +1 -0
- package/dist/src/plugin/shared/source-sidebar.d.ts +15 -0
- package/dist/src/plugin/shared/source-sidebar.d.ts.map +1 -0
- package/dist/src/plugin/shared/source-sidebar.js +41 -0
- package/dist/src/plugin/shared/source-sidebar.js.map +1 -0
- package/dist/src/plugin/shared/vault-menu.d.ts +5 -0
- package/dist/src/plugin/shared/vault-menu.d.ts.map +1 -0
- package/dist/src/plugin/shared/vault-menu.js +49 -0
- package/dist/src/plugin/shared/vault-menu.js.map +1 -0
- package/dist/src/plugin/shared/vault-request-credentials.d.ts +168 -0
- package/dist/src/plugin/shared/vault-request-credentials.d.ts.map +1 -0
- package/dist/src/plugin/shared/vault-request-credentials.js +485 -0
- package/dist/src/plugin/shared/vault-request-credentials.js.map +1 -0
- package/dist/src/plugin/storage.d.ts +127 -1
- package/dist/src/plugin/storage.d.ts.map +1 -1
- package/dist/src/plugin/storage.js +188 -3
- package/dist/src/plugin/storage.js.map +1 -1
- package/dist/src/plugin/token.d.ts +23 -1
- package/dist/src/plugin/token.d.ts.map +1 -1
- package/dist/src/plugin/token.js +117 -58
- package/dist/src/plugin/token.js.map +1 -1
- package/dist/src/plugin/ui/quota-status.d.ts +1 -10
- package/dist/src/plugin/ui/quota-status.d.ts.map +1 -1
- package/dist/src/plugin/ui/quota-status.js +6 -42
- package/dist/src/plugin/ui/quota-status.js.map +1 -1
- package/dist/src/plugin/vault-activation.d.ts +11 -0
- package/dist/src/plugin/vault-activation.d.ts.map +1 -0
- package/dist/src/plugin/vault-activation.js +53 -0
- package/dist/src/plugin/vault-activation.js.map +1 -0
- package/dist/src/plugin/vault-custody.d.ts +131 -0
- package/dist/src/plugin/vault-custody.d.ts.map +1 -0
- package/dist/src/plugin/vault-custody.js +381 -0
- package/dist/src/plugin/vault-custody.js.map +1 -0
- package/dist/src/quota-presentation.d.ts +18 -0
- package/dist/src/quota-presentation.d.ts.map +1 -0
- package/dist/src/quota-presentation.js +58 -0
- package/dist/src/quota-presentation.js.map +1 -0
- package/dist/src/rpc/notifications.d.ts +2 -2
- package/dist/src/rpc/notifications.d.ts.map +1 -1
- package/dist/src/rpc/notifications.js +1 -1
- package/dist/src/rpc/notifications.js.map +1 -1
- package/dist/src/rpc/port-file.d.ts +2 -12
- package/dist/src/rpc/port-file.d.ts.map +1 -1
- package/dist/src/rpc/port-file.js +5 -107
- package/dist/src/rpc/port-file.js.map +1 -1
- package/dist/src/rpc/protocol.d.ts +47 -16
- package/dist/src/rpc/protocol.d.ts.map +1 -1
- package/dist/src/rpc/rpc-client.d.ts +27 -3
- package/dist/src/rpc/rpc-client.d.ts.map +1 -1
- package/dist/src/rpc/rpc-client.js +55 -45
- package/dist/src/rpc/rpc-client.js.map +1 -1
- package/dist/src/rpc/rpc-server.d.ts +13 -2
- package/dist/src/rpc/rpc-server.d.ts.map +1 -1
- package/dist/src/rpc/rpc-server.js +38 -212
- package/dist/src/rpc/rpc-server.js.map +1 -1
- package/dist/src/server.d.ts +30 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +29 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/sidebar-projection.d.ts +102 -0
- package/dist/src/sidebar-projection.d.ts.map +1 -0
- package/dist/src/sidebar-projection.js +146 -0
- package/dist/src/sidebar-projection.js.map +1 -0
- package/dist/src/sidebar-state.d.ts +13 -5
- package/dist/src/sidebar-state.d.ts.map +1 -1
- package/dist/src/sidebar-state.js +49 -16
- package/dist/src/sidebar-state.js.map +1 -1
- package/dist/src/tui/command-dialogs.d.ts +58 -52
- package/dist/src/tui/command-dialogs.d.ts.map +1 -1
- package/dist/src/tui/command-dialogs.js +379 -571
- package/dist/src/tui/command-dialogs.js.map +1 -1
- package/dist/src/tui/file-logger.d.ts +2 -3
- package/dist/src/tui/file-logger.d.ts.map +1 -1
- package/dist/src/tui/file-logger.js +21 -7
- package/dist/src/tui/file-logger.js.map +1 -1
- package/dist/src/tui/host-api.d.ts +196 -0
- package/dist/src/tui/host-api.d.ts.map +1 -0
- package/dist/src/tui/host-api.js +357 -0
- package/dist/src/tui/host-api.js.map +1 -0
- package/dist/src/tui/host-v1.d.ts +60 -0
- package/dist/src/tui/host-v1.d.ts.map +1 -0
- package/dist/src/tui/host-v1.js +147 -0
- package/dist/src/tui/host-v1.js.map +1 -0
- package/dist/src/tui/vault-setup.d.ts +98 -0
- package/dist/src/tui/vault-setup.d.ts.map +1 -0
- package/dist/src/tui/vault-setup.js +198 -0
- package/dist/src/tui/vault-setup.js.map +1 -0
- package/dist/src/tui.d.ts +4 -11
- package/dist/src/tui.d.ts.map +1 -1
- package/dist/src/tui.js +33 -75
- package/dist/src/tui.js.map +1 -1
- package/dist/tui-build-map.json +380 -0
- package/dist/tui-ga-build-map.json +187 -0
- package/dist/types/src/antigravity/oauth.d.ts +2 -0
- package/dist/types/src/antigravity/oauth.d.ts.map +1 -0
- package/dist/types/src/cli.d.ts +66 -0
- package/dist/types/src/cli.d.ts.map +1 -0
- package/dist/types/src/common-auth-embedded/commands/builtins.d.ts +71 -0
- package/dist/types/src/common-auth-embedded/commands/index.d.ts +10 -0
- package/dist/types/src/common-auth-embedded/commands/menu.d.ts +61 -0
- package/dist/types/src/common-auth-embedded/commands/model.d.ts +238 -0
- package/dist/types/src/common-auth-embedded/commands/pi.d.ts +23 -0
- package/dist/types/src/common-auth-embedded/commands/seam.d.ts +72 -0
- package/dist/types/src/common-auth-embedded/fs/refresh-file-lock.d.ts +33 -0
- package/dist/types/src/common-auth-embedded/logger/capture-sink.d.ts +14 -0
- package/dist/types/src/common-auth-embedded/logger/engine.d.ts +100 -0
- package/dist/types/src/common-auth-embedded/logger/index.d.ts +6 -0
- package/dist/types/src/common-auth-embedded/logger/redact.d.ts +11 -0
- package/dist/types/src/common-auth-embedded/quota/codec.d.ts +11 -0
- package/dist/types/src/common-auth-embedded/quota/format.d.ts +46 -0
- package/dist/types/src/common-auth-embedded/quota/index.d.ts +10 -0
- package/dist/types/src/common-auth-embedded/quota/map.d.ts +63 -0
- package/dist/types/src/common-auth-embedded/quota/merge.d.ts +48 -0
- package/dist/types/src/common-auth-embedded/quota/projection.d.ts +64 -0
- package/dist/types/src/common-auth-embedded/store/attribution.d.ts +28 -0
- package/dist/types/src/common-auth-embedded/store/errors.d.ts +55 -0
- package/dist/types/src/common-auth-embedded/store/hooks.d.ts +12 -0
- package/dist/types/src/common-auth-embedded/store/identity.d.ts +39 -0
- package/dist/types/src/common-auth-embedded/store/index.d.ts +21 -0
- package/dist/types/src/common-auth-embedded/store/mutate.d.ts +189 -0
- package/dist/types/src/common-auth-embedded/store/pool.d.ts +196 -0
- package/dist/types/src/common-auth-embedded/store/provider-state.d.ts +131 -0
- package/dist/types/src/common-auth-embedded/store/publication.d.ts +47 -0
- package/dist/types/src/common-auth-embedded/store/pull.d.ts +36 -0
- package/dist/types/src/common-auth-embedded/store/refresh-lock.d.ts +63 -0
- package/dist/types/src/common-auth-embedded/store/refresh.d.ts +72 -0
- package/dist/types/src/common-auth-embedded/store/rows.d.ts +313 -0
- package/dist/types/src/common-auth-embedded/store/runtime.d.ts +36 -0
- package/dist/types/src/common-auth-embedded/store/schema.d.ts +443 -0
- package/dist/types/src/common-auth-embedded/store/settings.d.ts +63 -0
- package/dist/types/src/common-auth-embedded/store/torn.d.ts +78 -0
- package/dist/types/src/constants.d.ts +3 -0
- package/dist/types/src/constants.d.ts.map +1 -0
- package/dist/types/src/ga/proxy-guard.d.ts +120 -0
- package/dist/types/src/ga/proxy-guard.d.ts.map +1 -0
- package/dist/types/src/ga/rpc/protocol.d.ts +504 -0
- package/dist/types/src/ga/rpc/protocol.d.ts.map +1 -0
- package/dist/types/src/ga/server/auth.d.ts +9 -0
- package/dist/types/src/ga/server/auth.d.ts.map +1 -0
- package/dist/types/src/ga/server/index.d.ts +576 -0
- package/dist/types/src/ga/server/index.d.ts.map +1 -0
- package/dist/types/src/hooks/auto-update-checker/cache.d.ts +3 -0
- package/dist/types/src/hooks/auto-update-checker/cache.d.ts.map +1 -0
- package/dist/types/src/hooks/auto-update-checker/checker.d.ts +16 -0
- package/dist/types/src/hooks/auto-update-checker/checker.d.ts.map +1 -0
- package/dist/types/src/hooks/auto-update-checker/constants.d.ts +9 -0
- package/dist/types/src/hooks/auto-update-checker/constants.d.ts.map +1 -0
- package/dist/types/src/hooks/auto-update-checker/index.d.ts +34 -0
- package/dist/types/src/hooks/auto-update-checker/index.d.ts.map +1 -0
- package/dist/types/src/hooks/auto-update-checker/logging.d.ts +3 -0
- package/dist/types/src/hooks/auto-update-checker/logging.d.ts.map +1 -0
- package/dist/types/src/hooks/auto-update-checker/types.d.ts +25 -0
- package/dist/types/src/hooks/auto-update-checker/types.d.ts.map +1 -0
- package/dist/types/src/logging/provider-key-policy.d.ts +9 -0
- package/dist/types/src/logging/provider-key-policy.d.ts.map +1 -0
- package/dist/types/src/plugin/account-access.d.ts +214 -0
- package/dist/types/src/plugin/account-access.d.ts.map +1 -0
- package/dist/types/src/plugin/account-blocks.d.ts +102 -0
- package/dist/types/src/plugin/account-blocks.d.ts.map +1 -0
- package/dist/types/src/plugin/account-command-oauth.d.ts +34 -0
- package/dist/types/src/plugin/account-command-oauth.d.ts.map +1 -0
- package/dist/types/src/plugin/accounts.d.ts +94 -0
- package/dist/types/src/plugin/accounts.d.ts.map +1 -0
- package/dist/types/src/plugin/agy-request-metadata.d.ts +2 -0
- package/dist/types/src/plugin/agy-request-metadata.d.ts.map +1 -0
- package/dist/types/src/plugin/agy-transport.d.ts +2 -0
- package/dist/types/src/plugin/agy-transport.d.ts.map +1 -0
- package/dist/types/src/plugin/auth-doctor.d.ts +30 -0
- package/dist/types/src/plugin/auth-doctor.d.ts.map +1 -0
- package/dist/types/src/plugin/auth-drift.d.ts +13 -0
- package/dist/types/src/plugin/auth-drift.d.ts.map +1 -0
- package/dist/types/src/plugin/auth-loader.d.ts +114 -0
- package/dist/types/src/plugin/auth-loader.d.ts.map +1 -0
- package/dist/types/src/plugin/auth.d.ts +2 -0
- package/dist/types/src/plugin/auth.d.ts.map +1 -0
- package/dist/types/src/plugin/background-quota-refresh.d.ts +192 -0
- package/dist/types/src/plugin/background-quota-refresh.d.ts.map +1 -0
- package/dist/types/src/plugin/cache/signature-cache.d.ts +156 -0
- package/dist/types/src/plugin/cache/signature-cache.d.ts.map +1 -0
- package/dist/types/src/plugin/cache.d.ts +109 -0
- package/dist/types/src/plugin/cache.d.ts.map +1 -0
- package/dist/types/src/plugin/catalog.d.ts +9 -0
- package/dist/types/src/plugin/catalog.d.ts.map +1 -0
- package/dist/types/src/plugin/cli.d.ts +44 -0
- package/dist/types/src/plugin/cli.d.ts.map +1 -0
- package/dist/types/src/plugin/command-apply.d.ts +58 -0
- package/dist/types/src/plugin/command-apply.d.ts.map +1 -0
- package/dist/types/src/plugin/command-data.d.ts +330 -0
- package/dist/types/src/plugin/command-data.d.ts.map +1 -0
- package/dist/types/src/plugin/commands.d.ts +164 -0
- package/dist/types/src/plugin/commands.d.ts.map +1 -0
- package/dist/types/src/plugin/config/index.d.ts +16 -0
- package/dist/types/src/plugin/config/index.d.ts.map +1 -0
- package/dist/types/src/plugin/config/loader.d.ts +72 -0
- package/dist/types/src/plugin/config/loader.d.ts.map +1 -0
- package/dist/types/src/plugin/config/models.d.ts +3 -0
- package/dist/types/src/plugin/config/models.d.ts.map +1 -0
- package/dist/types/src/plugin/config/operator-settings-schema.d.ts +29 -0
- package/dist/types/src/plugin/config/operator-settings-schema.d.ts.map +1 -0
- package/dist/types/src/plugin/config/schema.d.ts +162 -0
- package/dist/types/src/plugin/config/schema.d.ts.map +1 -0
- package/dist/types/src/plugin/config/updater.d.ts +55 -0
- package/dist/types/src/plugin/config/updater.d.ts.map +1 -0
- package/dist/types/src/plugin/config/writer.d.ts +41 -0
- package/dist/types/src/plugin/config/writer.d.ts.map +1 -0
- package/dist/types/src/plugin/core/streaming/index.d.ts +3 -0
- package/dist/types/src/plugin/core/streaming/index.d.ts.map +1 -0
- package/dist/types/src/plugin/core/streaming/transformer.d.ts +12 -0
- package/dist/types/src/plugin/core/streaming/transformer.d.ts.map +1 -0
- package/dist/types/src/plugin/core/streaming/types.d.ts +34 -0
- package/dist/types/src/plugin/core/streaming/types.d.ts.map +1 -0
- package/dist/types/src/plugin/debug.d.ts +144 -0
- package/dist/types/src/plugin/debug.d.ts.map +1 -0
- package/dist/types/src/plugin/dependencies.d.ts +129 -0
- package/dist/types/src/plugin/dependencies.d.ts.map +1 -0
- package/dist/types/src/plugin/errors.d.ts +55 -0
- package/dist/types/src/plugin/errors.d.ts.map +1 -0
- package/dist/types/src/plugin/event-handler.d.ts +53 -0
- package/dist/types/src/plugin/event-handler.d.ts.map +1 -0
- package/dist/types/src/plugin/fetch/retry-state.d.ts +61 -0
- package/dist/types/src/plugin/fetch/retry-state.d.ts.map +1 -0
- package/dist/types/src/plugin/fetch/warmup.d.ts +30 -0
- package/dist/types/src/plugin/fetch/warmup.d.ts.map +1 -0
- package/dist/types/src/plugin/fetch-interceptor.d.ts +114 -0
- package/dist/types/src/plugin/fetch-interceptor.d.ts.map +1 -0
- package/dist/types/src/plugin/fetch-routing.d.ts +31 -0
- package/dist/types/src/plugin/fetch-routing.d.ts.map +1 -0
- package/dist/types/src/plugin/fingerprint.d.ts +2 -0
- package/dist/types/src/plugin/fingerprint.d.ts.map +1 -0
- package/dist/types/src/plugin/ga-location-services.d.ts +389 -0
- package/dist/types/src/plugin/ga-location-services.d.ts.map +1 -0
- package/dist/types/src/plugin/gemini-dump.d.ts +72 -0
- package/dist/types/src/plugin/gemini-dump.d.ts.map +1 -0
- package/dist/types/src/plugin/google-search-tool.d.ts +10 -0
- package/dist/types/src/plugin/google-search-tool.d.ts.map +1 -0
- package/dist/types/src/plugin/image-saver.d.ts +6 -0
- package/dist/types/src/plugin/image-saver.d.ts.map +1 -0
- package/dist/types/src/plugin/index.d.ts +30 -0
- package/dist/types/src/plugin/index.d.ts.map +1 -0
- package/dist/types/src/plugin/killswitch.d.ts +93 -0
- package/dist/types/src/plugin/killswitch.d.ts.map +1 -0
- package/dist/types/src/plugin/lifecycle.d.ts +63 -0
- package/dist/types/src/plugin/lifecycle.d.ts.map +1 -0
- package/dist/types/src/plugin/logger.d.ts +83 -0
- package/dist/types/src/plugin/logger.d.ts.map +1 -0
- package/dist/types/src/plugin/logging-utils.d.ts +57 -0
- package/dist/types/src/plugin/logging-utils.d.ts.map +1 -0
- package/dist/types/src/plugin/model-registry.d.ts +2 -0
- package/dist/types/src/plugin/model-registry.d.ts.map +1 -0
- package/dist/types/src/plugin/neutral-types.d.ts +42 -0
- package/dist/types/src/plugin/neutral-types.d.ts.map +1 -0
- package/dist/types/src/plugin/oauth-login.d.ts +22 -0
- package/dist/types/src/plugin/oauth-login.d.ts.map +1 -0
- package/dist/types/src/plugin/oauth-methods.d.ts +43 -0
- package/dist/types/src/plugin/oauth-methods.d.ts.map +1 -0
- package/dist/types/src/plugin/operator-settings.d.ts +74 -0
- package/dist/types/src/plugin/operator-settings.d.ts.map +1 -0
- package/dist/types/src/plugin/persist-account-pool.d.ts +98 -0
- package/dist/types/src/plugin/persist-account-pool.d.ts.map +1 -0
- package/dist/types/src/plugin/project.d.ts +2 -0
- package/dist/types/src/plugin/project.d.ts.map +1 -0
- package/dist/types/src/plugin/prompt-context.d.ts +18 -0
- package/dist/types/src/plugin/prompt-context.d.ts.map +1 -0
- package/dist/types/src/plugin/quota.d.ts +441 -0
- package/dist/types/src/plugin/quota.d.ts.map +1 -0
- package/dist/types/src/plugin/recovery/constants.d.ts +22 -0
- package/dist/types/src/plugin/recovery/constants.d.ts.map +1 -0
- package/dist/types/src/plugin/recovery/storage.d.ts +24 -0
- package/dist/types/src/plugin/recovery/storage.d.ts.map +1 -0
- package/dist/types/src/plugin/recovery/types.d.ts +116 -0
- package/dist/types/src/plugin/recovery/types.d.ts.map +1 -0
- package/dist/types/src/plugin/recovery.d.ts +61 -0
- package/dist/types/src/plugin/recovery.d.ts.map +1 -0
- package/dist/types/src/plugin/refresh-queue.d.ts +133 -0
- package/dist/types/src/plugin/refresh-queue.d.ts.map +1 -0
- package/dist/types/src/plugin/request-helpers.d.ts +304 -0
- package/dist/types/src/plugin/request-helpers.d.ts.map +1 -0
- package/dist/types/src/plugin/request.d.ts +161 -0
- package/dist/types/src/plugin/request.d.ts.map +1 -0
- package/dist/types/src/plugin/rotation.d.ts +2 -0
- package/dist/types/src/plugin/rotation.d.ts.map +1 -0
- package/dist/types/src/plugin/search.d.ts +25 -0
- package/dist/types/src/plugin/search.d.ts.map +1 -0
- package/dist/types/src/plugin/server.d.ts +23 -0
- package/dist/types/src/plugin/server.d.ts.map +1 -0
- package/dist/types/src/plugin/session-context.d.ts +22 -0
- package/dist/types/src/plugin/session-context.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/local-grant.d.ts +26 -0
- package/dist/types/src/plugin/shared/local-grant.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/request-cancellation.d.ts +12 -0
- package/dist/types/src/plugin/shared/request-cancellation.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/request-services.d.ts +375 -0
- package/dist/types/src/plugin/shared/request-services.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/runtime.d.ts +217 -0
- package/dist/types/src/plugin/shared/runtime.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/source-sidebar.d.ts +15 -0
- package/dist/types/src/plugin/shared/source-sidebar.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/vault-menu.d.ts +5 -0
- package/dist/types/src/plugin/shared/vault-menu.d.ts.map +1 -0
- package/dist/types/src/plugin/shared/vault-request-credentials.d.ts +168 -0
- package/dist/types/src/plugin/shared/vault-request-credentials.d.ts.map +1 -0
- package/dist/types/src/plugin/storage.d.ts +221 -0
- package/dist/types/src/plugin/storage.d.ts.map +1 -0
- package/dist/types/src/plugin/stores/signature-store.d.ts +5 -0
- package/dist/types/src/plugin/stores/signature-store.d.ts.map +1 -0
- package/dist/types/src/plugin/thinking-recovery.d.ts +90 -0
- package/dist/types/src/plugin/thinking-recovery.d.ts.map +1 -0
- package/dist/types/src/plugin/token.d.ts +41 -0
- package/dist/types/src/plugin/token.d.ts.map +1 -0
- package/dist/types/src/plugin/transform/cross-model-sanitizer.d.ts +2 -0
- package/dist/types/src/plugin/transform/cross-model-sanitizer.d.ts.map +1 -0
- package/dist/types/src/plugin/transform/index.d.ts +2 -0
- package/dist/types/src/plugin/transform/index.d.ts.map +1 -0
- package/dist/types/src/plugin/transform/model-resolver.d.ts +2 -0
- package/dist/types/src/plugin/transform/model-resolver.d.ts.map +1 -0
- package/dist/types/src/plugin/transform/types.d.ts +2 -0
- package/dist/types/src/plugin/transform/types.d.ts.map +1 -0
- package/dist/types/src/plugin/types.d.ts +36 -0
- package/dist/types/src/plugin/types.d.ts.map +1 -0
- package/dist/types/src/plugin/ui/ansi.d.ts +32 -0
- package/dist/types/src/plugin/ui/ansi.d.ts.map +1 -0
- package/dist/types/src/plugin/ui/auth-menu.d.ts +59 -0
- package/dist/types/src/plugin/ui/auth-menu.d.ts.map +1 -0
- package/dist/types/src/plugin/ui/confirm.d.ts +2 -0
- package/dist/types/src/plugin/ui/confirm.d.ts.map +1 -0
- package/dist/types/src/plugin/ui/quota-status.d.ts +73 -0
- package/dist/types/src/plugin/ui/quota-status.d.ts.map +1 -0
- package/dist/types/src/plugin/ui/select.d.ts +23 -0
- package/dist/types/src/plugin/ui/select.d.ts.map +1 -0
- package/dist/types/src/plugin/vault-activation.d.ts +11 -0
- package/dist/types/src/plugin/vault-activation.d.ts.map +1 -0
- package/dist/types/src/plugin/vault-custody.d.ts +131 -0
- package/dist/types/src/plugin/vault-custody.d.ts.map +1 -0
- package/dist/types/src/plugin/version.d.ts +2 -0
- package/dist/types/src/plugin/version.d.ts.map +1 -0
- package/dist/types/src/quota-presentation.d.ts +18 -0
- package/dist/types/src/quota-presentation.d.ts.map +1 -0
- package/dist/types/src/rpc/notifications.d.ts +6 -0
- package/dist/types/src/rpc/notifications.d.ts.map +1 -0
- package/dist/types/src/rpc/protocol.d.ts +53 -0
- package/dist/types/src/rpc/protocol.d.ts.map +1 -0
- package/dist/types/src/rpc/rpc-dir.d.ts +4 -0
- package/dist/types/src/rpc/rpc-dir.d.ts.map +1 -0
- package/dist/types/src/rpc/rpc-server.d.ts +24 -0
- package/dist/types/src/rpc/rpc-server.d.ts.map +1 -0
- package/dist/types/src/server.d.ts +30 -0
- package/dist/types/src/server.d.ts.map +1 -0
- package/dist/types/src/sidebar-state.d.ts +365 -0
- package/dist/types/src/sidebar-state.d.ts.map +1 -0
- package/dist/types/src/tui/host-api.d.ts +196 -0
- package/dist/types/src/tui/host-api.d.ts.map +1 -0
- package/package.json +45 -18
- package/server.js +6 -0
- package/src/common-auth-embedded/NOTICE.txt +21 -0
- package/src/common-auth-embedded/auth-menu/accounts.d.ts +97 -0
- package/src/common-auth-embedded/auth-menu/accounts.js +387 -0
- package/src/common-auth-embedded/auth-menu/ansi.d.ts +26 -0
- package/src/common-auth-embedded/auth-menu/ansi.js +98 -0
- package/src/common-auth-embedded/auth-menu/confirm.d.ts +7 -0
- package/src/common-auth-embedded/auth-menu/confirm.js +21 -0
- package/src/common-auth-embedded/auth-menu/doctor.d.ts +52 -0
- package/src/common-auth-embedded/auth-menu/doctor.js +81 -0
- package/src/common-auth-embedded/auth-menu/index.d.ts +17 -0
- package/src/common-auth-embedded/auth-menu/index.js +12 -0
- package/src/common-auth-embedded/auth-menu/login.d.ts +55 -0
- package/src/common-auth-embedded/auth-menu/login.js +83 -0
- package/src/common-auth-embedded/auth-menu/menu.d.ts +59 -0
- package/src/common-auth-embedded/auth-menu/menu.js +73 -0
- package/src/common-auth-embedded/auth-menu/opencode-v1.d.ts +49 -0
- package/src/common-auth-embedded/auth-menu/opencode-v1.js +47 -0
- package/src/common-auth-embedded/auth-menu/select.d.ts +21 -0
- package/src/common-auth-embedded/auth-menu/select.js +159 -0
- package/src/common-auth-embedded/auth-menu/terminal.d.ts +43 -0
- package/src/common-auth-embedded/auth-menu/terminal.js +19 -0
- package/src/common-auth-embedded/claustrum/consumer.d.ts +102 -0
- package/src/common-auth-embedded/claustrum/consumer.js +298 -0
- package/src/common-auth-embedded/claustrum/custody.d.ts +175 -0
- package/src/common-auth-embedded/claustrum/custody.js +354 -0
- package/src/common-auth-embedded/claustrum/enrollment.d.ts +158 -0
- package/src/common-auth-embedded/claustrum/enrollment.js +759 -0
- package/src/common-auth-embedded/claustrum/errors.d.ts +16 -0
- package/src/common-auth-embedded/claustrum/errors.js +8 -0
- package/src/common-auth-embedded/claustrum/host-slot.d.ts +39 -0
- package/src/common-auth-embedded/claustrum/host-slot.js +72 -0
- package/src/common-auth-embedded/claustrum/index.d.ts +18 -0
- package/src/common-auth-embedded/claustrum/index.js +22 -0
- package/src/common-auth-embedded/claustrum/interlock.d.ts +27 -0
- package/src/common-auth-embedded/claustrum/interlock.js +29 -0
- package/src/common-auth-embedded/claustrum/roster.d.ts +208 -0
- package/src/common-auth-embedded/claustrum/roster.js +536 -0
- package/src/common-auth-embedded/commands/builtins.d.ts +71 -0
- package/src/common-auth-embedded/commands/builtins.js +534 -0
- package/src/common-auth-embedded/commands/index.d.ts +10 -0
- package/src/common-auth-embedded/commands/index.js +5 -0
- package/src/common-auth-embedded/commands/menu.d.ts +61 -0
- package/src/common-auth-embedded/commands/menu.js +300 -0
- package/src/common-auth-embedded/commands/model.d.ts +238 -0
- package/src/common-auth-embedded/commands/model.js +16 -0
- package/src/common-auth-embedded/commands/pi.d.ts +23 -0
- package/src/common-auth-embedded/commands/pi.js +206 -0
- package/src/common-auth-embedded/commands/seam.d.ts +72 -0
- package/src/common-auth-embedded/commands/seam.js +301 -0
- package/src/common-auth-embedded/fs/atomic-write.d.ts +20 -0
- package/src/common-auth-embedded/fs/atomic-write.js +80 -0
- package/src/common-auth-embedded/fs/index.d.ts +7 -0
- package/src/common-auth-embedded/fs/index.js +6 -0
- package/src/common-auth-embedded/fs/lock-constants.d.ts +14 -0
- package/src/common-auth-embedded/fs/lock-constants.js +14 -0
- package/src/common-auth-embedded/fs/refresh-file-lock.d.ts +33 -0
- package/src/common-auth-embedded/fs/refresh-file-lock.js +501 -0
- package/src/common-auth-embedded/fs/with-lock.d.ts +33 -0
- package/src/common-auth-embedded/fs/with-lock.js +48 -0
- package/src/common-auth-embedded/logger/capture-sink.d.ts +14 -0
- package/src/common-auth-embedded/logger/capture-sink.js +13 -0
- package/src/common-auth-embedded/logger/engine.d.ts +100 -0
- package/src/common-auth-embedded/logger/engine.js +246 -0
- package/src/common-auth-embedded/logger/index.d.ts +6 -0
- package/src/common-auth-embedded/logger/index.js +3 -0
- package/src/common-auth-embedded/logger/redact.d.ts +11 -0
- package/src/common-auth-embedded/logger/redact.js +83 -0
- package/src/common-auth-embedded/opencode2/errors.d.ts +25 -0
- package/src/common-auth-embedded/opencode2/errors.js +15 -0
- package/src/common-auth-embedded/opencode2/index.d.ts +8 -0
- package/src/common-auth-embedded/opencode2/index.js +4 -0
- package/src/common-auth-embedded/opencode2/install.d.ts +55 -0
- package/src/common-auth-embedded/opencode2/install.js +886 -0
- package/src/common-auth-embedded/opencode2/integration.d.ts +112 -0
- package/src/common-auth-embedded/opencode2/integration.js +143 -0
- package/src/common-auth-embedded/opencode2/sse.d.ts +12 -0
- package/src/common-auth-embedded/opencode2/sse.js +60 -0
- package/src/common-auth-embedded/opencode2/types.d.ts +413 -0
- package/src/common-auth-embedded/pi-slot/index.d.ts +3 -0
- package/src/common-auth-embedded/pi-slot/index.js +2 -0
- package/src/common-auth-embedded/pi-slot/lock.js +212 -0
- package/src/common-auth-embedded/pi-slot/slot.d.ts +49 -0
- package/src/common-auth-embedded/pi-slot/slot.js +383 -0
- package/src/common-auth-embedded/quota/codec.d.ts +11 -0
- package/src/common-auth-embedded/quota/codec.js +12 -0
- package/src/common-auth-embedded/quota/format.d.ts +46 -0
- package/src/common-auth-embedded/quota/format.js +138 -0
- package/src/common-auth-embedded/quota/index.d.ts +10 -0
- package/src/common-auth-embedded/quota/index.js +5 -0
- package/src/common-auth-embedded/quota/map.d.ts +63 -0
- package/src/common-auth-embedded/quota/map.js +105 -0
- package/src/common-auth-embedded/quota/merge.d.ts +48 -0
- package/src/common-auth-embedded/quota/merge.js +162 -0
- package/src/common-auth-embedded/quota/projection.d.ts +64 -0
- package/src/common-auth-embedded/quota/projection.js +134 -0
- package/src/common-auth-embedded/routing/admission.d.ts +93 -0
- package/src/common-auth-embedded/routing/admission.js +142 -0
- package/src/common-auth-embedded/routing/index.d.ts +8 -0
- package/src/common-auth-embedded/routing/index.js +4 -0
- package/src/common-auth-embedded/routing/ordered.d.ts +47 -0
- package/src/common-auth-embedded/routing/ordered.js +58 -0
- package/src/common-auth-embedded/routing/pins.d.ts +22 -0
- package/src/common-auth-embedded/routing/pins.js +34 -0
- package/src/common-auth-embedded/routing/sticky.d.ts +158 -0
- package/src/common-auth-embedded/routing/sticky.js +339 -0
- package/src/common-auth-embedded/rpc/client.d.ts +3 -0
- package/src/common-auth-embedded/rpc/client.js +2 -0
- package/src/common-auth-embedded/rpc/index.d.ts +10 -0
- package/src/common-auth-embedded/rpc/index.js +5 -0
- package/src/common-auth-embedded/rpc/notifications.d.ts +73 -0
- package/src/common-auth-embedded/rpc/notifications.js +100 -0
- package/src/common-auth-embedded/rpc/port-file.d.ts +33 -0
- package/src/common-auth-embedded/rpc/port-file.js +217 -0
- package/src/common-auth-embedded/rpc/rpc-client.d.ts +30 -0
- package/src/common-auth-embedded/rpc/rpc-client.js +253 -0
- package/src/common-auth-embedded/rpc/rpc-server.d.ts +58 -0
- package/src/common-auth-embedded/rpc/rpc-server.js +311 -0
- package/src/common-auth-embedded/rpc/server-registry.d.ts +11 -0
- package/src/common-auth-embedded/rpc/server-registry.js +47 -0
- package/src/common-auth-embedded/source-output.json +1326 -0
- package/src/common-auth-embedded/store/attribution.d.ts +28 -0
- package/src/common-auth-embedded/store/attribution.js +60 -0
- package/src/common-auth-embedded/store/errors.d.ts +55 -0
- package/src/common-auth-embedded/store/errors.js +38 -0
- package/src/common-auth-embedded/store/hooks.d.ts +12 -0
- package/src/common-auth-embedded/store/hooks.js +34 -0
- package/src/common-auth-embedded/store/identity.d.ts +39 -0
- package/src/common-auth-embedded/store/identity.js +79 -0
- package/src/common-auth-embedded/store/index.d.ts +21 -0
- package/src/common-auth-embedded/store/index.js +7 -0
- package/src/common-auth-embedded/store/mutate.d.ts +189 -0
- package/src/common-auth-embedded/store/mutate.js +500 -0
- package/src/common-auth-embedded/store/pool.d.ts +196 -0
- package/src/common-auth-embedded/store/pool.js +120 -0
- package/src/common-auth-embedded/store/provider-state.d.ts +131 -0
- package/src/common-auth-embedded/store/provider-state.js +226 -0
- package/src/common-auth-embedded/store/publication.d.ts +47 -0
- package/src/common-auth-embedded/store/publication.js +304 -0
- package/src/common-auth-embedded/store/pull.d.ts +36 -0
- package/src/common-auth-embedded/store/pull.js +143 -0
- package/src/common-auth-embedded/store/refresh-lock.d.ts +63 -0
- package/src/common-auth-embedded/store/refresh-lock.js +136 -0
- package/src/common-auth-embedded/store/refresh.d.ts +72 -0
- package/src/common-auth-embedded/store/refresh.js +225 -0
- package/src/common-auth-embedded/store/reserved.js +13 -0
- package/src/common-auth-embedded/store/rows.d.ts +313 -0
- package/src/common-auth-embedded/store/rows.js +1258 -0
- package/src/common-auth-embedded/store/runtime.d.ts +36 -0
- package/src/common-auth-embedded/store/runtime.js +68 -0
- package/src/common-auth-embedded/store/schema.d.ts +443 -0
- package/src/common-auth-embedded/store/schema.js +754 -0
- package/src/common-auth-embedded/store/settings.d.ts +63 -0
- package/src/common-auth-embedded/store/settings.js +120 -0
- package/src/common-auth-embedded/store/torn.d.ts +78 -0
- package/src/common-auth-embedded/store/torn.js +294 -0
- package/src/common-auth-embedded/tui/index.d.ts +8 -0
- package/src/common-auth-embedded/tui/index.js +21 -0
- package/src/common-auth-embedded/util/any-signal.js +42 -0
- package/src/plugin/command-data.ts +3 -0
- package/src/rpc/port-file.ts +6 -140
- package/src/rpc/protocol.ts +59 -24
- package/src/rpc/rpc-client.ts +101 -71
- package/src/sidebar-state.ts +82 -24
- package/src/tui/command-dialogs.tsx +412 -776
- package/src/tui/entry.d.mts +17 -0
- package/src/tui/entry.mjs +34 -66
- package/src/tui/file-logger.ts +22 -7
- package/src/tui-compiled/common-auth-embedded/logger/capture-sink.js +13 -0
- package/src/tui-compiled/common-auth-embedded/logger/engine.js +246 -0
- package/src/tui-compiled/common-auth-embedded/logger/index.js +3 -0
- package/src/tui-compiled/common-auth-embedded/logger/redact.js +83 -0
- package/src/tui-compiled/common-auth-embedded/quota/codec.js +12 -0
- package/src/tui-compiled/common-auth-embedded/quota/format.js +138 -0
- package/src/tui-compiled/common-auth-embedded/quota/index.js +5 -0
- package/src/tui-compiled/common-auth-embedded/quota/map.js +105 -0
- package/src/tui-compiled/common-auth-embedded/quota/merge.js +162 -0
- package/src/tui-compiled/common-auth-embedded/quota/projection.js +134 -0
- package/src/tui-compiled/common-auth-embedded/rpc/client.js +2 -0
- package/src/tui-compiled/common-auth-embedded/rpc/port-file.js +217 -0
- package/src/tui-compiled/common-auth-embedded/rpc/rpc-client.js +253 -0
- package/src/tui-compiled/logging/provider-key-policy.js +3 -0
- package/src/tui-compiled/quota-presentation.js +42 -0
- package/src/tui-compiled/rpc/rpc-client.js +35 -0
- package/src/tui-compiled/rpc/rpc-dir.js +13 -0
- package/src/tui-compiled/selector.js +21 -0
- package/src/tui-compiled/sidebar-state.js +401 -0
- package/src/tui-compiled/tui/command-dialogs.js +424 -0
- package/src/tui-compiled/tui/file-logger.js +73 -0
- package/src/tui-compiled/tui/host-api.js +269 -0
- package/src/tui-compiled/tui/host-v1.js +228 -0
- package/src/tui-compiled/tui-preferences.js +230 -0
- package/src/tui-compiled/{tui.tsx → tui.js} +140 -231
- package/src/tui-ga-compiled/host-ga.js +1304 -0
- package/src/tui-ga-compiled/selector.js +21 -0
- package/src/tui-ga-compiled/shared/07365a7d2ccade4c-host-api.js +269 -0
- package/src/tui-ga-compiled/shared/0e19a88ff3535906-command-dialogs.js +424 -0
- package/src/tui-ga-compiled/shared/1ff34afa7c42d196-projection.js +134 -0
- package/src/tui-ga-compiled/shared/77138df80c7ae006-map.js +105 -0
- package/src/tui-ga-compiled/shared/8ae1927e5910ea81-sidebar-projection.js +112 -0
- package/src/tui-ga-compiled/shared/98cc0c186c46c42d-quota-presentation.js +42 -0
- package/src/tui-ga-compiled/shared/aef2402f8fc342f0-format.js +138 -0
- package/src/tui-ga-compiled/shared/bf17cbee28e58197-index.js +5 -0
- package/src/tui-ga-compiled/shared/ca21dc417b36dc5d-codec.js +12 -0
- package/src/tui-ga-compiled/shared/ecc214300932dfb6-merge.js +162 -0
- package/src/tui-ga-raw/host-ga.tsx +1740 -0
- package/src/tui-ga-raw/selector.js +21 -0
- package/src/tui-ga-raw/shared/07365a7d2ccade4c-host-api.js +269 -0
- package/src/tui-ga-raw/shared/0e19a88ff3535906-command-dialogs.tsx +468 -0
- package/src/tui-ga-raw/shared/1ff34afa7c42d196-projection.js +134 -0
- package/src/tui-ga-raw/shared/77138df80c7ae006-map.js +105 -0
- package/src/tui-ga-raw/shared/8ae1927e5910ea81-sidebar-projection.js +112 -0
- package/src/tui-ga-raw/shared/98cc0c186c46c42d-quota-presentation.js +42 -0
- package/src/tui-ga-raw/shared/aef2402f8fc342f0-format.js +138 -0
- package/src/tui-ga-raw/shared/bf17cbee28e58197-index.js +5 -0
- package/src/tui-ga-raw/shared/ca21dc417b36dc5d-codec.js +12 -0
- package/src/tui-ga-raw/shared/ecc214300932dfb6-merge.js +162 -0
- package/src/tui-raw/common-auth-embedded/logger/capture-sink.js +13 -0
- package/src/tui-raw/common-auth-embedded/logger/engine.js +246 -0
- package/src/tui-raw/common-auth-embedded/logger/index.js +3 -0
- package/src/tui-raw/common-auth-embedded/logger/redact.js +83 -0
- package/src/tui-raw/common-auth-embedded/quota/codec.js +12 -0
- package/src/tui-raw/common-auth-embedded/quota/format.js +138 -0
- package/src/tui-raw/common-auth-embedded/quota/index.js +5 -0
- package/src/tui-raw/common-auth-embedded/quota/map.js +105 -0
- package/src/tui-raw/common-auth-embedded/quota/merge.js +162 -0
- package/src/tui-raw/common-auth-embedded/quota/projection.js +134 -0
- package/src/tui-raw/common-auth-embedded/rpc/client.js +2 -0
- package/src/tui-raw/common-auth-embedded/rpc/port-file.js +217 -0
- package/src/tui-raw/common-auth-embedded/rpc/rpc-client.js +253 -0
- package/src/tui-raw/logging/provider-key-policy.js +3 -0
- package/src/tui-raw/quota-presentation.js +42 -0
- package/src/tui-raw/rpc/rpc-client.js +35 -0
- package/src/tui-raw/rpc/rpc-dir.js +13 -0
- package/src/tui-raw/selector.js +21 -0
- package/src/tui-raw/sidebar-state.js +401 -0
- package/src/tui-raw/tui/command-dialogs.tsx +468 -0
- package/src/tui-raw/tui/file-logger.js +73 -0
- package/src/tui-raw/tui/host-api.js +269 -0
- package/src/tui-raw/tui/host-v1.tsx +249 -0
- package/src/tui-raw/tui-preferences.js +230 -0
- package/src/tui-raw/tui.tsx +1088 -0
- package/src/tui.tsx +58 -141
- package/tui.js +6 -0
- package/src/tui-compiled/plugin/command-data.ts +0 -931
- package/src/tui-compiled/rpc/port-file.ts +0 -143
- package/src/tui-compiled/rpc/protocol.ts +0 -31
- package/src/tui-compiled/rpc/rpc-client.ts +0 -102
- package/src/tui-compiled/rpc/rpc-dir.ts +0 -24
- package/src/tui-compiled/sidebar-state.ts +0 -991
- package/src/tui-compiled/tui/command-dialogs.tsx +0 -779
- package/src/tui-compiled/tui/file-logger.ts +0 -145
- package/src/tui-compiled/tui-preferences.ts +0 -416
|
@@ -0,0 +1,1740 @@
|
|
|
1
|
+
/** @jsxImportSource @opentui/solid */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenCode GA adapter for the shared `/antigravity` drawer and sidebar.
|
|
5
|
+
*
|
|
6
|
+
* Everything goes through the host's native location RPC: the server plugin
|
|
7
|
+
* registers `antigravity-auth` (version 1) with the methods `state` and
|
|
8
|
+
* `apply` at its location, and this adapter calls them with the host
|
|
9
|
+
* client's `rpc.call`, naming the location explicitly. There is no port
|
|
10
|
+
* file, no PID discovery, no private HTTP port and no sidebar file here.
|
|
11
|
+
*
|
|
12
|
+
* Contract rules this client keeps (the server enforces the same ones):
|
|
13
|
+
*
|
|
14
|
+
* - Generation: the first `state` sends `generation: null`; every later call
|
|
15
|
+
* sends the generation the server last answered with. When the server
|
|
16
|
+
* answers with a different one (`reset: 'generation-changed'`) the client
|
|
17
|
+
* rebinds: every scope's cursor restarts at 0. An `apply` answered with
|
|
18
|
+
* `stale-generation` or `disposed` changed nothing; the drawer says so and
|
|
19
|
+
* the next `state` rebinds.
|
|
20
|
+
* - Scope: the current session (`{ kind: 'session', sessionID }`) or the
|
|
21
|
+
* sessionless scope on the home screen. Each scope has its own cursor. A
|
|
22
|
+
* drawer applies in the scope its menu arrived in, never the scope that
|
|
23
|
+
* happens to be current when the user chooses.
|
|
24
|
+
* - Cursor: the client sends the highest cursor it has handled; the answer
|
|
25
|
+
* holds the next notifications and the cursor to send next.
|
|
26
|
+
* - Disposal: after cleanup, or after the client rebinds, an answer to a
|
|
27
|
+
* request sent earlier is dropped unread, so a late completion can never
|
|
28
|
+
* open a dialog, show a toast or change the sidebar.
|
|
29
|
+
*
|
|
30
|
+
* Every answer is validated field by field before use; an answer that does
|
|
31
|
+
* not match is refused and logged by field name only.
|
|
32
|
+
*
|
|
33
|
+
* The wire shapes mirror the facade's `ga/rpc/protocol.ts` (clean v1:
|
|
34
|
+
* accounts carry opaque `selector`s, typed account actions name accounts
|
|
35
|
+
* only by selector, every snapshot carries the location's settings). GA
|
|
36
|
+
* notifications name a dialog command only, so this host builds the
|
|
37
|
+
* `/antigravity` menu from the latest snapshot and the shared drawer renders
|
|
38
|
+
* it; after every apply the menu is rebuilt from a fresh `state` read.
|
|
39
|
+
*
|
|
40
|
+
* Nothing here imports account storage, tokens, OAuth, the vault client or
|
|
41
|
+
* server code, and nothing writes to the terminal or forces a theme.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
import { createSignal, For, type JSX, Show } from "solid-js"
|
|
45
|
+
import {
|
|
46
|
+
type ProjectedSidebar,
|
|
47
|
+
type ProjectionAccount,
|
|
48
|
+
type ProjectionRoute,
|
|
49
|
+
type ProjectionStatus,
|
|
50
|
+
projectAccount,
|
|
51
|
+
projectSidebar,
|
|
52
|
+
} from "./shared/8ae1927e5910ea81-sidebar-projection.js"
|
|
53
|
+
import {
|
|
54
|
+
MenuRefusedError,
|
|
55
|
+
openAntigravityMenu,
|
|
56
|
+
} from "./shared/0e19a88ff3535906-command-dialogs.tsx"
|
|
57
|
+
import {
|
|
58
|
+
ANTIGRAVITY_MENU_COMMAND,
|
|
59
|
+
ANTIGRAVITY_MENU_TITLE,
|
|
60
|
+
type MenuAction,
|
|
61
|
+
type MenuApplyRequest,
|
|
62
|
+
type MenuApplyResult,
|
|
63
|
+
type MenuModel,
|
|
64
|
+
type MenuParseResult,
|
|
65
|
+
type MenuSection,
|
|
66
|
+
type MenuUi,
|
|
67
|
+
} from "./shared/07365a7d2ccade4c-host-api.js"
|
|
68
|
+
|
|
69
|
+
export const GA_TUI_ID = 'cortexkit.antigravity-auth' as const
|
|
70
|
+
export const GA_RPC_ID = 'antigravity-auth' as const
|
|
71
|
+
export const GA_RPC_VERSION = 1 as const
|
|
72
|
+
|
|
73
|
+
/** How often the TUI pulls state and notifications from its location. */
|
|
74
|
+
export const GA_SIDEBAR_PULL_MS = 1_000
|
|
75
|
+
|
|
76
|
+
/** Pulls in one tick while the server reports more notifications waiting. */
|
|
77
|
+
const MAX_PULLS_PER_TICK = 4
|
|
78
|
+
|
|
79
|
+
// ── Host surface (structural subset of the GA TUI context) ─────────────────
|
|
80
|
+
|
|
81
|
+
export interface GaLocationRef {
|
|
82
|
+
readonly directory: string
|
|
83
|
+
readonly workspaceID?: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface GaRpcCallInput {
|
|
87
|
+
readonly rpcID: string
|
|
88
|
+
readonly method: string
|
|
89
|
+
readonly location?: GaLocationRef
|
|
90
|
+
readonly input: unknown
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface GaSelectOption {
|
|
94
|
+
readonly title: string
|
|
95
|
+
readonly value: string
|
|
96
|
+
readonly description?: string
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type GaRoute =
|
|
100
|
+
| { readonly type: 'home' }
|
|
101
|
+
| { readonly type: 'session'; readonly sessionID: string }
|
|
102
|
+
| { readonly type: 'plugin'; readonly id: string; readonly name: string }
|
|
103
|
+
|
|
104
|
+
export interface GaSlotClaim {
|
|
105
|
+
readonly append: 'sidebar.content'
|
|
106
|
+
readonly render: (input: { readonly sessionID: string }) => JSX.Element
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The parts of the GA TUI `Context` this adapter uses. */
|
|
110
|
+
export interface GaTuiContext {
|
|
111
|
+
readonly location: GaLocationRef | undefined
|
|
112
|
+
readonly client: {
|
|
113
|
+
readonly rpc: {
|
|
114
|
+
call(input: GaRpcCallInput): Promise<unknown>
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
readonly renderer?: { copyToClipboardOSC52?(text: string): boolean }
|
|
118
|
+
readonly ui: {
|
|
119
|
+
readonly dialog: {
|
|
120
|
+
set(options: { readonly size?: 'medium' | 'large' | 'xlarge' }): void
|
|
121
|
+
clear(): void
|
|
122
|
+
alert(options: {
|
|
123
|
+
readonly title: string
|
|
124
|
+
readonly message: string
|
|
125
|
+
}): Promise<void>
|
|
126
|
+
confirm(options: {
|
|
127
|
+
readonly title: string
|
|
128
|
+
readonly message: string
|
|
129
|
+
}): Promise<boolean | undefined>
|
|
130
|
+
prompt(options: {
|
|
131
|
+
readonly title: string
|
|
132
|
+
readonly description?: string
|
|
133
|
+
readonly placeholder?: string
|
|
134
|
+
readonly value?: string
|
|
135
|
+
}): Promise<string | undefined>
|
|
136
|
+
select<Value>(options: {
|
|
137
|
+
readonly title: string
|
|
138
|
+
readonly options: readonly {
|
|
139
|
+
readonly title: string
|
|
140
|
+
readonly value: Value
|
|
141
|
+
readonly description?: string
|
|
142
|
+
readonly category?: string
|
|
143
|
+
readonly footer?: string
|
|
144
|
+
}[]
|
|
145
|
+
readonly current?: Value
|
|
146
|
+
}): Promise<Value | undefined>
|
|
147
|
+
}
|
|
148
|
+
readonly toast: {
|
|
149
|
+
show(options: {
|
|
150
|
+
readonly message: string
|
|
151
|
+
readonly variant?: 'info' | 'success' | 'warning' | 'error'
|
|
152
|
+
}): void
|
|
153
|
+
}
|
|
154
|
+
readonly router: { current(): GaRoute }
|
|
155
|
+
readonly slot: (claim: GaSlotClaim) => () => void
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface GaLogger {
|
|
160
|
+
warn(message: string, detail?: Record<string, unknown>): void
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ── Wire shapes ─────────────────────────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
export type GaScope =
|
|
166
|
+
| { readonly kind: 'session'; readonly sessionID: string }
|
|
167
|
+
| { readonly kind: 'sessionless' }
|
|
168
|
+
|
|
169
|
+
/** The dialog commands the server names in notifications and text applies. */
|
|
170
|
+
export const GA_COMMANDS = [
|
|
171
|
+
'antigravity-quota',
|
|
172
|
+
'antigravity-account',
|
|
173
|
+
'antigravity-routing',
|
|
174
|
+
'antigravity-killswitch',
|
|
175
|
+
'antigravity-dump',
|
|
176
|
+
'antigravity-logging',
|
|
177
|
+
] as const
|
|
178
|
+
export type GaCommand = (typeof GA_COMMANDS)[number]
|
|
179
|
+
|
|
180
|
+
export const GA_LOG_LEVELS = [
|
|
181
|
+
'error',
|
|
182
|
+
'warn',
|
|
183
|
+
'info',
|
|
184
|
+
'debug',
|
|
185
|
+
'trace',
|
|
186
|
+
] as const
|
|
187
|
+
export type GaLogLevel = (typeof GA_LOG_LEVELS)[number]
|
|
188
|
+
|
|
189
|
+
export interface GaNotification {
|
|
190
|
+
readonly cursor: number
|
|
191
|
+
readonly type: 'open-dialog'
|
|
192
|
+
readonly command: GaCommand
|
|
193
|
+
readonly text: string
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** A redacted account plus the opaque selector that names its credential. */
|
|
197
|
+
export interface GaAccount extends ProjectionAccount {
|
|
198
|
+
readonly selector: string
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** The location's operator settings, read fresh for every `state` answer. */
|
|
202
|
+
export interface GaSettings {
|
|
203
|
+
readonly routing: {
|
|
204
|
+
readonly cliFirst: boolean
|
|
205
|
+
readonly quotaStyleFallback: boolean
|
|
206
|
+
}
|
|
207
|
+
readonly killswitch: {
|
|
208
|
+
readonly enabled: boolean
|
|
209
|
+
readonly minimumRemainingPercent: number
|
|
210
|
+
}
|
|
211
|
+
readonly logLevel: GaLogLevel
|
|
212
|
+
readonly dump: { readonly enabled: boolean }
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export type GaAccountsStatus =
|
|
216
|
+
| { readonly kind: 'complete' }
|
|
217
|
+
| { readonly kind: 'over-limit'; readonly count: number; readonly limit: 64 }
|
|
218
|
+
|
|
219
|
+
export interface GaSnapshot {
|
|
220
|
+
readonly kind: 'snapshot'
|
|
221
|
+
readonly generation: string
|
|
222
|
+
readonly scope: GaScope
|
|
223
|
+
readonly reset: 'initial' | 'generation-changed' | 'cursor-ahead' | null
|
|
224
|
+
readonly cursor: number
|
|
225
|
+
readonly dropped: number
|
|
226
|
+
readonly more: boolean
|
|
227
|
+
readonly notifications: readonly GaNotification[]
|
|
228
|
+
readonly readSeq: number
|
|
229
|
+
readonly accountsStatus: GaAccountsStatus
|
|
230
|
+
readonly accounts: readonly GaAccount[]
|
|
231
|
+
readonly route: ProjectionRoute | null
|
|
232
|
+
readonly status: ProjectionStatus & { readonly routingAuthoritative: boolean }
|
|
233
|
+
readonly settings: GaSettings
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export type GaStateOutput =
|
|
237
|
+
| GaSnapshot
|
|
238
|
+
| { readonly kind: 'disposed'; readonly generation: string }
|
|
239
|
+
|
|
240
|
+
/** A typed account action; accounts are named only by selector. */
|
|
241
|
+
export type GaAccountAction =
|
|
242
|
+
| {
|
|
243
|
+
readonly kind: 'select'
|
|
244
|
+
readonly selector: string
|
|
245
|
+
readonly target: 'active' | 'claude' | 'gemini'
|
|
246
|
+
}
|
|
247
|
+
| { readonly kind: 'enable'; readonly selector: string }
|
|
248
|
+
| { readonly kind: 'disable'; readonly selector: string }
|
|
249
|
+
| { readonly kind: 'remove'; readonly selector: string }
|
|
250
|
+
|
|
251
|
+
/** What the client sends besides version, generation and scope. */
|
|
252
|
+
export type GaApplyBody =
|
|
253
|
+
| { readonly command: GaCommand; readonly arguments: string }
|
|
254
|
+
| {
|
|
255
|
+
readonly command: 'antigravity-account'
|
|
256
|
+
readonly action: GaAccountAction
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export type GaTargetOutcome =
|
|
260
|
+
| 'applied'
|
|
261
|
+
| 'stale-target'
|
|
262
|
+
| 'unknown-target'
|
|
263
|
+
| 'unsupported-index-action'
|
|
264
|
+
| 'failed'
|
|
265
|
+
|
|
266
|
+
/** The command result fields this TUI reads; the rest are validated only. */
|
|
267
|
+
export interface GaCommandResult {
|
|
268
|
+
readonly command: GaCommand
|
|
269
|
+
readonly status: 'applied' | 'rejected' | 'failed'
|
|
270
|
+
readonly text: string
|
|
271
|
+
readonly authorizationUrl?: string | null
|
|
272
|
+
readonly targetOutcome?: GaTargetOutcome | null
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export type GaApplyOutput =
|
|
276
|
+
| {
|
|
277
|
+
readonly kind: 'applied'
|
|
278
|
+
readonly generation: string
|
|
279
|
+
readonly scope: GaScope
|
|
280
|
+
readonly result: GaCommandResult
|
|
281
|
+
}
|
|
282
|
+
| { readonly kind: 'stale-generation'; readonly generation: string }
|
|
283
|
+
| { readonly kind: 'disposed'; readonly generation: string }
|
|
284
|
+
|
|
285
|
+
const GENERATION = /^[A-Za-z0-9_-]{1,64}$/
|
|
286
|
+
const SESSION_ID = /^[\x21-\x7e]{1,256}$/
|
|
287
|
+
const ACCOUNT_ID = /^acct-(0|[1-9][0-9]{0,5})$/
|
|
288
|
+
const ACCOUNT_LABEL = /^Account [1-9][0-9]{0,5}$/
|
|
289
|
+
const SELECTOR = /^sel-[A-Za-z0-9_-]{32}$/
|
|
290
|
+
const TARGET_OUTCOMES: readonly GaTargetOutcome[] = [
|
|
291
|
+
'applied',
|
|
292
|
+
'stale-target',
|
|
293
|
+
'unknown-target',
|
|
294
|
+
'unsupported-index-action',
|
|
295
|
+
'failed',
|
|
296
|
+
]
|
|
297
|
+
|
|
298
|
+
type Issues = string[]
|
|
299
|
+
|
|
300
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
301
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
302
|
+
return false
|
|
303
|
+
}
|
|
304
|
+
const proto = Object.getPrototypeOf(value)
|
|
305
|
+
return proto === Object.prototype || proto === null
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function keys(
|
|
309
|
+
record: Record<string, unknown>,
|
|
310
|
+
required: readonly string[],
|
|
311
|
+
optional: readonly string[],
|
|
312
|
+
path: string,
|
|
313
|
+
issues: Issues,
|
|
314
|
+
): void {
|
|
315
|
+
for (const key of Object.keys(record)) {
|
|
316
|
+
if (!required.includes(key) && !optional.includes(key)) {
|
|
317
|
+
issues.push(`${path}.${key}: unexpected field`)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
for (const key of required) {
|
|
321
|
+
if (!(key in record)) issues.push(`${path}.${key}: missing`)
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function isCursor(value: unknown): value is number {
|
|
326
|
+
return (
|
|
327
|
+
typeof value === 'number' &&
|
|
328
|
+
Number.isSafeInteger(value) &&
|
|
329
|
+
value >= 0 &&
|
|
330
|
+
!Object.is(value, -0)
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function isTime(value: unknown): value is number {
|
|
335
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function checkVersion(
|
|
339
|
+
record: Record<string, unknown>,
|
|
340
|
+
path: string,
|
|
341
|
+
issues: Issues,
|
|
342
|
+
) {
|
|
343
|
+
if (record.version !== GA_RPC_VERSION)
|
|
344
|
+
issues.push(`${path}.version: unsupported`)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function checkGeneration(value: unknown, path: string, issues: Issues) {
|
|
348
|
+
if (typeof value !== 'string' || !GENERATION.test(value)) {
|
|
349
|
+
issues.push(`${path}: expected a generation token`)
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function checkScope(value: unknown, path: string, issues: Issues) {
|
|
354
|
+
if (!isRecord(value)) {
|
|
355
|
+
issues.push(`${path}: expected a scope`)
|
|
356
|
+
return
|
|
357
|
+
}
|
|
358
|
+
if (value.kind === 'sessionless') {
|
|
359
|
+
keys(value, ['kind'], [], path, issues)
|
|
360
|
+
return
|
|
361
|
+
}
|
|
362
|
+
if (value.kind === 'session') {
|
|
363
|
+
keys(value, ['kind', 'sessionID'], [], path, issues)
|
|
364
|
+
if (
|
|
365
|
+
typeof value.sessionID !== 'string' ||
|
|
366
|
+
!SESSION_ID.test(value.sessionID)
|
|
367
|
+
) {
|
|
368
|
+
issues.push(`${path}.sessionID: expected a session id`)
|
|
369
|
+
}
|
|
370
|
+
return
|
|
371
|
+
}
|
|
372
|
+
issues.push(`${path}.kind: unknown scope`)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function checkPercent(value: unknown, path: string, issues: Issues) {
|
|
376
|
+
if (
|
|
377
|
+
typeof value !== 'number' ||
|
|
378
|
+
!Number.isFinite(value) ||
|
|
379
|
+
value < 0 ||
|
|
380
|
+
value > 100
|
|
381
|
+
) {
|
|
382
|
+
issues.push(`${path}: expected a percentage`)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function checkQuotaEntry(value: unknown, path: string, issues: Issues) {
|
|
387
|
+
if (value === undefined) return
|
|
388
|
+
if (!isRecord(value)) {
|
|
389
|
+
issues.push(`${path}: expected a quota reading`)
|
|
390
|
+
return
|
|
391
|
+
}
|
|
392
|
+
keys(
|
|
393
|
+
value,
|
|
394
|
+
['remainingPercent'],
|
|
395
|
+
['resetAt', 'windows', 'checkedAt'],
|
|
396
|
+
path,
|
|
397
|
+
issues,
|
|
398
|
+
)
|
|
399
|
+
checkPercent(value.remainingPercent, `${path}.remainingPercent`, issues)
|
|
400
|
+
if (value.resetAt !== undefined && !isTime(value.resetAt)) {
|
|
401
|
+
issues.push(`${path}.resetAt: expected a time`)
|
|
402
|
+
}
|
|
403
|
+
if (value.checkedAt !== undefined && !isTime(value.checkedAt))
|
|
404
|
+
issues.push(`${path}.checkedAt: expected a time`)
|
|
405
|
+
if (value.windows === undefined) return
|
|
406
|
+
if (!Array.isArray(value.windows) || value.windows.length > 4) {
|
|
407
|
+
issues.push(`${path}.windows: expected at most four windows`)
|
|
408
|
+
return
|
|
409
|
+
}
|
|
410
|
+
value.windows.forEach((window, index) => {
|
|
411
|
+
const at = `${path}.windows.${index}`
|
|
412
|
+
if (!isRecord(window)) {
|
|
413
|
+
issues.push(`${at}: expected a window`)
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
keys(
|
|
417
|
+
window,
|
|
418
|
+
['window', 'remainingPercent'],
|
|
419
|
+
['resetAt', 'checkedAt'],
|
|
420
|
+
at,
|
|
421
|
+
issues,
|
|
422
|
+
)
|
|
423
|
+
if (window.window !== 'weekly' && window.window !== '5h') {
|
|
424
|
+
issues.push(`${at}.window: unknown window`)
|
|
425
|
+
}
|
|
426
|
+
if (window.checkedAt !== undefined && !isTime(window.checkedAt))
|
|
427
|
+
issues.push(`${at}.checkedAt: expected a time`)
|
|
428
|
+
checkPercent(window.remainingPercent, `${at}.remainingPercent`, issues)
|
|
429
|
+
if (window.resetAt !== undefined && !isTime(window.resetAt)) {
|
|
430
|
+
issues.push(`${at}.resetAt: expected a time`)
|
|
431
|
+
}
|
|
432
|
+
})
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* One redacted account. The field list is closed: an email, token, project
|
|
437
|
+
* id or fingerprint arrives as an unexpected field and the whole answer is
|
|
438
|
+
* refused.
|
|
439
|
+
*/
|
|
440
|
+
function checkAccount(value: unknown, path: string, issues: Issues) {
|
|
441
|
+
if (!isRecord(value)) {
|
|
442
|
+
issues.push(`${path}: expected an account`)
|
|
443
|
+
return
|
|
444
|
+
}
|
|
445
|
+
keys(
|
|
446
|
+
value,
|
|
447
|
+
['selector', 'id', 'label', 'enabled', 'health', 'current', 'quota'],
|
|
448
|
+
['cooldownUntil', 'tier'],
|
|
449
|
+
path,
|
|
450
|
+
issues,
|
|
451
|
+
)
|
|
452
|
+
if (typeof value.selector !== 'string' || !SELECTOR.test(value.selector)) {
|
|
453
|
+
issues.push(`${path}.selector: expected an opaque selector`)
|
|
454
|
+
}
|
|
455
|
+
if (typeof value.id !== 'string' || !ACCOUNT_ID.test(value.id)) {
|
|
456
|
+
issues.push(`${path}.id: expected an ordinal account id`)
|
|
457
|
+
}
|
|
458
|
+
if (typeof value.label !== 'string' || !ACCOUNT_LABEL.test(value.label)) {
|
|
459
|
+
issues.push(`${path}.label: expected an ordinal account label`)
|
|
460
|
+
}
|
|
461
|
+
if (typeof value.enabled !== 'boolean')
|
|
462
|
+
issues.push(`${path}.enabled: expected true/false`)
|
|
463
|
+
if (typeof value.current !== 'boolean')
|
|
464
|
+
issues.push(`${path}.current: expected true/false`)
|
|
465
|
+
checkPercent(value.health, `${path}.health`, issues)
|
|
466
|
+
if (value.cooldownUntil !== undefined && !isTime(value.cooldownUntil)) {
|
|
467
|
+
issues.push(`${path}.cooldownUntil: expected a time`)
|
|
468
|
+
}
|
|
469
|
+
if (!isRecord(value.quota)) {
|
|
470
|
+
issues.push(`${path}.quota: expected quota readings`)
|
|
471
|
+
} else {
|
|
472
|
+
keys(value.quota, [], ['gemini', 'non-gemini'], `${path}.quota`, issues)
|
|
473
|
+
checkQuotaEntry(value.quota.gemini, `${path}.quota.gemini`, issues)
|
|
474
|
+
checkQuotaEntry(
|
|
475
|
+
value.quota['non-gemini'],
|
|
476
|
+
`${path}.quota.non-gemini`,
|
|
477
|
+
issues,
|
|
478
|
+
)
|
|
479
|
+
}
|
|
480
|
+
if (value.tier !== undefined) {
|
|
481
|
+
const tier = value.tier
|
|
482
|
+
if (!isRecord(tier)) {
|
|
483
|
+
issues.push(`${path}.tier: expected a plan tier`)
|
|
484
|
+
} else {
|
|
485
|
+
keys(tier, ['id', 'capturedAt'], ['paidId'], `${path}.tier`, issues)
|
|
486
|
+
if (typeof tier.id !== 'string')
|
|
487
|
+
issues.push(`${path}.tier.id: expected text`)
|
|
488
|
+
if (tier.paidId !== undefined && typeof tier.paidId !== 'string') {
|
|
489
|
+
issues.push(`${path}.tier.paidId: expected text`)
|
|
490
|
+
}
|
|
491
|
+
if (!isTime(tier.capturedAt))
|
|
492
|
+
issues.push(`${path}.tier.capturedAt: expected a time`)
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function checkRoute(value: unknown, path: string, issues: Issues) {
|
|
498
|
+
if (value === null) return
|
|
499
|
+
if (!isRecord(value)) {
|
|
500
|
+
issues.push(`${path}: expected a route`)
|
|
501
|
+
return
|
|
502
|
+
}
|
|
503
|
+
keys(
|
|
504
|
+
value,
|
|
505
|
+
['accountId', 'modelFamily', 'headerStyle', 'strategy', 'updatedAt'],
|
|
506
|
+
[],
|
|
507
|
+
path,
|
|
508
|
+
issues,
|
|
509
|
+
)
|
|
510
|
+
if (
|
|
511
|
+
typeof value.accountId !== 'string' ||
|
|
512
|
+
!ACCOUNT_ID.test(value.accountId)
|
|
513
|
+
) {
|
|
514
|
+
issues.push(`${path}.accountId: expected an ordinal account id`)
|
|
515
|
+
}
|
|
516
|
+
if (value.modelFamily !== 'claude' && value.modelFamily !== 'gemini') {
|
|
517
|
+
issues.push(`${path}.modelFamily: unknown family`)
|
|
518
|
+
}
|
|
519
|
+
if (
|
|
520
|
+
value.headerStyle !== 'antigravity' &&
|
|
521
|
+
value.headerStyle !== 'gemini-cli'
|
|
522
|
+
) {
|
|
523
|
+
issues.push(`${path}.headerStyle: unknown header style`)
|
|
524
|
+
}
|
|
525
|
+
if (
|
|
526
|
+
value.strategy !== null &&
|
|
527
|
+
value.strategy !== 'sticky' &&
|
|
528
|
+
value.strategy !== 'round-robin' &&
|
|
529
|
+
value.strategy !== 'hybrid'
|
|
530
|
+
) {
|
|
531
|
+
issues.push(`${path}.strategy: unknown strategy`)
|
|
532
|
+
}
|
|
533
|
+
if (!isTime(value.updatedAt))
|
|
534
|
+
issues.push(`${path}.updatedAt: expected a time`)
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
function checkStatus(value: unknown, path: string, issues: Issues) {
|
|
538
|
+
if (!isRecord(value)) {
|
|
539
|
+
issues.push(`${path}: expected a status`)
|
|
540
|
+
return
|
|
541
|
+
}
|
|
542
|
+
keys(
|
|
543
|
+
value,
|
|
544
|
+
['checkedAt', 'quotaBackoffUntil', 'routingAuthoritative'],
|
|
545
|
+
[],
|
|
546
|
+
path,
|
|
547
|
+
issues,
|
|
548
|
+
)
|
|
549
|
+
if (value.checkedAt !== null && !isTime(value.checkedAt)) {
|
|
550
|
+
issues.push(`${path}.checkedAt: expected a time or null`)
|
|
551
|
+
}
|
|
552
|
+
if (value.quotaBackoffUntil !== null && !isTime(value.quotaBackoffUntil)) {
|
|
553
|
+
issues.push(`${path}.quotaBackoffUntil: expected a time or null`)
|
|
554
|
+
}
|
|
555
|
+
if (typeof value.routingAuthoritative !== 'boolean') {
|
|
556
|
+
issues.push(`${path}.routingAuthoritative: expected true/false`)
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function checkNotification(value: unknown, path: string, issues: Issues) {
|
|
561
|
+
if (!isRecord(value)) {
|
|
562
|
+
issues.push(`${path}: expected a notification`)
|
|
563
|
+
return
|
|
564
|
+
}
|
|
565
|
+
keys(value, ['cursor', 'type', 'command', 'text'], [], path, issues)
|
|
566
|
+
if (!isCursor(value.cursor) || value.cursor < 1) {
|
|
567
|
+
issues.push(`${path}.cursor: expected a positive cursor`)
|
|
568
|
+
}
|
|
569
|
+
if (value.type !== 'open-dialog') {
|
|
570
|
+
issues.push(`${path}.type: unknown notification type`)
|
|
571
|
+
}
|
|
572
|
+
if (!GA_COMMANDS.includes(value.command as GaCommand)) {
|
|
573
|
+
issues.push(`${path}.command: unknown command`)
|
|
574
|
+
}
|
|
575
|
+
if (typeof value.text !== 'string') issues.push(`${path}.text: expected text`)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function checkBool(value: unknown, path: string, issues: Issues) {
|
|
579
|
+
if (typeof value !== 'boolean') issues.push(`${path}: expected true/false`)
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
function checkSettings(value: unknown, path: string, issues: Issues) {
|
|
583
|
+
if (!isRecord(value)) {
|
|
584
|
+
issues.push(`${path}: expected settings`)
|
|
585
|
+
return
|
|
586
|
+
}
|
|
587
|
+
keys(value, ['routing', 'killswitch', 'logLevel', 'dump'], [], path, issues)
|
|
588
|
+
const { routing, killswitch, dump } = value
|
|
589
|
+
if (!isRecord(routing)) issues.push(`${path}.routing: expected an object`)
|
|
590
|
+
else {
|
|
591
|
+
keys(
|
|
592
|
+
routing,
|
|
593
|
+
['cliFirst', 'quotaStyleFallback'],
|
|
594
|
+
[],
|
|
595
|
+
`${path}.routing`,
|
|
596
|
+
issues,
|
|
597
|
+
)
|
|
598
|
+
checkBool(routing.cliFirst, `${path}.routing.cliFirst`, issues)
|
|
599
|
+
checkBool(
|
|
600
|
+
routing.quotaStyleFallback,
|
|
601
|
+
`${path}.routing.quotaStyleFallback`,
|
|
602
|
+
issues,
|
|
603
|
+
)
|
|
604
|
+
}
|
|
605
|
+
if (!isRecord(killswitch))
|
|
606
|
+
issues.push(`${path}.killswitch: expected an object`)
|
|
607
|
+
else {
|
|
608
|
+
keys(
|
|
609
|
+
killswitch,
|
|
610
|
+
['enabled', 'minimumRemainingPercent'],
|
|
611
|
+
[],
|
|
612
|
+
`${path}.killswitch`,
|
|
613
|
+
issues,
|
|
614
|
+
)
|
|
615
|
+
checkBool(killswitch.enabled, `${path}.killswitch.enabled`, issues)
|
|
616
|
+
checkPercent(
|
|
617
|
+
killswitch.minimumRemainingPercent,
|
|
618
|
+
`${path}.killswitch.minimumRemainingPercent`,
|
|
619
|
+
issues,
|
|
620
|
+
)
|
|
621
|
+
}
|
|
622
|
+
if (!GA_LOG_LEVELS.includes(value.logLevel as GaLogLevel)) {
|
|
623
|
+
issues.push(`${path}.logLevel: unknown level`)
|
|
624
|
+
}
|
|
625
|
+
if (!isRecord(dump)) issues.push(`${path}.dump: expected an object`)
|
|
626
|
+
else {
|
|
627
|
+
keys(dump, ['enabled'], [], `${path}.dump`, issues)
|
|
628
|
+
checkBool(dump.enabled, `${path}.dump.enabled`, issues)
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
function checkAccountsStatus(value: unknown, path: string, issues: Issues) {
|
|
633
|
+
if (!isRecord(value)) {
|
|
634
|
+
issues.push(`${path}: expected an accounts status`)
|
|
635
|
+
return
|
|
636
|
+
}
|
|
637
|
+
if (value.kind === 'complete') {
|
|
638
|
+
keys(value, ['kind'], [], path, issues)
|
|
639
|
+
return
|
|
640
|
+
}
|
|
641
|
+
if (value.kind === 'over-limit') {
|
|
642
|
+
keys(value, ['kind', 'count', 'limit'], [], path, issues)
|
|
643
|
+
if (!isCursor(value.count)) issues.push(`${path}.count: expected a count`)
|
|
644
|
+
if (value.limit !== 64) issues.push(`${path}.limit: unexpected limit`)
|
|
645
|
+
return
|
|
646
|
+
}
|
|
647
|
+
issues.push(`${path}.kind: unknown accounts status`)
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function checkAccountList(value: unknown, path: string, issues: Issues) {
|
|
651
|
+
if (value === null) return
|
|
652
|
+
if (!Array.isArray(value) || value.length > 64) {
|
|
653
|
+
issues.push(`${path}: expected at most 64 accounts`)
|
|
654
|
+
return
|
|
655
|
+
}
|
|
656
|
+
value.forEach((entry, index) => {
|
|
657
|
+
checkAccount(entry, `${path}.${index}`, issues)
|
|
658
|
+
})
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/** One command result, with the closed field list of its command. */
|
|
662
|
+
function checkCommandResult(value: unknown, path: string, issues: Issues) {
|
|
663
|
+
if (!isRecord(value)) {
|
|
664
|
+
issues.push(`${path}: expected a command result`)
|
|
665
|
+
return
|
|
666
|
+
}
|
|
667
|
+
const base = ['command', 'status', 'text']
|
|
668
|
+
if (
|
|
669
|
+
value.status !== 'applied' &&
|
|
670
|
+
value.status !== 'rejected' &&
|
|
671
|
+
value.status !== 'failed'
|
|
672
|
+
) {
|
|
673
|
+
issues.push(`${path}.status: unknown status`)
|
|
674
|
+
}
|
|
675
|
+
if (typeof value.text !== 'string') issues.push(`${path}.text: expected text`)
|
|
676
|
+
switch (value.command) {
|
|
677
|
+
case 'antigravity-quota':
|
|
678
|
+
keys(value, [...base, 'accounts'], [], path, issues)
|
|
679
|
+
checkAccountList(value.accounts, `${path}.accounts`, issues)
|
|
680
|
+
return
|
|
681
|
+
case 'antigravity-account':
|
|
682
|
+
keys(
|
|
683
|
+
value,
|
|
684
|
+
[...base, 'accounts', 'authorizationUrl', 'targetOutcome'],
|
|
685
|
+
[],
|
|
686
|
+
path,
|
|
687
|
+
issues,
|
|
688
|
+
)
|
|
689
|
+
checkAccountList(value.accounts, `${path}.accounts`, issues)
|
|
690
|
+
if (
|
|
691
|
+
value.authorizationUrl !== null &&
|
|
692
|
+
!(
|
|
693
|
+
typeof value.authorizationUrl === 'string' &&
|
|
694
|
+
/^https:\/\//.test(value.authorizationUrl) &&
|
|
695
|
+
value.authorizationUrl.length <= 4096
|
|
696
|
+
)
|
|
697
|
+
) {
|
|
698
|
+
issues.push(`${path}.authorizationUrl: expected an https link or null`)
|
|
699
|
+
}
|
|
700
|
+
if (
|
|
701
|
+
value.targetOutcome !== null &&
|
|
702
|
+
!TARGET_OUTCOMES.includes(value.targetOutcome as GaTargetOutcome)
|
|
703
|
+
) {
|
|
704
|
+
issues.push(`${path}.targetOutcome: unknown outcome`)
|
|
705
|
+
}
|
|
706
|
+
return
|
|
707
|
+
case 'antigravity-routing':
|
|
708
|
+
keys(value, [...base, 'routing'], [], path, issues)
|
|
709
|
+
return
|
|
710
|
+
case 'antigravity-killswitch':
|
|
711
|
+
keys(value, [...base, 'killswitch'], [], path, issues)
|
|
712
|
+
return
|
|
713
|
+
case 'antigravity-dump':
|
|
714
|
+
keys(value, [...base, 'dump'], [], path, issues)
|
|
715
|
+
return
|
|
716
|
+
case 'antigravity-logging':
|
|
717
|
+
keys(value, [...base, 'logLevel'], [], path, issues)
|
|
718
|
+
return
|
|
719
|
+
default:
|
|
720
|
+
issues.push(`${path}.command: unknown command`)
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/** Unwraps the host's `{ output }` answer. */
|
|
725
|
+
function unwrap(raw: unknown, issues: Issues): unknown {
|
|
726
|
+
if (!isRecord(raw)) {
|
|
727
|
+
issues.push('answer: expected an object')
|
|
728
|
+
return undefined
|
|
729
|
+
}
|
|
730
|
+
keys(raw, ['output'], [], 'answer', issues)
|
|
731
|
+
return raw.output
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
function finish<T>(value: unknown, issues: Issues): MenuParseResult<T> {
|
|
735
|
+
return issues.length === 0
|
|
736
|
+
? { ok: true, value: value as T }
|
|
737
|
+
: { ok: false, issues }
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/** Validates a `state` answer (the host's `{ output }` wrapper included). */
|
|
741
|
+
export function parseGaStateAnswer(
|
|
742
|
+
raw: unknown,
|
|
743
|
+
): MenuParseResult<GaStateOutput> {
|
|
744
|
+
const issues: Issues = []
|
|
745
|
+
const output = unwrap(raw, issues)
|
|
746
|
+
if (issues.length > 0) return { ok: false, issues }
|
|
747
|
+
if (!isRecord(output))
|
|
748
|
+
return { ok: false, issues: ['output: expected an object'] }
|
|
749
|
+
checkVersion(output, 'output', issues)
|
|
750
|
+
if (output.kind === 'disposed') {
|
|
751
|
+
keys(output, ['version', 'kind', 'generation'], [], 'output', issues)
|
|
752
|
+
checkGeneration(output.generation, 'output.generation', issues)
|
|
753
|
+
return finish(output, issues)
|
|
754
|
+
}
|
|
755
|
+
if (output.kind !== 'snapshot') {
|
|
756
|
+
return { ok: false, issues: ['output.kind: unknown answer'] }
|
|
757
|
+
}
|
|
758
|
+
keys(
|
|
759
|
+
output,
|
|
760
|
+
[
|
|
761
|
+
'version',
|
|
762
|
+
'kind',
|
|
763
|
+
'generation',
|
|
764
|
+
'scope',
|
|
765
|
+
'reset',
|
|
766
|
+
'cursor',
|
|
767
|
+
'dropped',
|
|
768
|
+
'more',
|
|
769
|
+
'notifications',
|
|
770
|
+
'readSeq',
|
|
771
|
+
'accountsStatus',
|
|
772
|
+
'accounts',
|
|
773
|
+
'route',
|
|
774
|
+
'status',
|
|
775
|
+
'settings',
|
|
776
|
+
],
|
|
777
|
+
[],
|
|
778
|
+
'output',
|
|
779
|
+
issues,
|
|
780
|
+
)
|
|
781
|
+
if (!isCursor(output.readSeq)) issues.push('output.readSeq: expected a count')
|
|
782
|
+
checkAccountsStatus(output.accountsStatus, 'output.accountsStatus', issues)
|
|
783
|
+
checkSettings(output.settings, 'output.settings', issues)
|
|
784
|
+
checkGeneration(output.generation, 'output.generation', issues)
|
|
785
|
+
checkScope(output.scope, 'output.scope', issues)
|
|
786
|
+
if (
|
|
787
|
+
output.reset !== null &&
|
|
788
|
+
output.reset !== 'initial' &&
|
|
789
|
+
output.reset !== 'generation-changed' &&
|
|
790
|
+
output.reset !== 'cursor-ahead'
|
|
791
|
+
) {
|
|
792
|
+
issues.push('output.reset: unknown reset')
|
|
793
|
+
}
|
|
794
|
+
if (!isCursor(output.cursor)) issues.push('output.cursor: expected a cursor')
|
|
795
|
+
if (!isCursor(output.dropped)) issues.push('output.dropped: expected a count')
|
|
796
|
+
if (typeof output.more !== 'boolean')
|
|
797
|
+
issues.push('output.more: expected true/false')
|
|
798
|
+
if (
|
|
799
|
+
!Array.isArray(output.notifications) ||
|
|
800
|
+
output.notifications.length > 32
|
|
801
|
+
) {
|
|
802
|
+
issues.push('output.notifications: expected at most 32 notifications')
|
|
803
|
+
} else {
|
|
804
|
+
output.notifications.forEach((entry, index) => {
|
|
805
|
+
checkNotification(entry, `output.notifications.${index}`, issues)
|
|
806
|
+
})
|
|
807
|
+
}
|
|
808
|
+
if (!Array.isArray(output.accounts) || output.accounts.length > 64) {
|
|
809
|
+
issues.push('output.accounts: expected at most 64 accounts')
|
|
810
|
+
} else {
|
|
811
|
+
output.accounts.forEach((entry, index) => {
|
|
812
|
+
checkAccount(entry, `output.accounts.${index}`, issues)
|
|
813
|
+
})
|
|
814
|
+
}
|
|
815
|
+
checkRoute(output.route, 'output.route', issues)
|
|
816
|
+
checkStatus(output.status, 'output.status', issues)
|
|
817
|
+
return finish(output, issues)
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/** Validates an `apply` answer (the host's `{ output }` wrapper included). */
|
|
821
|
+
export function parseGaApplyAnswer(
|
|
822
|
+
raw: unknown,
|
|
823
|
+
): MenuParseResult<GaApplyOutput> {
|
|
824
|
+
const issues: Issues = []
|
|
825
|
+
const output = unwrap(raw, issues)
|
|
826
|
+
if (issues.length > 0) return { ok: false, issues }
|
|
827
|
+
if (!isRecord(output))
|
|
828
|
+
return { ok: false, issues: ['output: expected an object'] }
|
|
829
|
+
checkVersion(output, 'output', issues)
|
|
830
|
+
if (output.kind === 'stale-generation' || output.kind === 'disposed') {
|
|
831
|
+
keys(output, ['version', 'kind', 'generation'], [], 'output', issues)
|
|
832
|
+
checkGeneration(output.generation, 'output.generation', issues)
|
|
833
|
+
return finish(output, issues)
|
|
834
|
+
}
|
|
835
|
+
if (output.kind !== 'applied') {
|
|
836
|
+
return { ok: false, issues: ['output.kind: unknown answer'] }
|
|
837
|
+
}
|
|
838
|
+
keys(
|
|
839
|
+
output,
|
|
840
|
+
['version', 'kind', 'generation', 'scope', 'result'],
|
|
841
|
+
[],
|
|
842
|
+
'output',
|
|
843
|
+
issues,
|
|
844
|
+
)
|
|
845
|
+
checkGeneration(output.generation, 'output.generation', issues)
|
|
846
|
+
checkScope(output.scope, 'output.scope', issues)
|
|
847
|
+
checkCommandResult(output.result, 'output.result', issues)
|
|
848
|
+
return finish(output, issues)
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// ── Location client ─────────────────────────────────────────────────────────
|
|
852
|
+
|
|
853
|
+
/** The server restarted or was disposed; the action did nothing. */
|
|
854
|
+
export class GaStaleError extends Error {
|
|
855
|
+
constructor(readonly reason: 'stale-generation' | 'disposed' | 'not-bound') {
|
|
856
|
+
super(
|
|
857
|
+
reason === 'not-bound'
|
|
858
|
+
? 'Antigravity auth is not connected at this location yet.'
|
|
859
|
+
: 'Antigravity auth restarted; nothing was changed. Reopen /antigravity.',
|
|
860
|
+
)
|
|
861
|
+
this.name = 'GaStaleError'
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/** This client was disposed; its answers are no longer read. */
|
|
866
|
+
export class GaClientDisposedError extends Error {
|
|
867
|
+
constructor() {
|
|
868
|
+
super('Antigravity TUI client disposed')
|
|
869
|
+
this.name = 'GaClientDisposedError'
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
export function scopeKey(scope: GaScope): string {
|
|
874
|
+
return scope.kind === 'session' ? `session:${scope.sessionID}` : 'sessionless'
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
export type GaPullResult =
|
|
878
|
+
| { readonly kind: 'snapshot'; readonly snapshot: GaSnapshot }
|
|
879
|
+
| { readonly kind: 'server-disposed' }
|
|
880
|
+
/** The answer arrived after a rebind or disposal and was dropped unread. */
|
|
881
|
+
| { readonly kind: 'dropped' }
|
|
882
|
+
|
|
883
|
+
export interface GaLocationClient {
|
|
884
|
+
/** The generation the client is bound to, or null before the first answer. */
|
|
885
|
+
generation(): string | null
|
|
886
|
+
/** The next cursor this client sends for `scope`. */
|
|
887
|
+
cursor(scope: GaScope): number
|
|
888
|
+
pull(scope: GaScope): Promise<GaPullResult>
|
|
889
|
+
apply(scope: GaScope, body: GaApplyBody): Promise<GaCommandResult>
|
|
890
|
+
dispose(): void
|
|
891
|
+
disposed(): boolean
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
export function createGaLocationClient(options: {
|
|
895
|
+
readonly call: (input: GaRpcCallInput) => Promise<unknown>
|
|
896
|
+
readonly location: GaLocationRef | undefined
|
|
897
|
+
readonly logger?: GaLogger
|
|
898
|
+
}): GaLocationClient {
|
|
899
|
+
let generation: string | null = null
|
|
900
|
+
const cursors = new Map<string, number>()
|
|
901
|
+
let isDisposed = false
|
|
902
|
+
// Bumped on every rebind and on disposal. A request remembers the epoch
|
|
903
|
+
// it was sent in; an answer from an older epoch is dropped unread.
|
|
904
|
+
let epoch = 0
|
|
905
|
+
|
|
906
|
+
const call = (method: 'state' | 'apply', input: unknown) =>
|
|
907
|
+
options.call({
|
|
908
|
+
rpcID: GA_RPC_ID,
|
|
909
|
+
method,
|
|
910
|
+
...(options.location ? { location: options.location } : {}),
|
|
911
|
+
input,
|
|
912
|
+
})
|
|
913
|
+
|
|
914
|
+
const rebind = (next: string | null) => {
|
|
915
|
+
if (next === generation) return
|
|
916
|
+
generation = next
|
|
917
|
+
cursors.clear()
|
|
918
|
+
epoch += 1
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// State pulls run one at a time, so two pulls can never send the same
|
|
922
|
+
// cursor and hand the same notification over twice.
|
|
923
|
+
let pullChain: Promise<unknown> = Promise.resolve()
|
|
924
|
+
|
|
925
|
+
const pullNow = async (scope: GaScope): Promise<GaPullResult> => {
|
|
926
|
+
if (isDisposed) throw new GaClientDisposedError()
|
|
927
|
+
const sentEpoch = epoch
|
|
928
|
+
const key = scopeKey(scope)
|
|
929
|
+
const raw = await call('state', {
|
|
930
|
+
version: GA_RPC_VERSION,
|
|
931
|
+
generation,
|
|
932
|
+
scope,
|
|
933
|
+
cursor: cursors.get(key) ?? 0,
|
|
934
|
+
})
|
|
935
|
+
if (isDisposed || sentEpoch !== epoch) return { kind: 'dropped' }
|
|
936
|
+
const parsed = parseGaStateAnswer(raw)
|
|
937
|
+
if (!parsed.ok) {
|
|
938
|
+
options.logger?.warn('ga-state-refused', { issues: parsed.issues })
|
|
939
|
+
throw new MenuRefusedError(parsed.issues)
|
|
940
|
+
}
|
|
941
|
+
const output = parsed.value
|
|
942
|
+
if (output.kind === 'disposed') {
|
|
943
|
+
// The activation we were bound to is gone; the next pull binds to
|
|
944
|
+
// whichever one the location runs now.
|
|
945
|
+
rebind(null)
|
|
946
|
+
return { kind: 'server-disposed' }
|
|
947
|
+
}
|
|
948
|
+
if (scopeKey(output.scope) !== key) {
|
|
949
|
+
options.logger?.warn('ga-state-scope-mismatch', {})
|
|
950
|
+
throw new MenuRefusedError(['output.scope: not the requested scope'])
|
|
951
|
+
}
|
|
952
|
+
if (output.generation !== generation) {
|
|
953
|
+
rebind(output.generation)
|
|
954
|
+
}
|
|
955
|
+
cursors.set(key, output.cursor)
|
|
956
|
+
return { kind: 'snapshot', snapshot: output }
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
return {
|
|
960
|
+
generation: () => generation,
|
|
961
|
+
cursor: (scope) => cursors.get(scopeKey(scope)) ?? 0,
|
|
962
|
+
disposed: () => isDisposed,
|
|
963
|
+
dispose() {
|
|
964
|
+
isDisposed = true
|
|
965
|
+
epoch += 1
|
|
966
|
+
},
|
|
967
|
+
pull(scope) {
|
|
968
|
+
const run = pullChain.then(() => pullNow(scope))
|
|
969
|
+
pullChain = run.catch(() => undefined)
|
|
970
|
+
return run
|
|
971
|
+
},
|
|
972
|
+
async apply(scope, body) {
|
|
973
|
+
if (isDisposed) throw new GaClientDisposedError()
|
|
974
|
+
const bound = generation
|
|
975
|
+
if (bound === null) throw new GaStaleError('not-bound')
|
|
976
|
+
const sentEpoch = epoch
|
|
977
|
+
const raw = await call('apply', {
|
|
978
|
+
version: GA_RPC_VERSION,
|
|
979
|
+
generation: bound,
|
|
980
|
+
scope,
|
|
981
|
+
...body,
|
|
982
|
+
})
|
|
983
|
+
if (isDisposed) throw new GaClientDisposedError()
|
|
984
|
+
const parsed = parseGaApplyAnswer(raw)
|
|
985
|
+
if (!parsed.ok) {
|
|
986
|
+
options.logger?.warn('ga-apply-refused', { issues: parsed.issues })
|
|
987
|
+
throw new MenuRefusedError(parsed.issues)
|
|
988
|
+
}
|
|
989
|
+
const output = parsed.value
|
|
990
|
+
if (output.kind === 'stale-generation' || output.kind === 'disposed') {
|
|
991
|
+
if (sentEpoch === epoch) rebind(null)
|
|
992
|
+
throw new GaStaleError(output.kind)
|
|
993
|
+
}
|
|
994
|
+
if (
|
|
995
|
+
output.generation !== bound ||
|
|
996
|
+
scopeKey(output.scope) !== scopeKey(scope)
|
|
997
|
+
) {
|
|
998
|
+
throw new MenuRefusedError([
|
|
999
|
+
'output: answered for another activation or scope',
|
|
1000
|
+
])
|
|
1001
|
+
}
|
|
1002
|
+
return output.result
|
|
1003
|
+
},
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// ── Menu over the native state ──────────────────────────────────────────────
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* GA notifications name only a dialog command, so this host builds the
|
|
1011
|
+
* `/antigravity` menu itself from the latest `state` answer: the accounts
|
|
1012
|
+
* with their opaque selectors and the location's settings, both read fresh
|
|
1013
|
+
* for that answer. The shared drawer renders it like the OpenCode 1 menu.
|
|
1014
|
+
* Each item and action id encodes what the action sends; an account is named
|
|
1015
|
+
* only by its selector, never by position or `acct-<n>` id.
|
|
1016
|
+
*/
|
|
1017
|
+
const SECTION_FOR_COMMAND: Readonly<Record<GaCommand, string>> = {
|
|
1018
|
+
'antigravity-account': 'accounts',
|
|
1019
|
+
'antigravity-quota': 'quota',
|
|
1020
|
+
'antigravity-routing': 'routing',
|
|
1021
|
+
'antigravity-killswitch': 'limits',
|
|
1022
|
+
'antigravity-dump': 'diagnostics',
|
|
1023
|
+
'antigravity-logging': 'diagnostics',
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
export function sectionForCommand(command: GaCommand): string {
|
|
1027
|
+
return SECTION_FOR_COMMAND[command]
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
const ACCOUNT_ITEM_PREFIX = 'account:'
|
|
1031
|
+
|
|
1032
|
+
function onOff(value: boolean): string {
|
|
1033
|
+
return value ? 'on' : 'off'
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
function quotaLine(account: GaAccount, now: number): string {
|
|
1037
|
+
const projected = projectSidebar({
|
|
1038
|
+
accounts: [account],
|
|
1039
|
+
route: null,
|
|
1040
|
+
status: { checkedAt: 0, quotaBackoffUntil: null },
|
|
1041
|
+
now,
|
|
1042
|
+
}).accounts[0]
|
|
1043
|
+
const pools = (projected?.quota ?? [])
|
|
1044
|
+
.map(
|
|
1045
|
+
(row) =>
|
|
1046
|
+
`${row.label} ${row.figure}${row.reset ? ` · ${row.reset}` : ''}`,
|
|
1047
|
+
)
|
|
1048
|
+
.join(' · ')
|
|
1049
|
+
return `${account.label}: ${pools}`
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
export function buildGaMenu(snapshot: GaSnapshot, now: number): MenuModel {
|
|
1053
|
+
const { settings } = snapshot
|
|
1054
|
+
const overLimit = snapshot.accountsStatus.kind === 'over-limit'
|
|
1055
|
+
const accountLines = overLimit
|
|
1056
|
+
? [
|
|
1057
|
+
`${snapshot.accountsStatus.kind === 'over-limit' ? snapshot.accountsStatus.count : 0} accounts; more than this view can list. Manage them from the command line.`,
|
|
1058
|
+
]
|
|
1059
|
+
: [
|
|
1060
|
+
snapshot.accounts.length === 0
|
|
1061
|
+
? 'No accounts yet.'
|
|
1062
|
+
: `${snapshot.accounts.length} account${snapshot.accounts.length === 1 ? '' : 's'}`,
|
|
1063
|
+
]
|
|
1064
|
+
const sections: MenuSection[] = [
|
|
1065
|
+
{
|
|
1066
|
+
id: 'accounts',
|
|
1067
|
+
slot: 'accounts',
|
|
1068
|
+
title: 'Accounts',
|
|
1069
|
+
lines: accountLines,
|
|
1070
|
+
items: snapshot.accounts.map((account) => {
|
|
1071
|
+
const projected = projectAccount(account, now)
|
|
1072
|
+
const use = (
|
|
1073
|
+
id: string,
|
|
1074
|
+
label: string,
|
|
1075
|
+
description: string,
|
|
1076
|
+
): MenuAction => ({ id, label, description, knobs: [] })
|
|
1077
|
+
return {
|
|
1078
|
+
id: `${ACCOUNT_ITEM_PREFIX}${account.selector}`,
|
|
1079
|
+
label: account.label,
|
|
1080
|
+
detail: `${projected.status} · ${projected.health}`,
|
|
1081
|
+
actions: [
|
|
1082
|
+
account.enabled
|
|
1083
|
+
? use(
|
|
1084
|
+
'disable',
|
|
1085
|
+
'Disable',
|
|
1086
|
+
'Stop routing requests to this account.',
|
|
1087
|
+
)
|
|
1088
|
+
: use(
|
|
1089
|
+
'enable',
|
|
1090
|
+
'Enable',
|
|
1091
|
+
'Route requests to this account again.',
|
|
1092
|
+
),
|
|
1093
|
+
use(
|
|
1094
|
+
'select-active',
|
|
1095
|
+
'Use for all models',
|
|
1096
|
+
'Make this the current account.',
|
|
1097
|
+
),
|
|
1098
|
+
use(
|
|
1099
|
+
'select-claude',
|
|
1100
|
+
'Use for Claude',
|
|
1101
|
+
'Make this the current Claude account.',
|
|
1102
|
+
),
|
|
1103
|
+
use(
|
|
1104
|
+
'select-gemini',
|
|
1105
|
+
'Use for Gemini',
|
|
1106
|
+
'Make this the current Gemini account.',
|
|
1107
|
+
),
|
|
1108
|
+
{
|
|
1109
|
+
id: 'remove',
|
|
1110
|
+
label: 'Remove',
|
|
1111
|
+
description: 'Delete this account from this machine.',
|
|
1112
|
+
knobs: [],
|
|
1113
|
+
confirm: {
|
|
1114
|
+
message: `Remove ${account.label}? This cannot be undone.`,
|
|
1115
|
+
irreversible: true,
|
|
1116
|
+
},
|
|
1117
|
+
},
|
|
1118
|
+
],
|
|
1119
|
+
}
|
|
1120
|
+
}),
|
|
1121
|
+
actions: [
|
|
1122
|
+
{
|
|
1123
|
+
id: 'add',
|
|
1124
|
+
label: 'Add account',
|
|
1125
|
+
description: 'Sign in with Google in your browser.',
|
|
1126
|
+
knobs: [],
|
|
1127
|
+
},
|
|
1128
|
+
],
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
id: 'quota',
|
|
1132
|
+
slot: 'quota',
|
|
1133
|
+
title: 'Quota',
|
|
1134
|
+
lines: overLimit
|
|
1135
|
+
? ['Quota is not listed while the account list is over the limit.']
|
|
1136
|
+
: snapshot.accounts.length === 0
|
|
1137
|
+
? ['No accounts yet.']
|
|
1138
|
+
: snapshot.accounts.map((account) => quotaLine(account, now)),
|
|
1139
|
+
items: [],
|
|
1140
|
+
actions: [
|
|
1141
|
+
{
|
|
1142
|
+
id: 'refresh',
|
|
1143
|
+
label: 'Check quota now',
|
|
1144
|
+
description: 'Ask Google for every account’s current quota.',
|
|
1145
|
+
knobs: [],
|
|
1146
|
+
},
|
|
1147
|
+
],
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
id: 'routing',
|
|
1151
|
+
slot: 'routing',
|
|
1152
|
+
title: 'Routing',
|
|
1153
|
+
lines: [
|
|
1154
|
+
`Gemini CLI first: ${onOff(settings.routing.cliFirst)}`,
|
|
1155
|
+
`Quota-style fallback: ${onOff(settings.routing.quotaStyleFallback)}`,
|
|
1156
|
+
],
|
|
1157
|
+
items: [],
|
|
1158
|
+
actions: [
|
|
1159
|
+
{
|
|
1160
|
+
id: settings.routing.cliFirst ? 'cli-first-off' : 'cli-first-on',
|
|
1161
|
+
label: `Turn Gemini CLI first ${settings.routing.cliFirst ? 'off' : 'on'}`,
|
|
1162
|
+
knobs: [],
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
id: settings.routing.quotaStyleFallback
|
|
1166
|
+
? 'quota-fallback-off'
|
|
1167
|
+
: 'quota-fallback-on',
|
|
1168
|
+
label: `Turn quota-style fallback ${settings.routing.quotaStyleFallback ? 'off' : 'on'}`,
|
|
1169
|
+
knobs: [],
|
|
1170
|
+
},
|
|
1171
|
+
],
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
id: 'limits',
|
|
1175
|
+
slot: 'limits',
|
|
1176
|
+
title: 'Limits',
|
|
1177
|
+
lines: [
|
|
1178
|
+
`Killswitch: ${onOff(settings.killswitch.enabled)}`,
|
|
1179
|
+
`Minimum remaining quota: ${settings.killswitch.minimumRemainingPercent}%`,
|
|
1180
|
+
],
|
|
1181
|
+
items: [],
|
|
1182
|
+
actions: [
|
|
1183
|
+
{
|
|
1184
|
+
id: settings.killswitch.enabled ? 'killswitch-off' : 'killswitch-on',
|
|
1185
|
+
label: `Turn killswitch ${settings.killswitch.enabled ? 'off' : 'on'}`,
|
|
1186
|
+
description: 'Skip accounts whose quota is below the minimum.',
|
|
1187
|
+
knobs: [],
|
|
1188
|
+
},
|
|
1189
|
+
{
|
|
1190
|
+
id: 'killswitch-minimum',
|
|
1191
|
+
label: 'Set minimum remaining quota',
|
|
1192
|
+
knobs: [
|
|
1193
|
+
{
|
|
1194
|
+
kind: 'number',
|
|
1195
|
+
id: 'percent',
|
|
1196
|
+
label: 'Percent (0-100)',
|
|
1197
|
+
value: settings.killswitch.minimumRemainingPercent,
|
|
1198
|
+
min: 0,
|
|
1199
|
+
max: 100,
|
|
1200
|
+
required: true,
|
|
1201
|
+
},
|
|
1202
|
+
],
|
|
1203
|
+
},
|
|
1204
|
+
],
|
|
1205
|
+
},
|
|
1206
|
+
{
|
|
1207
|
+
id: 'diagnostics',
|
|
1208
|
+
slot: 'diagnostics',
|
|
1209
|
+
title: 'Diagnostics',
|
|
1210
|
+
lines: [
|
|
1211
|
+
`Logging: ${settings.logLevel}`,
|
|
1212
|
+
`Wire dump: ${onOff(settings.dump.enabled)}`,
|
|
1213
|
+
],
|
|
1214
|
+
items: [],
|
|
1215
|
+
actions: [
|
|
1216
|
+
{
|
|
1217
|
+
id: 'log-level',
|
|
1218
|
+
label: 'Set log level',
|
|
1219
|
+
knobs: [
|
|
1220
|
+
{
|
|
1221
|
+
kind: 'choice',
|
|
1222
|
+
id: 'level',
|
|
1223
|
+
label: 'Level',
|
|
1224
|
+
value: settings.logLevel,
|
|
1225
|
+
choices: GA_LOG_LEVELS.map((level) => ({
|
|
1226
|
+
value: level,
|
|
1227
|
+
label: level,
|
|
1228
|
+
})),
|
|
1229
|
+
},
|
|
1230
|
+
],
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
id: settings.dump.enabled ? 'dump-off' : 'dump-on',
|
|
1234
|
+
label: `Turn wire dump ${settings.dump.enabled ? 'off' : 'on'}`,
|
|
1235
|
+
description: 'Write request and response bodies to the dump folder.',
|
|
1236
|
+
knobs: [],
|
|
1237
|
+
},
|
|
1238
|
+
],
|
|
1239
|
+
},
|
|
1240
|
+
]
|
|
1241
|
+
return {
|
|
1242
|
+
command: ANTIGRAVITY_MENU_COMMAND,
|
|
1243
|
+
title: ANTIGRAVITY_MENU_TITLE,
|
|
1244
|
+
sections,
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
/** Why a drawer choice could not be turned into a native apply. */
|
|
1249
|
+
export class GaMenuChoiceError extends Error {
|
|
1250
|
+
constructor(message: string) {
|
|
1251
|
+
super(message)
|
|
1252
|
+
this.name = 'GaMenuChoiceError'
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
const TEXT_ACTIONS: Readonly<Record<string, GaApplyBody>> = {
|
|
1257
|
+
'accounts/add': {
|
|
1258
|
+
command: 'antigravity-account',
|
|
1259
|
+
arguments: 'add-oauth-start',
|
|
1260
|
+
},
|
|
1261
|
+
'quota/refresh': { command: 'antigravity-quota', arguments: 'refresh' },
|
|
1262
|
+
'routing/cli-first-on': {
|
|
1263
|
+
command: 'antigravity-routing',
|
|
1264
|
+
arguments: 'cli_first=true',
|
|
1265
|
+
},
|
|
1266
|
+
'routing/cli-first-off': {
|
|
1267
|
+
command: 'antigravity-routing',
|
|
1268
|
+
arguments: 'cli_first=false',
|
|
1269
|
+
},
|
|
1270
|
+
'routing/quota-fallback-on': {
|
|
1271
|
+
command: 'antigravity-routing',
|
|
1272
|
+
arguments: 'quota_style_fallback=true',
|
|
1273
|
+
},
|
|
1274
|
+
'routing/quota-fallback-off': {
|
|
1275
|
+
command: 'antigravity-routing',
|
|
1276
|
+
arguments: 'quota_style_fallback=false',
|
|
1277
|
+
},
|
|
1278
|
+
'limits/killswitch-on': {
|
|
1279
|
+
command: 'antigravity-killswitch',
|
|
1280
|
+
arguments: 'enabled=true',
|
|
1281
|
+
},
|
|
1282
|
+
'limits/killswitch-off': {
|
|
1283
|
+
command: 'antigravity-killswitch',
|
|
1284
|
+
arguments: 'enabled=false',
|
|
1285
|
+
},
|
|
1286
|
+
'diagnostics/dump-on': { command: 'antigravity-dump', arguments: 'on' },
|
|
1287
|
+
'diagnostics/dump-off': { command: 'antigravity-dump', arguments: 'off' },
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
/**
|
|
1291
|
+
* The native apply for one drawer choice. Explicit target values are sent
|
|
1292
|
+
* ("turn on"), never a toggle, so a repeated or late choice cannot flip a
|
|
1293
|
+
* setting back. An account item sends its selector exactly as the server
|
|
1294
|
+
* issued it; a malformed one is refused here rather than guessed at.
|
|
1295
|
+
*/
|
|
1296
|
+
export function gaApplyBody(request: MenuApplyRequest): GaApplyBody {
|
|
1297
|
+
const key = `${request.sectionId}/${request.actionId}`
|
|
1298
|
+
if (request.sectionId === 'accounts' && request.itemId !== undefined) {
|
|
1299
|
+
if (!request.itemId.startsWith(ACCOUNT_ITEM_PREFIX)) {
|
|
1300
|
+
throw new GaMenuChoiceError('That account entry is not valid.')
|
|
1301
|
+
}
|
|
1302
|
+
const selector = request.itemId.slice(ACCOUNT_ITEM_PREFIX.length)
|
|
1303
|
+
if (!SELECTOR.test(selector)) {
|
|
1304
|
+
throw new GaMenuChoiceError('That account entry is not valid.')
|
|
1305
|
+
}
|
|
1306
|
+
const action: GaAccountAction | undefined =
|
|
1307
|
+
request.actionId === 'enable'
|
|
1308
|
+
? { kind: 'enable', selector }
|
|
1309
|
+
: request.actionId === 'disable'
|
|
1310
|
+
? { kind: 'disable', selector }
|
|
1311
|
+
: request.actionId === 'remove'
|
|
1312
|
+
? { kind: 'remove', selector }
|
|
1313
|
+
: request.actionId === 'select-active'
|
|
1314
|
+
? { kind: 'select', selector, target: 'active' }
|
|
1315
|
+
: request.actionId === 'select-claude'
|
|
1316
|
+
? { kind: 'select', selector, target: 'claude' }
|
|
1317
|
+
: request.actionId === 'select-gemini'
|
|
1318
|
+
? { kind: 'select', selector, target: 'gemini' }
|
|
1319
|
+
: undefined
|
|
1320
|
+
if (!action) throw new GaMenuChoiceError('Unknown account action.')
|
|
1321
|
+
if (action.kind === 'remove' && request.confirmed !== true) {
|
|
1322
|
+
throw new GaMenuChoiceError('Removing an account needs a confirmation.')
|
|
1323
|
+
}
|
|
1324
|
+
return { command: 'antigravity-account', action }
|
|
1325
|
+
}
|
|
1326
|
+
if (request.itemId !== undefined) {
|
|
1327
|
+
throw new GaMenuChoiceError('Unknown menu entry.')
|
|
1328
|
+
}
|
|
1329
|
+
const fixed = TEXT_ACTIONS[key]
|
|
1330
|
+
if (fixed) return fixed
|
|
1331
|
+
if (key === 'limits/killswitch-minimum') {
|
|
1332
|
+
const percent = request.values.percent
|
|
1333
|
+
if (
|
|
1334
|
+
typeof percent !== 'number' ||
|
|
1335
|
+
!Number.isInteger(percent) ||
|
|
1336
|
+
percent < 0 ||
|
|
1337
|
+
percent > 100
|
|
1338
|
+
) {
|
|
1339
|
+
throw new GaMenuChoiceError(
|
|
1340
|
+
'The minimum must be a whole number from 0 to 100.',
|
|
1341
|
+
)
|
|
1342
|
+
}
|
|
1343
|
+
return {
|
|
1344
|
+
command: 'antigravity-killswitch',
|
|
1345
|
+
arguments: `minimum_remaining_percent=${percent}`,
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
if (key === 'diagnostics/log-level') {
|
|
1349
|
+
const level = request.values.level
|
|
1350
|
+
if (!GA_LOG_LEVELS.includes(level as GaLogLevel)) {
|
|
1351
|
+
throw new GaMenuChoiceError('Unknown log level.')
|
|
1352
|
+
}
|
|
1353
|
+
return { command: 'antigravity-logging', arguments: String(level) }
|
|
1354
|
+
}
|
|
1355
|
+
throw new GaMenuChoiceError('Unknown menu action.')
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
const TARGET_TEXT: Readonly<
|
|
1359
|
+
Record<Exclude<GaTargetOutcome, 'applied'>, string>
|
|
1360
|
+
> = {
|
|
1361
|
+
'stale-target':
|
|
1362
|
+
'That account changed since the list was shown; nothing was changed. Choose it again from the refreshed list.',
|
|
1363
|
+
'unknown-target':
|
|
1364
|
+
'That account is no longer known; nothing was changed. Choose it again from the refreshed list.',
|
|
1365
|
+
'unsupported-index-action':
|
|
1366
|
+
'Accounts can only be chosen from the list; nothing was changed.',
|
|
1367
|
+
failed: 'The account action did not complete.',
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
/**
|
|
1371
|
+
* Turns a native command result into the drawer's result. `ok` is true only
|
|
1372
|
+
* when the command applied and, for an account action, its target applied.
|
|
1373
|
+
* A sign-in link is shown in full: on GA the browser returns to this
|
|
1374
|
+
* machine's sign-in listener, so there is nothing to paste.
|
|
1375
|
+
*/
|
|
1376
|
+
export function gaMenuResult(
|
|
1377
|
+
result: GaCommandResult,
|
|
1378
|
+
menu: MenuModel,
|
|
1379
|
+
): MenuApplyResult {
|
|
1380
|
+
const outcome = result.targetOutcome ?? null
|
|
1381
|
+
const ok =
|
|
1382
|
+
result.status === 'applied' && (outcome === null || outcome === 'applied')
|
|
1383
|
+
let text = result.text
|
|
1384
|
+
if (outcome !== null && outcome !== 'applied') {
|
|
1385
|
+
text = `${TARGET_TEXT[outcome]}`
|
|
1386
|
+
}
|
|
1387
|
+
if (result.authorizationUrl) {
|
|
1388
|
+
text = `Open ${result.authorizationUrl} in your browser and sign in.\nThe account is added when the browser returns here; there is nothing to paste.`
|
|
1389
|
+
}
|
|
1390
|
+
return {
|
|
1391
|
+
command: ANTIGRAVITY_MENU_COMMAND,
|
|
1392
|
+
ok,
|
|
1393
|
+
text,
|
|
1394
|
+
...(ok ? {} : { code: outcome ?? result.status }),
|
|
1395
|
+
menu,
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
// ── Dialogs ─────────────────────────────────────────────────────────────────
|
|
1400
|
+
|
|
1401
|
+
/**
|
|
1402
|
+
* `MenuUi` over the GA dialog API. After `isActive()` turns false every call
|
|
1403
|
+
* is inert: a select resolves as dismissed and nothing is shown.
|
|
1404
|
+
*/
|
|
1405
|
+
export function createGaMenuUi(
|
|
1406
|
+
context: GaTuiContext,
|
|
1407
|
+
isActive: () => boolean,
|
|
1408
|
+
): MenuUi {
|
|
1409
|
+
const { dialog, toast } = context.ui
|
|
1410
|
+
return {
|
|
1411
|
+
async select(input) {
|
|
1412
|
+
if (!isActive()) return undefined
|
|
1413
|
+
dialog.set({ size: 'xlarge' })
|
|
1414
|
+
const chosen = await dialog.select<string>({
|
|
1415
|
+
title: input.title,
|
|
1416
|
+
options: input.options.map((option) => ({ ...option })),
|
|
1417
|
+
...(input.current === undefined ? {} : { current: input.current }),
|
|
1418
|
+
})
|
|
1419
|
+
return isActive() ? chosen : undefined
|
|
1420
|
+
},
|
|
1421
|
+
async prompt(input) {
|
|
1422
|
+
if (!isActive()) return undefined
|
|
1423
|
+
dialog.set({ size: 'xlarge' })
|
|
1424
|
+
const value = await dialog.prompt({ ...input })
|
|
1425
|
+
return isActive() ? value : undefined
|
|
1426
|
+
},
|
|
1427
|
+
async confirm(input) {
|
|
1428
|
+
if (!isActive()) return false
|
|
1429
|
+
const yes = await dialog.confirm({ ...input })
|
|
1430
|
+
return isActive() && yes === true
|
|
1431
|
+
},
|
|
1432
|
+
async alert(input) {
|
|
1433
|
+
if (!isActive()) return
|
|
1434
|
+
await dialog.alert({ ...input })
|
|
1435
|
+
},
|
|
1436
|
+
toast(message, kind = 'info') {
|
|
1437
|
+
if (isActive()) toast.show({ message, variant: kind })
|
|
1438
|
+
},
|
|
1439
|
+
clear() {
|
|
1440
|
+
if (isActive()) dialog.clear()
|
|
1441
|
+
},
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
// ── Poller ──────────────────────────────────────────────────────────────────
|
|
1446
|
+
|
|
1447
|
+
export function currentScope(route: GaRoute): GaScope {
|
|
1448
|
+
return route.type === 'session'
|
|
1449
|
+
? { kind: 'session', sessionID: route.sessionID }
|
|
1450
|
+
: { kind: 'sessionless' }
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
export interface GaPollerOptions {
|
|
1454
|
+
readonly client: GaLocationClient
|
|
1455
|
+
readonly scope: () => GaScope
|
|
1456
|
+
readonly onSnapshot: (snapshot: GaSnapshot) => void
|
|
1457
|
+
readonly onNotification: (
|
|
1458
|
+
notification: GaNotification,
|
|
1459
|
+
scope: GaScope,
|
|
1460
|
+
) => void
|
|
1461
|
+
readonly logger?: GaLogger
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
/**
|
|
1465
|
+
* One poll tick: pull the current scope, hand every new notification over in
|
|
1466
|
+
* cursor order, and keep pulling (bounded) while the server says more are
|
|
1467
|
+
* waiting. Never throws; a failed pull is logged and the next tick retries.
|
|
1468
|
+
*/
|
|
1469
|
+
export async function pollGaOnce(options: GaPollerOptions): Promise<void> {
|
|
1470
|
+
const scope = options.scope()
|
|
1471
|
+
for (let pulls = 0; pulls < MAX_PULLS_PER_TICK; pulls += 1) {
|
|
1472
|
+
let result: GaPullResult
|
|
1473
|
+
try {
|
|
1474
|
+
result = await options.client.pull(scope)
|
|
1475
|
+
} catch (error) {
|
|
1476
|
+
if (!(error instanceof GaClientDisposedError)) {
|
|
1477
|
+
options.logger?.warn('ga-pull-failed', {
|
|
1478
|
+
error: error instanceof Error ? error.name : typeof error,
|
|
1479
|
+
})
|
|
1480
|
+
}
|
|
1481
|
+
return
|
|
1482
|
+
}
|
|
1483
|
+
if (result.kind !== 'snapshot') return
|
|
1484
|
+
const { snapshot } = result
|
|
1485
|
+
options.onSnapshot(snapshot)
|
|
1486
|
+
for (const notification of [...snapshot.notifications].sort(
|
|
1487
|
+
(a, b) => a.cursor - b.cursor,
|
|
1488
|
+
)) {
|
|
1489
|
+
if (options.client.disposed()) return
|
|
1490
|
+
options.onNotification(notification, snapshot.scope)
|
|
1491
|
+
}
|
|
1492
|
+
if (!snapshot.more) return
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// ── Sidebar ─────────────────────────────────────────────────────────────────
|
|
1497
|
+
|
|
1498
|
+
interface SidebarView {
|
|
1499
|
+
readonly scope: GaScope
|
|
1500
|
+
readonly projected: ProjectedSidebar
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
function GaSidebar(props: {
|
|
1504
|
+
readonly view: () => SidebarView | undefined
|
|
1505
|
+
readonly sessionID: string
|
|
1506
|
+
}): JSX.Element {
|
|
1507
|
+
// The route line belongs to one session; show it only in that session's
|
|
1508
|
+
// sidebar, never another session's.
|
|
1509
|
+
const route = () => {
|
|
1510
|
+
const view = props.view()
|
|
1511
|
+
if (view === undefined || view.scope.kind !== 'session') return null
|
|
1512
|
+
return view.scope.sessionID === props.sessionID
|
|
1513
|
+
? view.projected.route
|
|
1514
|
+
: null
|
|
1515
|
+
}
|
|
1516
|
+
return (
|
|
1517
|
+
<box flexDirection='column' width='100%'>
|
|
1518
|
+
<text>
|
|
1519
|
+
<b>Antigravity</b>
|
|
1520
|
+
</text>
|
|
1521
|
+
<Show when={props.view()} fallback={<text>connecting…</text>}>
|
|
1522
|
+
{(view) => (
|
|
1523
|
+
<>
|
|
1524
|
+
<For each={view().projected.accounts}>
|
|
1525
|
+
{(account) => (
|
|
1526
|
+
<box flexDirection='column' width='100%'>
|
|
1527
|
+
<box
|
|
1528
|
+
flexDirection='row'
|
|
1529
|
+
justifyContent='space-between'
|
|
1530
|
+
width='100%'
|
|
1531
|
+
>
|
|
1532
|
+
<text>{account.label}</text>
|
|
1533
|
+
<text>{account.status}</text>
|
|
1534
|
+
</box>
|
|
1535
|
+
<For each={account.quota}>
|
|
1536
|
+
{(row) => (
|
|
1537
|
+
<box
|
|
1538
|
+
flexDirection='row'
|
|
1539
|
+
justifyContent='space-between'
|
|
1540
|
+
width='100%'
|
|
1541
|
+
>
|
|
1542
|
+
<text>{`${row.label.padEnd(6)}${row.figure}`}</text>
|
|
1543
|
+
<text>{row.reset}</text>
|
|
1544
|
+
</box>
|
|
1545
|
+
)}
|
|
1546
|
+
</For>
|
|
1547
|
+
<text>{` ${account.health}`}</text>
|
|
1548
|
+
</box>
|
|
1549
|
+
)}
|
|
1550
|
+
</For>
|
|
1551
|
+
<Show when={route()}>
|
|
1552
|
+
{(line) => <text>{`Route ${line()}`}</text>}
|
|
1553
|
+
</Show>
|
|
1554
|
+
<For each={view().projected.notices}>
|
|
1555
|
+
{(notice) => <text>{notice}</text>}
|
|
1556
|
+
</For>
|
|
1557
|
+
</>
|
|
1558
|
+
)}
|
|
1559
|
+
</Show>
|
|
1560
|
+
</box>
|
|
1561
|
+
)
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// ── Plugin setup ────────────────────────────────────────────────────────────
|
|
1565
|
+
|
|
1566
|
+
export interface GaSetupOptions {
|
|
1567
|
+
readonly logger?: GaLogger
|
|
1568
|
+
readonly now?: () => number
|
|
1569
|
+
/** Replaces the interval timer (tests). Returns a function that stops it. */
|
|
1570
|
+
readonly schedule?: (tick: () => void, intervalMs: number) => () => void
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
function defaultSchedule(tick: () => void, intervalMs: number): () => void {
|
|
1574
|
+
const timer = setInterval(tick, intervalMs)
|
|
1575
|
+
return () => clearInterval(timer)
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
/**
|
|
1579
|
+
* GA TUI setup: claims the sidebar, starts the location poller and opens the
|
|
1580
|
+
* drawer for every menu the server pushes. Returns the cleanup that stops
|
|
1581
|
+
* all of it; after cleanup no answer, dialog or toast from this setup
|
|
1582
|
+
* reaches the host.
|
|
1583
|
+
*/
|
|
1584
|
+
export function setupGaTui(
|
|
1585
|
+
context: GaTuiContext,
|
|
1586
|
+
options: GaSetupOptions = {},
|
|
1587
|
+
): () => Promise<void> {
|
|
1588
|
+
const logger = options.logger
|
|
1589
|
+
const now = options.now ?? Date.now
|
|
1590
|
+
const client = createGaLocationClient({
|
|
1591
|
+
call: (input) => context.client.rpc.call(input),
|
|
1592
|
+
location: context.location,
|
|
1593
|
+
...(logger ? { logger } : {}),
|
|
1594
|
+
})
|
|
1595
|
+
const active = () => !client.disposed()
|
|
1596
|
+
const ui = createGaMenuUi(context, active)
|
|
1597
|
+
const [view, setView] = createSignal<SidebarView | undefined>(undefined)
|
|
1598
|
+
|
|
1599
|
+
const releaseSlot = context.ui.slot({
|
|
1600
|
+
append: 'sidebar.content',
|
|
1601
|
+
render: (input) => <GaSidebar view={view} sessionID={input.sessionID} />,
|
|
1602
|
+
})
|
|
1603
|
+
|
|
1604
|
+
// The latest snapshot per scope; the drawer's menu is built from it.
|
|
1605
|
+
const latest = new Map<string, GaSnapshot>()
|
|
1606
|
+
|
|
1607
|
+
const showSnapshot = (snapshot: GaSnapshot) => {
|
|
1608
|
+
latest.set(scopeKey(snapshot.scope), snapshot)
|
|
1609
|
+
setView({
|
|
1610
|
+
scope: snapshot.scope,
|
|
1611
|
+
projected: projectSidebar({
|
|
1612
|
+
accounts: snapshot.accounts,
|
|
1613
|
+
route: snapshot.route,
|
|
1614
|
+
status: snapshot.status,
|
|
1615
|
+
now: now(),
|
|
1616
|
+
}),
|
|
1617
|
+
})
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
/**
|
|
1621
|
+
* Pulls fresh state for `scope` and returns the menu built from it. Any
|
|
1622
|
+
* notifications the pull carries are handled like a poll tick's.
|
|
1623
|
+
*/
|
|
1624
|
+
const freshMenu = async (scope: GaScope): Promise<MenuModel | undefined> => {
|
|
1625
|
+
let fresh: GaSnapshot | undefined
|
|
1626
|
+
await pollGaOnce({
|
|
1627
|
+
client,
|
|
1628
|
+
scope: () => scope,
|
|
1629
|
+
onSnapshot: (snapshot) => {
|
|
1630
|
+
fresh = snapshot
|
|
1631
|
+
showSnapshot(snapshot)
|
|
1632
|
+
},
|
|
1633
|
+
onNotification,
|
|
1634
|
+
...(logger ? { logger } : {}),
|
|
1635
|
+
})
|
|
1636
|
+
return fresh ? buildGaMenu(fresh, now()) : undefined
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
const applyChoice = async (
|
|
1640
|
+
scope: GaScope,
|
|
1641
|
+
request: MenuApplyRequest,
|
|
1642
|
+
shown: () => MenuModel,
|
|
1643
|
+
): Promise<MenuApplyResult> => {
|
|
1644
|
+
const refused = async (text: string, code: string) => ({
|
|
1645
|
+
command: ANTIGRAVITY_MENU_COMMAND,
|
|
1646
|
+
ok: false,
|
|
1647
|
+
text,
|
|
1648
|
+
code,
|
|
1649
|
+
menu: (await freshMenu(scope)) ?? shown(),
|
|
1650
|
+
})
|
|
1651
|
+
let body: GaApplyBody
|
|
1652
|
+
try {
|
|
1653
|
+
body = gaApplyBody(request)
|
|
1654
|
+
} catch (error) {
|
|
1655
|
+
if (error instanceof GaMenuChoiceError)
|
|
1656
|
+
return refused(error.message, 'invalid-choice')
|
|
1657
|
+
throw error
|
|
1658
|
+
}
|
|
1659
|
+
let result: GaCommandResult
|
|
1660
|
+
try {
|
|
1661
|
+
result = await client.apply(scope, body)
|
|
1662
|
+
} catch (error) {
|
|
1663
|
+
if (error instanceof GaStaleError)
|
|
1664
|
+
return refused(error.message, error.reason)
|
|
1665
|
+
throw error
|
|
1666
|
+
}
|
|
1667
|
+
// Settings and accounts shown next come from a fresh read, not from the
|
|
1668
|
+
// apply's answer.
|
|
1669
|
+
const menu = (await freshMenu(scope)) ?? shown()
|
|
1670
|
+
return gaMenuResult(result, menu)
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
function onNotification(notification: GaNotification, scope: GaScope) {
|
|
1674
|
+
const snapshot = latest.get(scopeKey(scope))
|
|
1675
|
+
if (!snapshot) return
|
|
1676
|
+
let shown = buildGaMenu(snapshot, now())
|
|
1677
|
+
void openAntigravityMenu(
|
|
1678
|
+
{
|
|
1679
|
+
ui,
|
|
1680
|
+
apply: async (request) => {
|
|
1681
|
+
const result = await applyChoice(scope, request, () => shown)
|
|
1682
|
+
shown = result.menu
|
|
1683
|
+
return result
|
|
1684
|
+
},
|
|
1685
|
+
...(context.renderer?.copyToClipboardOSC52
|
|
1686
|
+
? {
|
|
1687
|
+
copy: (text: string) =>
|
|
1688
|
+
context.renderer?.copyToClipboardOSC52?.(text) === true,
|
|
1689
|
+
}
|
|
1690
|
+
: {}),
|
|
1691
|
+
onError: (message, detail) => logger?.warn(message, detail),
|
|
1692
|
+
startSection: sectionForCommand(notification.command),
|
|
1693
|
+
},
|
|
1694
|
+
{ command: ANTIGRAVITY_MENU_COMMAND, menu: shown },
|
|
1695
|
+
).catch((error: unknown) => {
|
|
1696
|
+
logger?.warn('menu-drawer-failed', {
|
|
1697
|
+
error: error instanceof Error ? error.name : typeof error,
|
|
1698
|
+
})
|
|
1699
|
+
})
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
let inFlight = false
|
|
1703
|
+
const tick = () => {
|
|
1704
|
+
if (inFlight || !active()) return
|
|
1705
|
+
inFlight = true
|
|
1706
|
+
void pollGaOnce({
|
|
1707
|
+
client,
|
|
1708
|
+
scope: () => currentScope(context.ui.router.current()),
|
|
1709
|
+
onSnapshot: showSnapshot,
|
|
1710
|
+
onNotification,
|
|
1711
|
+
...(logger ? { logger } : {}),
|
|
1712
|
+
}).finally(() => {
|
|
1713
|
+
inFlight = false
|
|
1714
|
+
})
|
|
1715
|
+
}
|
|
1716
|
+
const stop = (options.schedule ?? defaultSchedule)(tick, GA_SIDEBAR_PULL_MS)
|
|
1717
|
+
tick()
|
|
1718
|
+
|
|
1719
|
+
let cleaned = false
|
|
1720
|
+
return async () => {
|
|
1721
|
+
if (cleaned) return
|
|
1722
|
+
cleaned = true
|
|
1723
|
+
stop()
|
|
1724
|
+
client.dispose()
|
|
1725
|
+
releaseSlot()
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
/**
|
|
1730
|
+
* The GA TUI plugin definition (`{ id, setup }`, the 2.0.22 TUI plugin
|
|
1731
|
+
* shape). Importing this module starts nothing; `setup` binds to the
|
|
1732
|
+
* context's location and returns the cleanup that stops everything it
|
|
1733
|
+
* started.
|
|
1734
|
+
*/
|
|
1735
|
+
const gaTuiPlugin = {
|
|
1736
|
+
id: GA_TUI_ID,
|
|
1737
|
+
setup: (context: GaTuiContext): (() => Promise<void>) => setupGaTui(context),
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
export default gaTuiPlugin
|