dsh-subscriptions 0.2.0 → 0.2.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 (99) hide show
  1. package/README.md +212 -180
  2. package/lib/auth/claude-code-creds.js +31 -9
  3. package/lib/auth/device-flow.js +16 -9
  4. package/lib/auth/oauth-flow.js +13 -10
  5. package/lib/auth/rpc.js +74 -23
  6. package/lib/auth/store.js +80 -31
  7. package/lib/client/CursorCard.d.ts +1 -1
  8. package/lib/client/CursorCard.js +50 -16
  9. package/lib/client/ExternalUsageCards.d.ts +1 -1
  10. package/lib/client/ExternalUsageCards.js +37 -16
  11. package/lib/client/ImageGallery.d.ts +2 -2
  12. package/lib/client/ImageGallery.js +92 -33
  13. package/lib/client/ImageGenerateToolview.js +50 -14
  14. package/lib/client/OllamaCard.d.ts +1 -1
  15. package/lib/client/OllamaCard.js +26 -8
  16. package/lib/client/OllamaSettingsManager.js +113 -30
  17. package/lib/client/ProviderAccountManager.d.ts +1 -1
  18. package/lib/client/ProviderAccountManager.js +164 -49
  19. package/lib/client/ProviderModelEditor.js +107 -26
  20. package/lib/client/SpeedSelect.d.ts +62 -14
  21. package/lib/client/SpeedSelect.js +257 -46
  22. package/lib/client/SubscriptionUsageBadge.d.ts +4 -10
  23. package/lib/client/SubscriptionUsageBadge.js +300 -112
  24. package/lib/client/SubscriptionsSection.js +258 -85
  25. package/lib/client/UsageBadgeDisplaySetting.js +35 -12
  26. package/lib/client/UsageMeter.d.ts +1 -1
  27. package/lib/client/UsageMeter.js +62 -24
  28. package/lib/client/VideoGenerateToolview.js +69 -17
  29. package/lib/client/account-preferences.d.ts +8 -0
  30. package/lib/client/account-preferences.js +20 -5
  31. package/lib/client/host-contract.d.ts +11 -2
  32. package/lib/client/host-contract.js +20 -3
  33. package/lib/client/index.d.ts +5 -5
  34. package/lib/client/index.js +34 -12
  35. package/lib/client/locales.d.ts +10 -0
  36. package/lib/client/locales.js +61 -51
  37. package/lib/client/ollama-draft.js +21 -12
  38. package/lib/client/reset-action.js +6 -4
  39. package/lib/client/reset-credits-view.d.ts +1 -1
  40. package/lib/client/reset-credits-view.js +66 -17
  41. package/lib/client/subscription-card-styles.js +94 -24
  42. package/lib/client/usage-color-preferences.js +4 -2
  43. package/lib/client/usage-pace.js +30 -12
  44. package/lib/client.js +287 -47
  45. package/lib/client.js.map +1 -1
  46. package/lib/http.js +1 -1
  47. package/lib/index.d.ts +3 -3
  48. package/lib/index.js +118 -64
  49. package/lib/model-defaults.js +4 -2
  50. package/lib/provider-settings.d.ts +12 -0
  51. package/lib/provider-settings.js +58 -16
  52. package/lib/providers/account-preferences.js +51 -22
  53. package/lib/providers/accounts.js +15 -9
  54. package/lib/providers/antigravity-oauth-client.js +2 -2
  55. package/lib/providers/antigravity.js +141 -68
  56. package/lib/providers/catalog-store.js +120 -41
  57. package/lib/providers/claude-cli-version.js +3 -3
  58. package/lib/providers/claude.d.ts +9 -2
  59. package/lib/providers/claude.js +153 -90
  60. package/lib/providers/codex-client-version.js +3 -3
  61. package/lib/providers/codex-search.js +40 -13
  62. package/lib/providers/codex.js +196 -112
  63. package/lib/providers/common.js +71 -39
  64. package/lib/providers/copilot.js +143 -82
  65. package/lib/providers/cursor-adapter.js +42 -18
  66. package/lib/providers/cursor-auth.d.ts +1 -1
  67. package/lib/providers/cursor-auth.js +69 -24
  68. package/lib/providers/cursor-model-settings.js +14 -5
  69. package/lib/providers/cursor-usage.js +27 -13
  70. package/lib/providers/external-usage-controller.js +14 -5
  71. package/lib/providers/external-usage.js +59 -23
  72. package/lib/providers/grok.js +152 -89
  73. package/lib/providers/image-pool.js +29 -11
  74. package/lib/providers/minimax-usage.js +31 -11
  75. package/lib/providers/npm-cli-version.js +10 -3
  76. package/lib/providers/ollama-settings.js +24 -8
  77. package/lib/providers/ollama-web.js +29 -11
  78. package/lib/providers/ollama.js +129 -66
  79. package/lib/providers/pool-family.js +11 -3
  80. package/lib/providers/pool-health.js +28 -8
  81. package/lib/providers/pool-usage.js +16 -9
  82. package/lib/providers/pool.d.ts +8 -0
  83. package/lib/providers/pool.js +81 -42
  84. package/lib/providers/rate-limit.js +8 -2
  85. package/lib/providers/replay.js +40 -17
  86. package/lib/providers/reset-redemption.js +18 -6
  87. package/lib/tools/image-generate.js +123 -65
  88. package/lib/tools/registration.js +5 -2
  89. package/lib/tools/video-generate.js +51 -31
  90. package/lib/tools/x-search.js +50 -22
  91. package/lib/translate/anthropic.js +85 -37
  92. package/lib/translate/antigravity-schema.js +71 -28
  93. package/lib/translate/antigravity-thinking.js +22 -9
  94. package/lib/translate/antigravity.js +141 -50
  95. package/lib/translate/chat-completions.js +67 -23
  96. package/lib/translate/resolved.js +55 -21
  97. package/lib/translate/responses.js +69 -29
  98. package/lib/translate/sse.js +4 -1
  99. package/package.json +26 -4
@@ -16,11 +16,16 @@ export function validatePreferences(provider, input) {
16
16
  const raw = input;
17
17
  const result = {};
18
18
  if (raw.accounts !== undefined) {
19
- if (!raw.accounts || typeof raw.accounts !== 'object' || Array.isArray(raw.accounts))
19
+ if (!raw.accounts ||
20
+ typeof raw.accounts !== 'object' ||
21
+ Array.isArray(raw.accounts))
20
22
  throw new Error('accounts must be an account-to-preferences map');
21
23
  result.accounts = Object.create(null);
22
24
  for (const [key, value] of Object.entries(raw.accounts)) {
23
- if (!key.trim() || !value || typeof value !== 'object' || Array.isArray(value))
25
+ if (!key.trim() ||
26
+ !value ||
27
+ typeof value !== 'object' ||
28
+ Array.isArray(value))
24
29
  throw new Error('invalid account preferences');
25
30
  const account = value;
26
31
  const parsed = {};
@@ -37,7 +42,8 @@ export function validatePreferences(provider, input) {
37
42
  }
38
43
  }
39
44
  if (account.poolModels !== undefined) {
40
- if (!Array.isArray(account.poolModels) || account.poolModels.some(id => typeof id !== 'string' || !id.trim()))
45
+ if (!Array.isArray(account.poolModels) ||
46
+ account.poolModels.some((id) => typeof id !== 'string' || !id.trim()))
41
47
  throw new Error('poolModels must be an array of model ids');
42
48
  parsed.poolModels = [...new Set(account.poolModels)];
43
49
  }
@@ -45,7 +51,8 @@ export function validatePreferences(provider, input) {
45
51
  }
46
52
  }
47
53
  if (raw.visibleModels !== undefined) {
48
- if (!Array.isArray(raw.visibleModels) || raw.visibleModels.some(id => typeof id !== 'string' || !id.trim())) {
54
+ if (!Array.isArray(raw.visibleModels) ||
55
+ raw.visibleModels.some((id) => typeof id !== 'string' || !id.trim())) {
49
56
  throw new Error('visibleModels must be an array of model ids');
50
57
  }
51
58
  result.visibleModels = [...new Set(raw.visibleModels)];
@@ -54,23 +61,37 @@ export function validatePreferences(provider, input) {
54
61
  if (provider !== 'codex' && provider !== 'claude') {
55
62
  throw new Error('context window overrides are supported only for Codex and Claude');
56
63
  }
57
- if (!raw.contextWindows || typeof raw.contextWindows !== 'object' || Array.isArray(raw.contextWindows)) {
64
+ if (!raw.contextWindows ||
65
+ typeof raw.contextWindows !== 'object' ||
66
+ Array.isArray(raw.contextWindows)) {
58
67
  throw new Error('contextWindows must be a model-to-token map');
59
68
  }
60
69
  result.contextWindows = Object.create(null);
61
70
  for (const [model, value] of Object.entries(raw.contextWindows)) {
62
- if (!model.trim() || typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0) {
71
+ if (!model.trim() ||
72
+ typeof value !== 'number' ||
73
+ !Number.isSafeInteger(value) ||
74
+ value <= 0) {
63
75
  throw new Error('context windows must be positive safe integers');
64
76
  }
65
77
  result.contextWindows[model] = value;
66
78
  }
67
79
  }
80
+ if (raw.promptCacheTtl !== undefined) {
81
+ if (provider !== 'claude')
82
+ throw new Error('the prompt-cache TTL override is supported only for Claude');
83
+ if (raw.promptCacheTtl !== '5m' && raw.promptCacheTtl !== '1h') {
84
+ throw new Error('promptCacheTtl must be "5m" or "1h"');
85
+ }
86
+ result.promptCacheTtl = raw.promptCacheTtl;
87
+ }
68
88
  if (raw.tools !== undefined) {
69
89
  if (!raw.tools || typeof raw.tools !== 'object' || Array.isArray(raw.tools))
70
90
  throw new Error('tools must be an object');
71
91
  result.tools = {};
72
92
  for (const [tool, enabled] of Object.entries(raw.tools)) {
73
- if (!PROVIDER_TOOLS[provider].includes(tool) || typeof enabled !== 'boolean') {
93
+ if (!PROVIDER_TOOLS[provider].includes(tool) ||
94
+ typeof enabled !== 'boolean') {
74
95
  throw new Error(`unsupported tool setting: ${provider}/${tool}`);
75
96
  }
76
97
  result.tools[tool] = enabled;
@@ -93,29 +114,44 @@ export class ProviderSettingsStore {
93
114
  if (Object.hasOwn(raw.providers, provider))
94
115
  this.current.providers[provider] = validatePreferences(provider, raw.providers[provider]);
95
116
  }
96
- this.current.toolHistory = raw.toolHistory.map(revision => {
97
- if (!PROVIDER_IDS.includes(revision.provider) || !Number.isSafeInteger(revision.at) || revision.at < 0)
117
+ this.current.toolHistory = raw.toolHistory
118
+ .map((revision) => {
119
+ if (!PROVIDER_IDS.includes(revision.provider) ||
120
+ !Number.isSafeInteger(revision.at) ||
121
+ revision.at < 0)
98
122
  throw new Error('invalid tool history');
99
- const tools = validatePreferences(revision.provider, { tools: revision.tools }).tools ?? {};
123
+ const tools = validatePreferences(revision.provider, { tools: revision.tools })
124
+ .tools ?? {};
100
125
  return { at: revision.at, provider: revision.provider, tools };
101
- }).sort((a, b) => a.at - b.at);
126
+ })
127
+ .sort((a, b) => a.at - b.at);
102
128
  }
103
129
  catch (error) {
104
130
  if (error.code !== 'ENOENT')
105
- throw new Error(`Cannot read provider settings at ${path}`, { cause: error });
131
+ throw new Error(`Cannot read provider settings at ${path}`, {
132
+ cause: error,
133
+ });
106
134
  }
107
135
  }
108
136
  get(provider) {
109
137
  return structuredClone(this.current.providers[provider] ?? {});
110
138
  }
111
139
  visible(provider, model) {
112
- return this.current.providers[provider]?.visibleModels?.includes(model) ?? true;
140
+ return (this.current.providers[provider]?.visibleModels?.includes(model) ?? true);
113
141
  }
114
142
  /** The user's local context-window override for one model; absent follows the provider. */
115
143
  contextWindow(model, provider = 'codex') {
116
144
  const windows = this.current.providers[provider]?.contextWindows;
117
145
  return windows && Object.hasOwn(windows, model) ? windows[model] : undefined;
118
146
  }
147
+ /**
148
+ * The Claude route's prompt-cache TTL override, read live so a saved change
149
+ * takes effect from the next request without a restart. Absent means follow
150
+ * the `claudePromptCacheTtl` config.
151
+ */
152
+ promptCacheTtl() {
153
+ return this.current.providers.claude?.promptCacheTtl;
154
+ }
119
155
  /** Creation-time policy survives restarts and never changes an existing session. */
120
156
  toolEnabled(provider, tool, createdAt = Date.now()) {
121
157
  let enabled = true;
@@ -133,13 +169,19 @@ export class ProviderSettingsStore {
133
169
  const next = structuredClone(this.current);
134
170
  const before = next.providers[provider]?.tools ?? {};
135
171
  next.providers[provider] = preferences;
136
- if (PROVIDER_TOOLS[provider].some(tool => (before[tool] !== false) !== (preferences.tools?.[tool] !== false))) {
137
- next.toolHistory.push({ at: Date.now(), provider, tools: preferences.tools ?? {} });
172
+ if (PROVIDER_TOOLS[provider].some((tool) => (before[tool] !== false) !== (preferences.tools?.[tool] !== false))) {
173
+ next.toolHistory.push({
174
+ at: Date.now(),
175
+ provider,
176
+ tools: preferences.tools ?? {},
177
+ });
138
178
  }
139
179
  await mkdir(dirname(this.path), { recursive: true });
140
180
  const temporary = `${this.path}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
141
181
  try {
142
- await writeFile(temporary, JSON.stringify(next, null, 2), { mode: 0o600 });
182
+ await writeFile(temporary, JSON.stringify(next, null, 2), {
183
+ mode: 0o600,
184
+ });
143
185
  await rename(temporary, this.path);
144
186
  }
145
187
  finally {
@@ -24,7 +24,8 @@ export function parseAccountModelId(id) {
24
24
  }
25
25
  }
26
26
  export function accountAllowsPool(preferences, model) {
27
- return preferences?.poolEnabled !== false && (preferences?.poolModels?.includes(model) ?? true);
27
+ return (preferences?.poolEnabled !== false &&
28
+ (preferences?.poolModels?.includes(model) ?? true));
28
29
  }
29
30
  /** Keeps the registered route separate from raw adapters and pool member seams. */
30
31
  export class AccountPreferencesAdapter extends LlmAdapter {
@@ -35,20 +36,24 @@ export class AccountPreferencesAdapter extends LlmAdapter {
35
36
  }
36
37
  preference(account) {
37
38
  const accounts = this.options.settings.get(this.options.provider).accounts;
38
- return accounts && Object.hasOwn(accounts, account) ? accounts[account] : undefined;
39
+ return accounts && Object.hasOwn(accounts, account)
40
+ ? accounts[account]
41
+ : undefined;
39
42
  }
40
43
  async models(account) {
41
- const models = await withTimeout(signal => this.options.adapter.listOwnModels(this.options.provider, account, signal), this.options.discoveryTimeoutMs ?? DISCOVERY_TIMEOUT_MS);
44
+ const models = await withTimeout((signal) => this.options.adapter.listOwnModels(this.options.provider, account, signal), this.options.discoveryTimeoutMs ?? DISCOVERY_TIMEOUT_MS);
42
45
  if (models !== undefined)
43
46
  return models;
44
47
  // Discovery timed out: the catalog this account listed last time beats
45
48
  // "no models", which would fail the turn with "No eligible account".
46
- return await this.options.adapter.lastKnownOwnModels?.(this.options.provider, account) ?? [];
49
+ return ((await this.options.adapter.lastKnownOwnModels?.(this.options.provider, account)) ?? []);
47
50
  }
48
51
  async requireAccount(account, model, independent) {
49
- if (!(await this.options.accounts()).some(entry => entry.key === account)
50
- || (independent ? this.preference(account)?.independentEntry !== true : !accountAllowsPool(this.preference(account), model))
51
- || !(await this.models(account)).some(entry => entry.id === model)) {
52
+ if (!(await this.options.accounts()).some((entry) => entry.key === account) ||
53
+ (independent
54
+ ? this.preference(account)?.independentEntry !== true
55
+ : !accountAllowsPool(this.preference(account), model)) ||
56
+ !(await this.models(account)).some((entry) => entry.id === model)) {
52
57
  throw new LlmError(`Account route unavailable: ${this.options.provider}/${account}/${model}`, 'NO_ADAPTER');
53
58
  }
54
59
  }
@@ -60,7 +65,9 @@ export class AccountPreferencesAdapter extends LlmAdapter {
60
65
  await this.requireAccount(key, model, false);
61
66
  return key;
62
67
  }
63
- catch { /* unavailable catalog */ }
68
+ catch {
69
+ /* unavailable catalog */
70
+ }
64
71
  }
65
72
  throw new LlmError(`No eligible account for ${this.options.provider}/${model}`, 'NO_ADAPTER');
66
73
  }
@@ -76,7 +83,8 @@ export class AccountPreferencesAdapter extends LlmAdapter {
76
83
  await this.requireAccount(key, model, false);
77
84
  return key;
78
85
  };
79
- return new Proxy(raw, { get: (target, property) => {
86
+ return new Proxy(raw, {
87
+ get: (target, property) => {
80
88
  if (property === 'streamAccount')
81
89
  return async function* (options, account) {
82
90
  let key;
@@ -94,34 +102,51 @@ export class AccountPreferencesAdapter extends LlmAdapter {
94
102
  return async (provider, model, account) => raw.resolveOwnModel(provider, model, await keyFor(account, model));
95
103
  const value = Reflect.get(target, property);
96
104
  return typeof value === 'function' ? value.bind(target) : value;
97
- } });
105
+ },
106
+ });
98
107
  }
99
108
  async listModels(provider) {
100
109
  const result = new Map();
101
- const catalogs = await Promise.all((await this.options.accounts()).map(async (account) => ({ ...account, models: await this.models(account.key).catch(() => []) })));
110
+ const catalogs = await Promise.all((await this.options.accounts()).map(async (account) => ({
111
+ ...account,
112
+ models: await this.models(account.key).catch(() => []),
113
+ })));
102
114
  for (const { key, label, models } of catalogs) {
103
115
  const preferences = this.preference(key);
104
116
  for (const model of models) {
105
117
  if (model.id.startsWith(ACCOUNT_MODEL_PREFIX))
106
118
  continue;
107
- if (accountAllowsPool(preferences, model.id) && this.options.settings.visible(this.options.provider, model.id) && !result.has(model.id))
119
+ if (accountAllowsPool(preferences, model.id) &&
120
+ this.options.settings.visible(this.options.provider, model.id) &&
121
+ !result.has(model.id))
108
122
  result.set(model.id, model);
109
- if (preferences?.independentEntry === true && this.options.settings.visible(this.options.provider, model.id)) {
123
+ if (preferences?.independentEntry === true &&
124
+ this.options.settings.visible(this.options.provider, model.id)) {
110
125
  const id = accountModelId(key, model.id);
111
- result.set(id, { ...model, id, name: `${preferences.alias || label} · ${model.name}` });
126
+ result.set(id, {
127
+ ...model,
128
+ id,
129
+ name: `${preferences.alias || label} · ${model.name}`,
130
+ });
112
131
  }
113
132
  }
114
133
  }
115
- for (const model of await this.options.pool()?.modelsForProvider(this.options.provider) ?? []) {
116
- if (model.id.startsWith(ACCOUNT_MODEL_PREFIX) || !this.options.settings.visible(this.options.provider, model.id))
134
+ for (const model of (await this.options
135
+ .pool()
136
+ ?.modelsForProvider(this.options.provider)) ?? []) {
137
+ if (model.id.startsWith(ACCOUNT_MODEL_PREFIX) ||
138
+ !this.options.settings.visible(this.options.provider, model.id))
117
139
  continue;
118
140
  try {
119
141
  await this.options.pool().resolveModel(provider, model.id);
120
142
  result.set(model.id, model);
121
143
  }
122
- catch { /* excluded tier */ }
144
+ catch {
145
+ /* excluded tier */
146
+ }
123
147
  }
124
- const priority = (model) => model.priority ?? Number.MAX_SAFE_INTEGER;
148
+ const priority = (model) => model.priority ??
149
+ Number.MAX_SAFE_INTEGER;
125
150
  return [...result.values()].sort((left, right) => priority(left) - priority(right));
126
151
  }
127
152
  async resolveModel(provider, id) {
@@ -129,11 +154,15 @@ export class AccountPreferencesAdapter extends LlmAdapter {
129
154
  if (independent) {
130
155
  await this.requireAccount(independent.account, independent.model, true);
131
156
  const info = await this.options.adapter.resolveOwnModel(provider, independent.model, independent.account);
132
- const label = (await this.options.accounts()).find(entry => entry.key === independent.account)?.label ?? independent.account;
133
- return { ...info, id, name: `${this.preference(independent.account)?.alias || label} · ${info.name}` };
157
+ const label = (await this.options.accounts()).find((entry) => entry.key === independent.account)?.label ?? independent.account;
158
+ return {
159
+ ...info,
160
+ id,
161
+ name: `${this.preference(independent.account)?.alias || label} · ${info.name}`,
162
+ };
134
163
  }
135
164
  const pool = this.options.pool();
136
- if (pool && await pool.owns(this.options.provider, id))
165
+ if (pool && (await pool.owns(this.options.provider, id)))
137
166
  return pool.resolveModel(provider, id);
138
167
  return this.options.adapter.resolveOwnModel(provider, id, await this.fallback(id));
139
168
  }
@@ -145,7 +174,7 @@ export class AccountPreferencesAdapter extends LlmAdapter {
145
174
  return;
146
175
  }
147
176
  const pool = this.options.pool();
148
- if (pool && await pool.owns(this.options.provider, options.model)) {
177
+ if (pool && (await pool.owns(this.options.provider, options.model))) {
149
178
  yield* pool.stream(options);
150
179
  return;
151
180
  }
@@ -15,7 +15,9 @@ export { DISCOVERY_TIMEOUT_MS } from './common.js';
15
15
  /** Catalog sort hint when the provider advertised one (Codex `priority`). */
16
16
  function catalogPriority(model) {
17
17
  const ranked = model;
18
- return typeof ranked.priority === 'number' ? ranked.priority : Number.MAX_SAFE_INTEGER;
18
+ return typeof ranked.priority === 'number'
19
+ ? ranked.priority
20
+ : Number.MAX_SAFE_INTEGER;
19
21
  }
20
22
  /**
21
23
  * Merge per-account catalogs, keeping the first occurrence of each model id.
@@ -31,7 +33,9 @@ export async function unionAccountCatalogs(accounts, listOne, options) {
31
33
  try {
32
34
  if (timeoutMs === undefined)
33
35
  return await listOne(account, caller);
34
- const models = await withTimeout(timeoutSignal => listOne(account, caller === undefined ? timeoutSignal : AbortSignal.any([timeoutSignal, caller])), timeoutMs);
36
+ const models = await withTimeout((timeoutSignal) => listOne(account, caller === undefined
37
+ ? timeoutSignal
38
+ : AbortSignal.any([timeoutSignal, caller])), timeoutMs);
35
39
  return models ?? [];
36
40
  }
37
41
  catch (error) {
@@ -63,10 +67,10 @@ export class AccountTokenManager {
63
67
  const provider = options.provider;
64
68
  this.io = options.io ?? {
65
69
  list: () => listAccounts(provider),
66
- get: account => getAccountSession(provider, account),
70
+ get: (account) => getAccountSession(provider, account),
67
71
  save: (account, session) => saveAccountSession(provider, account, session),
68
- remove: account => deleteAccountSession(provider, account),
69
- resolve: account => resolveAccountKey(provider, account),
72
+ remove: (account) => deleteAccountSession(provider, account),
73
+ resolve: (account) => resolveAccountKey(provider, account),
70
74
  };
71
75
  }
72
76
  /** The provider's accounts, default first (straight from the store). */
@@ -86,7 +90,7 @@ export class AccountTokenManager {
86
90
  * @throws LlmError MISSING_CREDENTIAL when the account is not logged in.
87
91
  */
88
92
  async session(account, forceRefresh = false) {
89
- const requested = account ?? await this.defaultAccount();
93
+ const requested = account ?? (await this.defaultAccount());
90
94
  if (requested === undefined)
91
95
  throw this.missingCredential();
92
96
  const key = await this.resolveAccount(requested);
@@ -128,7 +132,9 @@ export class AccountTokenManager {
128
132
  }
129
133
  },
130
134
  remove: () => io.remove(boundAccount),
131
- onRemoved: () => { this.options.onAccountRemoved?.(boundAccount); },
135
+ onRemoved: () => {
136
+ this.options.onAccountRemoved?.(boundAccount);
137
+ },
132
138
  });
133
139
  this.managers.set(account, manager);
134
140
  }
@@ -136,7 +142,7 @@ export class AccountTokenManager {
136
142
  }
137
143
  /** The logged-out error, mirroring TokenManager's own message. */
138
144
  missingCredential() {
139
- return new LlmError(`dsh-subscriptions: not logged in to ${this.options.displayName}; `
140
- + 'log in via Settings → Subscriptions in the dsh web app', 'MISSING_CREDENTIAL');
145
+ return new LlmError(`dsh-subscriptions: not logged in to ${this.options.displayName}; ` +
146
+ 'log in via Settings → Subscriptions in the dsh web app', 'MISSING_CREDENTIAL');
141
147
  }
142
148
  }
@@ -3,5 +3,5 @@
3
3
  * These application constants are distinct from user access/refresh tokens.
4
4
  * Source: https://github.com/Rahularya01/pi-antigravity/blob/697858cafcf1faddf2ae898d2f053b2ff26c05e6/src/auth/oauth.ts
5
5
  */
6
- export const ANTIGRAVITY_DEFAULT_CLIENT_ID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
7
- export const ANTIGRAVITY_DEFAULT_CLIENT_SECRET = "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";
6
+ export const ANTIGRAVITY_DEFAULT_CLIENT_ID = '1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com';
7
+ export const ANTIGRAVITY_DEFAULT_CLIENT_SECRET = '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';