dsh-antigravity-auth 0.1.4-rc.6 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +14 -6
- package/README.zh.md +12 -6
- package/docs/dsh-source-verification.md +9 -9
- package/lib/client.cjs +1 -2
- package/lib/client.cjs.map +1 -1
- package/lib/index.js +3 -1
- package/lib/search.js +4 -15
- package/lib/types/account-routes.d.ts.map +1 -1
- package/lib/types/search.d.ts.map +1 -1
- package/package.json +54 -55
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.1.4] - 2026-10-30
|
|
6
|
+
|
|
7
|
+
- Verify the plugin against the coherent DSH `0.2.1-rc.5` graph and forward the admitted request peer for account RPC.
|
|
8
|
+
- Respect DSH WebRuntime provider selection without mutating its private selection state.
|
|
9
|
+
- Remove the DSH version range restriction from published peers and retire the unused `dsh-invariants` peer.
|
|
10
|
+
|
|
5
11
|
## [0.1.4-rc.6] - 2026-10-13
|
|
6
12
|
|
|
7
13
|
- Adapt the plugin to DSH `0.2.0-rc.2` and keep the tested dependency graph coherent.
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# dsh-antigravity-auth
|
|
2
2
|
|
|
3
|
-
> **DSH compatibility:**
|
|
3
|
+
> **DSH compatibility:** Version `0.1.4` declares no DSH version range restriction. Its tested development baseline is DSH `0.2.1-rc.5`; other versions have not been verified by these checks. See [verification](docs/dsh-source-verification.md).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/dsh-antigravity-auth)
|
|
6
6
|
[](https://awesome-dsh-plugin.com)
|
|
7
7
|
|
|
8
8
|
English | [中文](README.zh.md)
|
|
9
9
|
|
|
10
|
-
Release: **v0.1.4
|
|
10
|
+
Release: **v0.1.4** (npm tag: `latest`).
|
|
11
11
|
|
|
12
12
|
A self-contained [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
13
13
|
**Antigravity Capability Bundle**. It integrates Antigravity's private OAuth session
|
|
@@ -27,6 +27,10 @@ The settings section follows the DSH interface language (English or Chinese), in
|
|
|
27
27
|
> may be rate-limited or changed without notice. Do not rely on it for
|
|
28
28
|
> production workloads.
|
|
29
29
|
|
|
30
|
+
## 0.1.4: DSH 0.2.1 compatibility
|
|
31
|
+
|
|
32
|
+
Updates the tested DSH graph to `0.2.1-rc.5`, forwards the request's admitted peer to account RPC, and respects the Host's Web Search provider selection. DSH peers are unrestricted so installation is not rejected solely by the Host version; this does not imply untested versions will work. The full package and fixed-source checks pass. The disposable Web Host and logged-out account status route were exercised without live OAuth or private endpoint calls.
|
|
33
|
+
|
|
30
34
|
## 0.1.4-rc.6: DSH 0.2.0-rc.2 adaptation and selection fixes
|
|
31
35
|
|
|
32
36
|
This release raises the minimum and tested DSH dependency graph to `0.2.0-rc.2`, while preserving the existing credential, replay, and cancellation behavior. It also isolates Host test fixtures from live profile data, adds the `google` provider alias, normalizes Antigravity project IDs, and preserves an explicit `deepseek-official` Web Search selection instead of overriding it during automatic registration. The complete package and tagged-source checks pass; live account and private transport behavior remain unverified.
|
|
@@ -90,6 +94,10 @@ The `antigravity-search` Host row registers provider ID `antigravity` through
|
|
|
90
94
|
the audited Wire Identity dispatcher. Results include the generated output and deduplicated,
|
|
91
95
|
validated HTTP(S) source references.
|
|
92
96
|
|
|
97
|
+
DSH owns the active search-provider selection. Select `antigravity` in the
|
|
98
|
+
Host's Web Search configuration when multiple providers are available; the
|
|
99
|
+
plugin does not overwrite an existing selection.
|
|
100
|
+
|
|
93
101
|
### Image Creation & Editing
|
|
94
102
|
|
|
95
103
|
`generate_image` presents a unified operation dispatching to Antigravity image endpoints:
|
|
@@ -111,22 +119,22 @@ Multimodal `analyze_video` tool accepts workspace MP4 videos, performing bounded
|
|
|
111
119
|
|
|
112
120
|
## Requirements (current checkout)
|
|
113
121
|
|
|
114
|
-
- DeepSeek Harness `0.2.
|
|
122
|
+
- DeepSeek Harness `0.2.1-rc.5` (tested coherent dependency graph).
|
|
115
123
|
- Node.js `^22.19.0` or `>=24.0.0`.
|
|
116
124
|
- `pnpm` available on `PATH` (`11.7.0` is the tested project package manager).
|
|
117
125
|
- A Google account with Antigravity access.
|
|
118
126
|
|
|
119
127
|
## Install (published release)
|
|
120
128
|
|
|
121
|
-
Stop `dsh web`,
|
|
129
|
+
Stop `dsh web`, then install the latest release into the intended profile:
|
|
122
130
|
|
|
123
131
|
```sh
|
|
124
132
|
dsh --version
|
|
125
|
-
dsh plugin --profile web add
|
|
133
|
+
dsh plugin --profile web add dsh-antigravity-auth
|
|
126
134
|
dsh plugin --profile web list
|
|
127
135
|
```
|
|
128
136
|
|
|
129
|
-
Verify the entry, restart `dsh web`, and refresh the browser.
|
|
137
|
+
Verify the entry, restart `dsh web`, and refresh the browser. The example uses the `web` profile; replace it with the intended profile, such as `desktop`.
|
|
130
138
|
|
|
131
139
|
## Terminal login command
|
|
132
140
|
|
package/README.zh.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# dsh-antigravity-auth
|
|
2
2
|
|
|
3
|
-
> **DSH 兼容性:**
|
|
3
|
+
> **DSH 兼容性:** `0.1.4` 不限制 DSH 版本范围,开发测试基线为 DSH `0.2.1-rc.5`;这些检查未验证其他版本。见[验证说明](docs/dsh-source-verification.md)。
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/dsh-antigravity-auth)
|
|
6
6
|
[](https://awesome-dsh-plugin.com)
|
|
7
7
|
|
|
8
8
|
[English](README.md) | 中文
|
|
9
9
|
|
|
10
|
-
发布版本:**v0.1.4
|
|
10
|
+
发布版本:**v0.1.4**(npm 标签:`latest`)。
|
|
11
11
|
|
|
12
12
|
这是一个自包含的 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
|
|
13
13
|
**Antigravity 能力包**。它集成了 Antigravity 的私有 OAuth 登录态与 Wire Identity 线路身份,提供:
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
> **⚠️ 非官方通道——仅限个人开发。** 私有、受账户权限控制的 Antigravity
|
|
25
25
|
> 后端服务未获官方支持、可随时撤销,也可能在没有通知的情况下被限流或变更。请勿依赖它承载生产任务。
|
|
26
26
|
|
|
27
|
+
## 0.1.4:适配 DSH 0.2.1
|
|
28
|
+
|
|
29
|
+
开发测试依赖图升级至 DSH `0.2.1-rc.5`,账号 RPC 转发当前请求通过认证的身份,网页搜索保留 Host 的提供方选择。DSH peer 不设版本范围,安装不会仅因 Host 版本被拦截;这不代表未经验证的版本一定可用。完整包检查和固定源码检查已通过,并在隔离 Web Host 中验证未登录状态接口;没有发起真实 OAuth 或私有接口请求。
|
|
30
|
+
|
|
27
31
|
## 0.1.4-rc.6:适配 DSH 0.2.0-rc.2 与选择保持修复
|
|
28
32
|
|
|
29
33
|
此版本将最低及已测试的 DSH 依赖图升级到 `0.2.0-rc.2`,并保留既有凭据隔离、历史重放与取消行为。同时隔离 Host 测试 fixture 与真实 profile 数据,增加 `google` 提供方别名,规范化 Antigravity project ID,并在自动注册时保留用户明确选择的 `deepseek-official` 网页搜索提供方。完整包检查与固定源码检查已通过;真实账号和私有传输尚未验证。
|
|
@@ -84,6 +88,8 @@
|
|
|
84
88
|
|
|
85
89
|
`antigravity-search` Host 行通过 `@deepseek-ai/dsh-web` 注册 ID 为 `antigravity` 的全局搜索提供方。基于审计过的 Wire Identity 线路分发请求,返回真实 grounding 来源与去重检验过的 HTTP(S) 链接。
|
|
86
90
|
|
|
91
|
+
搜索提供方由 DSH 选择。存在多个可用提供方时,请在 Host 的网页搜索配置中选择 `antigravity`;插件不会覆盖已有选择。
|
|
92
|
+
|
|
87
93
|
### 图片创作与编辑
|
|
88
94
|
|
|
89
95
|
`generate_image` 为模型提供统一操作接口,分发至 Antigravity 图片端点:
|
|
@@ -105,22 +111,22 @@
|
|
|
105
111
|
|
|
106
112
|
## 环境要求(当前源码)
|
|
107
113
|
|
|
108
|
-
- DeepSeek Harness `0.2.
|
|
114
|
+
- DeepSeek Harness `0.2.1-rc.5`(统一依赖图;npm 与对应源码制品分别验证)。
|
|
109
115
|
- Node.js `^22.19.0` 或 `>=24.0.0`。
|
|
110
116
|
- `PATH` 中可用 `pnpm`(本项目测试版本为 `11.7.0`)。
|
|
111
117
|
- 具有 Antigravity 权限的 Google 账号。
|
|
112
118
|
|
|
113
119
|
## 安装(已发布版本)
|
|
114
120
|
|
|
115
|
-
先停止 `dsh web
|
|
121
|
+
先停止 `dsh web`,再将最新发布版安装到目标 profile:
|
|
116
122
|
|
|
117
123
|
```sh
|
|
118
124
|
dsh --version
|
|
119
|
-
dsh plugin --profile web add
|
|
125
|
+
dsh plugin --profile web add dsh-antigravity-auth
|
|
120
126
|
dsh plugin --profile web list
|
|
121
127
|
```
|
|
122
128
|
|
|
123
|
-
核对条目后重启 `dsh web`
|
|
129
|
+
核对条目后重启 `dsh web` 并刷新浏览器。示例使用 `web` profile;请按实际情况替换为 `desktop` 等目标 profile。
|
|
124
130
|
|
|
125
131
|
## 终端登录命令
|
|
126
132
|
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# DSH source compatibility verification
|
|
2
2
|
|
|
3
|
-
This checkout
|
|
4
|
-
source tag at `
|
|
5
|
-
the lockfile,
|
|
6
|
-
|
|
3
|
+
This checkout tests the published DSH `0.2.1-rc.5` graph and its matching
|
|
4
|
+
source tag at `b830ec950faba0a46dda564be3e2d854afed94f1`. Development dependencies,
|
|
5
|
+
the lockfile, and package smoke checks use this baseline. This check does not
|
|
6
|
+
prove behavior on other DSH versions.
|
|
7
7
|
|
|
8
8
|
## Build the official artifacts once
|
|
9
9
|
|
|
10
10
|
Use a separate scratch directory, outside any plugin or live DSH installation:
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
git clone --depth 1 --branch dsh-v0.2.
|
|
13
|
+
git clone --depth 1 --branch dsh-v0.2.1-rc.5 https://github.com/deepseek-ai/deepseek-harness.git harness
|
|
14
14
|
cd harness
|
|
15
15
|
git rev-parse HEAD
|
|
16
|
-
# Must be
|
|
16
|
+
# Must be b830ec950faba0a46dda564be3e2d854afed94f1.
|
|
17
17
|
PNPM_CONFIG_MINIMUM_RELEASE_AGE=0 pnpm install --frozen-lockfile --ignore-scripts
|
|
18
18
|
pnpm run build:lib
|
|
19
19
|
pnpm --filter './packages/**' --filter './vendor/*' -r pack --pack-destination ../dsh-packages
|
|
@@ -51,12 +51,12 @@ repository, an installed package, or a user profile.
|
|
|
51
51
|
|
|
52
52
|
Package smoke checks accept both registry and source-artifact lock identities
|
|
53
53
|
while continuing to verify the selected version. Both registry and source
|
|
54
|
-
checks target `0.2.
|
|
54
|
+
checks target `0.2.1-rc.5`; source checks use `DSH_VERIFY_VERSION` explicitly.
|
|
55
55
|
|
|
56
56
|
## 中文说明
|
|
57
57
|
|
|
58
|
-
当前检出版本以已发布的 DSH `0.2.
|
|
59
|
-
|
|
58
|
+
当前检出版本以已发布的 DSH `0.2.1-rc.5` 为开发和验证基线,
|
|
59
|
+
锁文件与打包检查使用同一套依赖图;此检查不能证明其他 DSH 版本的运行结果。
|
|
60
60
|
|
|
61
61
|
按上面的固定 tag 构建、打包一次,然后在本插件目录运行
|
|
62
62
|
`pnpm run check:dsh-source -- /绝对路径/dsh-packages`。脚本在临时目录内安装
|
package/lib/client.cjs
CHANGED
|
@@ -1198,8 +1198,7 @@ window.__ModuleLoader__.load({
|
|
|
1198
1198
|
base: void 0,
|
|
1199
1199
|
user: void 0,
|
|
1200
1200
|
revision: void 0,
|
|
1201
|
-
writable: false
|
|
1202
|
-
mode: "memory"
|
|
1201
|
+
writable: false
|
|
1203
1202
|
};
|
|
1204
1203
|
function useCapabilitySettings(scope) {
|
|
1205
1204
|
const subscribe = (0, react.useCallback)((listener) => scope?.subscribe(listener) ?? (() => {}), [scope]);
|
package/lib/client.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","names":["useCallback","useSyncExternalStore","useRef","useState"],"sources":["../src/status.ts","../src/login-types.ts","../src/model-catalog.ts","../src/rpc-vocabulary.ts","../src/safe-text.ts","../src/rpc-contract.ts","../src/client/styles.ts","../src/client/AntigravityAuthSettings.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/** Value-free login and capability status shared by Host and browser code. */\n\nimport type { LoginActionResult, LoginCompletionResult, LoginErrorCode, LoginPhase, LoginStartResult, LoginStatusView } from './login-types.ts'\nimport type { CredentialStatusView, LogoutResult, RevokeActionResult, RevokeStatusView } from './credential-coordinator.ts'\nimport type { QuotaStatusView } from './quota.ts'\n\nexport const ANTIGRAVITY_PLUGIN_ID = 'dsh-antigravity-auth' as const\nexport const CAPABILITY_ROW_IDS = ['auth-llm', 'search', 'image', 'video'] as const\nexport const LLM_FAMILY_IDS = ['gemini', 'claude', 'gpt-oss'] as const\n\nexport type CapabilityRowId = (typeof CAPABILITY_ROW_IDS)[number]\nexport type LlmFamilyId = (typeof LLM_FAMILY_IDS)[number]\nexport type CapabilityGateState = 'available' | 'disabled' | 'poc-pending' | 'protocol-drift'\nexport type CapabilityGateReasonCode =\n | 'gate-not-run'\n | 'project-unavailable'\n | 'capability-ready'\n | 'unauthenticated'\n | 'rate-limited'\n | 'cancelled'\n | 'gate-0-failed'\n | 'gate-failed'\n | 'unsupported-video'\n | 'protocol-drift'\n\nexport const CAPABILITY_GATE_OUTCOMES = [\n 'passed',\n 'unauthenticated',\n 'rate-limited',\n 'cancelled',\n 'attribution-rejected',\n 'protocol-drift',\n 'unsupported-video',\n 'failed',\n] as const\n\nexport type CapabilityGateOutcome = (typeof CAPABILITY_GATE_OUTCOMES)[number]\n\nexport interface CapabilityGateResult {\n readonly outcome: CapabilityGateOutcome\n readonly checkedAt: string\n}\n\nexport interface CapabilityGateEvidence {\n /** Credential-lineage fence; evidence from another account is ignored. */\n readonly subject?: string\n readonly gate0?: CapabilityGateResult\n readonly llmFamilies?: Readonly<Partial<Record<LlmFamilyId, CapabilityGateResult>>>\n readonly capabilities?: Readonly<Partial<Record<CapabilityRowId, CapabilityGateResult>>>\n}\nexport type { LoginActionResult, LoginErrorCode, LoginPhase, LoginStartResult, LoginStatusView }\n\nexport interface CapabilityGateStatus {\n readonly id: CapabilityRowId\n readonly state: CapabilityGateState\n readonly reasonCode: CapabilityGateReasonCode\n}\n\nexport interface AntigravityStatusView {\n readonly pluginId: typeof ANTIGRAVITY_PLUGIN_ID\n readonly phase: 'bootstrap'\n readonly privateSelfUse: true\n readonly singleAccount: true\n readonly riskAcknowledgementRequired: true\n readonly riskAcknowledged: boolean\n readonly login: LoginStatusView\n /** Credential state is value-safe; tokens and grant errors never cross this boundary. */\n readonly credential?: CredentialStatusView\n readonly revoke?: RevokeStatusView\n readonly capabilities: readonly CapabilityGateStatus[]\n}\n\nexport interface RiskAcknowledgementResult {\n readonly acknowledged: true\n}\n\nexport interface BootstrapStatusService {\n status(): Promise<AntigravityStatusView>\n acknowledgeRisk(): Promise<RiskAcknowledgementResult>\n startLogin(): Promise<LoginStartResult>\n completeCallback(callbackUrl: string): Promise<LoginCompletionResult>\n cancelLogin(): Promise<{ readonly phase: LoginPhase; readonly errorCode?: LoginErrorCode }>\n logout(): Promise<LogoutResult>\n revoke(confirmed: boolean, signal?: AbortSignal): Promise<RevokeActionResult>\n usage?(signal?: AbortSignal, force?: boolean): Promise<QuotaStatusView>\n dispose(): Promise<void>\n}\n\nconst CAPABILITY_DEFINITIONS: readonly CapabilityGateStatus[] = Object.freeze(\n CAPABILITY_ROW_IDS.map(id => Object.freeze({ id, state: 'disabled' as const, reasonCode: 'unauthenticated' as const })),\n)\n\nconst PROJECT_DISCOVERY_FAILURES = new Set([\n 'project-unavailable',\n 'project-authentication-failed',\n 'project-forbidden',\n 'project-rate-limited',\n 'project-offline',\n 'project-malformed',\n 'project-protocol-drift',\n])\n\nexport function createStatusView(\n riskAcknowledged: boolean,\n login: LoginStatusView,\n credential?: CredentialStatusView,\n revoke?: RevokeStatusView,\n gates: CapabilityGateEvidence = {},\n): AntigravityStatusView {\n return Object.freeze({\n pluginId: ANTIGRAVITY_PLUGIN_ID,\n phase: 'bootstrap',\n privateSelfUse: true,\n singleAccount: true,\n riskAcknowledgementRequired: true,\n riskAcknowledged,\n login: Object.freeze({ ...login }),\n ...(credential === undefined ? {} : { credential: Object.freeze({ ...credential }) }),\n ...(revoke === undefined ? {} : { revoke: Object.freeze({ ...revoke }) }),\n capabilities: Object.freeze(capabilitiesFor(login, gates).map(capability => Object.freeze({ ...capability }))),\n })\n}\n\nfunction capabilitiesFor(login: LoginStatusView, gates: CapabilityGateEvidence): readonly CapabilityGateStatus[] {\n const projectBlocked = !login.projectAvailable\n && (login.configured\n || (login.errorCode !== undefined && PROJECT_DISCOVERY_FAILURES.has(login.errorCode)))\n if (projectBlocked) return CAPABILITY_DEFINITIONS.map(capability => ({\n id: capability.id,\n state: 'disabled' as const,\n reasonCode: 'project-unavailable' as const,\n }))\n if (!login.projectAvailable) return CAPABILITY_DEFINITIONS\n if (gates.gate0?.outcome !== 'passed') {\n return CAPABILITY_ROW_IDS.map(id => gate0Status(id, gates.gate0))\n }\n return CAPABILITY_ROW_IDS.map(id => gateStatus(\n id,\n id === 'auth-llm' ? llmFamilyResult(gates) : gates.capabilities?.[id],\n ))\n}\n\nfunction llmFamilyResult(gates: CapabilityGateEvidence): CapabilityGateResult | undefined {\n const results = LLM_FAMILY_IDS.map(family => gates.llmFamilies?.[family])\n const failure = results.find(result => result !== undefined && result.outcome !== 'passed')\n if (failure !== undefined) return failure\n if (results.some(result => result?.outcome !== 'passed')) return undefined\n return results.reduce((latest, result) => (\n latest === undefined || Date.parse(result!.checkedAt) > Date.parse(latest.checkedAt) ? result : latest\n ), undefined as CapabilityGateResult | undefined)\n}\n\nfunction gate0Status(id: CapabilityRowId, result: CapabilityGateResult | undefined): CapabilityGateStatus {\n if (result?.outcome === 'failed' || result?.outcome === 'attribution-rejected') {\n return { id, state: 'disabled', reasonCode: 'gate-0-failed' }\n }\n return gateStatus(id, result)\n}\n\nfunction gateStatus(id: CapabilityRowId, result: CapabilityGateResult | undefined): CapabilityGateStatus {\n if (result === undefined) return { id, state: 'poc-pending', reasonCode: 'gate-not-run' }\n if (result.outcome === 'passed') return { id, state: 'available', reasonCode: 'capability-ready' }\n if (result.outcome === 'protocol-drift') return { id, state: 'protocol-drift', reasonCode: 'protocol-drift' }\n if (result.outcome === 'attribution-rejected') return { id, state: 'disabled', reasonCode: 'gate-0-failed' }\n if (result.outcome === 'unauthenticated') return { id, state: 'disabled', reasonCode: 'unauthenticated' }\n if (result.outcome === 'rate-limited') return { id, state: 'disabled', reasonCode: 'rate-limited' }\n if (result.outcome === 'cancelled') return { id, state: 'disabled', reasonCode: 'cancelled' }\n if (result.outcome === 'unsupported-video') return { id, state: 'disabled', reasonCode: 'unsupported-video' }\n return { id, state: 'disabled', reasonCode: 'gate-failed' }\n}\n","/** Browser-safe login state shared by the Host OAuth flow and settings RPC. */\n\nexport const LOGIN_PHASES = [\n 'idle',\n 'pending',\n 'success',\n 'cancelled',\n 'expired',\n 'port-conflict',\n 'failed',\n] as const\n\nexport type LoginPhase = (typeof LOGIN_PHASES)[number]\n\nexport const LOGIN_ERROR_CODES = [\n 'invalid-method',\n 'invalid-path',\n 'invalid-host',\n 'duplicate-parameter',\n 'invalid-parameters',\n 'missing-state',\n 'state-mismatch',\n 'missing-code',\n 'oauth-error',\n 'no-pending-flow',\n 'expired',\n 'cancelled',\n 'port-conflict',\n 'token-exchange-failed',\n 'project-unavailable',\n 'project-authentication-failed',\n 'project-forbidden',\n 'project-rate-limited',\n 'project-offline',\n 'project-malformed',\n 'project-protocol-drift',\n 'project-validation-failed',\n 'persistence-failed',\n 'credential-conflict',\n 'invalid-callback-url',\n 'risk-acknowledgement-required',\n 'internal',\n] as const\n\nexport type LoginErrorCode = (typeof LOGIN_ERROR_CODES)[number]\n\nexport function isLoginPhase(value: unknown): value is LoginPhase {\n return typeof value === 'string' && LOGIN_PHASES.includes(value as LoginPhase)\n}\n\nexport function isLoginErrorCode(value: unknown): value is LoginErrorCode {\n return typeof value === 'string' && LOGIN_ERROR_CODES.includes(value as LoginErrorCode)\n}\n\nexport interface LoginStatusView {\n readonly phase: LoginPhase\n readonly configured: boolean\n readonly projectAvailable: boolean\n readonly authorizationUrl?: string\n readonly expiresAt?: string\n readonly maskedEmail?: string\n readonly errorCode?: LoginErrorCode\n}\n\nexport interface LoginStartResult {\n readonly started: true\n readonly phase: 'pending'\n readonly authorizationUrl: string\n readonly expiresAt: string\n}\n\nexport interface LoginActionResult {\n readonly phase: LoginPhase\n readonly errorCode?: LoginErrorCode\n}\n\nexport type LoginCompletionResult =\n | { readonly completed: true; readonly phase: 'success' }\n | { readonly completed: false; readonly phase: 'failed' | 'cancelled'; readonly errorCode: LoginErrorCode }\n\nexport type { LoginStatusView as AntigravityLoginStatusView }\n","/** Browser-safe advisory model-catalog state shared by Host RPC and settings. */\n\nexport const ANTIGRAVITY_MODEL_CATALOG_STATES = [\n 'snapshot',\n 'live-available',\n 'refresh-failed',\n 'protocol-drift',\n] as const\n\nexport type AntigravityModelCatalogState = (typeof ANTIGRAVITY_MODEL_CATALOG_STATES)[number]\nexport type AntigravityModelAvailability = 'snapshot' | 'live-available' | 'unavailable'\n\nexport interface AntigravityModelCatalogEntry {\n readonly id: string\n readonly name: string\n readonly state: AntigravityModelAvailability\n}\n\nexport interface AntigravityModelCatalogView {\n readonly state: AntigravityModelCatalogState\n readonly models: readonly AntigravityModelCatalogEntry[]\n readonly checkedAt?: string\n}\n\nexport interface AntigravityModelCatalogService {\n catalogSnapshot(): AntigravityModelCatalogView\n modelCatalog(signal?: AbortSignal, forceRefresh?: boolean): Promise<AntigravityModelCatalogView>\n}\n","/** Closed, browser-safe RPC error vocabulary shared by Host and client. */\n\nimport { LOGIN_ERROR_CODES, type LoginErrorCode } from './login-types.ts'\n\nconst OPERATION_ERROR_CODES = [\n 'loopback-required',\n 'invalid-grant',\n 'network',\n 'timeout',\n 'rate-limited',\n 'server-error',\n 'http-error',\n 'invalid-response',\n 'conflict',\n 'storage',\n] as const\n\nexport const SAFE_RPC_ERROR_CODES = [\n 'bad-request',\n ...LOGIN_ERROR_CODES,\n ...OPERATION_ERROR_CODES,\n] as const\n\nexport type SafeRpcErrorCode = (typeof SAFE_RPC_ERROR_CODES)[number]\n\nconst SAFE_RPC_ERROR_MESSAGES: Readonly<Partial<Record<SafeRpcErrorCode, string>>> = Object.freeze({\n 'bad-request': 'antigravity-auth: invalid request',\n 'loopback-required': 'Antigravity account controls require a loopback-bound DSH Host',\n cancelled: 'The operation was cancelled',\n 'risk-acknowledgement-required': 'Risk acknowledgement is required before login',\n 'port-conflict': 'The fixed OAuth callback port is already in use',\n 'invalid-method': 'The OAuth callback method is not accepted',\n 'invalid-path': 'The OAuth callback path is not accepted',\n 'invalid-host': 'The OAuth callback host is not accepted',\n 'duplicate-parameter': 'The OAuth callback contains duplicate parameters',\n 'invalid-parameters': 'The OAuth callback parameters are not accepted',\n 'missing-state': 'The OAuth callback state is missing',\n 'state-mismatch': 'The OAuth callback state was not accepted',\n 'missing-code': 'The OAuth callback code is missing',\n 'oauth-error': 'The OAuth provider rejected authorization',\n expired: 'The OAuth login expired',\n 'no-pending-flow': 'There is no pending OAuth login',\n 'project-unavailable': 'No usable project is available for this account',\n 'project-authentication-failed': 'The Antigravity project probe requires authentication',\n 'project-forbidden': 'The Antigravity project probe was forbidden',\n 'project-rate-limited': 'The Antigravity project probe is rate-limited',\n 'project-offline': 'The Antigravity project probe is offline',\n 'project-malformed': 'The Antigravity project response was malformed',\n 'project-protocol-drift': 'The Antigravity project protocol changed',\n 'project-validation-failed': 'Project validation failed',\n 'credential-conflict': 'The login changed while it was completing',\n 'persistence-failed': 'The login could not be saved',\n 'token-exchange-failed': 'The authorization code could not be exchanged',\n 'invalid-callback-url': 'The callback URL is invalid',\n 'invalid-grant': 'The account must be authenticated again',\n network: 'The operation could not reach the provider',\n timeout: 'The operation timed out',\n 'rate-limited': 'The operation is rate-limited',\n 'server-error': 'The provider is unavailable',\n 'http-error': 'The provider rejected the operation',\n 'invalid-response': 'The provider response was not accepted',\n conflict: 'The account changed while the operation was running',\n storage: 'The local account state could not be updated',\n})\n\nexport function isSafeRpcErrorCode(value: unknown): value is SafeRpcErrorCode {\n return typeof value === 'string' && SAFE_RPC_ERROR_CODES.includes(value as SafeRpcErrorCode)\n}\n\nexport function safeRpcErrorMessage(code: SafeRpcErrorCode | LoginErrorCode): string {\n return SAFE_RPC_ERROR_MESSAGES[code] ?? 'antigravity-auth: operation failed'\n}\n","/** Shared bounded text predicate for Host trust-boundary values. */\n\nexport function isBoundedSafeText(value: unknown, maxLength: number, minLength = 1): value is string {\n if (typeof value !== 'string'\n || !Number.isSafeInteger(maxLength)\n || !Number.isSafeInteger(minLength)\n || minLength < 0\n || maxLength < minLength\n || value.length < minLength\n || value.length > maxLength) return false\n for (let index = 0; index < value.length; index += 1) {\n const codePoint = value.charCodeAt(index)\n if (codePoint < 0x20 || codePoint === 0x7f) return false\n }\n return true\n}\n","/** Browser-safe, value-free RPC contract for the Antigravity login flow. */\n\nimport type { ConnectionRpcResult as RpcResult } from '@deepseek-ai/dsh-client-connection/client'\nimport { CAPABILITY_ROW_IDS } from './status.ts'\nimport type {\n AntigravityStatusView,\n CapabilityGateReasonCode,\n CapabilityGateState,\n CapabilityRowId,\n LoginActionResult,\n LoginPhase,\n LoginStartResult,\n LoginStatusView,\n RiskAcknowledgementResult,\n} from './status.ts'\nimport { isLoginErrorCode, isLoginPhase } from './login-types.ts'\nimport type { CredentialErrorCode, CredentialState, CredentialStatusView, RevokeActionResult, RevokeErrorCode, RevokeState, RevokeStatusView } from './credential-coordinator.ts'\nimport type { QuotaGroupView, QuotaState, QuotaStatusView, QuotaWindowKind } from './quota.ts'\nimport {\n ANTIGRAVITY_MODEL_CATALOG_STATES,\n type AntigravityModelAvailability,\n type AntigravityModelCatalogView,\n} from './model-catalog.ts'\nimport { isSafeRpcErrorCode, safeRpcErrorMessage } from './rpc-vocabulary.ts'\nimport { isBoundedSafeText } from './safe-text.ts'\n\nexport const ANTIGRAVITY_AUTH_RPC_CHANNEL = '/api'\nexport const ANTIGRAVITY_AUTH_RPC_NAMESPACE = 'antigravity-auth' as const\n\nexport interface AntigravityAuthRpcClient {\n status(signal?: AbortSignal): Promise<RpcResult<{ status: AntigravityStatusView }>>\n acknowledgeRisk(signal?: AbortSignal): Promise<RpcResult<RiskAcknowledgementResult>>\n login(signal?: AbortSignal): Promise<RpcResult<LoginStartResult>>\n cancelLogin(signal?: AbortSignal): Promise<RpcResult<LoginActionResult>>\n logout(signal?: AbortSignal): Promise<RpcResult<{ state: 'logged-out' }>>\n revoke(signal?: AbortSignal): Promise<RpcResult<RevokeActionResult>>\n models(signal?: AbortSignal, force?: boolean): Promise<RpcResult<AntigravityModelCatalogView>>\n usage?(signal?: AbortSignal, force?: boolean): Promise<RpcResult<QuotaStatusView>>\n}\n\nexport interface AntigravityAuthConnectionRpc {\n call(\n channel: string,\n endpoint: string,\n payload: unknown,\n signal?: AbortSignal,\n ): Promise<RpcResult<unknown>>\n}\n\n/** Build the browser face over the plugin-owned guarded account channel. */\nexport function createAntigravityAuthRpcClient(rpc: AntigravityAuthConnectionRpc): AntigravityAuthRpcClient {\n return {\n status: signal => callValidated(rpc, 'status', {}, signal, value => {\n const status = parseStatusResult(value)\n return status === undefined ? undefined : { status }\n }),\n acknowledgeRisk: signal => callValidated(rpc, 'acknowledge-risk', { acknowledge: true }, signal, parseAcknowledgementResult),\n login: signal => callValidated(rpc, 'login', {}, signal, parseLoginResult),\n cancelLogin: signal => callValidated(rpc, 'cancel', {}, signal, parseActionResult),\n logout: signal => callValidated(rpc, 'logout', {}, signal, parseLogoutResult),\n revoke: signal => callValidated(rpc, 'revoke', { confirmed: true }, signal, parseRevokeResult),\n models: (signal, force = false) => callValidated(rpc, 'models', { force }, signal, parseModelCatalogResult),\n usage: (signal, force = false) => callValidated(rpc, 'usage', { force }, signal, parseUsageResult),\n }\n}\n\nasync function callValidated<T>(\n rpc: AntigravityAuthConnectionRpc,\n endpoint: string,\n payload: unknown,\n signal: AbortSignal | undefined,\n parse: (value: unknown) => T | undefined,\n): Promise<RpcResult<T>> {\n let result: RpcResult<unknown>\n try {\n result = await rpc.call(ANTIGRAVITY_AUTH_RPC_CHANNEL, `${ANTIGRAVITY_AUTH_RPC_NAMESPACE}/${endpoint}`, payload, signal)\n } catch {\n return invalidResponse(endpoint)\n }\n if (!result.ok) return sanitizeFailure(result, endpoint)\n const value = parse(result.value)\n return value === undefined ? invalidResponse(endpoint) : { ok: true, value }\n}\n\nfunction sanitizeFailure(result: Extract<RpcResult<unknown>, { readonly ok: false }>, endpoint: string): RpcResult<never> {\n const error: unknown = result.error\n if (!isRecord(error)\n || !hasExactKeys(error, ['code', 'message', 'details'])\n || !isSafeRpcErrorCode(error.code)\n || typeof error.message !== 'string'\n || !isBoundedSafeText(error.message, 512)\n || !isSafeErrorDetails(error.details)) return invalidResponse(endpoint)\n return {\n ok: false,\n error: {\n code: error.code as never,\n message: safeRpcErrorMessage(error.code),\n details: {},\n },\n }\n}\n\nfunction isSafeErrorDetails(value: unknown): boolean {\n if (!isRecord(value)) return false\n if (Object.keys(value).length === 0) return true\n return hasExactKeys(value, ['issues']) && Array.isArray(value.issues) && value.issues.length === 0\n}\n\n/** Parse a closed, value-safe advisory model catalog received by the browser. */\nexport function parseModelCatalogResult(value: unknown): AntigravityModelCatalogView | undefined {\n if (!isRecord(value)\n || !hasExactKeys(value, ['state', 'models', ...(value.checkedAt === undefined ? [] : ['checkedAt'])])\n || !ANTIGRAVITY_MODEL_CATALOG_STATES.includes(value.state as never)\n || !Array.isArray(value.models)\n || value.models.length === 0\n || value.models.length > 64\n || (value.checkedAt !== undefined && !isIsoTime(value.checkedAt))) return undefined\n const models: Array<{ id: string; name: string; state: AntigravityModelAvailability }> = []\n const ids = new Set<string>()\n for (const model of value.models) {\n if (!isRecord(model)\n || !hasExactKeys(model, ['id', 'name', 'state'])\n || !isBoundedSafeText(model.id, 256)\n || !isBoundedSafeText(model.name, 256)\n || (model.state !== 'snapshot' && model.state !== 'live-available' && model.state !== 'unavailable')\n || ids.has(model.id)) return undefined\n if (value.state === 'live-available' ? model.state === 'snapshot' : model.state !== 'snapshot') return undefined\n ids.add(model.id)\n models.push({ id: model.id, name: model.name, state: model.state })\n }\n return {\n state: value.state as AntigravityModelCatalogView['state'],\n models,\n ...(typeof value.checkedAt === 'string' ? { checkedAt: value.checkedAt } : {}),\n }\n}\n\n/** Parse a value-safe, normalized quota envelope received by the browser. */\nexport function parseUsageResult(value: unknown): QuotaStatusView | undefined {\n if (!isRecord(value) || !hasExactKeys(value, ['state', ...(value.checkedAt === undefined ? [] : ['checkedAt']), ...(value.groups === undefined ? [] : ['groups'])])) return undefined\n if (!isQuotaState(value.state)) return undefined\n if (value.checkedAt !== undefined && !isIsoTime(value.checkedAt)) return undefined\n if (value.state === 'available' && value.groups === undefined) return undefined\n if (value.groups !== undefined) {\n if (!Array.isArray(value.groups) || value.groups.length === 0 || value.groups.length > 2) return undefined\n const groups: QuotaGroupView[] = []\n const groupNames = new Set<string>()\n for (const rawGroup of value.groups) {\n if (!isRecord(rawGroup) || !hasExactKeys(rawGroup, ['group', 'modelCount', 'windows']) || (rawGroup.group !== 'gemini' && rawGroup.group !== 'non-gemini') || !Number.isSafeInteger(rawGroup.modelCount) || (rawGroup.modelCount as number) < 0 || !Array.isArray(rawGroup.windows)) return undefined\n if (groupNames.has(rawGroup.group)) return undefined\n groupNames.add(rawGroup.group)\n const modelCount = rawGroup.modelCount as number\n if (rawGroup.windows.length === 0 || rawGroup.windows.length > 2) return undefined\n const windows: Array<{ window: QuotaWindowKind; remainingFraction: number; resetTime: string }> = []\n const windowKinds = new Set<QuotaWindowKind>()\n for (const rawWindow of rawGroup.windows) {\n if (!isRecord(rawWindow) || !hasExactKeys(rawWindow, ['window', 'remainingFraction', 'resetTime']) || (rawWindow.window !== '5h' && rawWindow.window !== 'weekly') || windowKinds.has(rawWindow.window) || typeof rawWindow.remainingFraction !== 'number' || !Number.isFinite(rawWindow.remainingFraction) || rawWindow.remainingFraction < 0 || rawWindow.remainingFraction > 1 || !isIsoTime(rawWindow.resetTime)) return undefined\n windowKinds.add(rawWindow.window)\n windows.push({ window: rawWindow.window, remainingFraction: rawWindow.remainingFraction, resetTime: rawWindow.resetTime })\n }\n groups.push({ group: rawGroup.group, modelCount, windows })\n }\n return { state: value.state, ...(typeof value.checkedAt === 'string' ? { checkedAt: value.checkedAt } : {}), groups }\n }\n return { state: value.state, ...(typeof value.checkedAt === 'string' ? { checkedAt: value.checkedAt } : {}) }\n}\n\n/** Parse the closed status envelope received by the browser. */\nexport function parseStatusResult(value: unknown): AntigravityStatusView | undefined {\n if (!isRecord(value) || !hasExactKeys(value, ['status'])) return undefined\n return parseStatus(value.status)\n}\n\nfunction parseStatus(value: unknown): AntigravityStatusView | undefined {\n if (!isRecord(value)\n || !hasAllowedKeys(value, [\n 'pluginId',\n 'phase',\n 'privateSelfUse',\n 'singleAccount',\n 'riskAcknowledgementRequired',\n 'riskAcknowledged',\n 'login',\n 'credential',\n 'revoke',\n 'capabilities',\n ])\n || value.pluginId !== 'dsh-antigravity-auth'\n || value.phase !== 'bootstrap'\n || value.privateSelfUse !== true\n || value.singleAccount !== true\n || value.riskAcknowledgementRequired !== true\n || typeof value.riskAcknowledged !== 'boolean'\n || !Array.isArray(value.capabilities)) return undefined\n\n const login = parseLoginStatus(value.login)\n if (login === undefined) return undefined\n const credential = value.credential === undefined ? undefined : parseCredentialStatus(value.credential)\n if (value.credential !== undefined && credential === undefined) return undefined\n const revoke = value.revoke === undefined ? undefined : parseRevokeStatus(value.revoke)\n if (value.revoke !== undefined && revoke === undefined) return undefined\n const seen = new Set<string>()\n const capabilities: CapabilityGateStatus[] = []\n for (const capability of value.capabilities) {\n const parsed = parseCapability(capability)\n if (parsed === undefined || seen.has(parsed.id)) return undefined\n seen.add(parsed.id)\n capabilities.push(parsed)\n }\n if (seen.size !== CAPABILITY_ROW_IDS.length || CAPABILITY_ROW_IDS.some(id => !seen.has(id))) return undefined\n\n return {\n pluginId: 'dsh-antigravity-auth',\n phase: 'bootstrap',\n privateSelfUse: true,\n singleAccount: true,\n riskAcknowledgementRequired: true,\n riskAcknowledged: value.riskAcknowledged,\n login,\n ...(credential === undefined ? {} : { credential }),\n ...(revoke === undefined ? {} : { revoke }),\n capabilities,\n }\n}\n\nfunction parseCredentialStatus(value: unknown): CredentialStatusView | undefined {\n if (!isRecord(value)\n || typeof value.state !== 'string'\n || !isCredentialState(value.state)\n || typeof value.configured !== 'boolean'\n || !hasAllowedKeys(value, ['state', 'configured', 'expiresAt', 'lastRefreshAt', 'errorCode'])) return undefined\n if (value.expiresAt !== undefined && !isIsoTime(value.expiresAt)) return undefined\n if (value.lastRefreshAt !== undefined && !isIsoTime(value.lastRefreshAt)) return undefined\n if (value.errorCode !== undefined && (typeof value.errorCode !== 'string' || !isCredentialErrorCode(value.errorCode))) return undefined\n return {\n state: value.state,\n configured: value.configured,\n ...(typeof value.expiresAt === 'string' ? { expiresAt: value.expiresAt } : {}),\n ...(typeof value.lastRefreshAt === 'string' ? { lastRefreshAt: value.lastRefreshAt } : {}),\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseRevokeStatus(value: unknown): RevokeStatusView | undefined {\n if (!isRecord(value)\n || typeof value.state !== 'string'\n || !isRevokeState(value.state)\n || !hasAllowedKeys(value, ['state', 'errorCode'])) return undefined\n if (value.errorCode !== undefined && (typeof value.errorCode !== 'string' || !isRevokeErrorCode(value.errorCode))) return undefined\n return {\n state: value.state,\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseLoginStatus(value: unknown): LoginStatusView | undefined {\n if (!isRecord(value)\n || typeof value.phase !== 'string'\n || !isLoginPhase(value.phase)\n || typeof value.configured !== 'boolean'\n || typeof value.projectAvailable !== 'boolean') return undefined\n const allowed = ['phase', 'configured', 'projectAvailable', 'authorizationUrl', 'expiresAt', 'maskedEmail', 'errorCode']\n if (Object.keys(value).some(key => !allowed.includes(key))) return undefined\n if (value.authorizationUrl !== undefined && !isSafeAuthorizationUrl(value.authorizationUrl)) return undefined\n if (value.expiresAt !== undefined && !isIsoTime(value.expiresAt)) return undefined\n if (value.maskedEmail !== undefined && (typeof value.maskedEmail !== 'string' || !isMaskedEmail(value.maskedEmail))) return undefined\n if (value.errorCode !== undefined && !isLoginErrorCode(value.errorCode)) return undefined\n if (isErrorPhase(value.phase)\n ? typeof value.errorCode !== 'string'\n : value.errorCode !== undefined) return undefined\n if (value.phase === 'pending'\n ? typeof value.authorizationUrl !== 'string' || typeof value.expiresAt !== 'string'\n : value.authorizationUrl !== undefined) return undefined\n return {\n phase: value.phase,\n configured: value.configured,\n projectAvailable: value.projectAvailable,\n ...(typeof value.authorizationUrl === 'string' ? { authorizationUrl: value.authorizationUrl } : {}),\n ...(typeof value.expiresAt === 'string' ? { expiresAt: value.expiresAt } : {}),\n ...(typeof value.maskedEmail === 'string' ? { maskedEmail: value.maskedEmail } : {}),\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseCapability(value: unknown): CapabilityGateStatus | undefined {\n if (!isRecord(value) || !hasExactKeys(value, ['id', 'state', 'reasonCode'])) return undefined\n if (!isCapabilityRowId(value.id) || !isCapabilityGateState(value.state) || !isCapabilityReasonCode(value.reasonCode)) {\n return undefined\n }\n return { id: value.id, state: value.state, reasonCode: value.reasonCode }\n}\n\nfunction parseAcknowledgementResult(value: unknown): RiskAcknowledgementResult | undefined {\n return isRecord(value) && hasExactKeys(value, ['acknowledged']) && value.acknowledged === true\n ? { acknowledged: true }\n : undefined\n}\n\nfunction parseLoginResult(value: unknown): LoginStartResult | undefined {\n return isRecord(value)\n && hasExactKeys(value, ['started', 'phase', 'authorizationUrl', 'expiresAt'])\n && value.started === true\n && value.phase === 'pending'\n && isSafeAuthorizationUrl(value.authorizationUrl)\n && isIsoTime(value.expiresAt)\n ? {\n started: true,\n phase: 'pending',\n authorizationUrl: value.authorizationUrl,\n expiresAt: value.expiresAt,\n }\n : undefined\n}\n\nfunction parseActionResult(value: unknown): LoginActionResult | undefined {\n if (!isRecord(value) || typeof value.phase !== 'string' || !isLoginPhase(value.phase)) return undefined\n if (Object.keys(value).some(key => key !== 'phase' && key !== 'errorCode')) return undefined\n if (value.errorCode !== undefined && !isLoginErrorCode(value.errorCode)) return undefined\n return {\n phase: value.phase,\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseLogoutResult(value: unknown): { readonly state: 'logged-out' } | undefined {\n return isRecord(value) && hasExactKeys(value, ['state']) && value.state === 'logged-out'\n ? { state: 'logged-out' }\n : undefined\n}\n\nfunction parseRevokeResult(value: unknown): RevokeActionResult | undefined {\n if (!isRecord(value) || typeof value.state !== 'string') return undefined\n if (value.state === 'confirmation-required' || value.state === 'revoked' || value.state === 'logged-out' || value.state === 'superseded') {\n return hasExactKeys(value, ['state']) ? { state: value.state } : undefined\n }\n if (value.state === 'failed'\n && hasExactKeys(value, ['state', 'errorCode'])\n && typeof value.errorCode === 'string'\n && isRevokeErrorCode(value.errorCode)) {\n return { state: 'failed', errorCode: value.errorCode }\n }\n return undefined\n}\n\nfunction isSafeAuthorizationUrl(value: unknown): value is string {\n if (typeof value !== 'string' || value.length === 0 || value.length > 8192) return false\n try {\n const parsed = new URL(value)\n const allowed = new Set(['client_id', 'response_type', 'redirect_uri', 'scope', 'code_challenge', 'code_challenge_method', 'state', 'access_type', 'prompt'])\n for (const [key, parameter] of parsed.searchParams) {\n if (!allowed.has(key) || parsed.searchParams.getAll(key).length !== 1 || !isBoundedSafeText(parameter, 4096)) return false\n }\n const state = parsed.searchParams.get('state')\n const clientId = parsed.searchParams.get('client_id')\n const challenge = parsed.searchParams.get('code_challenge')\n return parsed.protocol === 'https:'\n && parsed.hostname === 'accounts.google.com'\n && parsed.port === ''\n && parsed.username === ''\n && parsed.password === ''\n && parsed.pathname === '/o/oauth2/v2/auth'\n && parsed.hash.length === 0\n && typeof state === 'string'\n && /^[A-Za-z0-9_-]{43}$/u.test(state)\n && (clientId === null || (clientId.length <= 256 && clientId.endsWith('.apps.googleusercontent.com')))\n && (challenge === null || /^[A-Za-z0-9_-]{43}$/u.test(challenge))\n && (parsed.searchParams.get('response_type') === null || parsed.searchParams.get('response_type') === 'code')\n && (parsed.searchParams.get('redirect_uri') === null || parsed.searchParams.get('redirect_uri') === 'http://localhost:51121/oauth-callback')\n && (parsed.searchParams.get('code_challenge_method') === null || parsed.searchParams.get('code_challenge_method') === 'S256')\n && (parsed.searchParams.get('access_type') === null || parsed.searchParams.get('access_type') === 'offline')\n && (parsed.searchParams.get('prompt') === null || parsed.searchParams.get('prompt') === 'consent')\n } catch {\n return false\n }\n}\n\nfunction isMaskedEmail(value: string): boolean {\n return isBoundedSafeText(value, 256) && /^.[*]{3}[^@]*@[^@\\s]+$/u.test(value)\n}\n\nfunction isErrorPhase(value: LoginPhase): boolean {\n return value === 'cancelled' || value === 'expired' || value === 'port-conflict' || value === 'failed'\n}\n\nfunction isQuotaState(value: unknown): value is QuotaState {\n return value === 'available' || value === 'unauthenticated' || value === 'forbidden' || value === 'rate-limited' || value === 'offline' || value === 'timeout' || value === 'protocol-drift'\n}\n\nfunction isIsoTime(value: unknown): value is string {\n if (typeof value !== 'string' || value.length > 64) return false\n const timestamp = Date.parse(value)\n return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value\n}\n\nfunction isCapabilityRowId(value: unknown): value is CapabilityRowId {\n return typeof value === 'string' && CAPABILITY_ROW_IDS.includes(value as CapabilityRowId)\n}\n\nfunction isCapabilityGateState(value: unknown): value is CapabilityGateState {\n return value === 'available'\n || value === 'disabled'\n || value === 'poc-pending'\n || value === 'protocol-drift'\n}\n\nfunction isCapabilityReasonCode(value: unknown): value is CapabilityGateReasonCode {\n return value === 'gate-not-run'\n || value === 'project-unavailable'\n || value === 'capability-ready'\n || value === 'unauthenticated'\n || value === 'rate-limited'\n || value === 'cancelled'\n || value === 'gate-0-failed'\n || value === 'gate-failed'\n || value === 'unsupported-video'\n || value === 'protocol-drift'\n}\n\nfunction isCredentialState(value: unknown): value is CredentialState {\n return value === 'logged-out'\n || value === 'logged-in'\n || value === 'refreshing'\n || value === 'refresh-failed'\n || value === 're-login-required'\n}\n\nfunction isCredentialErrorCode(value: unknown): value is CredentialErrorCode {\n return value === 'invalid-grant'\n || value === 'network'\n || value === 'timeout'\n || value === 'rate-limited'\n || value === 'server-error'\n || value === 'http-error'\n || value === 'invalid-response'\n || value === 'conflict'\n || value === 'storage'\n || value === 'cancelled'\n}\n\nfunction isRevokeState(value: unknown): value is RevokeState {\n return value === 'idle'\n || value === 'pending'\n || value === 'confirmation-required'\n || value === 'revoked'\n || value === 'logged-out'\n || value === 'failed'\n || value === 'superseded'\n}\n\nfunction isRevokeErrorCode(value: unknown): value is RevokeErrorCode {\n return value === 'network'\n || value === 'timeout'\n || value === 'rate-limited'\n || value === 'server-error'\n || value === 'http-error'\n || value === 'invalid-response'\n || value === 'storage'\n}\n\nfunction hasAllowedKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {\n return Object.keys(value).every(key => allowed.includes(key))\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, expected: readonly string[]): boolean {\n const keys = Object.keys(value).sort()\n const sortedExpected = [...expected].sort()\n return keys.length === sortedExpected.length && keys.every((key, index) => key === sortedExpected[index])\n}\n\nfunction invalidResponse(endpoint: string): RpcResult<never> {\n return {\n ok: false,\n error: {\n code: 'internal',\n message: `antigravity-auth: invalid ${endpoint} response from Host`,\n details: {},\n },\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\ntype CapabilityGateStatus = AntigravityStatusView['capabilities'][number]\n","/** Embedded CSS stylesheet for value-safe Antigravity settings UI. */\n\nexport const SETTINGS_CSS = `\n.agy-settings {\n display: flex;\n flex-direction: column;\n gap: 16px;\n width: 100%;\n max-width: 820px;\n margin: 0 auto;\n padding: 4px 0 32px;\n color: var(--dsw-alias-label-primary, #e6edf3);\n font-family: var(--dsw-font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif);\n font-size: 13px;\n line-height: 1.5;\n box-sizing: border-box;\n -webkit-font-smoothing: antialiased;\n}\n\n.agy-settings *,\n.agy-settings *::before,\n.agy-settings *::after {\n box-sizing: border-box;\n}\n\n.agy-bundle-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 20px;\n}\n\n.agy-title-line {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.agy-bundle-title {\n margin: 0;\n font-size: 20px;\n line-height: 28px;\n font-weight: 600;\n letter-spacing: -0.015em;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-status-dot {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #10b981;\n box-shadow: 0 0 8px rgba(16, 185, 129, 0.4);\n flex: none;\n}\n\n.agy-bundle-intro,\n.agy-card-intro {\n margin: 4px 0 0;\n color: var(--dsw-alias-label-tertiary, #8b949e);\n font-size: 13px;\n line-height: 20px;\n}\n\n.agy-cards {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n\n.agy-card {\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 18px 20px;\n border-radius: 16px;\n background: var(--dsw-alias-bg-layer-2, rgba(255, 255, 255, 0.03));\n border: 1px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.08));\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.agy-card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n}\n\n.agy-card-identity {\n min-width: 0;\n flex: 1;\n}\n\n.agy-card-title-line {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.agy-card-title {\n margin: 0;\n font-size: 15px;\n line-height: 22px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-card-action {\n flex: none;\n display: flex;\n align-items: center;\n}\n\n.agy-risk-card {\n background: rgba(234, 179, 8, 0.04);\n border: 1px solid rgba(234, 179, 8, 0.2);\n border-radius: 14px;\n padding: 16px 18px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.agy-risk-text {\n color: var(--dsw-alias-label-secondary, #9ca3af);\n font-size: 13px;\n line-height: 19px;\n margin: 0;\n}\n\n.agy-link-group {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 12px;\n margin: 0;\n}\n\n.agy-link {\n color: var(--dsw-alias-interactive-text, #38bdf8);\n font-size: 12px;\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.agy-link:hover {\n text-decoration: underline;\n color: #7dd3fc;\n}\n\n.agy-ack-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.2));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.06));\n border-radius: 8px;\n cursor: pointer;\n user-select: none;\n font-size: 13px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-checkbox {\n flex: none;\n width: 16px;\n height: 16px;\n margin: 0;\n accent-color: var(--dsw-alias-button-primary-fill, #3b82f6);\n cursor: pointer;\n}\n\n.agy-checkbox:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.agy-facts {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px 16px;\n margin: 0;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-3, rgba(255, 255, 255, 0.02));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.05));\n}\n\n.agy-fact {\n min-width: 0;\n}\n\n.agy-fact dt {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8b949e);\n}\n\n.agy-fact dd {\n margin: 2px 0 0;\n font-size: 13px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #e6edf3);\n overflow-wrap: anywhere;\n font-variant-numeric: tabular-nums;\n}\n\n/* Quota Section */\n.agy-quota-section {\n display: flex;\n flex-direction: column;\n gap: 14px;\n margin-top: 4px;\n}\n\n.agy-quota-group {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.15));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.05));\n box-shadow: inset 0 0 0 1px var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.03));\n}\n\n.agy-quota-group-header {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.agy-quota-group-title {\n margin: 0;\n font-size: 12px;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary, #a1a1aa);\n}\n\n.agy-quota-group-desc {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-label-tertiary, #71717a);\n}\n\n.agy-quota-buckets {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 4px;\n}\n\n.agy-quota-bucket {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.agy-quota-bucket-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 12px;\n line-height: 18px;\n}\n\n.agy-quota-bucket-name {\n font-weight: 500;\n color: var(--dsw-alias-label-secondary, #d4d4d8);\n}\n\n.agy-quota-bucket-val {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace);\n color: var(--dsw-alias-label-primary, #ffffff);\n animation: agy-fade-in 250ms ease;\n}\n\n.agy-quota-bucket-val[data-tone='normal'] {\n color: var(--dsw-alias-state-success-label, #10b981);\n}\n\n.agy-quota-bucket-val[data-tone='warning'] {\n color: var(--dsw-alias-state-warn-label, #f59e0b);\n}\n\n.agy-quota-bucket-val[data-tone='error'] {\n color: var(--dsw-alias-state-error-label, #ef4444);\n}\n\n.agy-quota-querying {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary, #71717a);\n font-size: 12px;\n line-height: 18px;\n animation: agy-fade-in 200ms ease;\n}\n\n.agy-querying-spinner {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n border: 1.5px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.15));\n border-top-color: var(--dsw-alias-brand-primary, #4f6ef7);\n animation: agy-spin 0.8s linear infinite;\n display: inline-block;\n flex: none;\n}\n\n.agy-progress-track {\n position: relative;\n height: 6px;\n width: 100%;\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.2));\n box-shadow: inset 0 0 0 1px var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.08));\n overflow: hidden;\n}\n\n@keyframes agy-fill-progress {\n from {\n transform: scaleX(0);\n opacity: 0.7;\n }\n to {\n transform: scaleX(1);\n opacity: 1;\n }\n}\n\n.agy-progress-bar {\n height: 100%;\n border-radius: 999px;\n transform-origin: left center;\n animation: agy-fill-progress 650ms cubic-bezier(0.16, 1, 0.3, 1) forwards;\n transition: width 400ms cubic-bezier(0.16, 1, 0.3, 1), background 400ms ease;\n}\n\n.agy-progress-bar[data-tone='normal'] {\n background: linear-gradient(90deg, #f59e0b 0%, #10b981 35%, #059669 100%);\n}\n\n.agy-progress-bar[data-tone='warning'] {\n background: linear-gradient(90deg, #ef4444 0%, #f97316 40%, #f59e0b 100%);\n}\n\n.agy-progress-bar[data-tone='error'] {\n background: linear-gradient(90deg, #f87171 0%, #ef4444 50%, #dc2626 100%);\n}\n\n.agy-shimmer-track {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n border-radius: 999px;\n background: linear-gradient(\n 90deg,\n transparent 0%,\n var(--dsw-alias-fill-tertiary, rgba(255, 255, 255, 0.06)) 25%,\n var(--dsw-alias-fill-secondary, rgba(255, 255, 255, 0.14)) 50%,\n var(--dsw-alias-fill-tertiary, rgba(255, 255, 255, 0.06)) 75%,\n transparent 100%\n );\n background-size: 200% 100%;\n animation: agy-shimmer-stream 1.6s ease-in-out infinite;\n}\n\n@keyframes agy-shimmer-stream {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n\n@keyframes agy-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.agy-quota-subtext {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary, #71717a);\n font-variant-numeric: tabular-nums;\n}\n\n/* Actions */\n.agy-action-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n margin-top: 4px;\n}\n\n.agy-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 32px;\n padding: 0 14px;\n border-radius: 999px;\n font-size: 13px;\n font-weight: 500;\n line-height: 20px;\n cursor: pointer;\n border: 1px solid transparent;\n background: var(--dsw-alias-bg-layer-3, rgba(255, 255, 255, 0.08));\n color: var(--dsw-alias-label-primary, #e6edf3);\n text-decoration: none;\n transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;\n}\n\n.agy-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.12));\n}\n\n.agy-btn:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.agy-btn-primary {\n background: var(--dsw-alias-button-primary-fill, #18181b);\n color: var(--dsw-alias-label-primary-foreground, #ffffff);\n border: 1px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.15));\n}\n\n.agy-btn-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, #27272a);\n}\n\n.agy-btn-outline {\n background: transparent;\n border: 1px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.15));\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-btn-outline:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.08));\n}\n\n.agy-btn-ghost {\n background: transparent !important;\n border-color: transparent !important;\n color: var(--dsw-alias-label-secondary, #a1a1aa) !important;\n padding: 0 10px !important;\n border-radius: 6px !important;\n}\n\n.agy-btn-ghost:hover:not(:disabled) {\n background: var(--dsw-alias-fill-tertiary, rgba(255, 255, 255, 0.06)) !important;\n color: var(--dsw-alias-label-primary, #ffffff) !important;\n}\n\n.agy-refresh-btn {\n margin-left: auto;\n}\n\n.agy-footer-notice {\n margin: 6px 0 0;\n color: var(--dsw-alias-label-tertiary, #71717a);\n font-size: 11px;\n line-height: 17px;\n}\n\n.agy-privacy {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary, #6e7681);\n margin: 4px 0 0;\n}\n\n.agy-alert {\n padding: 10px 12px;\n border-radius: 8px;\n font-size: 12px;\n line-height: 18px;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n background: rgba(239, 68, 68, 0.1);\n border: 1px solid rgba(239, 68, 68, 0.25);\n color: #fca5a5;\n}\n\n.agy-item-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.agy-item-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 10px 14px;\n background: var(--dsw-alias-bg-layer-1, rgba(255, 255, 255, 0.02));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.05));\n border-radius: 8px;\n}\n\n.agy-item-title {\n font-size: 13px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 16px;\n white-space: nowrap;\n flex: none;\n}\n\n.agy-badge-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n flex: none;\n}\n\n.agy-badge-available {\n background: rgba(34, 197, 94, 0.12);\n color: #4ade80;\n border: 1px solid rgba(34, 197, 94, 0.25);\n}\n\n.agy-badge-available .agy-badge-dot {\n background: #22c55e;\n}\n\n.agy-badge-disabled {\n background: rgba(148, 163, 184, 0.1);\n color: #94a3b8;\n border: 1px solid rgba(148, 163, 184, 0.2);\n}\n\n.agy-badge-disabled .agy-badge-dot {\n background: #64748b;\n}\n\n.agy-badge-warning {\n background: rgba(234, 179, 8, 0.12);\n color: #facc15;\n border: 1px solid rgba(234, 179, 8, 0.25);\n}\n\n.agy-badge-warning .agy-badge-dot {\n background: #eab308;\n}\n\n.agy-badge-error {\n background: rgba(239, 68, 68, 0.12);\n color: #f87171;\n border: 1px solid rgba(239, 68, 68, 0.25);\n}\n\n.agy-badge-error .agy-badge-dot {\n background: #ef4444;\n}\n\n/* Switch Component */\n.agy-switch {\n position: relative;\n display: inline-flex;\n align-items: center;\n width: 36px;\n height: 20px;\n cursor: pointer;\n user-select: none;\n}\n\n.agy-switch input {\n opacity: 0;\n width: 0;\n height: 0;\n position: absolute;\n}\n\n.agy-switch-slider {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--dsw-alias-bg-layer-4, rgba(255, 255, 255, 0.15));\n border-radius: 20px;\n transition: 0.2s ease;\n}\n\n.agy-switch-slider::before {\n position: absolute;\n content: \"\";\n height: 14px;\n width: 14px;\n left: 3px;\n bottom: 3px;\n background-color: #ffffff;\n border-radius: 50%;\n transition: 0.2s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);\n}\n\n.agy-switch input:checked + .agy-switch-slider {\n background-color: var(--dsw-alias-button-primary-fill, #2563eb);\n}\n\n.agy-switch input:checked + .agy-switch-slider::before {\n transform: translateX(16px);\n}\n\n.agy-switch input:disabled + .agy-switch-slider {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.agy-spin-icon {\n display: inline-flex;\n animation: agy-spin 1s linear infinite;\n}\n\n@keyframes agy-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n`\n\nconst STYLE_ELEMENT_ID = 'dsh-antigravity-auth-styles'\n\nexport function ensureSettingsStyles(): void {\n if (typeof document === 'undefined') return\n if (document.getElementById(STYLE_ELEMENT_ID)) return\n const style = document.createElement('style')\n style.id = STYLE_ELEMENT_ID\n style.textContent = SETTINGS_CSS\n document.head.appendChild(style)\n}\n","/** Settings shell for value-safe Antigravity login status. */\n\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport type { ReactNode } from 'react'\nimport type { ConfigForm, ConfigFormSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { AntigravityAuthRpcClient } from '../rpc-contract.ts'\nimport type { QuotaStatusView } from '../quota.ts'\nimport type { AntigravitySearchSettings } from '../search.ts'\nimport type { AntigravityImageSettings } from '../image.ts'\nimport type { AntigravityVideoSettings } from '../video.ts'\nimport type { RevokeState } from '../credential-coordinator.ts'\nimport type {\n AntigravityStatusView,\n CapabilityRowId,\n LoginErrorCode,\n} from '../status.ts'\nimport type { AntigravityAuthKey } from './locales.ts'\nimport { ensureSettingsStyles } from './styles.ts'\n\nexport interface AntigravityAuthSettingsProps {\n rpc: AntigravityAuthRpcClient\n t: (key: AntigravityAuthKey) => string\n subscribe: (listener: () => void) => () => void\n searchScope?: ConfigForm<AntigravitySearchSettings>\n imageScope?: ConfigForm<AntigravityImageSettings>\n videoScope?: ConfigForm<AntigravityVideoSettings>\n}\n\ntype LoadState = 'loading' | 'ready' | 'error'\ntype BooleanSettings = { readonly enabled: boolean }\ntype SettingsSnapshot = ConfigFormSnapshot<BooleanSettings>\nconst EMPTY_SETTINGS_SNAPSHOT: SettingsSnapshot = { status: 'unavailable', value: undefined, base: undefined, user: undefined, revision: undefined, writable: false, mode: 'memory' }\n\nfunction useCapabilitySettings<T extends BooleanSettings>(scope: ConfigForm<T> | undefined): SettingsSnapshot & { readonly value: T | undefined } {\n const subscribe = useCallback((listener: () => void) => scope?.subscribe(listener) ?? (() => {}), [scope])\n const getSnapshot = useCallback(() => scope?.getSnapshot() ?? EMPTY_SETTINGS_SNAPSHOT, [scope])\n return useSyncExternalStore(subscribe, getSnapshot, () => EMPTY_SETTINGS_SNAPSHOT) as SettingsSnapshot & { readonly value: T | undefined }\n}\n\nfunction useUnmountSignal(): () => AbortSignal {\n const controller = useRef(new AbortController())\n useEffect(() => {\n const active = new AbortController()\n controller.current = active\n return () => active.abort()\n }, [])\n return useCallback(() => controller.current.signal, [])\n}\n\n/** One navigable settings section; credentials remain Host-only and actions use typed RPC. */\nexport function AntigravityAuthSettings({ rpc, t, subscribe, searchScope, imageScope, videoScope }: AntigravityAuthSettingsProps): ReactNode {\n const [status, setStatus] = useState<AntigravityStatusView | null>(null)\n const searchSettings = useCapabilitySettings(searchScope)\n const imageSettings = useCapabilitySettings(imageScope)\n const videoSettings = useCapabilitySettings(videoScope)\n const [quota, setQuota] = useState<QuotaStatusView | null>(null)\n const [quotaBusy, setQuotaBusy] = useState(false)\n const [quotaError, setQuotaError] = useState<string | null>(null)\n const [loadState, setLoadState] = useState<LoadState>('loading')\n const [_error, setError] = useState<string | null>(null)\n const [loginBusy, setLoginBusy] = useState(false)\n const [actionBusy, setActionBusy] = useState(false)\n const [resetTick, setResetTick] = useState(0)\n const statusGeneration = useRef(0)\n const quotaGeneration = useRef(0)\n const unmountSignal = useUnmountSignal()\n\n useEffect(() => {\n ensureSettingsStyles()\n }, [])\n\n useEffect(() => subscribe(() => { setResetTick(value => value + 1) }), [subscribe])\n\n const load = useCallback(async (signal?: AbortSignal, silent = false) => {\n const generation = ++statusGeneration.current\n if (!silent) {\n setLoadState(prev => (prev === 'ready' ? 'ready' : 'loading'))\n setError(null)\n }\n try {\n const result = await rpc.status(signal)\n if (signal?.aborted === true || generation !== statusGeneration.current) return\n if (!result.ok) {\n setLoadState('error')\n setError(result.error.message || t('statusFailed'))\n return\n }\n setStatus(result.value.status)\n setLoadState('ready')\n } catch (cause) {\n if (signal?.aborted === true || generation !== statusGeneration.current) return\n setLoadState('error')\n setError(messageOf(cause, t('statusFailed')))\n }\n }, [rpc, t])\n\n const loadQuota = useCallback(async (force = false, signal?: AbortSignal) => {\n if (rpc.usage === undefined) return\n const generation = ++quotaGeneration.current\n setQuotaBusy(true)\n setQuotaError(null)\n try {\n const result = await rpc.usage(signal, force)\n if (signal?.aborted === true || generation !== quotaGeneration.current) return\n if (!result.ok) {\n setQuotaError(result.error.message || t('quotaFailed'))\n return\n }\n setQuota(result.value)\n } catch (cause) {\n if (signal?.aborted === true || generation !== quotaGeneration.current) return\n setQuotaError(messageOf(cause, t('quotaFailed')))\n } finally {\n if (signal?.aborted !== true && generation === quotaGeneration.current) setQuotaBusy(false)\n }\n }, [rpc, t])\n\n useEffect(() => {\n if (status?.login.projectAvailable !== true || rpc.usage === undefined) {\n setQuota(null)\n return\n }\n const controller = new AbortController()\n void loadQuota(false, controller.signal)\n return () => controller.abort()\n }, [loadQuota, rpc.usage, status?.login.projectAvailable, resetTick])\n\n useEffect(() => {\n const controller = new AbortController()\n void load(controller.signal)\n return () => controller.abort()\n }, [load, resetTick])\n\n useEffect(() => {\n if (status?.login.phase !== 'pending') return\n const controller = new AbortController()\n const timer = globalThis.setInterval(() => { void load(controller.signal, true) }, 1_000)\n return () => {\n globalThis.clearInterval(timer)\n controller.abort()\n }\n }, [load, status?.login.phase])\n\n const startLogin = useCallback(async () => {\n const signal = unmountSignal()\n setLoginBusy(true)\n setError(null)\n try {\n if (status?.riskAcknowledged !== true) {\n await rpc.acknowledgeRisk(signal)\n }\n const result = await rpc.login(signal)\n if (signal.aborted) return\n if (!result.ok) {\n setError(result.error.message || t('loginFailed'))\n await load(signal)\n return\n }\n try {\n if (typeof window !== 'undefined' && typeof window.open === 'function' && result.value?.authorizationUrl && !window.navigator?.userAgent?.includes('jsdom')) {\n window.open(result.value.authorizationUrl, '_blank')\n }\n } catch {}\n setStatus(previous => {\n if (previous === null) return previous\n const { errorCode: _ignoredErrorCode, ...login } = previous.login\n return {\n ...previous,\n riskAcknowledged: true,\n login: {\n ...login,\n phase: 'pending',\n authorizationUrl: result.value.authorizationUrl,\n expiresAt: result.value.expiresAt,\n },\n }\n })\n } catch (cause) {\n if (!signal.aborted) setError(messageOf(cause, t('loginFailed')))\n } finally {\n if (!signal.aborted) setLoginBusy(false)\n }\n }, [load, rpc, status?.riskAcknowledged, t, unmountSignal])\n\n const cancelLogin = useCallback(async () => {\n const signal = unmountSignal()\n setLoginBusy(true)\n setError(null)\n try {\n const result = await rpc.cancelLogin(signal)\n if (signal.aborted) return\n if (!result.ok) {\n setError(result.error.message || t('cancelLoginFailed'))\n return\n }\n setStatus(previous => {\n if (previous === null) return previous\n const { errorCode: _ignoredErrorCode, ...login } = previous.login\n return {\n ...previous,\n login: result.value.errorCode === undefined\n ? { ...login, phase: result.value.phase }\n : { ...login, phase: result.value.phase, errorCode: result.value.errorCode },\n }\n })\n } catch (cause) {\n if (!signal.aborted) setError(messageOf(cause, t('cancelLoginFailed')))\n } finally {\n if (!signal.aborted) setLoginBusy(false)\n }\n }, [rpc, t, unmountSignal])\n\n const logout = useCallback(async () => {\n const signal = unmountSignal()\n setActionBusy(true)\n setError(null)\n try {\n const result = await rpc.logout(signal)\n if (signal.aborted) return\n if (!result.ok) {\n setError(result.error.message || t('logoutFailed'))\n return\n }\n await load(signal)\n } catch (cause) {\n if (!signal.aborted) setError(messageOf(cause, t('logoutFailed')))\n } finally {\n if (!signal.aborted) setActionBusy(false)\n }\n }, [load, rpc, t, unmountSignal])\n\n const projectError = projectErrorText(status?.login.errorCode, t)\n const isConfigured = status?.login.configured === true\n\n return (\n <section className=\"agy-settings\" data-plugin=\"dsh-antigravity-auth\" aria-labelledby=\"antigravity-auth-title\">\n <header className=\"agy-bundle-header\">\n <div>\n <div className=\"agy-title-line\">\n <h1 id=\"antigravity-auth-title\" className=\"agy-bundle-title\">{t('title')}</h1>\n {isConfigured ? (\n <span className=\"agy-status-dot\" role=\"status\" aria-label={t('ready')} />\n ) : null}\n </div>\n <p className=\"agy-bundle-intro\">{t('intro')}</p>\n </div>\n </header>\n\n <div className=\"agy-cards\">\n {/* Card 1: Auth & Quota */}\n <article className=\"agy-card\" aria-labelledby=\"antigravity-auth-card-title\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 id=\"antigravity-auth-card-title\" className=\"agy-card-title\">{t('authCardTitle')}</h2>\n <p className=\"agy-card-intro\">{t('authCardIntro')}</p>\n </div>\n </div>\n\n <QuotaVisualDashboard\n quota={quota}\n busy={quotaBusy}\n error={quotaError}\n onRefresh={() => { void loadQuota(true, unmountSignal()) }}\n t={t}\n />\n\n <div className=\"agy-action-row\">\n {status?.login.phase === 'pending' && typeof status.login.authorizationUrl === 'string' ? (\n <>\n <a className=\"agy-btn agy-btn-primary\" href={status.login.authorizationUrl} target=\"_blank\" rel=\"noreferrer\">\n {t('openAuthorization')}\n </a>\n <button className=\"agy-btn agy-btn-outline\" type=\"button\" disabled={loginBusy} onClick={() => { void cancelLogin() }}>\n {t('cancelLogin')}\n </button>\n </>\n ) : (\n <button className=\"agy-btn agy-btn-primary\" type=\"button\" disabled={status === null || loginBusy} onClick={() => { void startLogin() }}>\n {loginBusy ? t('startingLogin') : isConfigured ? t('relogin') : t('login')}\n </button>\n )}\n\n {isConfigured ? (\n <button className=\"agy-btn agy-btn-outline\" type=\"button\" disabled={actionBusy} onClick={() => { void logout() }}>\n {t('logout')}\n </button>\n ) : null}\n\n <button\n className=\"agy-btn agy-btn-ghost agy-refresh-btn\"\n type=\"button\"\n disabled={loadState === 'loading' || quotaBusy}\n onClick={() => {\n const minDelay = new Promise(resolve => setTimeout(resolve, 500))\n void Promise.all([load(unmountSignal()), loadQuota(true, unmountSignal()), minDelay])\n }}\n >\n <span className={quotaBusy || loadState === 'loading' ? 'agy-spin-icon' : ''}>\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/><path d=\"M3 3v5h5\"/><path d=\"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\"/><path d=\"M16 21h5v-5\"/></svg>\n </span>\n {quotaBusy || loadState === 'loading' ? t('queryingQuota') : t('refreshStatus')}\n </button>\n </div>\n <p className=\"agy-footer-notice\">{t('quotaFooterNotice')}</p>\n\n {status?.login.phase === 'expired' ? <p className=\"agy-alert\" role=\"alert\">{t('loginExpired')}</p> : null}\n {status?.login.phase === 'port-conflict' ? <p className=\"agy-alert\" role=\"alert\">{t('loginPortConflict')}</p> : null}\n {status?.login.phase === 'failed' ? <p className=\"agy-alert\" role=\"alert\">{t('loginFailed')}</p> : null}\n {projectError === undefined ? null : <p className=\"agy-alert\" role=\"alert\">{projectError}</p>}\n {status?.login.phase === 'pending' && status.login.expiresAt !== undefined ? (\n <p className=\"agy-card-subtext\">{t('expiresAt')}: <time dateTime={status.login.expiresAt}>{status.login.expiresAt}</time></p>\n ) : null}\n {status?.revoke === undefined || status.revoke.state === 'idle' ? null : (\n <p className=\"agy-card-subtext\" role=\"status\">{revokeStatusText(status.revoke.state, t)}</p>\n )}\n </article>\n\n {/* Card 2: Web Search */}\n <article className=\"agy-card\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 className=\"agy-card-title\">{t('search')}</h2>\n <p className=\"agy-card-intro\">{t('searchCardIntro')}</p>\n </div>\n <div className=\"agy-card-action\">\n <Switch\n label={t('toggleSearch')}\n checked={searchSettings.value?.enabled ?? false}\n disabled={!capabilityAvailable(status, 'search') || searchSettings.status !== 'ready' || !searchSettings.writable}\n onChange={next => { void searchScope?.set('enabled', next) }}\n />\n </div>\n </div>\n </article>\n\n {/* Card 3: Image Creation */}\n <article className=\"agy-card\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 className=\"agy-card-title\">{t('image')}</h2>\n <p className=\"agy-card-intro\">{t('imageCardIntro')}</p>\n </div>\n <div className=\"agy-card-action\">\n <Switch\n label={t('toggleImage')}\n checked={imageSettings.value?.enabled ?? false}\n disabled={!capabilityAvailable(status, 'image') || imageSettings.status !== 'ready' || !imageSettings.writable}\n onChange={next => { void imageScope?.set('enabled', next) }}\n />\n </div>\n </div>\n </article>\n\n {/* Card 4: Video Analysis */}\n <article className=\"agy-card\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 className=\"agy-card-title\">{t('video')}</h2>\n <p className=\"agy-card-intro\">{t('videoCardIntro')}</p>\n </div>\n <div className=\"agy-card-action\">\n <Switch\n label={t('toggleVideo')}\n checked={videoSettings.value?.enabled ?? false}\n disabled={!capabilityAvailable(status, 'video') || videoSettings.status !== 'ready' || !videoSettings.writable}\n onChange={next => { void videoScope?.set('enabled', next) }}\n />\n </div>\n </div>\n </article>\n </div>\n </section>\n )\n}\n\nfunction capabilityAvailable(status: AntigravityStatusView | null, id: CapabilityRowId): boolean {\n return status?.login.projectAvailable === true && status.capabilities.some(capability => capability.id === id && capability.state === 'available')\n}\n\nfunction Switch({\n label,\n checked,\n disabled,\n onChange,\n}: {\n readonly label: string\n readonly checked: boolean\n readonly disabled?: boolean\n readonly onChange: (checked: boolean) => void\n}): ReactNode {\n return (\n <label className=\"agy-switch\">\n <input\n type=\"checkbox\"\n aria-label={label}\n checked={checked}\n disabled={disabled}\n onChange={e => { onChange(e.target.checked) }}\n />\n <span className=\"agy-switch-slider\" />\n </label>\n )\n}\n\nfunction formatRefreshTime(resetTime: string, dayUnit: string, now = Date.now()): string {\n const target = new Date(resetTime).getTime()\n if (Number.isNaN(target)) return resetTime\n const diffMs = target - now\n if (diffMs <= 0) return '0m'\n const diffMinutes = Math.floor(diffMs / (60 * 1000))\n const hours = Math.floor(diffMinutes / 60)\n const remMinutes = diffMinutes % 60\n\n if (hours >= 24) {\n const days = Math.floor(hours / 24)\n return `${days}${dayUnit} ${hours % 24}h ${remMinutes}m`\n }\n if (hours > 0) {\n return `${hours}h ${remMinutes}m`\n }\n return `${remMinutes}m`\n}\n\nfunction quotaTone(fraction: number): 'normal' | 'warning' | 'error' {\n if (fraction < 0.3) return 'error'\n if (fraction <= 0.6) return 'warning'\n return 'normal'\n}\n\nfunction QuotaVisualDashboard({\n quota,\n busy,\n error,\n t,\n}: {\n readonly quota: QuotaStatusView | null\n readonly busy?: boolean\n readonly error: string | null\n readonly onRefresh?: () => void\n readonly t: AntigravityAuthSettingsProps['t']\n}): ReactNode {\n return (\n <div className=\"agy-quota-section\">\n {quota?.state === 'available' && quota.groups !== undefined && quota.groups.length > 0 ? (\n <div className=\"agy-quota-groups\">\n {quota.groups.map(group => {\n const groupTitle = group.group === 'gemini' ? t('geminiGroupTitle') : t('claudeGptGroupTitle')\n const groupDesc = group.group === 'gemini' ? t('geminiGroupDesc') : t('claudeGptGroupDesc')\n return (\n <div key={group.group} className=\"agy-quota-group\">\n <div className=\"agy-quota-group-header\">\n <span className=\"agy-quota-group-title\">{groupTitle}</span>\n <span className=\"agy-quota-group-desc\">{groupDesc}</span>\n </div>\n <div className=\"agy-quota-buckets\">\n {group.windows.map(window => {\n const windowName = window.window === '5h' ? t('window5hTitle') : t('windowWeeklyTitle')\n const pctFormatted = (window.remainingFraction * 100).toFixed(2) + '%'\n const pctRounded = Math.round(window.remainingFraction * 100)\n const refreshStr = formatRefreshTime(window.resetTime, t('quotaDayUnit'))\n const subtext = `${pctRounded}% ${t('remaining')} · ${t('refreshesIn').replace('{time}', refreshStr)}`\n const widthPct = Math.max(0, Math.min(100, window.remainingFraction * 100))\n const tone = quotaTone(window.remainingFraction)\n\n return (\n <div key={window.window} className=\"agy-quota-bucket\">\n <div className=\"agy-quota-bucket-head\">\n <span className=\"agy-quota-bucket-name\">{windowName}</span>\n {busy ? (\n <span className=\"agy-quota-querying\">\n <span className=\"agy-querying-spinner\" aria-hidden=\"true\" />\n <span>{t('queryingQuota')}</span>\n </span>\n ) : (\n <span className=\"agy-quota-bucket-val\" data-tone={tone}>{pctFormatted}</span>\n )}\n </div>\n <div className=\"agy-progress-track\">\n {busy ? (\n <div className=\"agy-shimmer-track\" aria-hidden=\"true\" />\n ) : (\n <div className=\"agy-progress-bar\" data-tone={tone} style={{ width: `${widthPct}%` }} />\n )}\n </div>\n <span className=\"agy-quota-subtext\">{subtext}</span>\n </div>\n )\n })}\n </div>\n </div>\n )\n })}\n </div>\n ) : null}\n {error === null ? null : <p className=\"agy-alert\" role=\"alert\">{error}</p>}\n </div>\n )\n}\n\nconst PROJECT_ERROR_KEYS: Readonly<Partial<Record<LoginErrorCode, AntigravityAuthKey>>> = {\n 'project-unavailable': 'projectUnavailable',\n 'project-authentication-failed': 'projectAuthenticationFailed',\n 'project-forbidden': 'projectForbidden',\n 'project-rate-limited': 'projectRateLimited',\n 'project-offline': 'projectOffline',\n 'project-malformed': 'projectMalformed',\n 'project-protocol-drift': 'projectProtocolDrift',\n}\nconst REVOKE_STATE_KEYS: Readonly<Record<RevokeState, AntigravityAuthKey>> = {\n idle: 'credentialLoggedOut',\n 'logged-out': 'credentialLoggedOut',\n pending: 'revokePending',\n revoked: 'revokeSuccess',\n failed: 'revokeFailed',\n superseded: 'revokeSuperseded',\n 'confirmation-required': 'revokeConfirmationRequired',\n}\n\nfunction projectErrorText(errorCode: LoginErrorCode | undefined, t: AntigravityAuthSettingsProps['t']): string | undefined {\n if (errorCode === undefined) return undefined\n const key = PROJECT_ERROR_KEYS[errorCode]\n return key === undefined ? undefined : t(key)\n}\n\nfunction revokeStatusText(state: RevokeState, t: AntigravityAuthSettingsProps['t']): string {\n return t(REVOKE_STATE_KEYS[state])\n}\n\nfunction messageOf(_error: unknown, fallback: string): string {\n return fallback\n}\n","/** English and Chinese copy for the private bootstrap settings section. */\n\nexport const en = {\n nav: 'Antigravity',\n title: 'Antigravity Auth',\n intro: 'Sign in with Antigravity Auth to access language models, image generation, web search, and video understanding.',\n riskTitle: 'Before you continue',\n risk: 'Google does not support third-party Antigravity login tools. Your account may be suspended or terminated.',\n terms: 'Review the Google FAQ before continuing.',\n additionalTerms: 'Review the Additional Terms.',\n singleAccount: 'One active account at a time. This bundle does not provide an account pool or quota rotation.',\n riskAcknowledgement: 'I understand the unofficial third-party login risk and want to continue.',\n acknowledgeBusy: 'Saving acknowledgement…',\n acknowledgeFailed: 'The risk acknowledgement could not be recorded.',\n login: 'Start Antigravity login',\n startingLogin: 'Starting login…',\n cancelLogin: 'Cancel login',\n cancelLoginFailed: 'The login cancellation failed.',\n openAuthorization: 'Open the Google authorization page',\n loginReady: 'Login is ready to start.',\n loginRequiresAck: 'Acknowledge the risk before login can begin.',\n loginPending: 'Login is waiting for the browser authorization callback.',\n loginSuccess: 'Login completed successfully.',\n loginCancelled: 'Login was cancelled.',\n loginExpired: 'The login expired. Start again to receive a new authorization link.',\n loginPortConflict: 'The fixed callback port is already in use. Close the conflicting process and try again.',\n loginFailed: 'The login could not be completed safely.',\n credentialLoggedIn: 'The Antigravity account is ready.',\n credentialRefreshing: 'Refreshing the Antigravity access token…',\n credentialRefreshFailed: 'The access token could not be refreshed. No fallback account or endpoint was used.',\n credentialReloginRequired: 'The Antigravity grant requires login again.',\n credentialLoggedOut: 'The Antigravity account is logged out on this Host.',\n logout: 'Log out locally',\n logoutFailed: 'The local logout could not be completed.',\n revoke: 'Revoke Google grant',\n revokeConfirm: 'Revoke this Google grant? This is separate from local logout.',\n revokePending: 'Revoking the Google grant…',\n revokeSuccess: 'The Google grant was revoked and local state was cleared.',\n revokeFailed: 'The Google grant could not be revoked. Local state was retained.',\n revokeSuperseded: 'The account changed before revocation completed. No newer account was cleared.',\n revokeConfirmationRequired: 'Confirm revocation before contacting Google.',\n account: 'Account',\n projectAvailable: 'Read-only project validation is available.',\n projectUnavailable: 'No usable project is available.',\n projectAuthenticationFailed: 'Project discovery requires a fresh authenticated grant.',\n projectForbidden: 'This account is not allowed to use the discovered project.',\n projectRateLimited: 'Project discovery was rate-limited. No fallback project was used.',\n projectOffline: 'Project discovery is temporarily offline. No fallback project was used.',\n projectMalformed: 'Project discovery returned a malformed response.',\n projectProtocolDrift: 'Project discovery no longer matches the audited protocol.',\n expiresAt: 'Authorization link expires',\n statusLoading: 'Loading capability status…',\n statusFailed: 'Capability status is unavailable.',\n retry: 'Retry',\n capabilityTitle: 'Capability gates',\n authLlm: 'Auth / LLM',\n search: 'Web Search',\n image: 'Image',\n video: 'Video',\n available: 'Available',\n ready: 'Ready',\n disabled: 'Disabled',\n pocPending: 'POC pending',\n protocolDrift: 'Protocol drift',\n gateNotRun: 'This capability gate has not been run.',\n gateUnauthenticated: 'This gate requires a fresh authenticated grant.',\n gateRateLimited: 'This gate was rate-limited; no fallback was attempted.',\n gateCancelled: 'This gate run was cancelled.',\n gate0Failed: 'The fixed Wire Identity was rejected by Gate 0.',\n gateFailed: 'This capability gate failed safely.',\n unsupportedVideo: 'The private endpoint rejected native video input.',\n acknowledged: 'Risk acknowledged for this Host session.',\n settingsTitle: 'Capability settings',\n toggleSearch: 'Enable grounded Web Search',\n toggleImage: 'Enable image generation and editing',\n toggleVideo: 'Enable video understanding POC',\n settingsUnavailable: 'Unavailable until login, project validation, the live gate, and a writable Host settings scope are ready.',\n modelsTitle: 'Models',\n modelsSnapshot: 'Showing the pinned audited snapshot; live availability has not been refreshed.',\n modelsLiveAvailable: 'Live account availability was intersected with the pinned snapshot.',\n modelsRefreshFailed: 'Live availability refresh failed safely; the pinned snapshot remains advisory.',\n modelsProtocolDrift: 'Live model discovery no longer matches the audited protocol.',\n modelsSnapshotEntry: 'Snapshot',\n modelsAvailableEntry: 'Live available',\n modelsUnavailableEntry: 'Unavailable to this account',\n modelsFailed: 'Model availability could not be loaded safely.',\n modelsLoading: 'Refreshing models…',\n modelsRefresh: 'Refresh model availability',\n quotaTitle: 'Usage and quota',\n quotaAvailable: 'Quota is available from the current account.',\n quotaUnknown: 'Quota has not been queried.',\n quotaUnauthenticated: 'Log in to query quota.',\n quotaForbidden: 'This account is not allowed to query quota.',\n quotaRateLimited: 'Quota is rate-limited; try again later.',\n quotaOffline: 'Quota is temporarily unavailable.',\n quotaProtocolDrift: 'Quota protocol drift was detected; raw provider data was discarded.',\n quotaFailed: 'Quota could not be loaded safely.',\n quotaLoading: 'Refreshing quota…',\n quotaRefresh: 'Refresh quota',\n quotaFiveHour: 'Five-hour window',\n quotaWeekly: 'Weekly window',\n searchCardIntro: 'Google Antigravity Search Provider used by the stock web_search tool.',\n imageCardIntro: 'Durable image generation tools for image-capable models (gemini-3.1-flash-image).',\n videoCardIntro: 'Workspace MP4 video understanding tools for multimodal models (gemini-3.7-flash).',\n privacyNotice: 'Share Antigravity login state and model routing.',\n relogin: 'Log in again with Google',\n authCardTitle: 'Login',\n authCardIntro: 'Share Antigravity session and Antigravity model routing.',\n queryingQuota: 'Querying quota…',\n geminiGroupTitle: 'GEMINI MODELS',\n geminiGroupDesc: 'Models within this group: Gemini Flash, Gemini Pro',\n claudeGptGroupTitle: 'CLAUDE AND GPT MODELS',\n claudeGptGroupDesc: 'Models within this group: Claude Opus, Claude Sonnet, GPT-OSS',\n window5hTitle: 'Five Hour Limit Remaining',\n windowWeeklyTitle: 'Weekly Limit Remaining',\n quotaFooterNotice: 'No token value is ever sent to the Web client, settings, logs, events, or tool metadata.',\n refreshStatus: 'Refresh status',\n remaining: 'remaining',\n refreshesIn: 'Refreshes in {time}',\n quotaDayUnit: 'd',\n} as const\n\nexport type AntigravityAuthKey = keyof typeof en\n\nexport const zh: Record<AntigravityAuthKey, string> = {\n nav: 'Antigravity',\n title: 'Antigravity Auth',\n intro: '通过 Antigravity Auth 登录,使用语言模型、图片生成、网页搜索和视频理解能力。',\n riskTitle: '继续前请确认',\n risk: 'Google 不支持第三方 Antigravity 登录工具,账号可能被暂停或终止。',\n terms: '继续前请阅读 Google FAQ。',\n additionalTerms: '请阅读 Additional Terms。',\n singleAccount: '同一时刻只有一个活动账号。本能力包不提供账号池或额度轮换。',\n riskAcknowledgement: '我已了解非官方第三方登录风险,并确认继续。',\n acknowledgeBusy: '正在保存确认…',\n acknowledgeFailed: '无法记录风险确认。',\n login: '开始 Antigravity 登录',\n startingLogin: '正在启动登录…',\n cancelLogin: '取消登录',\n cancelLoginFailed: '取消登录失败。',\n openAuthorization: '打开 Google 授权页面',\n loginReady: '可以开始登录。',\n loginRequiresAck: '请先确认风险,才能开始登录。',\n loginPending: '等待浏览器授权回调。',\n loginSuccess: '登录已成功完成。',\n loginCancelled: '登录已取消。',\n loginExpired: '登录已过期,请重新开始以获取新的授权链接。',\n loginPortConflict: '固定回调端口已被占用,请关闭冲突进程后重试。',\n loginFailed: '登录无法安全完成。',\n credentialLoggedIn: 'Antigravity 账号已就绪。',\n credentialRefreshing: '正在刷新 Antigravity access token…',\n credentialRefreshFailed: '无法刷新 access token,未使用备用账号或 endpoint。',\n credentialReloginRequired: '该 Antigravity grant 需要重新登录。',\n credentialLoggedOut: '该 Host 上的 Antigravity 账号已登出。',\n logout: '在本地登出',\n logoutFailed: '本地登出未完成。',\n revoke: '撤销 Google grant',\n revokeConfirm: '确定撤销此 Google grant 吗?这与本地登出是分开的操作。',\n revokePending: '正在撤销 Google grant…',\n revokeSuccess: 'Google grant 已撤销,本地状态已清除。',\n revokeFailed: '无法撤销 Google grant,本地状态已保留。',\n revokeSuperseded: '账号在撤销完成前发生变化,未清除新账号。',\n revokeConfirmationRequired: '请先确认撤销,再联系 Google。',\n account: '账号',\n projectAvailable: '只读 project 验证可用。',\n projectUnavailable: '没有可用的 project。',\n projectAuthenticationFailed: 'project discovery 需要重新认证的 grant。',\n projectForbidden: '该账号没有权限使用已发现的 project。',\n projectRateLimited: 'project discovery 被限流,未使用备用 project。',\n projectOffline: 'project discovery 暂时离线,未使用备用 project。',\n projectMalformed: 'project discovery 返回了格式错误的响应。',\n projectProtocolDrift: 'project discovery 已偏离经过审计的协议。',\n expiresAt: '授权链接过期时间',\n statusLoading: '正在加载能力状态…',\n statusFailed: '能力状态不可用。',\n retry: '重试',\n capabilityTitle: '能力门禁',\n authLlm: '认证 / LLM',\n search: '网页搜索',\n image: '图片',\n video: '视频',\n available: '可用',\n ready: '就绪',\n disabled: '已禁用',\n pocPending: 'POC 待验证',\n protocolDrift: '协议漂移',\n gateNotRun: '该能力门禁尚未运行。',\n gateUnauthenticated: '该门禁需要新的有效认证 grant。',\n gateRateLimited: '该门禁运行被限流,未尝试任何 fallback。',\n gateCancelled: '该门禁运行已取消。',\n gate0Failed: '固定 Wire Identity 未通过 Gate 0。',\n gateFailed: '该能力门禁已安全失败。',\n unsupportedVideo: '私有 endpoint 拒绝了原生视频输入。',\n acknowledged: '本 Host 会话已确认风险。',\n settingsTitle: '能力设置',\n toggleSearch: '启用有依据的网页搜索',\n toggleImage: '启用图片生成与编辑',\n toggleVideo: '启用视频理解 POC',\n settingsUnavailable: '登录、project 验证、对应 live gate 和可写 Host 设置范围就绪后才能使用。',\n modelsTitle: '模型',\n modelsSnapshot: '当前显示已审计的固定快照;尚未刷新真实账号可用性。',\n modelsLiveAvailable: '已将真实账号可用性与固定快照取交集。',\n modelsRefreshFailed: '真实可用性刷新已安全失败;固定快照仍仅供参考。',\n modelsProtocolDrift: '真实模型发现已不再符合已审计协议。',\n modelsSnapshotEntry: '固定快照',\n modelsAvailableEntry: '真实可用',\n modelsUnavailableEntry: '当前账号不可用',\n modelsFailed: '无法安全加载模型可用性。',\n modelsLoading: '正在刷新模型…',\n modelsRefresh: '刷新模型可用性',\n quotaTitle: '用量与配额',\n quotaAvailable: '当前账号的配额可用。',\n quotaUnknown: '尚未查询配额。',\n quotaUnauthenticated: '登录后才能查询配额。',\n quotaForbidden: '该账号无权查询配额。',\n quotaRateLimited: '配额查询被限流,请稍后重试。',\n quotaOffline: '配额暂时不可用。',\n quotaProtocolDrift: '检测到配额协议漂移,已丢弃原始 provider 数据。',\n quotaFailed: '无法安全加载配额。',\n quotaLoading: '正在刷新配额…',\n quotaRefresh: '刷新配额',\n quotaFiveHour: '五小时窗口',\n quotaWeekly: '每周窗口',\n searchCardIntro: '供内置 web_search 工具使用的 Google Antigravity 全局搜索能力。',\n imageCardIntro: '面向支持图片模型的持久化 generate_image 工具(gemini-3.1-flash-image)。',\n videoCardIntro: '面向本地 MP4 视频文件的多模态 analyze_video 理解工具。',\n privacyNotice: '共享 Antigravity 登录态与模型路由。',\n relogin: '重新登录 Google',\n authCardTitle: '登录',\n authCardIntro: '共享 Antigravity 登录态与 Antigravity 模型路由。',\n queryingQuota: '正在查询额度…',\n geminiGroupTitle: 'GEMINI 模型',\n geminiGroupDesc: '包含模型:Gemini Flash, Gemini Pro',\n claudeGptGroupTitle: 'CLAUDE 与 GPT 模型',\n claudeGptGroupDesc: '包含模型:Claude Opus, Claude Sonnet, GPT-OSS',\n window5hTitle: '5 小时限额剩余',\n windowWeeklyTitle: '周限额剩余',\n quotaFooterNotice: '任何 Token 值都不会发送到 Web 客户端、设置、日志、事件或工具元数据。',\n refreshStatus: '刷新状态',\n remaining: '剩余',\n refreshesIn: '{time} 后刷新',\n quotaDayUnit: '天',\n}\n","/** Browser half of the private Antigravity bootstrap capability bundle. */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { createAntigravityAuthRpcClient } from '../rpc-contract.ts'\nimport { AntigravityAuthSettings } from './AntigravityAuthSettings.tsx'\nimport { en, zh, type AntigravityAuthKey } from './locales.ts'\nimport type { AntigravityAuthSettingsProps } from './AntigravityAuthSettings.tsx'\nimport type { AntigravitySearchSettings } from '../search.ts'\nimport type { AntigravityImageSettings } from '../image.ts'\nimport type { AntigravityVideoSettings } from '../video.ts'\n\nconst NS = 'settings.antigravityAuth'\n\nexport { AntigravityAuthSettings } from './AntigravityAuthSettings.tsx'\nexport type { AntigravityAuthSettingsProps } from './AntigravityAuthSettings.tsx'\nexport { en, zh } from './locales.ts'\nexport type { AntigravityAuthKey } from './locales.ts'\n\n/** Client services required by the settings section and its loopback RPC. */\nexport const inject = ['slots', 'locale', 'connection', 'configForms']\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Copy for the Antigravity bootstrap settings section. */\n 'settings.antigravityAuth': AntigravityAuthKey\n }\n}\n\n/** Register one disposable settings section and no capability controls. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'antigravity-auth: copy dictionaries')\n\n const connection = ctx.get('connection') as unknown as ConnectionHandle\n if (!connection.isLoopback) return\n const rpc = createAntigravityAuthRpcClient(connection.rpc)\n const t = ctx.locale.bind(NS) as AntigravityAuthSettingsProps['t']\n const searchScope = ctx.configForms.get<AntigravitySearchSettings>('antigravity-search')\n const imageScope = ctx.configForms.get<AntigravityImageSettings>('antigravity-image')\n const videoScope = ctx.configForms.get<AntigravityVideoSettings>('antigravity-video')\n const listeners = new Set<() => void>()\n const subscribe = (listener: () => void): (() => void) => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n }\n const reset = (): void => {\n for (const listener of listeners) listener()\n }\n ctx.effect(() => ctx.on('connection/reset', reset), 'antigravity-auth: connection invalidation')\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'antigravity-auth',\n order: 20,\n label: () => t('nav'),\n inject: (): AntigravityAuthSettingsProps => ({ rpc, t, subscribe, searchScope, imageScope, videoScope }),\n }, AntigravityAuthSettings))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.cjs","names":["useCallback","useSyncExternalStore","useRef","useState"],"sources":["../src/status.ts","../src/login-types.ts","../src/model-catalog.ts","../src/rpc-vocabulary.ts","../src/safe-text.ts","../src/rpc-contract.ts","../src/client/styles.ts","../src/client/AntigravityAuthSettings.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/** Value-free login and capability status shared by Host and browser code. */\n\nimport type { LoginActionResult, LoginCompletionResult, LoginErrorCode, LoginPhase, LoginStartResult, LoginStatusView } from './login-types.ts'\nimport type { CredentialStatusView, LogoutResult, RevokeActionResult, RevokeStatusView } from './credential-coordinator.ts'\nimport type { QuotaStatusView } from './quota.ts'\n\nexport const ANTIGRAVITY_PLUGIN_ID = 'dsh-antigravity-auth' as const\nexport const CAPABILITY_ROW_IDS = ['auth-llm', 'search', 'image', 'video'] as const\nexport const LLM_FAMILY_IDS = ['gemini', 'claude', 'gpt-oss'] as const\n\nexport type CapabilityRowId = (typeof CAPABILITY_ROW_IDS)[number]\nexport type LlmFamilyId = (typeof LLM_FAMILY_IDS)[number]\nexport type CapabilityGateState = 'available' | 'disabled' | 'poc-pending' | 'protocol-drift'\nexport type CapabilityGateReasonCode =\n | 'gate-not-run'\n | 'project-unavailable'\n | 'capability-ready'\n | 'unauthenticated'\n | 'rate-limited'\n | 'cancelled'\n | 'gate-0-failed'\n | 'gate-failed'\n | 'unsupported-video'\n | 'protocol-drift'\n\nexport const CAPABILITY_GATE_OUTCOMES = [\n 'passed',\n 'unauthenticated',\n 'rate-limited',\n 'cancelled',\n 'attribution-rejected',\n 'protocol-drift',\n 'unsupported-video',\n 'failed',\n] as const\n\nexport type CapabilityGateOutcome = (typeof CAPABILITY_GATE_OUTCOMES)[number]\n\nexport interface CapabilityGateResult {\n readonly outcome: CapabilityGateOutcome\n readonly checkedAt: string\n}\n\nexport interface CapabilityGateEvidence {\n /** Credential-lineage fence; evidence from another account is ignored. */\n readonly subject?: string\n readonly gate0?: CapabilityGateResult\n readonly llmFamilies?: Readonly<Partial<Record<LlmFamilyId, CapabilityGateResult>>>\n readonly capabilities?: Readonly<Partial<Record<CapabilityRowId, CapabilityGateResult>>>\n}\nexport type { LoginActionResult, LoginErrorCode, LoginPhase, LoginStartResult, LoginStatusView }\n\nexport interface CapabilityGateStatus {\n readonly id: CapabilityRowId\n readonly state: CapabilityGateState\n readonly reasonCode: CapabilityGateReasonCode\n}\n\nexport interface AntigravityStatusView {\n readonly pluginId: typeof ANTIGRAVITY_PLUGIN_ID\n readonly phase: 'bootstrap'\n readonly privateSelfUse: true\n readonly singleAccount: true\n readonly riskAcknowledgementRequired: true\n readonly riskAcknowledged: boolean\n readonly login: LoginStatusView\n /** Credential state is value-safe; tokens and grant errors never cross this boundary. */\n readonly credential?: CredentialStatusView\n readonly revoke?: RevokeStatusView\n readonly capabilities: readonly CapabilityGateStatus[]\n}\n\nexport interface RiskAcknowledgementResult {\n readonly acknowledged: true\n}\n\nexport interface BootstrapStatusService {\n status(): Promise<AntigravityStatusView>\n acknowledgeRisk(): Promise<RiskAcknowledgementResult>\n startLogin(): Promise<LoginStartResult>\n completeCallback(callbackUrl: string): Promise<LoginCompletionResult>\n cancelLogin(): Promise<{ readonly phase: LoginPhase; readonly errorCode?: LoginErrorCode }>\n logout(): Promise<LogoutResult>\n revoke(confirmed: boolean, signal?: AbortSignal): Promise<RevokeActionResult>\n usage?(signal?: AbortSignal, force?: boolean): Promise<QuotaStatusView>\n dispose(): Promise<void>\n}\n\nconst CAPABILITY_DEFINITIONS: readonly CapabilityGateStatus[] = Object.freeze(\n CAPABILITY_ROW_IDS.map(id => Object.freeze({ id, state: 'disabled' as const, reasonCode: 'unauthenticated' as const })),\n)\n\nconst PROJECT_DISCOVERY_FAILURES = new Set([\n 'project-unavailable',\n 'project-authentication-failed',\n 'project-forbidden',\n 'project-rate-limited',\n 'project-offline',\n 'project-malformed',\n 'project-protocol-drift',\n])\n\nexport function createStatusView(\n riskAcknowledged: boolean,\n login: LoginStatusView,\n credential?: CredentialStatusView,\n revoke?: RevokeStatusView,\n gates: CapabilityGateEvidence = {},\n): AntigravityStatusView {\n return Object.freeze({\n pluginId: ANTIGRAVITY_PLUGIN_ID,\n phase: 'bootstrap',\n privateSelfUse: true,\n singleAccount: true,\n riskAcknowledgementRequired: true,\n riskAcknowledged,\n login: Object.freeze({ ...login }),\n ...(credential === undefined ? {} : { credential: Object.freeze({ ...credential }) }),\n ...(revoke === undefined ? {} : { revoke: Object.freeze({ ...revoke }) }),\n capabilities: Object.freeze(capabilitiesFor(login, gates).map(capability => Object.freeze({ ...capability }))),\n })\n}\n\nfunction capabilitiesFor(login: LoginStatusView, gates: CapabilityGateEvidence): readonly CapabilityGateStatus[] {\n const projectBlocked = !login.projectAvailable\n && (login.configured\n || (login.errorCode !== undefined && PROJECT_DISCOVERY_FAILURES.has(login.errorCode)))\n if (projectBlocked) return CAPABILITY_DEFINITIONS.map(capability => ({\n id: capability.id,\n state: 'disabled' as const,\n reasonCode: 'project-unavailable' as const,\n }))\n if (!login.projectAvailable) return CAPABILITY_DEFINITIONS\n if (gates.gate0?.outcome !== 'passed') {\n return CAPABILITY_ROW_IDS.map(id => gate0Status(id, gates.gate0))\n }\n return CAPABILITY_ROW_IDS.map(id => gateStatus(\n id,\n id === 'auth-llm' ? llmFamilyResult(gates) : gates.capabilities?.[id],\n ))\n}\n\nfunction llmFamilyResult(gates: CapabilityGateEvidence): CapabilityGateResult | undefined {\n const results = LLM_FAMILY_IDS.map(family => gates.llmFamilies?.[family])\n const failure = results.find(result => result !== undefined && result.outcome !== 'passed')\n if (failure !== undefined) return failure\n if (results.some(result => result?.outcome !== 'passed')) return undefined\n return results.reduce((latest, result) => (\n latest === undefined || Date.parse(result!.checkedAt) > Date.parse(latest.checkedAt) ? result : latest\n ), undefined as CapabilityGateResult | undefined)\n}\n\nfunction gate0Status(id: CapabilityRowId, result: CapabilityGateResult | undefined): CapabilityGateStatus {\n if (result?.outcome === 'failed' || result?.outcome === 'attribution-rejected') {\n return { id, state: 'disabled', reasonCode: 'gate-0-failed' }\n }\n return gateStatus(id, result)\n}\n\nfunction gateStatus(id: CapabilityRowId, result: CapabilityGateResult | undefined): CapabilityGateStatus {\n if (result === undefined) return { id, state: 'poc-pending', reasonCode: 'gate-not-run' }\n if (result.outcome === 'passed') return { id, state: 'available', reasonCode: 'capability-ready' }\n if (result.outcome === 'protocol-drift') return { id, state: 'protocol-drift', reasonCode: 'protocol-drift' }\n if (result.outcome === 'attribution-rejected') return { id, state: 'disabled', reasonCode: 'gate-0-failed' }\n if (result.outcome === 'unauthenticated') return { id, state: 'disabled', reasonCode: 'unauthenticated' }\n if (result.outcome === 'rate-limited') return { id, state: 'disabled', reasonCode: 'rate-limited' }\n if (result.outcome === 'cancelled') return { id, state: 'disabled', reasonCode: 'cancelled' }\n if (result.outcome === 'unsupported-video') return { id, state: 'disabled', reasonCode: 'unsupported-video' }\n return { id, state: 'disabled', reasonCode: 'gate-failed' }\n}\n","/** Browser-safe login state shared by the Host OAuth flow and settings RPC. */\n\nexport const LOGIN_PHASES = [\n 'idle',\n 'pending',\n 'success',\n 'cancelled',\n 'expired',\n 'port-conflict',\n 'failed',\n] as const\n\nexport type LoginPhase = (typeof LOGIN_PHASES)[number]\n\nexport const LOGIN_ERROR_CODES = [\n 'invalid-method',\n 'invalid-path',\n 'invalid-host',\n 'duplicate-parameter',\n 'invalid-parameters',\n 'missing-state',\n 'state-mismatch',\n 'missing-code',\n 'oauth-error',\n 'no-pending-flow',\n 'expired',\n 'cancelled',\n 'port-conflict',\n 'token-exchange-failed',\n 'project-unavailable',\n 'project-authentication-failed',\n 'project-forbidden',\n 'project-rate-limited',\n 'project-offline',\n 'project-malformed',\n 'project-protocol-drift',\n 'project-validation-failed',\n 'persistence-failed',\n 'credential-conflict',\n 'invalid-callback-url',\n 'risk-acknowledgement-required',\n 'internal',\n] as const\n\nexport type LoginErrorCode = (typeof LOGIN_ERROR_CODES)[number]\n\nexport function isLoginPhase(value: unknown): value is LoginPhase {\n return typeof value === 'string' && LOGIN_PHASES.includes(value as LoginPhase)\n}\n\nexport function isLoginErrorCode(value: unknown): value is LoginErrorCode {\n return typeof value === 'string' && LOGIN_ERROR_CODES.includes(value as LoginErrorCode)\n}\n\nexport interface LoginStatusView {\n readonly phase: LoginPhase\n readonly configured: boolean\n readonly projectAvailable: boolean\n readonly authorizationUrl?: string\n readonly expiresAt?: string\n readonly maskedEmail?: string\n readonly errorCode?: LoginErrorCode\n}\n\nexport interface LoginStartResult {\n readonly started: true\n readonly phase: 'pending'\n readonly authorizationUrl: string\n readonly expiresAt: string\n}\n\nexport interface LoginActionResult {\n readonly phase: LoginPhase\n readonly errorCode?: LoginErrorCode\n}\n\nexport type LoginCompletionResult =\n | { readonly completed: true; readonly phase: 'success' }\n | { readonly completed: false; readonly phase: 'failed' | 'cancelled'; readonly errorCode: LoginErrorCode }\n\nexport type { LoginStatusView as AntigravityLoginStatusView }\n","/** Browser-safe advisory model-catalog state shared by Host RPC and settings. */\n\nexport const ANTIGRAVITY_MODEL_CATALOG_STATES = [\n 'snapshot',\n 'live-available',\n 'refresh-failed',\n 'protocol-drift',\n] as const\n\nexport type AntigravityModelCatalogState = (typeof ANTIGRAVITY_MODEL_CATALOG_STATES)[number]\nexport type AntigravityModelAvailability = 'snapshot' | 'live-available' | 'unavailable'\n\nexport interface AntigravityModelCatalogEntry {\n readonly id: string\n readonly name: string\n readonly state: AntigravityModelAvailability\n}\n\nexport interface AntigravityModelCatalogView {\n readonly state: AntigravityModelCatalogState\n readonly models: readonly AntigravityModelCatalogEntry[]\n readonly checkedAt?: string\n}\n\nexport interface AntigravityModelCatalogService {\n catalogSnapshot(): AntigravityModelCatalogView\n modelCatalog(signal?: AbortSignal, forceRefresh?: boolean): Promise<AntigravityModelCatalogView>\n}\n","/** Closed, browser-safe RPC error vocabulary shared by Host and client. */\n\nimport { LOGIN_ERROR_CODES, type LoginErrorCode } from './login-types.ts'\n\nconst OPERATION_ERROR_CODES = [\n 'loopback-required',\n 'invalid-grant',\n 'network',\n 'timeout',\n 'rate-limited',\n 'server-error',\n 'http-error',\n 'invalid-response',\n 'conflict',\n 'storage',\n] as const\n\nexport const SAFE_RPC_ERROR_CODES = [\n 'bad-request',\n ...LOGIN_ERROR_CODES,\n ...OPERATION_ERROR_CODES,\n] as const\n\nexport type SafeRpcErrorCode = (typeof SAFE_RPC_ERROR_CODES)[number]\n\nconst SAFE_RPC_ERROR_MESSAGES: Readonly<Partial<Record<SafeRpcErrorCode, string>>> = Object.freeze({\n 'bad-request': 'antigravity-auth: invalid request',\n 'loopback-required': 'Antigravity account controls require a loopback-bound DSH Host',\n cancelled: 'The operation was cancelled',\n 'risk-acknowledgement-required': 'Risk acknowledgement is required before login',\n 'port-conflict': 'The fixed OAuth callback port is already in use',\n 'invalid-method': 'The OAuth callback method is not accepted',\n 'invalid-path': 'The OAuth callback path is not accepted',\n 'invalid-host': 'The OAuth callback host is not accepted',\n 'duplicate-parameter': 'The OAuth callback contains duplicate parameters',\n 'invalid-parameters': 'The OAuth callback parameters are not accepted',\n 'missing-state': 'The OAuth callback state is missing',\n 'state-mismatch': 'The OAuth callback state was not accepted',\n 'missing-code': 'The OAuth callback code is missing',\n 'oauth-error': 'The OAuth provider rejected authorization',\n expired: 'The OAuth login expired',\n 'no-pending-flow': 'There is no pending OAuth login',\n 'project-unavailable': 'No usable project is available for this account',\n 'project-authentication-failed': 'The Antigravity project probe requires authentication',\n 'project-forbidden': 'The Antigravity project probe was forbidden',\n 'project-rate-limited': 'The Antigravity project probe is rate-limited',\n 'project-offline': 'The Antigravity project probe is offline',\n 'project-malformed': 'The Antigravity project response was malformed',\n 'project-protocol-drift': 'The Antigravity project protocol changed',\n 'project-validation-failed': 'Project validation failed',\n 'credential-conflict': 'The login changed while it was completing',\n 'persistence-failed': 'The login could not be saved',\n 'token-exchange-failed': 'The authorization code could not be exchanged',\n 'invalid-callback-url': 'The callback URL is invalid',\n 'invalid-grant': 'The account must be authenticated again',\n network: 'The operation could not reach the provider',\n timeout: 'The operation timed out',\n 'rate-limited': 'The operation is rate-limited',\n 'server-error': 'The provider is unavailable',\n 'http-error': 'The provider rejected the operation',\n 'invalid-response': 'The provider response was not accepted',\n conflict: 'The account changed while the operation was running',\n storage: 'The local account state could not be updated',\n})\n\nexport function isSafeRpcErrorCode(value: unknown): value is SafeRpcErrorCode {\n return typeof value === 'string' && SAFE_RPC_ERROR_CODES.includes(value as SafeRpcErrorCode)\n}\n\nexport function safeRpcErrorMessage(code: SafeRpcErrorCode | LoginErrorCode): string {\n return SAFE_RPC_ERROR_MESSAGES[code] ?? 'antigravity-auth: operation failed'\n}\n","/** Shared bounded text predicate for Host trust-boundary values. */\n\nexport function isBoundedSafeText(value: unknown, maxLength: number, minLength = 1): value is string {\n if (typeof value !== 'string'\n || !Number.isSafeInteger(maxLength)\n || !Number.isSafeInteger(minLength)\n || minLength < 0\n || maxLength < minLength\n || value.length < minLength\n || value.length > maxLength) return false\n for (let index = 0; index < value.length; index += 1) {\n const codePoint = value.charCodeAt(index)\n if (codePoint < 0x20 || codePoint === 0x7f) return false\n }\n return true\n}\n","/** Browser-safe, value-free RPC contract for the Antigravity login flow. */\n\nimport type { ConnectionRpcResult as RpcResult } from '@deepseek-ai/dsh-client-connection/client'\nimport { CAPABILITY_ROW_IDS } from './status.ts'\nimport type {\n AntigravityStatusView,\n CapabilityGateReasonCode,\n CapabilityGateState,\n CapabilityRowId,\n LoginActionResult,\n LoginPhase,\n LoginStartResult,\n LoginStatusView,\n RiskAcknowledgementResult,\n} from './status.ts'\nimport { isLoginErrorCode, isLoginPhase } from './login-types.ts'\nimport type { CredentialErrorCode, CredentialState, CredentialStatusView, RevokeActionResult, RevokeErrorCode, RevokeState, RevokeStatusView } from './credential-coordinator.ts'\nimport type { QuotaGroupView, QuotaState, QuotaStatusView, QuotaWindowKind } from './quota.ts'\nimport {\n ANTIGRAVITY_MODEL_CATALOG_STATES,\n type AntigravityModelAvailability,\n type AntigravityModelCatalogView,\n} from './model-catalog.ts'\nimport { isSafeRpcErrorCode, safeRpcErrorMessage } from './rpc-vocabulary.ts'\nimport { isBoundedSafeText } from './safe-text.ts'\n\nexport const ANTIGRAVITY_AUTH_RPC_CHANNEL = '/api'\nexport const ANTIGRAVITY_AUTH_RPC_NAMESPACE = 'antigravity-auth' as const\n\nexport interface AntigravityAuthRpcClient {\n status(signal?: AbortSignal): Promise<RpcResult<{ status: AntigravityStatusView }>>\n acknowledgeRisk(signal?: AbortSignal): Promise<RpcResult<RiskAcknowledgementResult>>\n login(signal?: AbortSignal): Promise<RpcResult<LoginStartResult>>\n cancelLogin(signal?: AbortSignal): Promise<RpcResult<LoginActionResult>>\n logout(signal?: AbortSignal): Promise<RpcResult<{ state: 'logged-out' }>>\n revoke(signal?: AbortSignal): Promise<RpcResult<RevokeActionResult>>\n models(signal?: AbortSignal, force?: boolean): Promise<RpcResult<AntigravityModelCatalogView>>\n usage?(signal?: AbortSignal, force?: boolean): Promise<RpcResult<QuotaStatusView>>\n}\n\nexport interface AntigravityAuthConnectionRpc {\n call(\n channel: string,\n endpoint: string,\n payload: unknown,\n signal?: AbortSignal,\n ): Promise<RpcResult<unknown>>\n}\n\n/** Build the browser face over the plugin-owned guarded account channel. */\nexport function createAntigravityAuthRpcClient(rpc: AntigravityAuthConnectionRpc): AntigravityAuthRpcClient {\n return {\n status: signal => callValidated(rpc, 'status', {}, signal, value => {\n const status = parseStatusResult(value)\n return status === undefined ? undefined : { status }\n }),\n acknowledgeRisk: signal => callValidated(rpc, 'acknowledge-risk', { acknowledge: true }, signal, parseAcknowledgementResult),\n login: signal => callValidated(rpc, 'login', {}, signal, parseLoginResult),\n cancelLogin: signal => callValidated(rpc, 'cancel', {}, signal, parseActionResult),\n logout: signal => callValidated(rpc, 'logout', {}, signal, parseLogoutResult),\n revoke: signal => callValidated(rpc, 'revoke', { confirmed: true }, signal, parseRevokeResult),\n models: (signal, force = false) => callValidated(rpc, 'models', { force }, signal, parseModelCatalogResult),\n usage: (signal, force = false) => callValidated(rpc, 'usage', { force }, signal, parseUsageResult),\n }\n}\n\nasync function callValidated<T>(\n rpc: AntigravityAuthConnectionRpc,\n endpoint: string,\n payload: unknown,\n signal: AbortSignal | undefined,\n parse: (value: unknown) => T | undefined,\n): Promise<RpcResult<T>> {\n let result: RpcResult<unknown>\n try {\n result = await rpc.call(ANTIGRAVITY_AUTH_RPC_CHANNEL, `${ANTIGRAVITY_AUTH_RPC_NAMESPACE}/${endpoint}`, payload, signal)\n } catch {\n return invalidResponse(endpoint)\n }\n if (!result.ok) return sanitizeFailure(result, endpoint)\n const value = parse(result.value)\n return value === undefined ? invalidResponse(endpoint) : { ok: true, value }\n}\n\nfunction sanitizeFailure(result: Extract<RpcResult<unknown>, { readonly ok: false }>, endpoint: string): RpcResult<never> {\n const error: unknown = result.error\n if (!isRecord(error)\n || !hasExactKeys(error, ['code', 'message', 'details'])\n || !isSafeRpcErrorCode(error.code)\n || typeof error.message !== 'string'\n || !isBoundedSafeText(error.message, 512)\n || !isSafeErrorDetails(error.details)) return invalidResponse(endpoint)\n return {\n ok: false,\n error: {\n code: error.code as never,\n message: safeRpcErrorMessage(error.code),\n details: {},\n },\n }\n}\n\nfunction isSafeErrorDetails(value: unknown): boolean {\n if (!isRecord(value)) return false\n if (Object.keys(value).length === 0) return true\n return hasExactKeys(value, ['issues']) && Array.isArray(value.issues) && value.issues.length === 0\n}\n\n/** Parse a closed, value-safe advisory model catalog received by the browser. */\nexport function parseModelCatalogResult(value: unknown): AntigravityModelCatalogView | undefined {\n if (!isRecord(value)\n || !hasExactKeys(value, ['state', 'models', ...(value.checkedAt === undefined ? [] : ['checkedAt'])])\n || !ANTIGRAVITY_MODEL_CATALOG_STATES.includes(value.state as never)\n || !Array.isArray(value.models)\n || value.models.length === 0\n || value.models.length > 64\n || (value.checkedAt !== undefined && !isIsoTime(value.checkedAt))) return undefined\n const models: Array<{ id: string; name: string; state: AntigravityModelAvailability }> = []\n const ids = new Set<string>()\n for (const model of value.models) {\n if (!isRecord(model)\n || !hasExactKeys(model, ['id', 'name', 'state'])\n || !isBoundedSafeText(model.id, 256)\n || !isBoundedSafeText(model.name, 256)\n || (model.state !== 'snapshot' && model.state !== 'live-available' && model.state !== 'unavailable')\n || ids.has(model.id)) return undefined\n if (value.state === 'live-available' ? model.state === 'snapshot' : model.state !== 'snapshot') return undefined\n ids.add(model.id)\n models.push({ id: model.id, name: model.name, state: model.state })\n }\n return {\n state: value.state as AntigravityModelCatalogView['state'],\n models,\n ...(typeof value.checkedAt === 'string' ? { checkedAt: value.checkedAt } : {}),\n }\n}\n\n/** Parse a value-safe, normalized quota envelope received by the browser. */\nexport function parseUsageResult(value: unknown): QuotaStatusView | undefined {\n if (!isRecord(value) || !hasExactKeys(value, ['state', ...(value.checkedAt === undefined ? [] : ['checkedAt']), ...(value.groups === undefined ? [] : ['groups'])])) return undefined\n if (!isQuotaState(value.state)) return undefined\n if (value.checkedAt !== undefined && !isIsoTime(value.checkedAt)) return undefined\n if (value.state === 'available' && value.groups === undefined) return undefined\n if (value.groups !== undefined) {\n if (!Array.isArray(value.groups) || value.groups.length === 0 || value.groups.length > 2) return undefined\n const groups: QuotaGroupView[] = []\n const groupNames = new Set<string>()\n for (const rawGroup of value.groups) {\n if (!isRecord(rawGroup) || !hasExactKeys(rawGroup, ['group', 'modelCount', 'windows']) || (rawGroup.group !== 'gemini' && rawGroup.group !== 'non-gemini') || !Number.isSafeInteger(rawGroup.modelCount) || (rawGroup.modelCount as number) < 0 || !Array.isArray(rawGroup.windows)) return undefined\n if (groupNames.has(rawGroup.group)) return undefined\n groupNames.add(rawGroup.group)\n const modelCount = rawGroup.modelCount as number\n if (rawGroup.windows.length === 0 || rawGroup.windows.length > 2) return undefined\n const windows: Array<{ window: QuotaWindowKind; remainingFraction: number; resetTime: string }> = []\n const windowKinds = new Set<QuotaWindowKind>()\n for (const rawWindow of rawGroup.windows) {\n if (!isRecord(rawWindow) || !hasExactKeys(rawWindow, ['window', 'remainingFraction', 'resetTime']) || (rawWindow.window !== '5h' && rawWindow.window !== 'weekly') || windowKinds.has(rawWindow.window) || typeof rawWindow.remainingFraction !== 'number' || !Number.isFinite(rawWindow.remainingFraction) || rawWindow.remainingFraction < 0 || rawWindow.remainingFraction > 1 || !isIsoTime(rawWindow.resetTime)) return undefined\n windowKinds.add(rawWindow.window)\n windows.push({ window: rawWindow.window, remainingFraction: rawWindow.remainingFraction, resetTime: rawWindow.resetTime })\n }\n groups.push({ group: rawGroup.group, modelCount, windows })\n }\n return { state: value.state, ...(typeof value.checkedAt === 'string' ? { checkedAt: value.checkedAt } : {}), groups }\n }\n return { state: value.state, ...(typeof value.checkedAt === 'string' ? { checkedAt: value.checkedAt } : {}) }\n}\n\n/** Parse the closed status envelope received by the browser. */\nexport function parseStatusResult(value: unknown): AntigravityStatusView | undefined {\n if (!isRecord(value) || !hasExactKeys(value, ['status'])) return undefined\n return parseStatus(value.status)\n}\n\nfunction parseStatus(value: unknown): AntigravityStatusView | undefined {\n if (!isRecord(value)\n || !hasAllowedKeys(value, [\n 'pluginId',\n 'phase',\n 'privateSelfUse',\n 'singleAccount',\n 'riskAcknowledgementRequired',\n 'riskAcknowledged',\n 'login',\n 'credential',\n 'revoke',\n 'capabilities',\n ])\n || value.pluginId !== 'dsh-antigravity-auth'\n || value.phase !== 'bootstrap'\n || value.privateSelfUse !== true\n || value.singleAccount !== true\n || value.riskAcknowledgementRequired !== true\n || typeof value.riskAcknowledged !== 'boolean'\n || !Array.isArray(value.capabilities)) return undefined\n\n const login = parseLoginStatus(value.login)\n if (login === undefined) return undefined\n const credential = value.credential === undefined ? undefined : parseCredentialStatus(value.credential)\n if (value.credential !== undefined && credential === undefined) return undefined\n const revoke = value.revoke === undefined ? undefined : parseRevokeStatus(value.revoke)\n if (value.revoke !== undefined && revoke === undefined) return undefined\n const seen = new Set<string>()\n const capabilities: CapabilityGateStatus[] = []\n for (const capability of value.capabilities) {\n const parsed = parseCapability(capability)\n if (parsed === undefined || seen.has(parsed.id)) return undefined\n seen.add(parsed.id)\n capabilities.push(parsed)\n }\n if (seen.size !== CAPABILITY_ROW_IDS.length || CAPABILITY_ROW_IDS.some(id => !seen.has(id))) return undefined\n\n return {\n pluginId: 'dsh-antigravity-auth',\n phase: 'bootstrap',\n privateSelfUse: true,\n singleAccount: true,\n riskAcknowledgementRequired: true,\n riskAcknowledged: value.riskAcknowledged,\n login,\n ...(credential === undefined ? {} : { credential }),\n ...(revoke === undefined ? {} : { revoke }),\n capabilities,\n }\n}\n\nfunction parseCredentialStatus(value: unknown): CredentialStatusView | undefined {\n if (!isRecord(value)\n || typeof value.state !== 'string'\n || !isCredentialState(value.state)\n || typeof value.configured !== 'boolean'\n || !hasAllowedKeys(value, ['state', 'configured', 'expiresAt', 'lastRefreshAt', 'errorCode'])) return undefined\n if (value.expiresAt !== undefined && !isIsoTime(value.expiresAt)) return undefined\n if (value.lastRefreshAt !== undefined && !isIsoTime(value.lastRefreshAt)) return undefined\n if (value.errorCode !== undefined && (typeof value.errorCode !== 'string' || !isCredentialErrorCode(value.errorCode))) return undefined\n return {\n state: value.state,\n configured: value.configured,\n ...(typeof value.expiresAt === 'string' ? { expiresAt: value.expiresAt } : {}),\n ...(typeof value.lastRefreshAt === 'string' ? { lastRefreshAt: value.lastRefreshAt } : {}),\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseRevokeStatus(value: unknown): RevokeStatusView | undefined {\n if (!isRecord(value)\n || typeof value.state !== 'string'\n || !isRevokeState(value.state)\n || !hasAllowedKeys(value, ['state', 'errorCode'])) return undefined\n if (value.errorCode !== undefined && (typeof value.errorCode !== 'string' || !isRevokeErrorCode(value.errorCode))) return undefined\n return {\n state: value.state,\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseLoginStatus(value: unknown): LoginStatusView | undefined {\n if (!isRecord(value)\n || typeof value.phase !== 'string'\n || !isLoginPhase(value.phase)\n || typeof value.configured !== 'boolean'\n || typeof value.projectAvailable !== 'boolean') return undefined\n const allowed = ['phase', 'configured', 'projectAvailable', 'authorizationUrl', 'expiresAt', 'maskedEmail', 'errorCode']\n if (Object.keys(value).some(key => !allowed.includes(key))) return undefined\n if (value.authorizationUrl !== undefined && !isSafeAuthorizationUrl(value.authorizationUrl)) return undefined\n if (value.expiresAt !== undefined && !isIsoTime(value.expiresAt)) return undefined\n if (value.maskedEmail !== undefined && (typeof value.maskedEmail !== 'string' || !isMaskedEmail(value.maskedEmail))) return undefined\n if (value.errorCode !== undefined && !isLoginErrorCode(value.errorCode)) return undefined\n if (isErrorPhase(value.phase)\n ? typeof value.errorCode !== 'string'\n : value.errorCode !== undefined) return undefined\n if (value.phase === 'pending'\n ? typeof value.authorizationUrl !== 'string' || typeof value.expiresAt !== 'string'\n : value.authorizationUrl !== undefined) return undefined\n return {\n phase: value.phase,\n configured: value.configured,\n projectAvailable: value.projectAvailable,\n ...(typeof value.authorizationUrl === 'string' ? { authorizationUrl: value.authorizationUrl } : {}),\n ...(typeof value.expiresAt === 'string' ? { expiresAt: value.expiresAt } : {}),\n ...(typeof value.maskedEmail === 'string' ? { maskedEmail: value.maskedEmail } : {}),\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseCapability(value: unknown): CapabilityGateStatus | undefined {\n if (!isRecord(value) || !hasExactKeys(value, ['id', 'state', 'reasonCode'])) return undefined\n if (!isCapabilityRowId(value.id) || !isCapabilityGateState(value.state) || !isCapabilityReasonCode(value.reasonCode)) {\n return undefined\n }\n return { id: value.id, state: value.state, reasonCode: value.reasonCode }\n}\n\nfunction parseAcknowledgementResult(value: unknown): RiskAcknowledgementResult | undefined {\n return isRecord(value) && hasExactKeys(value, ['acknowledged']) && value.acknowledged === true\n ? { acknowledged: true }\n : undefined\n}\n\nfunction parseLoginResult(value: unknown): LoginStartResult | undefined {\n return isRecord(value)\n && hasExactKeys(value, ['started', 'phase', 'authorizationUrl', 'expiresAt'])\n && value.started === true\n && value.phase === 'pending'\n && isSafeAuthorizationUrl(value.authorizationUrl)\n && isIsoTime(value.expiresAt)\n ? {\n started: true,\n phase: 'pending',\n authorizationUrl: value.authorizationUrl,\n expiresAt: value.expiresAt,\n }\n : undefined\n}\n\nfunction parseActionResult(value: unknown): LoginActionResult | undefined {\n if (!isRecord(value) || typeof value.phase !== 'string' || !isLoginPhase(value.phase)) return undefined\n if (Object.keys(value).some(key => key !== 'phase' && key !== 'errorCode')) return undefined\n if (value.errorCode !== undefined && !isLoginErrorCode(value.errorCode)) return undefined\n return {\n phase: value.phase,\n ...(typeof value.errorCode === 'string' ? { errorCode: value.errorCode } : {}),\n }\n}\n\nfunction parseLogoutResult(value: unknown): { readonly state: 'logged-out' } | undefined {\n return isRecord(value) && hasExactKeys(value, ['state']) && value.state === 'logged-out'\n ? { state: 'logged-out' }\n : undefined\n}\n\nfunction parseRevokeResult(value: unknown): RevokeActionResult | undefined {\n if (!isRecord(value) || typeof value.state !== 'string') return undefined\n if (value.state === 'confirmation-required' || value.state === 'revoked' || value.state === 'logged-out' || value.state === 'superseded') {\n return hasExactKeys(value, ['state']) ? { state: value.state } : undefined\n }\n if (value.state === 'failed'\n && hasExactKeys(value, ['state', 'errorCode'])\n && typeof value.errorCode === 'string'\n && isRevokeErrorCode(value.errorCode)) {\n return { state: 'failed', errorCode: value.errorCode }\n }\n return undefined\n}\n\nfunction isSafeAuthorizationUrl(value: unknown): value is string {\n if (typeof value !== 'string' || value.length === 0 || value.length > 8192) return false\n try {\n const parsed = new URL(value)\n const allowed = new Set(['client_id', 'response_type', 'redirect_uri', 'scope', 'code_challenge', 'code_challenge_method', 'state', 'access_type', 'prompt'])\n for (const [key, parameter] of parsed.searchParams) {\n if (!allowed.has(key) || parsed.searchParams.getAll(key).length !== 1 || !isBoundedSafeText(parameter, 4096)) return false\n }\n const state = parsed.searchParams.get('state')\n const clientId = parsed.searchParams.get('client_id')\n const challenge = parsed.searchParams.get('code_challenge')\n return parsed.protocol === 'https:'\n && parsed.hostname === 'accounts.google.com'\n && parsed.port === ''\n && parsed.username === ''\n && parsed.password === ''\n && parsed.pathname === '/o/oauth2/v2/auth'\n && parsed.hash.length === 0\n && typeof state === 'string'\n && /^[A-Za-z0-9_-]{43}$/u.test(state)\n && (clientId === null || (clientId.length <= 256 && clientId.endsWith('.apps.googleusercontent.com')))\n && (challenge === null || /^[A-Za-z0-9_-]{43}$/u.test(challenge))\n && (parsed.searchParams.get('response_type') === null || parsed.searchParams.get('response_type') === 'code')\n && (parsed.searchParams.get('redirect_uri') === null || parsed.searchParams.get('redirect_uri') === 'http://localhost:51121/oauth-callback')\n && (parsed.searchParams.get('code_challenge_method') === null || parsed.searchParams.get('code_challenge_method') === 'S256')\n && (parsed.searchParams.get('access_type') === null || parsed.searchParams.get('access_type') === 'offline')\n && (parsed.searchParams.get('prompt') === null || parsed.searchParams.get('prompt') === 'consent')\n } catch {\n return false\n }\n}\n\nfunction isMaskedEmail(value: string): boolean {\n return isBoundedSafeText(value, 256) && /^.[*]{3}[^@]*@[^@\\s]+$/u.test(value)\n}\n\nfunction isErrorPhase(value: LoginPhase): boolean {\n return value === 'cancelled' || value === 'expired' || value === 'port-conflict' || value === 'failed'\n}\n\nfunction isQuotaState(value: unknown): value is QuotaState {\n return value === 'available' || value === 'unauthenticated' || value === 'forbidden' || value === 'rate-limited' || value === 'offline' || value === 'timeout' || value === 'protocol-drift'\n}\n\nfunction isIsoTime(value: unknown): value is string {\n if (typeof value !== 'string' || value.length > 64) return false\n const timestamp = Date.parse(value)\n return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value\n}\n\nfunction isCapabilityRowId(value: unknown): value is CapabilityRowId {\n return typeof value === 'string' && CAPABILITY_ROW_IDS.includes(value as CapabilityRowId)\n}\n\nfunction isCapabilityGateState(value: unknown): value is CapabilityGateState {\n return value === 'available'\n || value === 'disabled'\n || value === 'poc-pending'\n || value === 'protocol-drift'\n}\n\nfunction isCapabilityReasonCode(value: unknown): value is CapabilityGateReasonCode {\n return value === 'gate-not-run'\n || value === 'project-unavailable'\n || value === 'capability-ready'\n || value === 'unauthenticated'\n || value === 'rate-limited'\n || value === 'cancelled'\n || value === 'gate-0-failed'\n || value === 'gate-failed'\n || value === 'unsupported-video'\n || value === 'protocol-drift'\n}\n\nfunction isCredentialState(value: unknown): value is CredentialState {\n return value === 'logged-out'\n || value === 'logged-in'\n || value === 'refreshing'\n || value === 'refresh-failed'\n || value === 're-login-required'\n}\n\nfunction isCredentialErrorCode(value: unknown): value is CredentialErrorCode {\n return value === 'invalid-grant'\n || value === 'network'\n || value === 'timeout'\n || value === 'rate-limited'\n || value === 'server-error'\n || value === 'http-error'\n || value === 'invalid-response'\n || value === 'conflict'\n || value === 'storage'\n || value === 'cancelled'\n}\n\nfunction isRevokeState(value: unknown): value is RevokeState {\n return value === 'idle'\n || value === 'pending'\n || value === 'confirmation-required'\n || value === 'revoked'\n || value === 'logged-out'\n || value === 'failed'\n || value === 'superseded'\n}\n\nfunction isRevokeErrorCode(value: unknown): value is RevokeErrorCode {\n return value === 'network'\n || value === 'timeout'\n || value === 'rate-limited'\n || value === 'server-error'\n || value === 'http-error'\n || value === 'invalid-response'\n || value === 'storage'\n}\n\nfunction hasAllowedKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {\n return Object.keys(value).every(key => allowed.includes(key))\n}\n\nfunction hasExactKeys(value: Record<string, unknown>, expected: readonly string[]): boolean {\n const keys = Object.keys(value).sort()\n const sortedExpected = [...expected].sort()\n return keys.length === sortedExpected.length && keys.every((key, index) => key === sortedExpected[index])\n}\n\nfunction invalidResponse(endpoint: string): RpcResult<never> {\n return {\n ok: false,\n error: {\n code: 'internal',\n message: `antigravity-auth: invalid ${endpoint} response from Host`,\n details: {},\n },\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\ntype CapabilityGateStatus = AntigravityStatusView['capabilities'][number]\n","/** Embedded CSS stylesheet for value-safe Antigravity settings UI. */\n\nexport const SETTINGS_CSS = `\n.agy-settings {\n display: flex;\n flex-direction: column;\n gap: 16px;\n width: 100%;\n max-width: 820px;\n margin: 0 auto;\n padding: 4px 0 32px;\n color: var(--dsw-alias-label-primary, #e6edf3);\n font-family: var(--dsw-font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif);\n font-size: 13px;\n line-height: 1.5;\n box-sizing: border-box;\n -webkit-font-smoothing: antialiased;\n}\n\n.agy-settings *,\n.agy-settings *::before,\n.agy-settings *::after {\n box-sizing: border-box;\n}\n\n.agy-bundle-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 20px;\n}\n\n.agy-title-line {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.agy-bundle-title {\n margin: 0;\n font-size: 20px;\n line-height: 28px;\n font-weight: 600;\n letter-spacing: -0.015em;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-status-dot {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #10b981;\n box-shadow: 0 0 8px rgba(16, 185, 129, 0.4);\n flex: none;\n}\n\n.agy-bundle-intro,\n.agy-card-intro {\n margin: 4px 0 0;\n color: var(--dsw-alias-label-tertiary, #8b949e);\n font-size: 13px;\n line-height: 20px;\n}\n\n.agy-cards {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n\n.agy-card {\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 18px 20px;\n border-radius: 16px;\n background: var(--dsw-alias-bg-layer-2, rgba(255, 255, 255, 0.03));\n border: 1px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.08));\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.agy-card-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n}\n\n.agy-card-identity {\n min-width: 0;\n flex: 1;\n}\n\n.agy-card-title-line {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.agy-card-title {\n margin: 0;\n font-size: 15px;\n line-height: 22px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-card-action {\n flex: none;\n display: flex;\n align-items: center;\n}\n\n.agy-risk-card {\n background: rgba(234, 179, 8, 0.04);\n border: 1px solid rgba(234, 179, 8, 0.2);\n border-radius: 14px;\n padding: 16px 18px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.agy-risk-text {\n color: var(--dsw-alias-label-secondary, #9ca3af);\n font-size: 13px;\n line-height: 19px;\n margin: 0;\n}\n\n.agy-link-group {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 12px;\n margin: 0;\n}\n\n.agy-link {\n color: var(--dsw-alias-interactive-text, #38bdf8);\n font-size: 12px;\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.agy-link:hover {\n text-decoration: underline;\n color: #7dd3fc;\n}\n\n.agy-ack-row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.2));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.06));\n border-radius: 8px;\n cursor: pointer;\n user-select: none;\n font-size: 13px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-checkbox {\n flex: none;\n width: 16px;\n height: 16px;\n margin: 0;\n accent-color: var(--dsw-alias-button-primary-fill, #3b82f6);\n cursor: pointer;\n}\n\n.agy-checkbox:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n.agy-facts {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 12px 16px;\n margin: 0;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-3, rgba(255, 255, 255, 0.02));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.05));\n}\n\n.agy-fact {\n min-width: 0;\n}\n\n.agy-fact dt {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8b949e);\n}\n\n.agy-fact dd {\n margin: 2px 0 0;\n font-size: 13px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #e6edf3);\n overflow-wrap: anywhere;\n font-variant-numeric: tabular-nums;\n}\n\n/* Quota Section */\n.agy-quota-section {\n display: flex;\n flex-direction: column;\n gap: 14px;\n margin-top: 4px;\n}\n\n.agy-quota-group {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 14px 16px;\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.15));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.05));\n box-shadow: inset 0 0 0 1px var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.03));\n}\n\n.agy-quota-group-header {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.agy-quota-group-title {\n margin: 0;\n font-size: 12px;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary, #a1a1aa);\n}\n\n.agy-quota-group-desc {\n margin: 0;\n font-size: 12px;\n color: var(--dsw-alias-label-tertiary, #71717a);\n}\n\n.agy-quota-buckets {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 4px;\n}\n\n.agy-quota-bucket {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.agy-quota-bucket-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 12px;\n line-height: 18px;\n}\n\n.agy-quota-bucket-name {\n font-weight: 500;\n color: var(--dsw-alias-label-secondary, #d4d4d8);\n}\n\n.agy-quota-bucket-val {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace);\n color: var(--dsw-alias-label-primary, #ffffff);\n animation: agy-fade-in 250ms ease;\n}\n\n.agy-quota-bucket-val[data-tone='normal'] {\n color: var(--dsw-alias-state-success-label, #10b981);\n}\n\n.agy-quota-bucket-val[data-tone='warning'] {\n color: var(--dsw-alias-state-warn-label, #f59e0b);\n}\n\n.agy-quota-bucket-val[data-tone='error'] {\n color: var(--dsw-alias-state-error-label, #ef4444);\n}\n\n.agy-quota-querying {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--dsw-alias-label-tertiary, #71717a);\n font-size: 12px;\n line-height: 18px;\n animation: agy-fade-in 200ms ease;\n}\n\n.agy-querying-spinner {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n border: 1.5px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.15));\n border-top-color: var(--dsw-alias-brand-primary, #4f6ef7);\n animation: agy-spin 0.8s linear infinite;\n display: inline-block;\n flex: none;\n}\n\n.agy-progress-track {\n position: relative;\n height: 6px;\n width: 100%;\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.2));\n box-shadow: inset 0 0 0 1px var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.08));\n overflow: hidden;\n}\n\n@keyframes agy-fill-progress {\n from {\n transform: scaleX(0);\n opacity: 0.7;\n }\n to {\n transform: scaleX(1);\n opacity: 1;\n }\n}\n\n.agy-progress-bar {\n height: 100%;\n border-radius: 999px;\n transform-origin: left center;\n animation: agy-fill-progress 650ms cubic-bezier(0.16, 1, 0.3, 1) forwards;\n transition: width 400ms cubic-bezier(0.16, 1, 0.3, 1), background 400ms ease;\n}\n\n.agy-progress-bar[data-tone='normal'] {\n background: linear-gradient(90deg, #f59e0b 0%, #10b981 35%, #059669 100%);\n}\n\n.agy-progress-bar[data-tone='warning'] {\n background: linear-gradient(90deg, #ef4444 0%, #f97316 40%, #f59e0b 100%);\n}\n\n.agy-progress-bar[data-tone='error'] {\n background: linear-gradient(90deg, #f87171 0%, #ef4444 50%, #dc2626 100%);\n}\n\n.agy-shimmer-track {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n border-radius: 999px;\n background: linear-gradient(\n 90deg,\n transparent 0%,\n var(--dsw-alias-fill-tertiary, rgba(255, 255, 255, 0.06)) 25%,\n var(--dsw-alias-fill-secondary, rgba(255, 255, 255, 0.14)) 50%,\n var(--dsw-alias-fill-tertiary, rgba(255, 255, 255, 0.06)) 75%,\n transparent 100%\n );\n background-size: 200% 100%;\n animation: agy-shimmer-stream 1.6s ease-in-out infinite;\n}\n\n@keyframes agy-shimmer-stream {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n\n@keyframes agy-fade-in {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.agy-quota-subtext {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary, #71717a);\n font-variant-numeric: tabular-nums;\n}\n\n/* Actions */\n.agy-action-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n margin-top: 4px;\n}\n\n.agy-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 32px;\n padding: 0 14px;\n border-radius: 999px;\n font-size: 13px;\n font-weight: 500;\n line-height: 20px;\n cursor: pointer;\n border: 1px solid transparent;\n background: var(--dsw-alias-bg-layer-3, rgba(255, 255, 255, 0.08));\n color: var(--dsw-alias-label-primary, #e6edf3);\n text-decoration: none;\n transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;\n}\n\n.agy-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.12));\n}\n\n.agy-btn:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.agy-btn-primary {\n background: var(--dsw-alias-button-primary-fill, #18181b);\n color: var(--dsw-alias-label-primary-foreground, #ffffff);\n border: 1px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.15));\n}\n\n.agy-btn-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, #27272a);\n}\n\n.agy-btn-outline {\n background: transparent;\n border: 1px solid var(--dsw-alias-border-l2, rgba(255, 255, 255, 0.15));\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-btn-outline:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(255, 255, 255, 0.08));\n}\n\n.agy-btn-ghost {\n background: transparent !important;\n border-color: transparent !important;\n color: var(--dsw-alias-label-secondary, #a1a1aa) !important;\n padding: 0 10px !important;\n border-radius: 6px !important;\n}\n\n.agy-btn-ghost:hover:not(:disabled) {\n background: var(--dsw-alias-fill-tertiary, rgba(255, 255, 255, 0.06)) !important;\n color: var(--dsw-alias-label-primary, #ffffff) !important;\n}\n\n.agy-refresh-btn {\n margin-left: auto;\n}\n\n.agy-footer-notice {\n margin: 6px 0 0;\n color: var(--dsw-alias-label-tertiary, #71717a);\n font-size: 11px;\n line-height: 17px;\n}\n\n.agy-privacy {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-tertiary, #6e7681);\n margin: 4px 0 0;\n}\n\n.agy-alert {\n padding: 10px 12px;\n border-radius: 8px;\n font-size: 12px;\n line-height: 18px;\n margin: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n background: rgba(239, 68, 68, 0.1);\n border: 1px solid rgba(239, 68, 68, 0.25);\n color: #fca5a5;\n}\n\n.agy-item-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.agy-item-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 10px 14px;\n background: var(--dsw-alias-bg-layer-1, rgba(255, 255, 255, 0.02));\n border: 1px solid var(--dsw-alias-border-l1, rgba(255, 255, 255, 0.05));\n border-radius: 8px;\n}\n\n.agy-item-title {\n font-size: 13px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #e6edf3);\n}\n\n.agy-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 16px;\n white-space: nowrap;\n flex: none;\n}\n\n.agy-badge-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n flex: none;\n}\n\n.agy-badge-available {\n background: rgba(34, 197, 94, 0.12);\n color: #4ade80;\n border: 1px solid rgba(34, 197, 94, 0.25);\n}\n\n.agy-badge-available .agy-badge-dot {\n background: #22c55e;\n}\n\n.agy-badge-disabled {\n background: rgba(148, 163, 184, 0.1);\n color: #94a3b8;\n border: 1px solid rgba(148, 163, 184, 0.2);\n}\n\n.agy-badge-disabled .agy-badge-dot {\n background: #64748b;\n}\n\n.agy-badge-warning {\n background: rgba(234, 179, 8, 0.12);\n color: #facc15;\n border: 1px solid rgba(234, 179, 8, 0.25);\n}\n\n.agy-badge-warning .agy-badge-dot {\n background: #eab308;\n}\n\n.agy-badge-error {\n background: rgba(239, 68, 68, 0.12);\n color: #f87171;\n border: 1px solid rgba(239, 68, 68, 0.25);\n}\n\n.agy-badge-error .agy-badge-dot {\n background: #ef4444;\n}\n\n/* Switch Component */\n.agy-switch {\n position: relative;\n display: inline-flex;\n align-items: center;\n width: 36px;\n height: 20px;\n cursor: pointer;\n user-select: none;\n}\n\n.agy-switch input {\n opacity: 0;\n width: 0;\n height: 0;\n position: absolute;\n}\n\n.agy-switch-slider {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: var(--dsw-alias-bg-layer-4, rgba(255, 255, 255, 0.15));\n border-radius: 20px;\n transition: 0.2s ease;\n}\n\n.agy-switch-slider::before {\n position: absolute;\n content: \"\";\n height: 14px;\n width: 14px;\n left: 3px;\n bottom: 3px;\n background-color: #ffffff;\n border-radius: 50%;\n transition: 0.2s ease;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);\n}\n\n.agy-switch input:checked + .agy-switch-slider {\n background-color: var(--dsw-alias-button-primary-fill, #2563eb);\n}\n\n.agy-switch input:checked + .agy-switch-slider::before {\n transform: translateX(16px);\n}\n\n.agy-switch input:disabled + .agy-switch-slider {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.agy-spin-icon {\n display: inline-flex;\n animation: agy-spin 1s linear infinite;\n}\n\n@keyframes agy-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n`\n\nconst STYLE_ELEMENT_ID = 'dsh-antigravity-auth-styles'\n\nexport function ensureSettingsStyles(): void {\n if (typeof document === 'undefined') return\n if (document.getElementById(STYLE_ELEMENT_ID)) return\n const style = document.createElement('style')\n style.id = STYLE_ELEMENT_ID\n style.textContent = SETTINGS_CSS\n document.head.appendChild(style)\n}\n","/** Settings shell for value-safe Antigravity login status. */\n\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport type { ReactNode } from 'react'\nimport type { ConfigForm, ConfigFormSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { AntigravityAuthRpcClient } from '../rpc-contract.ts'\nimport type { QuotaStatusView } from '../quota.ts'\nimport type { AntigravitySearchSettings } from '../search.ts'\nimport type { AntigravityImageSettings } from '../image.ts'\nimport type { AntigravityVideoSettings } from '../video.ts'\nimport type { RevokeState } from '../credential-coordinator.ts'\nimport type {\n AntigravityStatusView,\n CapabilityRowId,\n LoginErrorCode,\n} from '../status.ts'\nimport type { AntigravityAuthKey } from './locales.ts'\nimport { ensureSettingsStyles } from './styles.ts'\n\nexport interface AntigravityAuthSettingsProps {\n rpc: AntigravityAuthRpcClient\n t: (key: AntigravityAuthKey) => string\n subscribe: (listener: () => void) => () => void\n searchScope?: ConfigForm<AntigravitySearchSettings>\n imageScope?: ConfigForm<AntigravityImageSettings>\n videoScope?: ConfigForm<AntigravityVideoSettings>\n}\n\ntype LoadState = 'loading' | 'ready' | 'error'\ntype BooleanSettings = { readonly enabled: boolean }\ntype SettingsSnapshot = ConfigFormSnapshot<BooleanSettings>\nconst EMPTY_SETTINGS_SNAPSHOT: SettingsSnapshot = { status: 'unavailable', value: undefined, base: undefined, user: undefined, revision: undefined, writable: false }\n\nfunction useCapabilitySettings<T extends BooleanSettings>(scope: ConfigForm<T> | undefined): SettingsSnapshot & { readonly value: T | undefined } {\n const subscribe = useCallback((listener: () => void) => scope?.subscribe(listener) ?? (() => {}), [scope])\n const getSnapshot = useCallback(() => scope?.getSnapshot() ?? EMPTY_SETTINGS_SNAPSHOT, [scope])\n return useSyncExternalStore(subscribe, getSnapshot, () => EMPTY_SETTINGS_SNAPSHOT) as SettingsSnapshot & { readonly value: T | undefined }\n}\n\nfunction useUnmountSignal(): () => AbortSignal {\n const controller = useRef(new AbortController())\n useEffect(() => {\n const active = new AbortController()\n controller.current = active\n return () => active.abort()\n }, [])\n return useCallback(() => controller.current.signal, [])\n}\n\n/** One navigable settings section; credentials remain Host-only and actions use typed RPC. */\nexport function AntigravityAuthSettings({ rpc, t, subscribe, searchScope, imageScope, videoScope }: AntigravityAuthSettingsProps): ReactNode {\n const [status, setStatus] = useState<AntigravityStatusView | null>(null)\n const searchSettings = useCapabilitySettings(searchScope)\n const imageSettings = useCapabilitySettings(imageScope)\n const videoSettings = useCapabilitySettings(videoScope)\n const [quota, setQuota] = useState<QuotaStatusView | null>(null)\n const [quotaBusy, setQuotaBusy] = useState(false)\n const [quotaError, setQuotaError] = useState<string | null>(null)\n const [loadState, setLoadState] = useState<LoadState>('loading')\n const [_error, setError] = useState<string | null>(null)\n const [loginBusy, setLoginBusy] = useState(false)\n const [actionBusy, setActionBusy] = useState(false)\n const [resetTick, setResetTick] = useState(0)\n const statusGeneration = useRef(0)\n const quotaGeneration = useRef(0)\n const unmountSignal = useUnmountSignal()\n\n useEffect(() => {\n ensureSettingsStyles()\n }, [])\n\n useEffect(() => subscribe(() => { setResetTick(value => value + 1) }), [subscribe])\n\n const load = useCallback(async (signal?: AbortSignal, silent = false) => {\n const generation = ++statusGeneration.current\n if (!silent) {\n setLoadState(prev => (prev === 'ready' ? 'ready' : 'loading'))\n setError(null)\n }\n try {\n const result = await rpc.status(signal)\n if (signal?.aborted === true || generation !== statusGeneration.current) return\n if (!result.ok) {\n setLoadState('error')\n setError(result.error.message || t('statusFailed'))\n return\n }\n setStatus(result.value.status)\n setLoadState('ready')\n } catch (cause) {\n if (signal?.aborted === true || generation !== statusGeneration.current) return\n setLoadState('error')\n setError(messageOf(cause, t('statusFailed')))\n }\n }, [rpc, t])\n\n const loadQuota = useCallback(async (force = false, signal?: AbortSignal) => {\n if (rpc.usage === undefined) return\n const generation = ++quotaGeneration.current\n setQuotaBusy(true)\n setQuotaError(null)\n try {\n const result = await rpc.usage(signal, force)\n if (signal?.aborted === true || generation !== quotaGeneration.current) return\n if (!result.ok) {\n setQuotaError(result.error.message || t('quotaFailed'))\n return\n }\n setQuota(result.value)\n } catch (cause) {\n if (signal?.aborted === true || generation !== quotaGeneration.current) return\n setQuotaError(messageOf(cause, t('quotaFailed')))\n } finally {\n if (signal?.aborted !== true && generation === quotaGeneration.current) setQuotaBusy(false)\n }\n }, [rpc, t])\n\n useEffect(() => {\n if (status?.login.projectAvailable !== true || rpc.usage === undefined) {\n setQuota(null)\n return\n }\n const controller = new AbortController()\n void loadQuota(false, controller.signal)\n return () => controller.abort()\n }, [loadQuota, rpc.usage, status?.login.projectAvailable, resetTick])\n\n useEffect(() => {\n const controller = new AbortController()\n void load(controller.signal)\n return () => controller.abort()\n }, [load, resetTick])\n\n useEffect(() => {\n if (status?.login.phase !== 'pending') return\n const controller = new AbortController()\n const timer = globalThis.setInterval(() => { void load(controller.signal, true) }, 1_000)\n return () => {\n globalThis.clearInterval(timer)\n controller.abort()\n }\n }, [load, status?.login.phase])\n\n const startLogin = useCallback(async () => {\n const signal = unmountSignal()\n setLoginBusy(true)\n setError(null)\n try {\n if (status?.riskAcknowledged !== true) {\n await rpc.acknowledgeRisk(signal)\n }\n const result = await rpc.login(signal)\n if (signal.aborted) return\n if (!result.ok) {\n setError(result.error.message || t('loginFailed'))\n await load(signal)\n return\n }\n try {\n if (typeof window !== 'undefined' && typeof window.open === 'function' && result.value?.authorizationUrl && !window.navigator?.userAgent?.includes('jsdom')) {\n window.open(result.value.authorizationUrl, '_blank')\n }\n } catch {}\n setStatus(previous => {\n if (previous === null) return previous\n const { errorCode: _ignoredErrorCode, ...login } = previous.login\n return {\n ...previous,\n riskAcknowledged: true,\n login: {\n ...login,\n phase: 'pending',\n authorizationUrl: result.value.authorizationUrl,\n expiresAt: result.value.expiresAt,\n },\n }\n })\n } catch (cause) {\n if (!signal.aborted) setError(messageOf(cause, t('loginFailed')))\n } finally {\n if (!signal.aborted) setLoginBusy(false)\n }\n }, [load, rpc, status?.riskAcknowledged, t, unmountSignal])\n\n const cancelLogin = useCallback(async () => {\n const signal = unmountSignal()\n setLoginBusy(true)\n setError(null)\n try {\n const result = await rpc.cancelLogin(signal)\n if (signal.aborted) return\n if (!result.ok) {\n setError(result.error.message || t('cancelLoginFailed'))\n return\n }\n setStatus(previous => {\n if (previous === null) return previous\n const { errorCode: _ignoredErrorCode, ...login } = previous.login\n return {\n ...previous,\n login: result.value.errorCode === undefined\n ? { ...login, phase: result.value.phase }\n : { ...login, phase: result.value.phase, errorCode: result.value.errorCode },\n }\n })\n } catch (cause) {\n if (!signal.aborted) setError(messageOf(cause, t('cancelLoginFailed')))\n } finally {\n if (!signal.aborted) setLoginBusy(false)\n }\n }, [rpc, t, unmountSignal])\n\n const logout = useCallback(async () => {\n const signal = unmountSignal()\n setActionBusy(true)\n setError(null)\n try {\n const result = await rpc.logout(signal)\n if (signal.aborted) return\n if (!result.ok) {\n setError(result.error.message || t('logoutFailed'))\n return\n }\n await load(signal)\n } catch (cause) {\n if (!signal.aborted) setError(messageOf(cause, t('logoutFailed')))\n } finally {\n if (!signal.aborted) setActionBusy(false)\n }\n }, [load, rpc, t, unmountSignal])\n\n const projectError = projectErrorText(status?.login.errorCode, t)\n const isConfigured = status?.login.configured === true\n\n return (\n <section className=\"agy-settings\" data-plugin=\"dsh-antigravity-auth\" aria-labelledby=\"antigravity-auth-title\">\n <header className=\"agy-bundle-header\">\n <div>\n <div className=\"agy-title-line\">\n <h1 id=\"antigravity-auth-title\" className=\"agy-bundle-title\">{t('title')}</h1>\n {isConfigured ? (\n <span className=\"agy-status-dot\" role=\"status\" aria-label={t('ready')} />\n ) : null}\n </div>\n <p className=\"agy-bundle-intro\">{t('intro')}</p>\n </div>\n </header>\n\n <div className=\"agy-cards\">\n {/* Card 1: Auth & Quota */}\n <article className=\"agy-card\" aria-labelledby=\"antigravity-auth-card-title\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 id=\"antigravity-auth-card-title\" className=\"agy-card-title\">{t('authCardTitle')}</h2>\n <p className=\"agy-card-intro\">{t('authCardIntro')}</p>\n </div>\n </div>\n\n <QuotaVisualDashboard\n quota={quota}\n busy={quotaBusy}\n error={quotaError}\n onRefresh={() => { void loadQuota(true, unmountSignal()) }}\n t={t}\n />\n\n <div className=\"agy-action-row\">\n {status?.login.phase === 'pending' && typeof status.login.authorizationUrl === 'string' ? (\n <>\n <a className=\"agy-btn agy-btn-primary\" href={status.login.authorizationUrl} target=\"_blank\" rel=\"noreferrer\">\n {t('openAuthorization')}\n </a>\n <button className=\"agy-btn agy-btn-outline\" type=\"button\" disabled={loginBusy} onClick={() => { void cancelLogin() }}>\n {t('cancelLogin')}\n </button>\n </>\n ) : (\n <button className=\"agy-btn agy-btn-primary\" type=\"button\" disabled={status === null || loginBusy} onClick={() => { void startLogin() }}>\n {loginBusy ? t('startingLogin') : isConfigured ? t('relogin') : t('login')}\n </button>\n )}\n\n {isConfigured ? (\n <button className=\"agy-btn agy-btn-outline\" type=\"button\" disabled={actionBusy} onClick={() => { void logout() }}>\n {t('logout')}\n </button>\n ) : null}\n\n <button\n className=\"agy-btn agy-btn-ghost agy-refresh-btn\"\n type=\"button\"\n disabled={loadState === 'loading' || quotaBusy}\n onClick={() => {\n const minDelay = new Promise(resolve => setTimeout(resolve, 500))\n void Promise.all([load(unmountSignal()), loadQuota(true, unmountSignal()), minDelay])\n }}\n >\n <span className={quotaBusy || loadState === 'loading' ? 'agy-spin-icon' : ''}>\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"/><path d=\"M3 3v5h5\"/><path d=\"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\"/><path d=\"M16 21h5v-5\"/></svg>\n </span>\n {quotaBusy || loadState === 'loading' ? t('queryingQuota') : t('refreshStatus')}\n </button>\n </div>\n <p className=\"agy-footer-notice\">{t('quotaFooterNotice')}</p>\n\n {status?.login.phase === 'expired' ? <p className=\"agy-alert\" role=\"alert\">{t('loginExpired')}</p> : null}\n {status?.login.phase === 'port-conflict' ? <p className=\"agy-alert\" role=\"alert\">{t('loginPortConflict')}</p> : null}\n {status?.login.phase === 'failed' ? <p className=\"agy-alert\" role=\"alert\">{t('loginFailed')}</p> : null}\n {projectError === undefined ? null : <p className=\"agy-alert\" role=\"alert\">{projectError}</p>}\n {status?.login.phase === 'pending' && status.login.expiresAt !== undefined ? (\n <p className=\"agy-card-subtext\">{t('expiresAt')}: <time dateTime={status.login.expiresAt}>{status.login.expiresAt}</time></p>\n ) : null}\n {status?.revoke === undefined || status.revoke.state === 'idle' ? null : (\n <p className=\"agy-card-subtext\" role=\"status\">{revokeStatusText(status.revoke.state, t)}</p>\n )}\n </article>\n\n {/* Card 2: Web Search */}\n <article className=\"agy-card\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 className=\"agy-card-title\">{t('search')}</h2>\n <p className=\"agy-card-intro\">{t('searchCardIntro')}</p>\n </div>\n <div className=\"agy-card-action\">\n <Switch\n label={t('toggleSearch')}\n checked={searchSettings.value?.enabled ?? false}\n disabled={!capabilityAvailable(status, 'search') || searchSettings.status !== 'ready' || !searchSettings.writable}\n onChange={next => { void searchScope?.set('enabled', next) }}\n />\n </div>\n </div>\n </article>\n\n {/* Card 3: Image Creation */}\n <article className=\"agy-card\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 className=\"agy-card-title\">{t('image')}</h2>\n <p className=\"agy-card-intro\">{t('imageCardIntro')}</p>\n </div>\n <div className=\"agy-card-action\">\n <Switch\n label={t('toggleImage')}\n checked={imageSettings.value?.enabled ?? false}\n disabled={!capabilityAvailable(status, 'image') || imageSettings.status !== 'ready' || !imageSettings.writable}\n onChange={next => { void imageScope?.set('enabled', next) }}\n />\n </div>\n </div>\n </article>\n\n {/* Card 4: Video Analysis */}\n <article className=\"agy-card\">\n <div className=\"agy-card-header\">\n <div className=\"agy-card-identity\">\n <h2 className=\"agy-card-title\">{t('video')}</h2>\n <p className=\"agy-card-intro\">{t('videoCardIntro')}</p>\n </div>\n <div className=\"agy-card-action\">\n <Switch\n label={t('toggleVideo')}\n checked={videoSettings.value?.enabled ?? false}\n disabled={!capabilityAvailable(status, 'video') || videoSettings.status !== 'ready' || !videoSettings.writable}\n onChange={next => { void videoScope?.set('enabled', next) }}\n />\n </div>\n </div>\n </article>\n </div>\n </section>\n )\n}\n\nfunction capabilityAvailable(status: AntigravityStatusView | null, id: CapabilityRowId): boolean {\n return status?.login.projectAvailable === true && status.capabilities.some(capability => capability.id === id && capability.state === 'available')\n}\n\nfunction Switch({\n label,\n checked,\n disabled,\n onChange,\n}: {\n readonly label: string\n readonly checked: boolean\n readonly disabled?: boolean\n readonly onChange: (checked: boolean) => void\n}): ReactNode {\n return (\n <label className=\"agy-switch\">\n <input\n type=\"checkbox\"\n aria-label={label}\n checked={checked}\n disabled={disabled}\n onChange={e => { onChange(e.target.checked) }}\n />\n <span className=\"agy-switch-slider\" />\n </label>\n )\n}\n\nfunction formatRefreshTime(resetTime: string, dayUnit: string, now = Date.now()): string {\n const target = new Date(resetTime).getTime()\n if (Number.isNaN(target)) return resetTime\n const diffMs = target - now\n if (diffMs <= 0) return '0m'\n const diffMinutes = Math.floor(diffMs / (60 * 1000))\n const hours = Math.floor(diffMinutes / 60)\n const remMinutes = diffMinutes % 60\n\n if (hours >= 24) {\n const days = Math.floor(hours / 24)\n return `${days}${dayUnit} ${hours % 24}h ${remMinutes}m`\n }\n if (hours > 0) {\n return `${hours}h ${remMinutes}m`\n }\n return `${remMinutes}m`\n}\n\nfunction quotaTone(fraction: number): 'normal' | 'warning' | 'error' {\n if (fraction < 0.3) return 'error'\n if (fraction <= 0.6) return 'warning'\n return 'normal'\n}\n\nfunction QuotaVisualDashboard({\n quota,\n busy,\n error,\n t,\n}: {\n readonly quota: QuotaStatusView | null\n readonly busy?: boolean\n readonly error: string | null\n readonly onRefresh?: () => void\n readonly t: AntigravityAuthSettingsProps['t']\n}): ReactNode {\n return (\n <div className=\"agy-quota-section\">\n {quota?.state === 'available' && quota.groups !== undefined && quota.groups.length > 0 ? (\n <div className=\"agy-quota-groups\">\n {quota.groups.map(group => {\n const groupTitle = group.group === 'gemini' ? t('geminiGroupTitle') : t('claudeGptGroupTitle')\n const groupDesc = group.group === 'gemini' ? t('geminiGroupDesc') : t('claudeGptGroupDesc')\n return (\n <div key={group.group} className=\"agy-quota-group\">\n <div className=\"agy-quota-group-header\">\n <span className=\"agy-quota-group-title\">{groupTitle}</span>\n <span className=\"agy-quota-group-desc\">{groupDesc}</span>\n </div>\n <div className=\"agy-quota-buckets\">\n {group.windows.map(window => {\n const windowName = window.window === '5h' ? t('window5hTitle') : t('windowWeeklyTitle')\n const pctFormatted = (window.remainingFraction * 100).toFixed(2) + '%'\n const pctRounded = Math.round(window.remainingFraction * 100)\n const refreshStr = formatRefreshTime(window.resetTime, t('quotaDayUnit'))\n const subtext = `${pctRounded}% ${t('remaining')} · ${t('refreshesIn').replace('{time}', refreshStr)}`\n const widthPct = Math.max(0, Math.min(100, window.remainingFraction * 100))\n const tone = quotaTone(window.remainingFraction)\n\n return (\n <div key={window.window} className=\"agy-quota-bucket\">\n <div className=\"agy-quota-bucket-head\">\n <span className=\"agy-quota-bucket-name\">{windowName}</span>\n {busy ? (\n <span className=\"agy-quota-querying\">\n <span className=\"agy-querying-spinner\" aria-hidden=\"true\" />\n <span>{t('queryingQuota')}</span>\n </span>\n ) : (\n <span className=\"agy-quota-bucket-val\" data-tone={tone}>{pctFormatted}</span>\n )}\n </div>\n <div className=\"agy-progress-track\">\n {busy ? (\n <div className=\"agy-shimmer-track\" aria-hidden=\"true\" />\n ) : (\n <div className=\"agy-progress-bar\" data-tone={tone} style={{ width: `${widthPct}%` }} />\n )}\n </div>\n <span className=\"agy-quota-subtext\">{subtext}</span>\n </div>\n )\n })}\n </div>\n </div>\n )\n })}\n </div>\n ) : null}\n {error === null ? null : <p className=\"agy-alert\" role=\"alert\">{error}</p>}\n </div>\n )\n}\n\nconst PROJECT_ERROR_KEYS: Readonly<Partial<Record<LoginErrorCode, AntigravityAuthKey>>> = {\n 'project-unavailable': 'projectUnavailable',\n 'project-authentication-failed': 'projectAuthenticationFailed',\n 'project-forbidden': 'projectForbidden',\n 'project-rate-limited': 'projectRateLimited',\n 'project-offline': 'projectOffline',\n 'project-malformed': 'projectMalformed',\n 'project-protocol-drift': 'projectProtocolDrift',\n}\nconst REVOKE_STATE_KEYS: Readonly<Record<RevokeState, AntigravityAuthKey>> = {\n idle: 'credentialLoggedOut',\n 'logged-out': 'credentialLoggedOut',\n pending: 'revokePending',\n revoked: 'revokeSuccess',\n failed: 'revokeFailed',\n superseded: 'revokeSuperseded',\n 'confirmation-required': 'revokeConfirmationRequired',\n}\n\nfunction projectErrorText(errorCode: LoginErrorCode | undefined, t: AntigravityAuthSettingsProps['t']): string | undefined {\n if (errorCode === undefined) return undefined\n const key = PROJECT_ERROR_KEYS[errorCode]\n return key === undefined ? undefined : t(key)\n}\n\nfunction revokeStatusText(state: RevokeState, t: AntigravityAuthSettingsProps['t']): string {\n return t(REVOKE_STATE_KEYS[state])\n}\n\nfunction messageOf(_error: unknown, fallback: string): string {\n return fallback\n}\n","/** English and Chinese copy for the private bootstrap settings section. */\n\nexport const en = {\n nav: 'Antigravity',\n title: 'Antigravity Auth',\n intro: 'Sign in with Antigravity Auth to access language models, image generation, web search, and video understanding.',\n riskTitle: 'Before you continue',\n risk: 'Google does not support third-party Antigravity login tools. Your account may be suspended or terminated.',\n terms: 'Review the Google FAQ before continuing.',\n additionalTerms: 'Review the Additional Terms.',\n singleAccount: 'One active account at a time. This bundle does not provide an account pool or quota rotation.',\n riskAcknowledgement: 'I understand the unofficial third-party login risk and want to continue.',\n acknowledgeBusy: 'Saving acknowledgement…',\n acknowledgeFailed: 'The risk acknowledgement could not be recorded.',\n login: 'Start Antigravity login',\n startingLogin: 'Starting login…',\n cancelLogin: 'Cancel login',\n cancelLoginFailed: 'The login cancellation failed.',\n openAuthorization: 'Open the Google authorization page',\n loginReady: 'Login is ready to start.',\n loginRequiresAck: 'Acknowledge the risk before login can begin.',\n loginPending: 'Login is waiting for the browser authorization callback.',\n loginSuccess: 'Login completed successfully.',\n loginCancelled: 'Login was cancelled.',\n loginExpired: 'The login expired. Start again to receive a new authorization link.',\n loginPortConflict: 'The fixed callback port is already in use. Close the conflicting process and try again.',\n loginFailed: 'The login could not be completed safely.',\n credentialLoggedIn: 'The Antigravity account is ready.',\n credentialRefreshing: 'Refreshing the Antigravity access token…',\n credentialRefreshFailed: 'The access token could not be refreshed. No fallback account or endpoint was used.',\n credentialReloginRequired: 'The Antigravity grant requires login again.',\n credentialLoggedOut: 'The Antigravity account is logged out on this Host.',\n logout: 'Log out locally',\n logoutFailed: 'The local logout could not be completed.',\n revoke: 'Revoke Google grant',\n revokeConfirm: 'Revoke this Google grant? This is separate from local logout.',\n revokePending: 'Revoking the Google grant…',\n revokeSuccess: 'The Google grant was revoked and local state was cleared.',\n revokeFailed: 'The Google grant could not be revoked. Local state was retained.',\n revokeSuperseded: 'The account changed before revocation completed. No newer account was cleared.',\n revokeConfirmationRequired: 'Confirm revocation before contacting Google.',\n account: 'Account',\n projectAvailable: 'Read-only project validation is available.',\n projectUnavailable: 'No usable project is available.',\n projectAuthenticationFailed: 'Project discovery requires a fresh authenticated grant.',\n projectForbidden: 'This account is not allowed to use the discovered project.',\n projectRateLimited: 'Project discovery was rate-limited. No fallback project was used.',\n projectOffline: 'Project discovery is temporarily offline. No fallback project was used.',\n projectMalformed: 'Project discovery returned a malformed response.',\n projectProtocolDrift: 'Project discovery no longer matches the audited protocol.',\n expiresAt: 'Authorization link expires',\n statusLoading: 'Loading capability status…',\n statusFailed: 'Capability status is unavailable.',\n retry: 'Retry',\n capabilityTitle: 'Capability gates',\n authLlm: 'Auth / LLM',\n search: 'Web Search',\n image: 'Image',\n video: 'Video',\n available: 'Available',\n ready: 'Ready',\n disabled: 'Disabled',\n pocPending: 'POC pending',\n protocolDrift: 'Protocol drift',\n gateNotRun: 'This capability gate has not been run.',\n gateUnauthenticated: 'This gate requires a fresh authenticated grant.',\n gateRateLimited: 'This gate was rate-limited; no fallback was attempted.',\n gateCancelled: 'This gate run was cancelled.',\n gate0Failed: 'The fixed Wire Identity was rejected by Gate 0.',\n gateFailed: 'This capability gate failed safely.',\n unsupportedVideo: 'The private endpoint rejected native video input.',\n acknowledged: 'Risk acknowledged for this Host session.',\n settingsTitle: 'Capability settings',\n toggleSearch: 'Enable grounded Web Search',\n toggleImage: 'Enable image generation and editing',\n toggleVideo: 'Enable video understanding POC',\n settingsUnavailable: 'Unavailable until login, project validation, the live gate, and a writable Host settings scope are ready.',\n modelsTitle: 'Models',\n modelsSnapshot: 'Showing the pinned audited snapshot; live availability has not been refreshed.',\n modelsLiveAvailable: 'Live account availability was intersected with the pinned snapshot.',\n modelsRefreshFailed: 'Live availability refresh failed safely; the pinned snapshot remains advisory.',\n modelsProtocolDrift: 'Live model discovery no longer matches the audited protocol.',\n modelsSnapshotEntry: 'Snapshot',\n modelsAvailableEntry: 'Live available',\n modelsUnavailableEntry: 'Unavailable to this account',\n modelsFailed: 'Model availability could not be loaded safely.',\n modelsLoading: 'Refreshing models…',\n modelsRefresh: 'Refresh model availability',\n quotaTitle: 'Usage and quota',\n quotaAvailable: 'Quota is available from the current account.',\n quotaUnknown: 'Quota has not been queried.',\n quotaUnauthenticated: 'Log in to query quota.',\n quotaForbidden: 'This account is not allowed to query quota.',\n quotaRateLimited: 'Quota is rate-limited; try again later.',\n quotaOffline: 'Quota is temporarily unavailable.',\n quotaProtocolDrift: 'Quota protocol drift was detected; raw provider data was discarded.',\n quotaFailed: 'Quota could not be loaded safely.',\n quotaLoading: 'Refreshing quota…',\n quotaRefresh: 'Refresh quota',\n quotaFiveHour: 'Five-hour window',\n quotaWeekly: 'Weekly window',\n searchCardIntro: 'Google Antigravity Search Provider used by the stock web_search tool.',\n imageCardIntro: 'Durable image generation tools for image-capable models (gemini-3.1-flash-image).',\n videoCardIntro: 'Workspace MP4 video understanding tools for multimodal models (gemini-3.7-flash).',\n privacyNotice: 'Share Antigravity login state and model routing.',\n relogin: 'Log in again with Google',\n authCardTitle: 'Login',\n authCardIntro: 'Share Antigravity session and Antigravity model routing.',\n queryingQuota: 'Querying quota…',\n geminiGroupTitle: 'GEMINI MODELS',\n geminiGroupDesc: 'Models within this group: Gemini Flash, Gemini Pro',\n claudeGptGroupTitle: 'CLAUDE AND GPT MODELS',\n claudeGptGroupDesc: 'Models within this group: Claude Opus, Claude Sonnet, GPT-OSS',\n window5hTitle: 'Five Hour Limit Remaining',\n windowWeeklyTitle: 'Weekly Limit Remaining',\n quotaFooterNotice: 'No token value is ever sent to the Web client, settings, logs, events, or tool metadata.',\n refreshStatus: 'Refresh status',\n remaining: 'remaining',\n refreshesIn: 'Refreshes in {time}',\n quotaDayUnit: 'd',\n} as const\n\nexport type AntigravityAuthKey = keyof typeof en\n\nexport const zh: Record<AntigravityAuthKey, string> = {\n nav: 'Antigravity',\n title: 'Antigravity Auth',\n intro: '通过 Antigravity Auth 登录,使用语言模型、图片生成、网页搜索和视频理解能力。',\n riskTitle: '继续前请确认',\n risk: 'Google 不支持第三方 Antigravity 登录工具,账号可能被暂停或终止。',\n terms: '继续前请阅读 Google FAQ。',\n additionalTerms: '请阅读 Additional Terms。',\n singleAccount: '同一时刻只有一个活动账号。本能力包不提供账号池或额度轮换。',\n riskAcknowledgement: '我已了解非官方第三方登录风险,并确认继续。',\n acknowledgeBusy: '正在保存确认…',\n acknowledgeFailed: '无法记录风险确认。',\n login: '开始 Antigravity 登录',\n startingLogin: '正在启动登录…',\n cancelLogin: '取消登录',\n cancelLoginFailed: '取消登录失败。',\n openAuthorization: '打开 Google 授权页面',\n loginReady: '可以开始登录。',\n loginRequiresAck: '请先确认风险,才能开始登录。',\n loginPending: '等待浏览器授权回调。',\n loginSuccess: '登录已成功完成。',\n loginCancelled: '登录已取消。',\n loginExpired: '登录已过期,请重新开始以获取新的授权链接。',\n loginPortConflict: '固定回调端口已被占用,请关闭冲突进程后重试。',\n loginFailed: '登录无法安全完成。',\n credentialLoggedIn: 'Antigravity 账号已就绪。',\n credentialRefreshing: '正在刷新 Antigravity access token…',\n credentialRefreshFailed: '无法刷新 access token,未使用备用账号或 endpoint。',\n credentialReloginRequired: '该 Antigravity grant 需要重新登录。',\n credentialLoggedOut: '该 Host 上的 Antigravity 账号已登出。',\n logout: '在本地登出',\n logoutFailed: '本地登出未完成。',\n revoke: '撤销 Google grant',\n revokeConfirm: '确定撤销此 Google grant 吗?这与本地登出是分开的操作。',\n revokePending: '正在撤销 Google grant…',\n revokeSuccess: 'Google grant 已撤销,本地状态已清除。',\n revokeFailed: '无法撤销 Google grant,本地状态已保留。',\n revokeSuperseded: '账号在撤销完成前发生变化,未清除新账号。',\n revokeConfirmationRequired: '请先确认撤销,再联系 Google。',\n account: '账号',\n projectAvailable: '只读 project 验证可用。',\n projectUnavailable: '没有可用的 project。',\n projectAuthenticationFailed: 'project discovery 需要重新认证的 grant。',\n projectForbidden: '该账号没有权限使用已发现的 project。',\n projectRateLimited: 'project discovery 被限流,未使用备用 project。',\n projectOffline: 'project discovery 暂时离线,未使用备用 project。',\n projectMalformed: 'project discovery 返回了格式错误的响应。',\n projectProtocolDrift: 'project discovery 已偏离经过审计的协议。',\n expiresAt: '授权链接过期时间',\n statusLoading: '正在加载能力状态…',\n statusFailed: '能力状态不可用。',\n retry: '重试',\n capabilityTitle: '能力门禁',\n authLlm: '认证 / LLM',\n search: '网页搜索',\n image: '图片',\n video: '视频',\n available: '可用',\n ready: '就绪',\n disabled: '已禁用',\n pocPending: 'POC 待验证',\n protocolDrift: '协议漂移',\n gateNotRun: '该能力门禁尚未运行。',\n gateUnauthenticated: '该门禁需要新的有效认证 grant。',\n gateRateLimited: '该门禁运行被限流,未尝试任何 fallback。',\n gateCancelled: '该门禁运行已取消。',\n gate0Failed: '固定 Wire Identity 未通过 Gate 0。',\n gateFailed: '该能力门禁已安全失败。',\n unsupportedVideo: '私有 endpoint 拒绝了原生视频输入。',\n acknowledged: '本 Host 会话已确认风险。',\n settingsTitle: '能力设置',\n toggleSearch: '启用有依据的网页搜索',\n toggleImage: '启用图片生成与编辑',\n toggleVideo: '启用视频理解 POC',\n settingsUnavailable: '登录、project 验证、对应 live gate 和可写 Host 设置范围就绪后才能使用。',\n modelsTitle: '模型',\n modelsSnapshot: '当前显示已审计的固定快照;尚未刷新真实账号可用性。',\n modelsLiveAvailable: '已将真实账号可用性与固定快照取交集。',\n modelsRefreshFailed: '真实可用性刷新已安全失败;固定快照仍仅供参考。',\n modelsProtocolDrift: '真实模型发现已不再符合已审计协议。',\n modelsSnapshotEntry: '固定快照',\n modelsAvailableEntry: '真实可用',\n modelsUnavailableEntry: '当前账号不可用',\n modelsFailed: '无法安全加载模型可用性。',\n modelsLoading: '正在刷新模型…',\n modelsRefresh: '刷新模型可用性',\n quotaTitle: '用量与配额',\n quotaAvailable: '当前账号的配额可用。',\n quotaUnknown: '尚未查询配额。',\n quotaUnauthenticated: '登录后才能查询配额。',\n quotaForbidden: '该账号无权查询配额。',\n quotaRateLimited: '配额查询被限流,请稍后重试。',\n quotaOffline: '配额暂时不可用。',\n quotaProtocolDrift: '检测到配额协议漂移,已丢弃原始 provider 数据。',\n quotaFailed: '无法安全加载配额。',\n quotaLoading: '正在刷新配额…',\n quotaRefresh: '刷新配额',\n quotaFiveHour: '五小时窗口',\n quotaWeekly: '每周窗口',\n searchCardIntro: '供内置 web_search 工具使用的 Google Antigravity 全局搜索能力。',\n imageCardIntro: '面向支持图片模型的持久化 generate_image 工具(gemini-3.1-flash-image)。',\n videoCardIntro: '面向本地 MP4 视频文件的多模态 analyze_video 理解工具。',\n privacyNotice: '共享 Antigravity 登录态与模型路由。',\n relogin: '重新登录 Google',\n authCardTitle: '登录',\n authCardIntro: '共享 Antigravity 登录态与 Antigravity 模型路由。',\n queryingQuota: '正在查询额度…',\n geminiGroupTitle: 'GEMINI 模型',\n geminiGroupDesc: '包含模型:Gemini Flash, Gemini Pro',\n claudeGptGroupTitle: 'CLAUDE 与 GPT 模型',\n claudeGptGroupDesc: '包含模型:Claude Opus, Claude Sonnet, GPT-OSS',\n window5hTitle: '5 小时限额剩余',\n windowWeeklyTitle: '周限额剩余',\n quotaFooterNotice: '任何 Token 值都不会发送到 Web 客户端、设置、日志、事件或工具元数据。',\n refreshStatus: '刷新状态',\n remaining: '剩余',\n refreshesIn: '{time} 后刷新',\n quotaDayUnit: '天',\n}\n","/** Browser half of the private Antigravity bootstrap capability bundle. */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { createAntigravityAuthRpcClient } from '../rpc-contract.ts'\nimport { AntigravityAuthSettings } from './AntigravityAuthSettings.tsx'\nimport { en, zh, type AntigravityAuthKey } from './locales.ts'\nimport type { AntigravityAuthSettingsProps } from './AntigravityAuthSettings.tsx'\nimport type { AntigravitySearchSettings } from '../search.ts'\nimport type { AntigravityImageSettings } from '../image.ts'\nimport type { AntigravityVideoSettings } from '../video.ts'\n\nconst NS = 'settings.antigravityAuth'\n\nexport { AntigravityAuthSettings } from './AntigravityAuthSettings.tsx'\nexport type { AntigravityAuthSettingsProps } from './AntigravityAuthSettings.tsx'\nexport { en, zh } from './locales.ts'\nexport type { AntigravityAuthKey } from './locales.ts'\n\n/** Client services required by the settings section and its loopback RPC. */\nexport const inject = ['slots', 'locale', 'connection', 'configForms']\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Copy for the Antigravity bootstrap settings section. */\n 'settings.antigravityAuth': AntigravityAuthKey\n }\n}\n\n/** Register one disposable settings section and no capability controls. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'antigravity-auth: copy dictionaries')\n\n const connection = ctx.get('connection') as unknown as ConnectionHandle\n if (!connection.isLoopback) return\n const rpc = createAntigravityAuthRpcClient(connection.rpc)\n const t = ctx.locale.bind(NS) as AntigravityAuthSettingsProps['t']\n const searchScope = ctx.configForms.get<AntigravitySearchSettings>('antigravity-search')\n const imageScope = ctx.configForms.get<AntigravityImageSettings>('antigravity-image')\n const videoScope = ctx.configForms.get<AntigravityVideoSettings>('antigravity-video')\n const listeners = new Set<() => void>()\n const subscribe = (listener: () => void): (() => void) => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n }\n const reset = (): void => {\n for (const listener of listeners) listener()\n }\n ctx.effect(() => ctx.on('connection/reset', reset), 'antigravity-auth: connection invalidation')\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'antigravity-auth',\n order: 20,\n label: () => t('nav'),\n inject: (): AntigravityAuthSettingsProps => ({ rpc, t, subscribe, searchScope, imageScope, videoScope }),\n }, AntigravityAuthSettings))\n}\n"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -350,6 +350,8 @@ function registerAccountRoutes(connection, namespace, endpoints, handler) {
|
|
|
350
350
|
methods: ["POST"],
|
|
351
351
|
requestBody: "buffered",
|
|
352
352
|
fetch: async (request) => {
|
|
353
|
+
const admission = connection.admit(request);
|
|
354
|
+
if ("rejection" in admission) return new Response(admission.rejection === 401 ? "unauthorized" : "forbidden", { status: admission.rejection });
|
|
353
355
|
if (request.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() !== "application/json") return new Response("content type must be application/json", { status: 415 });
|
|
354
356
|
let body;
|
|
355
357
|
try {
|
|
@@ -370,7 +372,7 @@ function registerAccountRoutes(connection, namespace, endpoints, handler) {
|
|
|
370
372
|
});
|
|
371
373
|
let result;
|
|
372
374
|
try {
|
|
373
|
-
result = method === `${namespace}/${endpoint}` ? await handler(endpoint, payload, request.signal,
|
|
375
|
+
result = method === `${namespace}/${endpoint}` ? await handler(endpoint, payload, request.signal, admission.peer) : failure("bad-request", "Account request method does not match its endpoint");
|
|
374
376
|
} catch {
|
|
375
377
|
result = failure("internal", "Account request failed");
|
|
376
378
|
}
|
package/lib/search.js
CHANGED
|
@@ -127,21 +127,10 @@ function apply(ctx, config = {
|
|
|
127
127
|
auth,
|
|
128
128
|
id: "search",
|
|
129
129
|
enabled: () => current().enabled,
|
|
130
|
-
register: () => {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}));
|
|
135
|
-
const previousSearchProviderId = candidate.web.searchProviderId;
|
|
136
|
-
if (previousSearchProviderId === void 0) candidate.web.searchProviderId = ANTIGRAVITY_SEARCH_PROVIDER_ID;
|
|
137
|
-
return () => {
|
|
138
|
-
if (candidate.web.searchProviderId === "antigravity") {
|
|
139
|
-
if (previousSearchProviderId !== void 0) candidate.web.searchProviderId = previousSearchProviderId;
|
|
140
|
-
else delete candidate.web.searchProviderId;
|
|
141
|
-
}
|
|
142
|
-
unregister();
|
|
143
|
-
};
|
|
144
|
-
},
|
|
130
|
+
register: () => candidate.web.registerSearchProvider(new AntigravitySearchProvider({
|
|
131
|
+
auth,
|
|
132
|
+
settings: () => current()
|
|
133
|
+
})),
|
|
145
134
|
ownsAuth: auth !== provided,
|
|
146
135
|
label: "antigravity-search: provider lifecycle"
|
|
147
136
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-routes.d.ts","sourceRoot":"","sources":["../../src/account-routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AAEpG,8EAA8E;AAC9E,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,oBAAoB,EAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,MAAM,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"account-routes.d.ts","sourceRoot":"","sources":["../../src/account-routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAA;AAEpG,8EAA8E;AAC9E,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,oBAAoB,EAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,EAAE,oBAAoB,GAC5B,MAAM,OAAO,CAAC,IAAI,CAAC,CAiCrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/search.ts"],"names":[],"mappings":"AAAA,mFAAmF;AAEnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAmB,MAAM,sBAAsB,CAAA;AAGjH,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACxF,OAAO,EASL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAA;AAI/B,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEhE,eAAO,MAAM,IAAI,uBAAuB,CAAA;AACxC,eAAO,MAAM,MAAM,UAA6B,CAAA;AAChD,eAAO,MAAM,8BAA8B,gBAAgB,CAAA;AAC3D,eAAO,MAAM,2BAA2B,wCAAmE,CAAA;AAC3G,eAAO,MAAM,wBAAwB,iCAAiC,CAAA;AACtE,eAAO,MAAM,qCAAqC,uBAAuB,CAAA;AAEzE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC3B,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;IACxB,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;CAC9B;AAED,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAIH,CAAA;AAE1B,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,GAAG;QAAE,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAA;KAAE,CAAA;IACpI,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,yBAAyB,CAAA;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;IACrC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED,qBAAa,yBAA0B,YAAW,iBAAiB;IAKrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,QAAQ,CAAC,EAAE,iBAAiC;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;gBAEf,OAAO,EAAE,gCAAgC;IAKtE,SAAS,IAAI,OAAO;IAId,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;CAiDxF;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,KAAK,SAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUlK;AAED,8EAA8E;AAC9E,wBAAgB,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,GAAE,MAA2E,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/search.ts"],"names":[],"mappings":"AAAA,mFAAmF;AAEnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAGxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAmB,MAAM,sBAAsB,CAAA;AAGjH,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACxF,OAAO,EASL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAA;AAI/B,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEhE,eAAO,MAAM,IAAI,uBAAuB,CAAA;AACxC,eAAO,MAAM,MAAM,UAA6B,CAAA;AAChD,eAAO,MAAM,8BAA8B,gBAAgB,CAAA;AAC3D,eAAO,MAAM,2BAA2B,wCAAmE,CAAA;AAC3G,eAAO,MAAM,wBAAwB,iCAAiC,CAAA;AACtE,eAAO,MAAM,qCAAqC,uBAAuB,CAAA;AAEzE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC3B,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;IACxB,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;CAC9B;AAED,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAIH,CAAA;AAE1B,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,GAAG;QAAE,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAA;KAAE,CAAA;IACpI,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,yBAAyB,CAAA;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;IACrC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED,qBAAa,yBAA0B,YAAW,iBAAiB;IAKrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,QAAQ,CAAC,EAAE,iBAAiC;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;gBAEf,OAAO,EAAE,gCAAgC;IAKtE,SAAS,IAAI,OAAO;IAId,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;CAiDxF;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,KAAK,SAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUlK;AAED,8EAA8E;AAC9E,wBAAgB,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,GAAE,MAA2E,GAAG,IAAI,CAyB9H"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-antigravity-auth",
|
|
3
|
-
"version": "0.1.4
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Unofficial Antigravity OAuth capability bundle with local account caching and manual switching for DeepSeek Harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -119,65 +119,64 @@
|
|
|
119
119
|
},
|
|
120
120
|
"peerDependencies": {
|
|
121
121
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
122
|
-
"@deepseek-ai/dsh-agent": "
|
|
123
|
-
"@deepseek-ai/dsh-api-remotes": "
|
|
124
|
-
"@deepseek-ai/dsh-attachment": "
|
|
125
|
-
"@deepseek-ai/dsh-client-connection": "
|
|
126
|
-
"@deepseek-ai/dsh-client-locale": "
|
|
127
|
-
"@deepseek-ai/dsh-client-ui-primitives": "
|
|
128
|
-
"@deepseek-ai/dsh-client-ui-renderer": "
|
|
129
|
-
"@deepseek-ai/dsh-client-ui-settings": "
|
|
130
|
-
"@deepseek-ai/dsh-client-ui-slots": "
|
|
131
|
-
"@deepseek-ai/dsh-commands": "
|
|
132
|
-
"@deepseek-ai/dsh-fs": "
|
|
133
|
-
"@deepseek-ai/dsh-host-webserver": "
|
|
134
|
-
"@deepseek-ai/dsh-
|
|
135
|
-
"@deepseek-ai/dsh-
|
|
136
|
-
"@deepseek-ai/dsh-
|
|
137
|
-
"@deepseek-ai/dsh-
|
|
138
|
-
"@deepseek-ai/dsh-
|
|
139
|
-
"@deepseek-ai/dsh-web": "^0.2.0-rc.2",
|
|
122
|
+
"@deepseek-ai/dsh-agent": "*",
|
|
123
|
+
"@deepseek-ai/dsh-api-remotes": "*",
|
|
124
|
+
"@deepseek-ai/dsh-attachment": "*",
|
|
125
|
+
"@deepseek-ai/dsh-client-connection": "*",
|
|
126
|
+
"@deepseek-ai/dsh-client-locale": "*",
|
|
127
|
+
"@deepseek-ai/dsh-client-ui-primitives": "*",
|
|
128
|
+
"@deepseek-ai/dsh-client-ui-renderer": "*",
|
|
129
|
+
"@deepseek-ai/dsh-client-ui-settings": "*",
|
|
130
|
+
"@deepseek-ai/dsh-client-ui-slots": "*",
|
|
131
|
+
"@deepseek-ai/dsh-commands": "*",
|
|
132
|
+
"@deepseek-ai/dsh-fs": "*",
|
|
133
|
+
"@deepseek-ai/dsh-host-webserver": "*",
|
|
134
|
+
"@deepseek-ai/dsh-llm": "*",
|
|
135
|
+
"@deepseek-ai/dsh-session": "*",
|
|
136
|
+
"@deepseek-ai/dsh-settings": "*",
|
|
137
|
+
"@deepseek-ai/dsh-tools": "*",
|
|
138
|
+
"@deepseek-ai/dsh-web": "*",
|
|
140
139
|
"@deepseek-ai/schemastery": "^3.18.4",
|
|
141
140
|
"react": "^18.2.0"
|
|
142
141
|
},
|
|
143
142
|
"devDependencies": {
|
|
144
143
|
"@cortexkit/antigravity-auth-core": "2.2.0",
|
|
145
|
-
"@deepseek-ai/cordis": "4.0.
|
|
146
|
-
"@deepseek-ai/cordis-plugin-
|
|
147
|
-
"@deepseek-ai/cordis-plugin-
|
|
148
|
-
"@deepseek-ai/
|
|
149
|
-
"@deepseek-ai/dsh-agent
|
|
150
|
-
"@deepseek-ai/dsh-
|
|
151
|
-
"@deepseek-ai/dsh-
|
|
152
|
-
"@deepseek-ai/dsh-
|
|
153
|
-
"@deepseek-ai/dsh-
|
|
154
|
-
"@deepseek-ai/dsh-client-
|
|
155
|
-
"@deepseek-ai/dsh-client-
|
|
156
|
-
"@deepseek-ai/dsh-client-ui-
|
|
157
|
-
"@deepseek-ai/dsh-client-ui-
|
|
158
|
-
"@deepseek-ai/dsh-client-ui-
|
|
159
|
-
"@deepseek-ai/dsh-
|
|
160
|
-
"@deepseek-ai/dsh-
|
|
161
|
-
"@deepseek-ai/dsh-
|
|
162
|
-
"@deepseek-ai/dsh-
|
|
163
|
-
"@deepseek-ai/dsh-
|
|
164
|
-
"@deepseek-ai/dsh-
|
|
165
|
-
"@deepseek-ai/dsh-llm": "0.2.
|
|
166
|
-
"@deepseek-ai/dsh-sandbox": "0.2.
|
|
167
|
-
"@deepseek-ai/dsh-scope": "0.2.
|
|
168
|
-
"@deepseek-ai/dsh-session": "0.2.
|
|
169
|
-
"@deepseek-ai/dsh-session-persistence": "0.2.
|
|
170
|
-
"@deepseek-ai/dsh-session-projection": "0.2.
|
|
171
|
-
"@deepseek-ai/dsh-settings": "0.2.
|
|
172
|
-
"@deepseek-ai/dsh-system-prompt": "0.2.
|
|
173
|
-
"@deepseek-ai/dsh-timeout": "0.2.
|
|
174
|
-
"@deepseek-ai/dsh-tools": "0.2.
|
|
175
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.
|
|
176
|
-
"@deepseek-ai/dsh-user-approval": "0.2.
|
|
177
|
-
"@deepseek-ai/dsh-util-crypto": "0.2.
|
|
178
|
-
"@deepseek-ai/dsh-util-values": "0.2.
|
|
179
|
-
"@deepseek-ai/dsh-web": "0.2.
|
|
180
|
-
"@deepseek-ai/schemastery": "3.18.
|
|
144
|
+
"@deepseek-ai/cordis": "4.0.5",
|
|
145
|
+
"@deepseek-ai/cordis-plugin-group": "1.0.5",
|
|
146
|
+
"@deepseek-ai/cordis-plugin-include": "1.0.10",
|
|
147
|
+
"@deepseek-ai/cordis-plugin-loader": "1.0.6",
|
|
148
|
+
"@deepseek-ai/dsh-agent": "0.2.1-rc.5",
|
|
149
|
+
"@deepseek-ai/dsh-agent-loop": "0.2.1-rc.5",
|
|
150
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.5",
|
|
151
|
+
"@deepseek-ai/dsh-attachment": "0.2.1-rc.5",
|
|
152
|
+
"@deepseek-ai/dsh-brand": "0.2.1-rc.5",
|
|
153
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-rc.5",
|
|
154
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.5",
|
|
155
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.5",
|
|
156
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.5",
|
|
157
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.5",
|
|
158
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.5",
|
|
159
|
+
"@deepseek-ai/dsh-commands": "0.2.1-rc.5",
|
|
160
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.5",
|
|
161
|
+
"@deepseek-ai/dsh-deque": "0.2.1-rc.5",
|
|
162
|
+
"@deepseek-ai/dsh-fs": "0.2.1-rc.5",
|
|
163
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-rc.5",
|
|
164
|
+
"@deepseek-ai/dsh-llm": "0.2.1-rc.5",
|
|
165
|
+
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.5",
|
|
166
|
+
"@deepseek-ai/dsh-scope": "0.2.1-rc.5",
|
|
167
|
+
"@deepseek-ai/dsh-session": "0.2.1-rc.5",
|
|
168
|
+
"@deepseek-ai/dsh-session-persistence": "0.2.1-rc.5",
|
|
169
|
+
"@deepseek-ai/dsh-session-projection": "0.2.1-rc.5",
|
|
170
|
+
"@deepseek-ai/dsh-settings": "0.2.1-rc.5",
|
|
171
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.1-rc.5",
|
|
172
|
+
"@deepseek-ai/dsh-timeout": "0.2.1-rc.5",
|
|
173
|
+
"@deepseek-ai/dsh-tools": "0.2.1-rc.5",
|
|
174
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.5",
|
|
175
|
+
"@deepseek-ai/dsh-user-approval": "0.2.1-rc.5",
|
|
176
|
+
"@deepseek-ai/dsh-util-crypto": "0.2.1-rc.5",
|
|
177
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-rc.5",
|
|
178
|
+
"@deepseek-ai/dsh-web": "0.2.1-rc.5",
|
|
179
|
+
"@deepseek-ai/schemastery": "3.18.5",
|
|
181
180
|
"@testing-library/react": "^16.3.2",
|
|
182
181
|
"@types/node": "^22.20.0",
|
|
183
182
|
"@types/react": "~18.3.31",
|