@jingyi0605/codingns4dsh 0.2.1-rc.6 → 0.2.1-rc.7

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 (124) hide show
  1. package/README.en.md +3 -3
  2. package/README.md +3 -3
  3. package/data/build/dist/client/bundle.js +1412 -103
  4. package/data/build/dist/client/bundle.js.map +1 -1
  5. package/data/build/dist/client/client.native-workspace-store.js +1 -1
  6. package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
  7. package/data/build/dist/client/client.transport.js +202 -0
  8. package/data/build/dist/client/client.transport.js.map +1 -1
  9. package/data/build/dist/client/desktop-assistant.js +202 -0
  10. package/data/build/dist/client/features/index.d.ts +2 -1
  11. package/data/build/dist/client/features/index.d.ts.map +1 -1
  12. package/data/build/dist/client/features/index.js +3 -1
  13. package/data/build/dist/client/features/index.js.map +1 -1
  14. package/data/build/dist/client/features/magpie-management-page.d.ts +7 -3
  15. package/data/build/dist/client/features/magpie-management-page.d.ts.map +1 -1
  16. package/data/build/dist/client/features/magpie-management-page.js +142 -8
  17. package/data/build/dist/client/features/magpie-management-page.js.map +1 -1
  18. package/data/build/dist/client/features/workspace-mcp.d.ts +3 -0
  19. package/data/build/dist/client/features/workspace-mcp.d.ts.map +1 -0
  20. package/data/build/dist/client/features/workspace-mcp.js +320 -0
  21. package/data/build/dist/client/features/workspace-mcp.js.map +1 -0
  22. package/data/build/dist/client/locale.d.ts.map +1 -1
  23. package/data/build/dist/client/locale.js +176 -0
  24. package/data/build/dist/client/locale.js.map +1 -1
  25. package/data/build/dist/client/locales/magpie.d.ts.map +1 -1
  26. package/data/build/dist/client/locales/magpie.js +12 -0
  27. package/data/build/dist/client/locales/magpie.js.map +1 -1
  28. package/data/build/dist/client/locales/usage.d.ts.map +1 -1
  29. package/data/build/dist/client/locales/usage.js +14 -0
  30. package/data/build/dist/client/locales/usage.js.map +1 -1
  31. package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
  32. package/data/build/dist/client/subscription-slot.js +104 -11
  33. package/data/build/dist/client/subscription-slot.js.map +1 -1
  34. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.d.ts +18 -0
  35. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.d.ts.map +1 -0
  36. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.js +172 -0
  37. package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.js.map +1 -0
  38. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.d.ts +28 -0
  39. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.d.ts.map +1 -0
  40. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.js +103 -0
  41. package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.js.map +1 -0
  42. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.d.ts +26 -0
  43. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.d.ts.map +1 -0
  44. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.js +86 -0
  45. package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.js.map +1 -0
  46. package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
  47. package/data/build/dist/dsh-capabilities/matrix.js +3 -0
  48. package/data/build/dist/dsh-capabilities/matrix.js.map +1 -1
  49. package/data/build/dist/dsh-capabilities/routes.d.ts.map +1 -1
  50. package/data/build/dist/dsh-capabilities/routes.js +9 -0
  51. package/data/build/dist/dsh-capabilities/routes.js.map +1 -1
  52. package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
  53. package/data/build/dist/dsh-capabilities/types.d.ts.map +1 -1
  54. package/data/build/dist/dsh-capabilities/types.js.map +1 -1
  55. package/data/build/dist/host/cli-adapters/claude-model-options.d.ts.map +1 -1
  56. package/data/build/dist/host/cli-adapters/claude-model-options.js +13 -2
  57. package/data/build/dist/host/cli-adapters/claude-model-options.js.map +1 -1
  58. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
  59. package/data/build/dist/host/cli-adapters/dsh-message-projector.js +1 -0
  60. package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
  61. package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
  62. package/data/build/dist/host/cli-adapters/feature.js +5 -1
  63. package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
  64. package/data/build/dist/host/cli-adapters/magpie-usage.d.ts +13 -2
  65. package/data/build/dist/host/cli-adapters/magpie-usage.d.ts.map +1 -1
  66. package/data/build/dist/host/cli-adapters/magpie-usage.js +180 -13
  67. package/data/build/dist/host/cli-adapters/magpie-usage.js.map +1 -1
  68. package/data/build/dist/host/features/index.d.ts +1 -0
  69. package/data/build/dist/host/features/index.d.ts.map +1 -1
  70. package/data/build/dist/host/features/index.js +3 -0
  71. package/data/build/dist/host/features/index.js.map +1 -1
  72. package/data/build/dist/host/features/workspace-mcp.d.ts +9 -0
  73. package/data/build/dist/host/features/workspace-mcp.d.ts.map +1 -0
  74. package/data/build/dist/host/features/workspace-mcp.js +197 -0
  75. package/data/build/dist/host/features/workspace-mcp.js.map +1 -0
  76. package/data/build/dist/host/index.d.ts.map +1 -1
  77. package/data/build/dist/host/index.js +6 -2
  78. package/data/build/dist/host/index.js.map +1 -1
  79. package/data/build/dist/host/native-session-bridge.d.ts +2 -0
  80. package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
  81. package/data/build/dist/host/native-session-bridge.js +30 -0
  82. package/data/build/dist/host/native-session-bridge.js.map +1 -1
  83. package/data/build/dist/host/rpc.d.ts +4 -1
  84. package/data/build/dist/host/rpc.d.ts.map +1 -1
  85. package/data/build/dist/host/rpc.js +57 -9
  86. package/data/build/dist/host/rpc.js.map +1 -1
  87. package/data/build/dist/host/session-handle-eviction.d.ts +4 -2
  88. package/data/build/dist/host/session-handle-eviction.d.ts.map +1 -1
  89. package/data/build/dist/host/session-handle-eviction.js +10 -9
  90. package/data/build/dist/host/session-handle-eviction.js.map +1 -1
  91. package/data/build/dist/host/terminal/terminal-process-service.d.ts +22 -0
  92. package/data/build/dist/host/terminal/terminal-process-service.d.ts.map +1 -1
  93. package/data/build/dist/host/terminal/terminal-process-service.js +102 -0
  94. package/data/build/dist/host/terminal/terminal-process-service.js.map +1 -1
  95. package/data/build/dist/host/terminal/terminal-service.d.ts +5 -1
  96. package/data/build/dist/host/terminal/terminal-service.d.ts.map +1 -1
  97. package/data/build/dist/host/terminal/terminal-service.js +32 -0
  98. package/data/build/dist/host/terminal/terminal-service.js.map +1 -1
  99. package/data/build/dist/host/workspace-mcp/api-key-store.d.ts +16 -0
  100. package/data/build/dist/host/workspace-mcp/api-key-store.d.ts.map +1 -0
  101. package/data/build/dist/host/workspace-mcp/api-key-store.js +65 -0
  102. package/data/build/dist/host/workspace-mcp/api-key-store.js.map +1 -0
  103. package/data/build/dist/host/workspace-mcp/tools.d.ts +54 -0
  104. package/data/build/dist/host/workspace-mcp/tools.d.ts.map +1 -0
  105. package/data/build/dist/host/workspace-mcp/tools.js +800 -0
  106. package/data/build/dist/host/workspace-mcp/tools.js.map +1 -0
  107. package/data/build/dist/host/workspace-mcp/transport.d.ts +35 -0
  108. package/data/build/dist/host/workspace-mcp/transport.d.ts.map +1 -0
  109. package/data/build/dist/host/workspace-mcp/transport.js +575 -0
  110. package/data/build/dist/host/workspace-mcp/transport.js.map +1 -0
  111. package/data/build/dist/shared/contracts/magpie-management.d.ts +15 -1
  112. package/data/build/dist/shared/contracts/magpie-management.d.ts.map +1 -1
  113. package/data/build/dist/shared/contracts/subscription.d.ts +7 -0
  114. package/data/build/dist/shared/contracts/subscription.d.ts.map +1 -1
  115. package/data/build/dist/shared/contracts/subscription.js.map +1 -1
  116. package/data/build/dist/shared/contracts/terminal.d.ts +2 -0
  117. package/data/build/dist/shared/contracts/terminal.d.ts.map +1 -1
  118. package/data/build/dist/shared/contracts/version.d.ts +1 -1
  119. package/data/build/dist/shared/contracts/version.js +1 -1
  120. package/package.json +1 -1
  121. package/profile/README.md +2 -2
  122. package/profile/package.json +2 -2
  123. package/profile/version.json +1 -1
  124. package/version.json +1 -1
@@ -183,6 +183,31 @@ export class MagpieUsageService {
183
183
  }
184
184
  return changed ? { ...resolvedCatalog, groups } : resolvedCatalog;
185
185
  }
186
+ async updateAccountPolicy(input, signal) {
187
+ const update = readMagpieAccountPolicyUpdate(input);
188
+ const path = update.policy === 'credits' ? '/api/settings/codex-credits' : '/api/settings/codex-auto-reset';
189
+ const body = update.policy === 'credits'
190
+ ? { user: update.user, on: update.enabled }
191
+ : { user: update.user, on: update.enabled, when: update.policy };
192
+ const result = await this.requestWebJson(path, { method: 'POST', body }, signal);
193
+ if (!result.ok)
194
+ throw new Error('Magpie account policy update failed');
195
+ const settings = parseMagpieAccountPolicies(result.value);
196
+ if (settings === null || !magpieAccountPolicyMatches(settings, update)) {
197
+ throw new Error('Magpie account policy update could not be verified');
198
+ }
199
+ return update;
200
+ }
201
+ async resetCodexAccount(input, signal) {
202
+ const user = readMagpieAccountUser(input);
203
+ const result = await this.requestWebJson('/api/usage/codex-reset', {
204
+ method: 'POST',
205
+ body: { user },
206
+ }, signal);
207
+ if (!result.ok)
208
+ throw new Error('Magpie Codex reset failed');
209
+ return { outcome: normalizeMagpieResetOutcome(result.value) };
210
+ }
186
211
  /** Return an exact, CLI-confirmed Magpie model record for trusted Host use. */
187
212
  async readModelMetadata(adapterId, modelId, signal) {
188
213
  signal?.throwIfAborted();
@@ -209,16 +234,16 @@ export class MagpieUsageService {
209
234
  return parseMagpieContextResponse(response.value, options);
210
235
  }
211
236
  /** Read bounded, graph-ready usage and quota data through authenticated Magpie Web. */
212
- async readDashboard(period, signal) {
237
+ async readDashboard(period, signal, force = false) {
213
238
  signal?.throwIfAborted();
214
239
  const cached = this.dashboardCache.get(period);
215
- if (cached !== undefined) {
240
+ if (!force && cached !== undefined) {
216
241
  if (this.now() - cached.loadedAt >= MAGPIE_DASHBOARD_CACHE_TTL_MS) {
217
242
  void this.refreshDashboard(period).catch(() => undefined);
218
243
  }
219
244
  return cached.dashboard;
220
245
  }
221
- return this.refreshDashboard(period, signal);
246
+ return this.refreshDashboard(period, signal, force);
222
247
  }
223
248
  /** Stream cumulative dashboard snapshots as each independent Web API part is ready. */
224
249
  async *readDashboardStream(period, signal, force = false) {
@@ -238,22 +263,25 @@ export class MagpieUsageService {
238
263
  if (latest !== undefined)
239
264
  this.dashboardCache.set(period, { dashboard: latest, loadedAt: this.now() });
240
265
  }
241
- async refreshDashboard(period, signal) {
266
+ async refreshDashboard(period, signal, force = false) {
242
267
  const pending = this.dashboardRefreshes.get(period);
243
- if (pending !== undefined)
268
+ if (!force && pending !== undefined)
244
269
  return awaitWithSignal(pending, signal);
245
- const request = (async () => {
270
+ let request = null;
271
+ const task = (async () => {
246
272
  let latest;
247
273
  for await (const chunk of this.readDashboardNetwork(period, signal))
248
274
  latest = chunk.dashboard;
249
275
  if (latest === undefined)
250
276
  throw new Error('Magpie dashboard returned no snapshot');
251
- this.dashboardCache.set(period, { dashboard: latest, loadedAt: this.now() });
277
+ if (request !== null && this.dashboardRefreshes.get(period) === request)
278
+ this.dashboardCache.set(period, { dashboard: latest, loadedAt: this.now() });
252
279
  return latest;
253
280
  })().finally(() => {
254
- if (this.dashboardRefreshes.get(period) === request)
281
+ if (request !== null && this.dashboardRefreshes.get(period) === request)
255
282
  this.dashboardRefreshes.delete(period);
256
283
  });
284
+ request = task;
257
285
  this.dashboardRefreshes.set(period, request);
258
286
  return awaitWithSignal(request, signal);
259
287
  }
@@ -262,19 +290,23 @@ export class MagpieUsageService {
262
290
  let dashboard = emptyMagpieDashboard(period, capturedAt);
263
291
  let quotas = null;
264
292
  let logoLoad;
293
+ let settingsRead = false;
265
294
  const results = new Map([
266
295
  ['usage', this.timedDashboardRead('usage', () => this.readWebJson(`/api/usage?period=${magpieWebPeriod(period)}`, signal))],
267
296
  ['quotas', this.timedDashboardRead('quotas', () => this.readWebJson('/api/usage/quotas', signal))],
297
+ ['settings', this.timedDashboardRead('settings', () => this.readWebJson('/api/settings', signal))],
268
298
  ['history', this.timedDashboardRead('history', () => this.readWebJson('/api/usage/quotas/history?days=30', signal))],
269
299
  ]);
270
300
  const completed = new Map();
301
+ let policies = null;
271
302
  while (results.size > 0) {
272
303
  const result = await Promise.race(results.values());
273
304
  results.delete(result.part);
274
305
  const response = asRecord(result.value);
275
306
  const partOk = result.ok && response?.ok === true;
276
307
  const partValue = partOk ? response.value : undefined;
277
- completed.set(result.part, partOk);
308
+ if (result.part !== 'settings')
309
+ completed.set(result.part, partOk);
278
310
  if (result.part === 'usage') {
279
311
  const parsed = partOk ? parseMagpieDashboardUsage(partValue) : null;
280
312
  dashboard = {
@@ -291,10 +323,21 @@ export class MagpieUsageService {
291
323
  };
292
324
  }
293
325
  else if (result.part === 'quotas') {
294
- quotas = partOk ? parseMagpieQuotaCards(partValue) : null;
326
+ const parsedQuotas = partOk ? parseMagpieQuotaCards(partValue) : null;
327
+ quotas = parsedQuotas === null ? null : applyMagpieDashboardAccountPolicies(parsedQuotas, policies);
295
328
  dashboard = { ...dashboard, quotaStatus: quotas === null ? 'unavailable' : 'available', quotas: quotas ?? [] };
329
+ if (quotas !== null && settingsRead)
330
+ logoLoad = this.timedDashboardRead('quota-logos', () => this.attachQuotaLogos(quotas, signal)).then((logoResult) => logoResult.value);
331
+ }
332
+ else if (result.part === 'settings') {
333
+ settingsRead = true;
334
+ policies = partOk ? parseMagpieAccountPolicies(partValue) : null;
335
+ if (quotas !== null && policies !== null) {
336
+ quotas = applyMagpieDashboardAccountPolicies(quotas, policies);
337
+ dashboard = { ...dashboard, quotas };
338
+ }
296
339
  if (quotas !== null)
297
- logoLoad = this.timedDashboardRead('quota-logos', () => this.attachQuotaLogos(quotas, signal)).then((result) => result.value);
340
+ logoLoad = this.timedDashboardRead('quota-logos', () => this.attachQuotaLogos(quotas, signal)).then((logoResult) => logoResult.value);
298
341
  }
299
342
  else {
300
343
  const parsed = partOk ? parseMagpieQuotaHistory(partValue) : null;
@@ -474,10 +517,11 @@ export class MagpieUsageService {
474
517
  }
475
518
  async readFromWeb(agent, modelId, sessionId, magpieSessionId, fallbackSessionId, signal, includeRoute, allowPendingSession) {
476
519
  const capturedAt = new Date(this.now()).toISOString();
477
- const [usageResult, sessionResult, quotaResult] = await Promise.all([
520
+ const [usageResult, sessionResult, quotaResult, settingsResult] = await Promise.all([
478
521
  this.readWebJson('/api/usage?period=today', signal),
479
522
  this.readWebJson('/api/usage?period=all', signal),
480
523
  this.readWebJson('/api/usage/quotas', signal),
524
+ agent === 'codex' ? this.readWebJson('/api/settings', signal) : Promise.resolve({ ok: false }),
481
525
  ]);
482
526
  const aggregate = usageResult.ok ? readTotals(usageResult.value) : null;
483
527
  const primarySession = sessionResult.ok && magpieSessionId !== null
@@ -519,7 +563,9 @@ export class MagpieUsageService {
519
563
  : !canReadRoute || !routeHistoryValid
520
564
  ? 'unavailable'
521
565
  : 'no-route';
522
- const allQuotas = quotaResult.ok ? parseMagpieQuotas(quotaResult.value) : null;
566
+ const allQuotas = quotaResult.ok
567
+ ? applyMagpieAccountPolicies(parseMagpieQuotas(quotaResult.value), settingsResult.ok ? settingsResult.value : null)
568
+ : null;
523
569
  const routeProviders = [...new Set([
524
570
  providerFromRoute(route),
525
571
  ...routeHistory.map((record) => record.provider),
@@ -730,6 +776,20 @@ export class MagpieUsageService {
730
776
  return { ok: false };
731
777
  }
732
778
  }
779
+ async requestWebJson(path, options, signal) {
780
+ if (this.webApi === undefined)
781
+ return { ok: false };
782
+ try {
783
+ return {
784
+ ok: true,
785
+ value: await this.webApi.requestJson(path, signal === undefined ? options : { ...options, signal }),
786
+ };
787
+ }
788
+ catch {
789
+ signal?.throwIfAborted();
790
+ return { ok: false };
791
+ }
792
+ }
733
793
  /** Provider management data is the canonical source when a usage row mislabels its upstream. */
734
794
  async readProviderCatalog(signal) {
735
795
  const cached = this.providerCatalog;
@@ -1395,6 +1455,113 @@ export function parseMagpieQuotas(value) {
1395
1455
  }
1396
1456
  return quotas;
1397
1457
  }
1458
+ function parseMagpieAccountPolicies(value) {
1459
+ const root = asRecord(value);
1460
+ if (root === null)
1461
+ return null;
1462
+ const autoResetUsers = readLowercaseSet(root.codexAutoReset, 500);
1463
+ const noCreditsUsers = readLowercaseSet(root.codexNoCredits, 500);
1464
+ const autoResetOnly = new Map();
1465
+ const only = asRecord(root.codexAutoResetOnly);
1466
+ if (only !== null) {
1467
+ for (const [user, value] of Object.entries(only).slice(0, 500)) {
1468
+ if (value === 'week' || value === 'expiring')
1469
+ autoResetOnly.set(user.toLocaleLowerCase(), value);
1470
+ }
1471
+ }
1472
+ if (autoResetUsers === null || noCreditsUsers === null)
1473
+ return null;
1474
+ return { autoResetUsers, autoResetOnly, noCreditsUsers };
1475
+ }
1476
+ function applyMagpieAccountPolicies(quotas, settingsValue) {
1477
+ if (quotas === null)
1478
+ return null;
1479
+ const settings = parseMagpieAccountPolicies(settingsValue);
1480
+ if (settings === null)
1481
+ return quotas;
1482
+ return quotas.map((quota) => {
1483
+ if (quota.provider.toLocaleLowerCase() !== 'codex' || quota.user === null)
1484
+ return quota;
1485
+ const user = quota.user.toLocaleLowerCase();
1486
+ const enabled = settings.autoResetUsers.has(user);
1487
+ const only = settings.autoResetOnly.get(user);
1488
+ return {
1489
+ ...quota,
1490
+ autoReset: {
1491
+ week: enabled && only !== 'expiring',
1492
+ expiring: enabled && only !== 'week',
1493
+ },
1494
+ useCredits: !settings.noCreditsUsers.has(user),
1495
+ };
1496
+ });
1497
+ }
1498
+ function applyMagpieDashboardAccountPolicies(quotas, settings) {
1499
+ return quotas.map((quota) => {
1500
+ if (quota.provider.toLocaleLowerCase() !== 'codex' || quota.user === null)
1501
+ return quota;
1502
+ if (settings === null)
1503
+ return { ...quota, policyStatus: 'unavailable' };
1504
+ const user = quota.user.toLocaleLowerCase();
1505
+ const enabled = settings.autoResetUsers.has(user);
1506
+ const only = settings.autoResetOnly.get(user);
1507
+ return {
1508
+ ...quota,
1509
+ autoReset: {
1510
+ week: enabled && only !== 'expiring',
1511
+ expiring: enabled && only !== 'week',
1512
+ },
1513
+ useCredits: !settings.noCreditsUsers.has(user),
1514
+ policyStatus: 'available',
1515
+ };
1516
+ });
1517
+ }
1518
+ function readLowercaseSet(value, maxItems) {
1519
+ if (value === undefined)
1520
+ return new Set();
1521
+ if (!Array.isArray(value) || value.length > maxItems)
1522
+ return null;
1523
+ const values = value.filter((item) => typeof item === 'string' && item.trim() !== '');
1524
+ return values.length === value.length
1525
+ ? new Set(values.map((item) => item.trim().toLocaleLowerCase()))
1526
+ : null;
1527
+ }
1528
+ function readMagpieAccountUser(value) {
1529
+ const record = asRecord(value);
1530
+ const user = typeof record?.user === 'string' ? record.user.trim() : '';
1531
+ if (user === '' || user.length > 180)
1532
+ throw new TypeError('Magpie account user is invalid');
1533
+ return user;
1534
+ }
1535
+ function readMagpieAccountPolicyUpdate(value) {
1536
+ const record = asRecord(value);
1537
+ const user = readMagpieAccountUser(value);
1538
+ const policy = record?.policy;
1539
+ if (policy !== 'week' && policy !== 'expiring' && policy !== 'credits') {
1540
+ throw new TypeError('Magpie account policy is invalid');
1541
+ }
1542
+ if (typeof record?.enabled !== 'boolean')
1543
+ throw new TypeError('Magpie account policy state is invalid');
1544
+ return { user, policy, enabled: record.enabled };
1545
+ }
1546
+ function magpieAccountPolicyMatches(settings, update) {
1547
+ const user = update.user.toLocaleLowerCase();
1548
+ if (update.policy === 'credits')
1549
+ return settings.noCreditsUsers.has(user) !== update.enabled;
1550
+ const enabled = settings.autoResetUsers.has(user);
1551
+ const only = settings.autoResetOnly.get(user);
1552
+ const current = update.policy === 'week'
1553
+ ? enabled && only !== 'expiring'
1554
+ : enabled && only !== 'week';
1555
+ return current === update.enabled;
1556
+ }
1557
+ function normalizeMagpieResetOutcome(value) {
1558
+ const record = asRecord(value);
1559
+ const outcome = record?.code ?? record?.outcome;
1560
+ if (outcome === 'reset' || outcome === 'alreadyRedeemed' || outcome === 'nothingToReset' || outcome === 'noCredit') {
1561
+ return outcome;
1562
+ }
1563
+ throw new Error('Magpie returned an unknown reset result');
1564
+ }
1398
1565
  /** Normalize the live aggregate and per-dimension usage response. */
1399
1566
  export function parseMagpieDashboardUsage(value) {
1400
1567
  const root = asRecord(value);