dsh-plugin-subscription-oauth 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +413 -2
  3. package/cordis.patch.yml +13 -0
  4. package/lib/auth/device-flow.d.ts +112 -0
  5. package/lib/auth/device-flow.js +319 -0
  6. package/lib/auth/device-id.d.ts +31 -0
  7. package/lib/auth/device-id.js +58 -0
  8. package/lib/auth/flow.d.ts +33 -0
  9. package/lib/auth/flow.js +12 -0
  10. package/lib/auth/glm-flow.d.ts +99 -0
  11. package/lib/auth/glm-flow.js +194 -0
  12. package/lib/auth/headers.d.ts +61 -0
  13. package/lib/auth/headers.js +106 -0
  14. package/lib/auth/pkce-flow.d.ts +78 -0
  15. package/lib/auth/pkce-flow.js +205 -0
  16. package/lib/auth/provider-controller.d.ts +241 -0
  17. package/lib/auth/provider-controller.js +502 -0
  18. package/lib/auth/registry.d.ts +91 -0
  19. package/lib/auth/registry.js +149 -0
  20. package/lib/auth/rpc.d.ts +31 -0
  21. package/lib/auth/rpc.js +200 -0
  22. package/lib/auth/store.d.ts +99 -0
  23. package/lib/auth/store.js +213 -0
  24. package/lib/auth/tokens.d.ts +76 -0
  25. package/lib/auth/tokens.js +103 -0
  26. package/lib/client/SubscriptionsSection.d.ts +34 -0
  27. package/lib/client/SubscriptionsSection.js +742 -0
  28. package/lib/client/index.d.ts +36 -0
  29. package/lib/client/index.js +47 -0
  30. package/lib/client/locales.d.ts +187 -0
  31. package/lib/client/locales.js +185 -0
  32. package/lib/client/styles.d.ts +18 -0
  33. package/lib/client/styles.js +257 -0
  34. package/lib/client/subscriptions-rpc.d.ts +24 -0
  35. package/lib/client/subscriptions-rpc.js +44 -0
  36. package/lib/client.js +2078 -0
  37. package/lib/client.js.map +1 -0
  38. package/lib/constants.d.ts +79 -0
  39. package/lib/constants.js +91 -0
  40. package/lib/errors.d.ts +28 -0
  41. package/lib/errors.js +34 -0
  42. package/lib/http.d.ts +24 -0
  43. package/lib/http.js +98 -0
  44. package/lib/index.d.ts +57 -0
  45. package/lib/index.js +185 -0
  46. package/lib/protocol.d.ts +316 -0
  47. package/lib/protocol.js +29 -0
  48. package/lib/providers/antigravity-catalog.d.ts +53 -0
  49. package/lib/providers/antigravity-catalog.js +269 -0
  50. package/lib/providers/antigravity.d.ts +331 -0
  51. package/lib/providers/antigravity.js +821 -0
  52. package/lib/providers/auto.d.ts +151 -0
  53. package/lib/providers/auto.js +351 -0
  54. package/lib/providers/catalog.d.ts +69 -0
  55. package/lib/providers/catalog.js +78 -0
  56. package/lib/providers/common.d.ts +51 -0
  57. package/lib/providers/common.js +169 -0
  58. package/lib/providers/glm-provider.d.ts +41 -0
  59. package/lib/providers/glm-provider.js +165 -0
  60. package/lib/providers/glm.d.ts +159 -0
  61. package/lib/providers/glm.js +445 -0
  62. package/lib/providers/grok.d.ts +224 -0
  63. package/lib/providers/grok.js +700 -0
  64. package/lib/providers/kimi-provider.d.ts +45 -0
  65. package/lib/providers/kimi-provider.js +148 -0
  66. package/lib/providers/kimi.d.ts +151 -0
  67. package/lib/providers/kimi.js +400 -0
  68. package/lib/providers/responses-stream.d.ts +58 -0
  69. package/lib/providers/responses-stream.js +115 -0
  70. package/lib/providers/usage.d.ts +65 -0
  71. package/lib/providers/usage.js +309 -0
  72. package/lib/settings.d.ts +122 -0
  73. package/lib/settings.js +333 -0
  74. package/lib/translate/antigravity-schema.d.ts +24 -0
  75. package/lib/translate/antigravity-schema.js +174 -0
  76. package/lib/translate/antigravity.d.ts +184 -0
  77. package/lib/translate/antigravity.js +419 -0
  78. package/lib/translate/responses.d.ts +156 -0
  79. package/lib/translate/responses.js +395 -0
  80. package/lib/translate/sse.d.ts +27 -0
  81. package/lib/translate/sse.js +82 -0
  82. package/package.json +126 -4
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Scoped stylesheet for the Subscriptions page and its manage dialog.
3
+ *
4
+ * The host loads plugin markup without its own control classes, and a bare
5
+ * `<button>` therefore renders with the browser's default raised chrome — which
6
+ * reads as a stray highlight in a dark theme. Rather than invent a look, this
7
+ * follows the control vocabulary of the sibling `dsh-plugin-subscriptions`
8
+ * plugin (same author-facing design as the shell's settings forms): a 6 px
9
+ * radius small control, a transparent fill, a hairline border from the theme's
10
+ * alias tokens, and the theme's hover/active/focus tokens for state.
11
+ *
12
+ * The tokens all carry fallbacks, so the page still renders correctly on a host
13
+ * build that does not define them.
14
+ *
15
+ * @module dsh-plugin-subscription-oauth/client/styles
16
+ */
17
+ /**
18
+ * Everything is scoped to this plugin's own roots, so no other surface in the
19
+ * shell can be affected by a rule here.
20
+ */
21
+ const scope = ':is(.dsh-subscriptions-settings, .dsh-subscription-manager)';
22
+ /** The page's and dialog's stylesheet. */
23
+ export const subscriptionsCss = `
24
+ .dsh-subscriptions-settings,
25
+ .dsh-subscription-manager {
26
+ font-family: inherit;
27
+ font-size: 13px;
28
+ line-height: 1.5;
29
+ /* Native controls (checkbox, dialog) follow the host theme, not the OS. */
30
+ color-scheme: light;
31
+ }
32
+ body[data-ds-dark-theme] ${scope} {
33
+ color-scheme: dark;
34
+ }
35
+ .dsh-subscription-manager {
36
+ box-sizing: border-box;
37
+ padding: 0;
38
+ border: 0;
39
+ border-radius: var(--dsw-radius-panel, 16px);
40
+ background: var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1));
41
+ color: var(--dsw-alias-label-primary);
42
+ box-shadow: var(--dsw-elevation-prominent, 0 20px 70px #0004);
43
+ }
44
+ .dsh-subscription-manager::backdrop {
45
+ background: var(--dsw-alias-bg-mask-1, #0006);
46
+ backdrop-filter: var(--dsw-mask-blur, none);
47
+ }
48
+ ${scope} h2 {
49
+ margin: 0;
50
+ font-size: 16px;
51
+ line-height: 24px;
52
+ font-weight: 500;
53
+ }
54
+ ${scope} strong,
55
+ ${scope} .dsh-subscription-label {
56
+ font-size: 13px;
57
+ line-height: 1.5;
58
+ font-weight: 500;
59
+ }
60
+ ${scope} small,
61
+ ${scope} .dsh-subscription-hint,
62
+ ${scope} [role="status"] {
63
+ margin: 0;
64
+ font-size: 12px;
65
+ line-height: 1.5;
66
+ color: var(--dsw-alias-label-tertiary);
67
+ }
68
+ ${scope} .dsh-subscription-error {
69
+ margin: 0;
70
+ font-size: 12px;
71
+ line-height: 1.5;
72
+ color: var(--dsw-alias-state-error-primary, #b42318);
73
+ }
74
+ ${scope} .dsh-subscription-success {
75
+ margin: 0;
76
+ font-size: 12px;
77
+ line-height: 1.5;
78
+ color: var(--dsw-alias-state-success-primary, #067647);
79
+ }
80
+ ${scope} label:has(> input[type="checkbox"]) {
81
+ cursor: pointer;
82
+ }
83
+ ${scope} input[type="checkbox"] {
84
+ accent-color: var(--dsw-alias-brand-primary);
85
+ }
86
+ /*
87
+ * A model's on/off control is a switch, not a checkbox: it takes effect
88
+ * immediately and its state is what matters, not a tick. Drawn from the theme
89
+ * tokens with appearance: none, so it follows the host palette in both themes
90
+ * instead of the platform's checkbox chrome.
91
+ */
92
+ ${scope} input[type="checkbox"].dsh-subscription-switch {
93
+ appearance: none;
94
+ -webkit-appearance: none;
95
+ position: relative;
96
+ box-sizing: border-box;
97
+ flex-shrink: 0;
98
+ width: 34px;
99
+ height: 20px;
100
+ margin: 0;
101
+ border: 0.5px solid var(--dsw-alias-border-l3, var(--dsw-alias-border-l2));
102
+ border-radius: 999px;
103
+ background: var(--dsw-alias-bg-layer-3, var(--dsw-alias-bg-layer-2));
104
+ cursor: pointer;
105
+ transition: background 120ms ease, border-color 120ms ease;
106
+ }
107
+ ${scope} input[type="checkbox"].dsh-subscription-switch::after {
108
+ content: '';
109
+ position: absolute;
110
+ top: 2px;
111
+ left: 2px;
112
+ width: 14px;
113
+ height: 14px;
114
+ border-radius: 50%;
115
+ background: var(--dsw-alias-label-primary-foreground, #fff);
116
+ box-shadow: 0 1px 2px #0003;
117
+ transition: transform 120ms ease;
118
+ }
119
+ ${scope} input[type="checkbox"].dsh-subscription-switch:checked {
120
+ border-color: transparent;
121
+ background: var(--dsw-alias-state-success-primary, var(--dsw-alias-brand-primary, #067647));
122
+ }
123
+ ${scope} input[type="checkbox"].dsh-subscription-switch:checked::after {
124
+ transform: translateX(14px);
125
+ }
126
+ ${scope} input[type="checkbox"].dsh-subscription-switch:disabled {
127
+ opacity: 0.4;
128
+ cursor: default;
129
+ }
130
+ ${scope} button {
131
+ box-sizing: border-box;
132
+ display: inline-flex;
133
+ align-items: center;
134
+ justify-content: center;
135
+ flex-shrink: 0;
136
+ min-height: 28px;
137
+ padding: 0 10px;
138
+ border: 0.5px solid var(--dsw-alias-border-l3, var(--dsw-alias-border-l2));
139
+ border-radius: var(--dsw-radius-sm, 6px);
140
+ background: transparent;
141
+ color: var(--dsw-alias-label-primary);
142
+ font: inherit;
143
+ font-size: 12px;
144
+ line-height: 18px;
145
+ cursor: pointer;
146
+ }
147
+ ${scope} button:hover:not(:disabled) {
148
+ background: var(--dsw-alias-interactive-bg-hover, var(--dsw-alias-bg-layer-3));
149
+ }
150
+ ${scope} button:active:not(:disabled) {
151
+ background: var(--dsw-alias-interactive-bg-active, var(--dsw-alias-bg-layer-3));
152
+ }
153
+ ${scope} button:disabled {
154
+ opacity: 0.4;
155
+ cursor: default;
156
+ }
157
+ /* A control that is present but should not read as a bordered button. */
158
+ ${scope} button.dsh-subscription-quiet {
159
+ min-height: 22px;
160
+ padding: 0 4px;
161
+ border-color: transparent;
162
+ color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-primary));
163
+ }
164
+ /* The free-text field for a hand-added model id. */
165
+ ${scope} input.dsh-subscription-input {
166
+ box-sizing: border-box;
167
+ flex: 1 1 auto;
168
+ min-width: 0;
169
+ min-height: 28px;
170
+ padding: 0 10px;
171
+ border: 0.5px solid var(--dsw-alias-border-l3, var(--dsw-alias-border-l2));
172
+ border-radius: var(--dsw-radius-sm, 6px);
173
+ background: var(--dsw-alias-bg-layer-1);
174
+ color: var(--dsw-alias-label-primary);
175
+ font: inherit;
176
+ font-size: 12px;
177
+ line-height: 18px;
178
+ }
179
+ ${scope} input.dsh-subscription-input::placeholder {
180
+ color: var(--dsw-alias-label-tertiary);
181
+ }
182
+ ${scope} input.dsh-subscription-input:focus-visible {
183
+ outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
184
+ outline-offset: 2px;
185
+ }
186
+ /* A drag handle: no border or fill, so it reads as a grip rather than a button. */
187
+ ${scope} button.dsh-subscription-handle {
188
+ min-height: 18px;
189
+ height: 18px;
190
+ padding: 0 2px;
191
+ border-color: transparent;
192
+ border-radius: var(--dsw-radius-sm, 6px);
193
+ background: transparent;
194
+ color: var(--dsw-alias-label-tertiary, var(--dsw-alias-label-secondary));
195
+ font-size: 12px;
196
+ line-height: 18px;
197
+ cursor: grab;
198
+ }
199
+ ${scope} button.dsh-subscription-handle:hover:not(:disabled) {
200
+ background: transparent;
201
+ color: var(--dsw-alias-label-primary);
202
+ }
203
+ ${scope} button.dsh-subscription-handle:active:not(:disabled) { cursor: grabbing; }
204
+ /* Controls inside the manage dialog are one step larger, like a form footer. */
205
+ ${scope} .dsh-subscription-dialog-actions button {
206
+ min-height: 34px;
207
+ padding: 0 14px;
208
+ border-radius: var(--dsw-radius-md, 8px);
209
+ font-size: 13px;
210
+ line-height: 1.5;
211
+ }
212
+ ${scope} button.dsh-subscription-primary {
213
+ border-color: transparent;
214
+ background: var(--dsw-alias-button-primary-fill, var(--dsw-alias-label-primary));
215
+ color: var(--dsw-alias-label-primary-foreground, var(--dsw-alias-bg-layer-1));
216
+ font-weight: 500;
217
+ }
218
+ ${scope} button.dsh-subscription-primary:hover:not(:disabled) {
219
+ background: var(--dsw-alias-button-primary-hover, var(--dsw-alias-label-secondary));
220
+ }
221
+ ${scope} button:focus-visible,
222
+ ${scope} input[type="checkbox"]:focus-visible,
223
+ ${scope} .dsh-subscription-disclosure:focus-visible {
224
+ outline: var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
225
+ outline-offset: 2px;
226
+ }
227
+ /* The catalog heading is a summary-style disclosure, not a bordered button. */
228
+ ${scope} .dsh-subscription-disclosure {
229
+ border-color: transparent;
230
+ border-radius: var(--dsw-radius-sm, 6px);
231
+ background: transparent;
232
+ padding: 0 4px;
233
+ font-size: 12px;
234
+ line-height: 18px;
235
+ font-weight: 500;
236
+ color: var(--dsw-alias-label-secondary, var(--dsw-alias-label-primary));
237
+ }
238
+ ${scope} .dsh-subscription-disclosure:hover:not(:disabled) {
239
+ background: transparent;
240
+ color: var(--dsw-alias-label-primary);
241
+ }
242
+ /* A usage meter: the track, with the fill sized by the caller. */
243
+ ${scope} .dsh-subscription-meter {
244
+ height: 6px;
245
+ border-radius: 999px;
246
+ background: var(--dsw-alias-bg-layer-3, var(--dsw-alias-bg-layer-2));
247
+ overflow: hidden;
248
+ }
249
+ ${scope} .dsh-subscription-meter > span {
250
+ display: block;
251
+ height: 100%;
252
+ background: var(--dsw-alias-state-success-primary, #067647);
253
+ }
254
+ ${scope} .dsh-subscription-meter > span[data-exhausted="true"] {
255
+ background: var(--dsw-alias-state-error-primary, #b42318);
256
+ }
257
+ `;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Browser caller for the plugin's own RPC channel.
3
+ *
4
+ * The node half mounts one exact `POST /api/subscription-oauth.<endpoint>` route
5
+ * per endpoint, so every call travels on the shared `/api` channel with a
6
+ * prefixed endpoint name — the same wire the rest of the shell uses.
7
+ *
8
+ * @module dsh-plugin-subscription-oauth/client/subscriptions-rpc
9
+ */
10
+ import type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client';
11
+ import type { RpcEndpoint, RpcMap } from '../protocol.js';
12
+ /** A failed call: either the transport rejected or the endpoint answered `ok: false`. */
13
+ export declare class SubscriptionsRpcError extends Error {
14
+ readonly code: string;
15
+ constructor(message: string, code: string);
16
+ }
17
+ /** Call one endpoint, unwrapping the transport result. */
18
+ export type SubscriptionsCall = <K extends RpcEndpoint>(endpoint: K, payload: RpcMap[K]['payload']) => Promise<RpcMap[K]['value']>;
19
+ /**
20
+ * Bind a caller to one connection's RPC transport.
21
+ * @param rpc - the browser connection's RPC caller.
22
+ * @returns a typed caller for this plugin's endpoints.
23
+ */
24
+ export declare function createSubscriptionsCall(rpc: ConnectionHandle['rpc']): SubscriptionsCall;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Browser caller for the plugin's own RPC channel.
3
+ *
4
+ * The node half mounts one exact `POST /api/subscription-oauth.<endpoint>` route
5
+ * per endpoint, so every call travels on the shared `/api` channel with a
6
+ * prefixed endpoint name — the same wire the rest of the shell uses.
7
+ *
8
+ * @module dsh-plugin-subscription-oauth/client/subscriptions-rpc
9
+ */
10
+ import { RPC_PREFIX } from '../protocol.js';
11
+ /** The shared channel the node half's routes are mounted on. */
12
+ const CHANNEL = '/api';
13
+ /** A failed call: either the transport rejected or the endpoint answered `ok: false`. */
14
+ export class SubscriptionsRpcError extends Error {
15
+ code;
16
+ constructor(message, code) {
17
+ super(message);
18
+ this.code = code;
19
+ this.name = 'SubscriptionsRpcError';
20
+ }
21
+ }
22
+ /** Human-readable message for any thrown value. */
23
+ function messageOf(error) {
24
+ return error instanceof Error ? error.message : String(error);
25
+ }
26
+ /**
27
+ * Bind a caller to one connection's RPC transport.
28
+ * @param rpc - the browser connection's RPC caller.
29
+ * @returns a typed caller for this plugin's endpoints.
30
+ */
31
+ export function createSubscriptionsCall(rpc) {
32
+ return async function call(endpoint, payload) {
33
+ let result;
34
+ try {
35
+ result = await rpc.call(CHANNEL, `${RPC_PREFIX}${endpoint}`, payload);
36
+ }
37
+ catch (error) {
38
+ throw new SubscriptionsRpcError(messageOf(error), 'RPC_TRANSPORT');
39
+ }
40
+ if (!result.ok)
41
+ throw new SubscriptionsRpcError(result.error.message, result.error.code);
42
+ return result.value;
43
+ };
44
+ }