dsh-coding-subscription-oauth 0.5.8 → 0.6.2

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.
Files changed (148) hide show
  1. package/CHANGELOG.md +217 -188
  2. package/CONTRIBUTING.md +120 -120
  3. package/INSTALL.md +241 -209
  4. package/LICENSE +19 -19
  5. package/NOTICE +11 -11
  6. package/README.de.md +298 -294
  7. package/README.es.md +299 -295
  8. package/README.fr.md +299 -295
  9. package/README.ja.md +299 -295
  10. package/README.ko.md +299 -295
  11. package/README.md +313 -307
  12. package/README.pt-BR.md +299 -295
  13. package/README.ru.md +299 -295
  14. package/README.zh-CN.md +311 -305
  15. package/compatibility/dsh-bom.json +30 -0
  16. package/cordis.patch.yml +13 -13
  17. package/docs/00-project-rules.md +195 -195
  18. package/docs/02-architecture.md +134 -129
  19. package/docs/02-architecture.zh-CN.md +134 -129
  20. package/lib/adapter.d.ts.map +1 -1
  21. package/lib/alias-adapter.d.ts +3 -1
  22. package/lib/alias-adapter.d.ts.map +1 -1
  23. package/lib/auth-routes.d.ts +8 -15
  24. package/lib/auth-routes.d.ts.map +1 -1
  25. package/lib/bin.js +746 -1402
  26. package/lib/bin.js.map +4 -4
  27. package/lib/capability-routes.d.ts +3 -3
  28. package/lib/capability-routes.d.ts.map +1 -1
  29. package/lib/capability-settings.d.ts +5 -4
  30. package/lib/capability-settings.d.ts.map +1 -1
  31. package/lib/client.js +27 -8
  32. package/lib/client.js.map +4 -4
  33. package/lib/compatibility.d.ts +46 -0
  34. package/lib/compatibility.d.ts.map +1 -0
  35. package/lib/dsh-host-adapter.d.ts +18 -0
  36. package/lib/dsh-host-adapter.d.ts.map +1 -0
  37. package/lib/gateway-auth.d.ts +1 -2
  38. package/lib/gateway-auth.d.ts.map +1 -1
  39. package/lib/gateway-routes.d.ts +3 -4
  40. package/lib/gateway-routes.d.ts.map +1 -1
  41. package/lib/gateway.d.ts +4 -0
  42. package/lib/gateway.d.ts.map +1 -1
  43. package/lib/ids.d.ts +3 -32
  44. package/lib/ids.d.ts.map +1 -1
  45. package/lib/imagine-routes.d.ts +2 -0
  46. package/lib/imagine-routes.d.ts.map +1 -1
  47. package/lib/index.d.ts +19 -4
  48. package/lib/index.d.ts.map +1 -1
  49. package/lib/index.js +26627 -1047
  50. package/lib/index.js.map +4 -4
  51. package/lib/invariant.js.map +1 -1
  52. package/lib/oauth-import-routes.d.ts +3 -4
  53. package/lib/oauth-import-routes.d.ts.map +1 -1
  54. package/lib/proxy.d.ts +3 -16
  55. package/lib/proxy.d.ts.map +1 -1
  56. package/lib/web-origin.d.ts +28 -4
  57. package/lib/web-origin.d.ts.map +1 -1
  58. package/lib/web-routes.d.ts.map +1 -1
  59. package/media/en/settings_accounts.png +0 -0
  60. package/media/en/settings_capabilities.png +0 -0
  61. package/media/en/settings_gateway.png +0 -0
  62. package/media/settings_accounts.png +0 -0
  63. package/media/settings_capabilities.png +0 -0
  64. package/media/settings_gateway.png +0 -0
  65. package/media/settings_overview.png +0 -0
  66. package/media/zh-CN/settings_accounts.png +0 -0
  67. package/media/zh-CN/settings_capabilities.png +0 -0
  68. package/media/zh-CN/settings_gateway.png +0 -0
  69. package/package.json +211 -174
  70. package/patches/dsh-agy@0.1.2.patch +25 -25
  71. package/scripts/release.mjs +186 -170
  72. package/scripts/smoke-deployed-routes.mjs +146 -146
  73. package/scripts/verify-deployed-catalog.mjs +87 -87
  74. package/src/adapter.ts +329 -268
  75. package/src/alias-adapter.ts +141 -147
  76. package/src/auth-routes.ts +921 -871
  77. package/src/auth.ts +67 -67
  78. package/src/bin.ts +350 -350
  79. package/src/capability-routes.ts +279 -275
  80. package/src/capability-runtime.ts +313 -313
  81. package/src/capability-settings.ts +658 -657
  82. package/src/capability-tools.ts +666 -666
  83. package/src/catalog.ts +271 -271
  84. package/src/client/GrokBuildSettings.tsx +770 -718
  85. package/src/client/api.ts +88 -88
  86. package/src/client/components/AboutTab.tsx +30 -30
  87. package/src/client/components/AccountsTab.tsx +241 -224
  88. package/src/client/components/Badge.tsx +33 -33
  89. package/src/client/components/CapabilitiesTab.tsx +265 -227
  90. package/src/client/components/CliPullPreview.tsx +116 -107
  91. package/src/client/components/CopyButton.tsx +57 -57
  92. package/src/client/components/GatewayTab.tsx +469 -409
  93. package/src/client/components/NoticeBanner.tsx +46 -46
  94. package/src/client/components/ProgressBar.tsx +53 -53
  95. package/src/client/components/ProviderCard.tsx +606 -502
  96. package/src/client/components/SettingsTabs.tsx +75 -75
  97. package/src/client/components/ToggleSwitch.tsx +71 -62
  98. package/src/client/constants.ts +224 -206
  99. package/src/client/display.ts +61 -61
  100. package/src/client/dshClientAdapter.ts +127 -0
  101. package/src/client/gatewaySnippets.ts +37 -36
  102. package/src/client/index.tsx +156 -37
  103. package/src/client/locales.ts +535 -491
  104. package/src/client/microStyles.ts +52 -33
  105. package/src/client/parsers.ts +396 -386
  106. package/src/client/styles.ts +325 -307
  107. package/src/client/types.ts +197 -185
  108. package/src/codex-http.ts +447 -447
  109. package/src/codex-images.ts +485 -485
  110. package/src/codex-model-capabilities.ts +320 -320
  111. package/src/codex-search.ts +245 -245
  112. package/src/codex-usage.ts +263 -263
  113. package/src/compatibility.ts +55 -0
  114. package/src/dsh-host-adapter.ts +173 -0
  115. package/src/gateway-anthropic-messages.ts +84 -84
  116. package/src/gateway-auth.ts +102 -100
  117. package/src/gateway-backend.ts +274 -274
  118. package/src/gateway-body.ts +49 -49
  119. package/src/gateway-config.ts +76 -76
  120. package/src/gateway-http.ts +104 -104
  121. package/src/gateway-openai-chat.ts +124 -124
  122. package/src/gateway-openai-responses.ts +53 -53
  123. package/src/gateway-parse.ts +224 -224
  124. package/src/gateway-protocol.ts +52 -52
  125. package/src/gateway-routes.ts +158 -152
  126. package/src/gateway.ts +258 -242
  127. package/src/grok-errors.ts +24 -24
  128. package/src/grok-imagine.ts +1627 -1627
  129. package/src/grok-import.ts +151 -151
  130. package/src/http-json.ts +82 -82
  131. package/src/ids.ts +59 -45
  132. package/src/imagine-routes.ts +463 -461
  133. package/src/index.ts +729 -592
  134. package/src/invariant.ts +17 -17
  135. package/src/kimi-errors.ts +26 -26
  136. package/src/media-store.ts +927 -927
  137. package/src/oauth-import-routes.ts +324 -314
  138. package/src/oauth-providers.ts +152 -152
  139. package/src/oauth-session.ts +183 -183
  140. package/src/oauth-sources.ts +1104 -1104
  141. package/src/oauth.ts +620 -620
  142. package/src/provider.ts +128 -128
  143. package/src/proxy.ts +11 -99
  144. package/src/redact.ts +72 -72
  145. package/src/session.ts +218 -218
  146. package/src/store.ts +217 -217
  147. package/src/web-origin.ts +296 -60
  148. package/src/web-routes.ts +38 -75
@@ -1,224 +1,241 @@
1
- /** Accounts tab: provider cards, CLI tips, and pull preview. */
2
-
3
- import { PROVIDERS } from "../constants.ts";
4
- import { allOfficialCliMissing, anyOfficialCliAvailable } from "../display.ts";
5
- import {
6
- accountGridStyle,
7
- bodyStyle,
8
- cardStyle,
9
- dotStyle,
10
- hintStyle,
11
- monoStyle,
12
- rowStyle,
13
- skeletonStyle,
14
- statusStyle,
15
- titleStyle,
16
- } from "../styles.ts";
17
- import type {
18
- CodingOAuthStatus,
19
- GrokBuildSettingsInjected,
20
- LoginMethod,
21
- ProviderSlug,
22
- SourcePreview,
23
- SourceStatus,
24
- UsageView,
25
- } from "../types.ts";
26
- import { Badge } from "./Badge.tsx";
27
- import { CliPullPreview } from "./CliPullPreview.tsx";
28
- import { NoticeBanner } from "./NoticeBanner.tsx";
29
- import { ProviderCard } from "./ProviderCard.tsx";
30
-
31
- export interface AccountsTabProps {
32
- t: GrokBuildSettingsInjected["t"];
33
- status: CodingOAuthStatus | undefined;
34
- remote: boolean;
35
- remoteTipDismissed: boolean;
36
- onDismissRemoteTip: () => void;
37
- sources: readonly SourceStatus[] | undefined;
38
- sourcesError: string | undefined;
39
- sourcesNotice: string | undefined;
40
- sourcesBusy: boolean;
41
- preview: SourcePreview | undefined;
42
- confirmOverwrite: boolean;
43
- busyProvider: ProviderSlug | undefined;
44
- codeInputs: Partial<Record<ProviderSlug, string>>;
45
- popupBlocked: Partial<Record<ProviderSlug, boolean>>;
46
- expandedProviders: Partial<Record<ProviderSlug, boolean>>;
47
- showUsage: boolean;
48
- usage: UsageView | undefined;
49
- usageError: string | undefined;
50
- usageLoading: boolean;
51
- onSignIn: (slug: ProviderSlug, method: LoginMethod) => void;
52
- onSignOut: (slug: ProviderSlug) => void;
53
- onCancelLogin: (slug: ProviderSlug) => void;
54
- onSubmitCode: (slug: ProviderSlug) => void;
55
- onCodeChange: (slug: ProviderSlug, value: string) => void;
56
- onToggleExpanded: (slug: ProviderSlug) => void;
57
- onPreviewSource: (slug: ProviderSlug) => void;
58
- onSaveModels: (slug: ProviderSlug, selected: string[]) => void;
59
- onConfirmOverwriteChange: (checked: boolean) => void;
60
- onCommitSource: () => void;
61
- onCancelSourcePreview: () => void;
62
- onRefreshSources: () => void;
63
- onDismissSourcesNotice: () => void;
64
- }
65
-
66
- export function AccountsTab({
67
- t,
68
- status,
69
- remote,
70
- remoteTipDismissed,
71
- onDismissRemoteTip,
72
- sources,
73
- sourcesError,
74
- sourcesNotice,
75
- sourcesBusy,
76
- preview,
77
- confirmOverwrite,
78
- busyProvider,
79
- codeInputs,
80
- popupBlocked,
81
- expandedProviders,
82
- showUsage,
83
- usage,
84
- usageError,
85
- usageLoading,
86
- onSignIn,
87
- onSignOut,
88
- onCancelLogin,
89
- onSubmitCode,
90
- onCodeChange,
91
- onToggleExpanded,
92
- onPreviewSource,
93
- onSaveModels,
94
- onConfirmOverwriteChange,
95
- onCommitSource,
96
- onCancelSourcePreview,
97
- onRefreshSources,
98
- onDismissSourcesNotice,
99
- }: AccountsTabProps) {
100
- if (status === undefined) {
101
- return (
102
- <div style={skeletonStyle} role="status" aria-busy="true">
103
- <div style={statusStyle}>
104
- <span aria-hidden="true" style={dotStyle("loading")} />
105
- {t("loadingAccount")}
106
- </div>
107
- </div>
108
- );
109
- }
110
-
111
- return (
112
- <>
113
- {remote && !remoteTipDismissed ? (
114
- <NoticeBanner
115
- message={t("remoteAccountsTip")}
116
- dismissLabel={t("remoteTipDismiss")}
117
- onDismiss={onDismissRemoteTip}
118
- />
119
- ) : null}
120
- {allOfficialCliMissing(sources) ? (
121
- <NoticeBanner
122
- message={t("sourcesAllMissingHint")}
123
- dismissLabel={t("sourcesCheckAgain")}
124
- onDismiss={() => {
125
- onRefreshSources();
126
- }}
127
- />
128
- ) : null}
129
- {anyOfficialCliAvailable(sources) ? <p style={hintStyle}>{t("sourcesAvailableHint")}</p> : null}
130
- {sourcesError === undefined ? null : (
131
- <p style={{ ...bodyStyle, color: "var(--dsw-alias-state-error-primary)" }} role="alert">
132
- {sourcesError}
133
- </p>
134
- )}
135
- {sourcesNotice === undefined ? null : (
136
- <NoticeBanner
137
- key={sourcesNotice}
138
- message={sourcesNotice}
139
- tone="success"
140
- autoHideMs={5000}
141
- onDismiss={onDismissSourcesNotice}
142
- />
143
- )}
144
- <div style={accountGridStyle}>
145
- {PROVIDERS.map((definition) => {
146
- const providerStatus = status.providers[definition.slug];
147
- const expanded = providerStatus.status === "signing-in" || expandedProviders[definition.slug] === true;
148
- return (
149
- <ProviderCard
150
- key={definition.slug}
151
- t={t}
152
- definition={definition}
153
- providerStatus={providerStatus}
154
- busy={busyProvider === definition.slug}
155
- sourcesBusy={sourcesBusy}
156
- remote={remote}
157
- codeInput={codeInputs[definition.slug] ?? ""}
158
- popupBlocked={popupBlocked[definition.slug] === true}
159
- expanded={expanded}
160
- source={sources?.find((entry) => entry.kind === definition.slug)}
161
- showUsage={showUsage}
162
- usage={usage}
163
- usageError={usageError}
164
- usageLoading={usageLoading}
165
- onSignIn={(method) => {
166
- onSignIn(definition.slug, method);
167
- }}
168
- onSignOut={() => {
169
- onSignOut(definition.slug);
170
- }}
171
- onCancelLogin={() => {
172
- onCancelLogin(definition.slug);
173
- }}
174
- onSubmitCode={() => {
175
- onSubmitCode(definition.slug);
176
- }}
177
- onCodeChange={(value) => {
178
- onCodeChange(definition.slug, value);
179
- }}
180
- onToggleExpanded={() => {
181
- onToggleExpanded(definition.slug);
182
- }}
183
- onPreviewSource={() => {
184
- onPreviewSource(definition.slug);
185
- }}
186
- onSaveModels={(selected) => {
187
- onSaveModels(definition.slug, selected);
188
- }}
189
- />
190
- );
191
- })}
192
- <div style={cardStyle}>
193
- <div style={rowStyle}>
194
- <div>
195
- <h3 style={{ ...titleStyle, fontSize: 16 }}>{t("antigravityTitle")}</h3>
196
- <p style={{ ...bodyStyle, marginTop: 4 }}>{t("antigravityDescription")}</p>
197
- <p style={{ ...bodyStyle, marginTop: 4 }}>
198
- <span style={monoStyle}>{status.antigravity.route}</span>
199
- </p>
200
- </div>
201
- <Badge
202
- label={status.antigravity.installed ? t("antigravityInstalled") : t("antigravityMissing")}
203
- tone={status.antigravity.installed ? "success" : "neutral"}
204
- installed={status.antigravity.installed}
205
- />
206
- </div>
207
- <p style={bodyStyle}>{t("antigravityCliHint")}</p>
208
- <code style={{ ...monoStyle, fontSize: 12, overflowWrap: "anywhere" }}>{t("antigravityCliCommand")}</code>
209
- </div>
210
- </div>
211
- {preview === undefined ? null : (
212
- <CliPullPreview
213
- t={t}
214
- preview={preview}
215
- confirmOverwrite={confirmOverwrite}
216
- sourcesBusy={sourcesBusy}
217
- onConfirmOverwriteChange={onConfirmOverwriteChange}
218
- onCommit={onCommitSource}
219
- onCancel={onCancelSourcePreview}
220
- />
221
- )}
222
- </>
223
- );
224
- }
1
+ /** Accounts tab: provider cards, CLI tips, and pull preview. */
2
+
3
+ import { Fragment, useEffect, useRef } from "react";
4
+ import { PROVIDERS } from "../constants.ts";
5
+ import { allOfficialCliMissing, anyOfficialCliAvailable } from "../display.ts";
6
+ import {
7
+ accountGridStyle,
8
+ bodyStyle,
9
+ cardStyle,
10
+ dotStyle,
11
+ hintStyle,
12
+ monoStyle,
13
+ rowStyle,
14
+ skeletonStyle,
15
+ statusStyle,
16
+ titleStyle,
17
+ } from "../styles.ts";
18
+ import type {
19
+ CodingOAuthStatus,
20
+ GrokBuildSettingsInjected,
21
+ LoginMethod,
22
+ ProviderSlug,
23
+ SourcePreview,
24
+ SourceStatus,
25
+ UsageView,
26
+ } from "../types.ts";
27
+ import { Badge } from "./Badge.tsx";
28
+ import { CliPullPreview } from "./CliPullPreview.tsx";
29
+ import { NoticeBanner } from "./NoticeBanner.tsx";
30
+ import { ProviderCard } from "./ProviderCard.tsx";
31
+
32
+ export interface AccountsTabProps {
33
+ t: GrokBuildSettingsInjected["t"];
34
+ status: CodingOAuthStatus | undefined;
35
+ remote: boolean;
36
+ remoteTipDismissed: boolean;
37
+ onDismissRemoteTip: () => void;
38
+ sources: readonly SourceStatus[] | undefined;
39
+ sourcesError: string | undefined;
40
+ sourcesNotice: string | undefined;
41
+ sourcesBusy: boolean;
42
+ preview: SourcePreview | undefined;
43
+ confirmOverwrite: boolean;
44
+ busyProvider: ProviderSlug | undefined;
45
+ codeInputs: Partial<Record<ProviderSlug, string>>;
46
+ popupBlocked: Partial<Record<ProviderSlug, boolean>>;
47
+ expandedProviders: Partial<Record<ProviderSlug, boolean>>;
48
+ showUsage: boolean;
49
+ usage: UsageView | undefined;
50
+ usageError: string | undefined;
51
+ usageLoading: boolean;
52
+ onSignIn: (slug: ProviderSlug, method: LoginMethod) => void;
53
+ onSignOut: (slug: ProviderSlug) => void;
54
+ onCancelLogin: (slug: ProviderSlug) => void;
55
+ onSubmitCode: (slug: ProviderSlug) => void;
56
+ onCodeChange: (slug: ProviderSlug, value: string) => void;
57
+ onToggleExpanded: (slug: ProviderSlug) => void;
58
+ onPreviewSource: (slug: ProviderSlug) => void;
59
+ onSaveModels: (slug: ProviderSlug, selected: string[]) => void;
60
+ onConfirmOverwriteChange: (checked: boolean) => void;
61
+ onCommitSource: () => void;
62
+ onCancelSourcePreview: () => void;
63
+ onRefreshSources: () => void;
64
+ onDismissSourcesNotice: () => void;
65
+ }
66
+
67
+ export function AccountsTab({
68
+ t,
69
+ status,
70
+ remote,
71
+ remoteTipDismissed,
72
+ onDismissRemoteTip,
73
+ sources,
74
+ sourcesError,
75
+ sourcesNotice,
76
+ sourcesBusy,
77
+ preview,
78
+ confirmOverwrite,
79
+ busyProvider,
80
+ codeInputs,
81
+ popupBlocked,
82
+ expandedProviders,
83
+ showUsage,
84
+ usage,
85
+ usageError,
86
+ usageLoading,
87
+ onSignIn,
88
+ onSignOut,
89
+ onCancelLogin,
90
+ onSubmitCode,
91
+ onCodeChange,
92
+ onToggleExpanded,
93
+ onPreviewSource,
94
+ onSaveModels,
95
+ onConfirmOverwriteChange,
96
+ onCommitSource,
97
+ onCancelSourcePreview,
98
+ onRefreshSources,
99
+ onDismissSourcesNotice,
100
+ }: AccountsTabProps) {
101
+ const previousPreviewKind = useRef<ProviderSlug | undefined>(undefined);
102
+ useEffect(() => {
103
+ if (preview !== undefined) {
104
+ previousPreviewKind.current = preview.kind;
105
+ document.getElementById(`coding-oauth-source-preview-${preview.kind}`)?.focus();
106
+ return;
107
+ }
108
+ const trigger = previousPreviewKind.current;
109
+ if (trigger === undefined || sourcesBusy) return;
110
+ previousPreviewKind.current = undefined;
111
+ document.getElementById(`coding-oauth-source-pull-${trigger}`)?.focus();
112
+ }, [preview, sourcesBusy]);
113
+
114
+ if (status === undefined) {
115
+ return (
116
+ <div style={skeletonStyle} role="status" aria-busy="true">
117
+ <div style={statusStyle}>
118
+ <span aria-hidden="true" style={dotStyle("loading")} />
119
+ {t("loadingAccount")}
120
+ </div>
121
+ </div>
122
+ );
123
+ }
124
+
125
+ return (
126
+ <>
127
+ {remote && !remoteTipDismissed ? (
128
+ <NoticeBanner
129
+ message={t("remoteAccountsTip")}
130
+ dismissLabel={t("remoteTipDismiss")}
131
+ onDismiss={onDismissRemoteTip}
132
+ />
133
+ ) : null}
134
+ {allOfficialCliMissing(sources) ? (
135
+ <NoticeBanner
136
+ message={t("sourcesAllMissingHint")}
137
+ dismissLabel={t("sourcesCheckAgain")}
138
+ onDismiss={() => {
139
+ onRefreshSources();
140
+ }}
141
+ />
142
+ ) : null}
143
+ {anyOfficialCliAvailable(sources) ? <p style={hintStyle}>{t("sourcesAvailableHint")}</p> : null}
144
+ {sourcesError === undefined ? null : (
145
+ <p style={{ ...bodyStyle, color: "var(--dsw-alias-state-error-primary)" }} role="alert">
146
+ {sourcesError}
147
+ </p>
148
+ )}
149
+ {sourcesNotice === undefined ? null : (
150
+ <NoticeBanner
151
+ key={sourcesNotice}
152
+ message={sourcesNotice}
153
+ tone="success"
154
+ autoHideMs={5000}
155
+ onDismiss={onDismissSourcesNotice}
156
+ />
157
+ )}
158
+ <div style={accountGridStyle}>
159
+ {PROVIDERS.map((definition) => {
160
+ const providerStatus = status.providers[definition.slug];
161
+ const expanded = providerStatus.status === "signing-in" || expandedProviders[definition.slug] === true;
162
+ return (
163
+ <Fragment key={definition.slug}>
164
+ <ProviderCard
165
+ t={t}
166
+ definition={definition}
167
+ providerStatus={providerStatus}
168
+ busy={busyProvider === definition.slug}
169
+ sourcesBusy={sourcesBusy}
170
+ remote={remote}
171
+ codeInput={codeInputs[definition.slug] ?? ""}
172
+ popupBlocked={popupBlocked[definition.slug] === true}
173
+ expanded={expanded}
174
+ source={sources?.find((entry) => entry.kind === definition.slug)}
175
+ showUsage={showUsage}
176
+ usage={usage}
177
+ usageError={usageError}
178
+ usageLoading={usageLoading}
179
+ onSignIn={(method) => {
180
+ onSignIn(definition.slug, method);
181
+ }}
182
+ onSignOut={() => {
183
+ onSignOut(definition.slug);
184
+ }}
185
+ onCancelLogin={() => {
186
+ onCancelLogin(definition.slug);
187
+ }}
188
+ onSubmitCode={() => {
189
+ onSubmitCode(definition.slug);
190
+ }}
191
+ onCodeChange={(value) => {
192
+ onCodeChange(definition.slug, value);
193
+ }}
194
+ onToggleExpanded={() => {
195
+ onToggleExpanded(definition.slug);
196
+ }}
197
+ onPreviewSource={() => {
198
+ onPreviewSource(definition.slug);
199
+ }}
200
+ onSaveModels={(selected) => {
201
+ onSaveModels(definition.slug, selected);
202
+ }}
203
+ />
204
+ {preview?.kind === definition.slug ? (
205
+ <div style={{ gridColumn: "1 / -1", minWidth: 0 }}>
206
+ <CliPullPreview
207
+ t={t}
208
+ preview={preview}
209
+ confirmOverwrite={confirmOverwrite}
210
+ sourcesBusy={sourcesBusy}
211
+ onConfirmOverwriteChange={onConfirmOverwriteChange}
212
+ onCommit={onCommitSource}
213
+ onCancel={onCancelSourcePreview}
214
+ />
215
+ </div>
216
+ ) : null}
217
+ </Fragment>
218
+ );
219
+ })}
220
+ <div style={cardStyle}>
221
+ <div style={rowStyle}>
222
+ <div>
223
+ <h3 style={{ ...titleStyle, fontSize: 16 }}>{t("antigravityTitle")}</h3>
224
+ <p style={{ ...bodyStyle, marginTop: 4 }}>{t("antigravityDescription")}</p>
225
+ <p style={{ ...bodyStyle, marginTop: 4 }}>
226
+ <span style={monoStyle}>{status.antigravity.route}</span>
227
+ </p>
228
+ </div>
229
+ <Badge
230
+ label={status.antigravity.installed ? t("antigravityInstalled") : t("antigravityMissing")}
231
+ tone={status.antigravity.installed ? "success" : "neutral"}
232
+ installed={status.antigravity.installed}
233
+ />
234
+ </div>
235
+ <p style={bodyStyle}>{t("antigravityCliHint")}</p>
236
+ <code style={{ ...monoStyle, fontSize: 12, overflowWrap: "anywhere" }}>{t("antigravityCliCommand")}</code>
237
+ </div>
238
+ </div>
239
+ </>
240
+ );
241
+ }
@@ -1,33 +1,33 @@
1
- /** Status capsule badge with semantic tone colors. */
2
-
3
- import { badgeStyle, dotStyle, providerStatusTone, type StatusTone } from "../styles.ts";
4
- import type { ProviderStatus } from "../types.ts";
5
-
6
- export interface BadgeProps {
7
- label: string;
8
- tone?: StatusTone;
9
- /** When set, derives tone from provider login status. */
10
- providerStatus?: ProviderStatus["status"];
11
- installed?: boolean;
12
- showDot?: boolean;
13
- }
14
-
15
- export function Badge({ label, tone, providerStatus, installed = true, showDot = true }: BadgeProps) {
16
- const resolvedTone =
17
- tone ?? (providerStatus !== undefined ? providerStatusTone(providerStatus, installed) : "neutral");
18
- return (
19
- <span style={badgeStyle(resolvedTone)} role="status">
20
- {showDot ? (
21
- <span
22
- aria-hidden="true"
23
- style={{
24
- ...dotStyle(providerStatus ?? (resolvedTone === "success" ? "signed-in" : "signed-out"), installed),
25
- width: 7,
26
- height: 7,
27
- }}
28
- />
29
- ) : null}
30
- <span>{label}</span>
31
- </span>
32
- );
33
- }
1
+ /** Status capsule badge with semantic tone colors. */
2
+
3
+ import { badgeStyle, dotStyle, providerStatusTone, type StatusTone } from "../styles.ts";
4
+ import type { ProviderStatus } from "../types.ts";
5
+
6
+ export interface BadgeProps {
7
+ label: string;
8
+ tone?: StatusTone;
9
+ /** When set, derives tone from provider login status. */
10
+ providerStatus?: ProviderStatus["status"];
11
+ installed?: boolean;
12
+ showDot?: boolean;
13
+ }
14
+
15
+ export function Badge({ label, tone, providerStatus, installed = true, showDot = true }: BadgeProps) {
16
+ const resolvedTone =
17
+ tone ?? (providerStatus !== undefined ? providerStatusTone(providerStatus, installed) : "neutral");
18
+ return (
19
+ <span style={badgeStyle(resolvedTone)} role="status">
20
+ {showDot ? (
21
+ <span
22
+ aria-hidden="true"
23
+ style={{
24
+ ...dotStyle(providerStatus ?? (resolvedTone === "success" ? "signed-in" : "signed-out"), installed),
25
+ width: 7,
26
+ height: 7,
27
+ }}
28
+ />
29
+ ) : null}
30
+ <span>{label}</span>
31
+ </span>
32
+ );
33
+ }