dsh-xdpool 2.2.0 → 2.3.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.
package/lib/index.d.ts CHANGED
@@ -273,6 +273,29 @@ interface WorkBuddyCheckinClaim {
273
273
  streakDays: number;
274
274
  isStreakDay: boolean;
275
275
  }
276
+ /**
277
+ * Service-outage compensation offer (the "500 credits" banner on
278
+ * /profile/plans-usage).
279
+ *
280
+ * Upstream shape, verified live on 2026-10-16:
281
+ * `{active: true, claimed: false, credit_num: 500, validity_period: 1,
282
+ * end_time: "2026-10-22 23:59:59"}`
283
+ */
284
+ interface WorkBuddyCompensationStatus {
285
+ /** An offer is running for this account (independent of claimability). */
286
+ active: boolean;
287
+ /** This account already collected the current offer. */
288
+ claimed: boolean;
289
+ /** Credits on offer — 500 for the DeepSeek-outage compensation. */
290
+ creditNum: number;
291
+ /** Claim deadline, upstream's own string, absent when there is no offer. */
292
+ endTime?: string;
293
+ }
294
+ /** Compensation claim result. Upstream returns the same envelope shape. */
295
+ interface WorkBuddyCompensationClaim {
296
+ claimed: boolean;
297
+ creditNum: number;
298
+ }
276
299
  /** Result of one upstream chat attempt. */
277
300
  type ChatStreamResult = {
278
301
  ok: true;
@@ -503,6 +526,22 @@ export declare class WorkBuddyUpstreamClient {
503
526
  fetchCheckinStatus(credential: WorkBuddyCredential): Promise<WorkBuddyCheckinStatus>;
504
527
  /** Claim today's check-in reward. The browser route guards this mutation. */
505
528
  claimDailyCheckin(credential: WorkBuddyCredential): Promise<WorkBuddyCheckinClaim>;
529
+ /**
530
+ * Read the service-outage compensation offer, if any.
531
+ *
532
+ * NOTE the missing `/v2`: unlike the check-in routes, this one lives at
533
+ * `/billing/meter/compensation-status` and the `/v2` variant answers a plain
534
+ * 404 (verified on both billing hosts). The web client calls it that way too.
535
+ */
536
+ fetchCompensationStatus(credential: WorkBuddyCredential): Promise<WorkBuddyCompensationStatus>;
537
+ /**
538
+ * Collect the running compensation offer.
539
+ *
540
+ * Idempotent upstream: a repeat claim answers `code: 0` with
541
+ * `claimed: true` rather than an error, so a second pass in the same day
542
+ * records as a no-op instead of a failure.
543
+ */
544
+ claimCompensation(credential: WorkBuddyCredential): Promise<WorkBuddyCompensationClaim>;
506
545
  /**
507
546
  * Public fingerprint fields every desktop event carries.
508
547
  *
@@ -1028,6 +1067,15 @@ export declare class WorkBuddyAccountPool {
1028
1067
  private readonly persistent;
1029
1068
  /** Path of the durable store; computed once so tests can pin it. */
1030
1069
  private readonly storePath;
1070
+ /**
1071
+ * Optional second source of credentials: the channel pack's account pool,
1072
+ * which holds the accounts the user signed in through the scan-login page.
1073
+ *
1074
+ * A function rather than a list because that pool is mounted asynchronously
1075
+ * and can be re-read on demand; `undefined` means "no such source", which is
1076
+ * the state every test and every pre-mount startup is in.
1077
+ */
1078
+ private externalSource?;
1031
1079
  constructor(options?: AccountPoolOptions);
1032
1080
  /**
1033
1081
  * Re-apply configuration that only affects discovery and cooldown policy,
@@ -1043,6 +1091,12 @@ export declare class WorkBuddyAccountPool {
1043
1091
  /** Per-account credit floor, keyed by account id. Absent keeps the current map. */
1044
1092
  creditReserves?: Readonly<Record<string, number>>;
1045
1093
  }): void;
1094
+ /**
1095
+ * Register (or clear, with `undefined`) the extra credential source that
1096
+ * `scan()` merges alongside the auth directories. Rescanning is the caller's
1097
+ * job: this only changes where the next scan looks.
1098
+ */
1099
+ applyExternalSource(source?: () => Promise<readonly WorkBuddyCredential[]>): void;
1046
1100
  /**
1047
1101
  * Replace the permanent ignore list.
1048
1102
  *
@@ -1454,6 +1508,17 @@ type PoolWebAggregatePatch = {
1454
1508
  enabled?: boolean;
1455
1509
  apiKey?: string;
1456
1510
  baseUrl?: string;
1511
+ /**
1512
+ * The chosen model set, replacing whatever this provider exposed before.
1513
+ *
1514
+ * This is a REPLACEMENT, not a delta, because the card sends the whole
1515
+ * selection in one go: the browser half holds no server-side roster to
1516
+ * patch against, and a delta would let two open tabs silently interleave
1517
+ * into a set neither of them chose. An empty array is not "zero models" —
1518
+ * `updateProviderSetting` drops the field, which returns the provider to
1519
+ * its discovered listing or the registry's own.
1520
+ */
1521
+ models?: readonly string[];
1457
1522
  } |
1458
1523
  /** Flip the lane's own master switch; `false` contributes no models at all. */
1459
1524
  {
@@ -1500,8 +1565,16 @@ interface PoolWebAggregateProvider {
1500
1565
  baseUrl?: string;
1501
1566
  /** True when the provider declares a model listing this lane can read. */
1502
1567
  hasListing: boolean;
1503
- /** Model ids currently exposed: the chosen set, or the registry's own. */
1568
+ /** Model ids currently exposed: the chosen set, or the whole roster. */
1504
1569
  models: readonly string[];
1570
+ /**
1571
+ * Every id this provider could offer, which is the roster after a fetch.
1572
+ *
1573
+ * Equal to `models` until the user narrows the choice. It exists so the card
1574
+ * can offer a checkbox per id — without it, choosing could only ever remove
1575
+ * rows and never put one back.
1576
+ */
1577
+ availableModels: readonly string[];
1505
1578
  /** True when the exposed set came from a live listing rather than the registry. */
1506
1579
  discovered: boolean;
1507
1580
  /** When the provider was first configured. */
@@ -1557,6 +1630,34 @@ interface PoolWebChannel {
1557
1630
  loginKind: 'browser';
1558
1631
  /** True when this plugin's own account pool already serves this channel. */
1559
1632
  ownedByPool: boolean;
1633
+ /**
1634
+ * True when the vendor's own login page offers a phone-code path.
1635
+ *
1636
+ * Not a capability this plugin provides — the pack drives the page, and all
1637
+ * this says is that the page behind the button holds a second door. Raccoon's
1638
+ * does (QR and SMS on one screen), and its QR is the one that goes stale while
1639
+ * the user reads the message.
1640
+ */
1641
+ smsHint?: boolean;
1642
+ /**
1643
+ * What the pack can report about this vendor's credits, when it can report
1644
+ * something at all.
1645
+ *
1646
+ * Absent is meaningful: it means `credits.balances` has no branch for this
1647
+ * provider, so no balance exists to show. Present-but-empty means balances
1648
+ * work but there is no daily check-in behind them.
1649
+ *
1650
+ * `unit` is the vendor's own currency and is never normalised across
1651
+ * vendors: Cline pays US dollars and ZCode pays token buckets, so a single
1652
+ * "credits" label would be wrong for a third of the roster.
1653
+ */
1654
+ credits?: {
1655
+ claim?: boolean;
1656
+ status?: boolean;
1657
+ unit?: 'tokens' | 'dollars';
1658
+ /** Percentages per quota bucket rather than a credit total. */
1659
+ quota?: boolean;
1660
+ };
1560
1661
  }
1561
1662
  /** The document {@link POOL_CHANNELS_PATH} answers with. */
1562
1663
  interface PoolWebChannelsStatus {
@@ -1984,12 +2085,14 @@ interface PoolWebAutomation {
1984
2085
  taskHours: readonly number[];
1985
2086
  streakHours: readonly number[];
1986
2087
  travelHours: readonly number[];
2088
+ compensationHours: readonly number[];
1987
2089
  jobs: {
1988
2090
  checkin: PoolWebAutomationJob;
1989
2091
  report: PoolWebAutomationJob;
1990
2092
  tasks: PoolWebAutomationJob;
1991
2093
  streak: PoolWebAutomationJob;
1992
2094
  travel: PoolWebAutomationJob;
2095
+ compensation: PoolWebAutomationJob;
1993
2096
  };
1994
2097
  /** Claimable tasks seen on the most recent task pass, across accounts. */
1995
2098
  claimableSeen: number;
@@ -2019,6 +2122,8 @@ interface PoolWebAutomationEarnings {
2019
2122
  bonusCredit: number;
2020
2123
  /** Credits from buddy adoption and the travel loop today. */
2021
2124
  travelCredit: number;
2125
+ /** Credits collected from the outage-compensation offer today. */
2126
+ compensationCredit: number;
2022
2127
  /** Local date the counters belong to (YYYY-MM-DD). */
2023
2128
  date: string;
2024
2129
  }
@@ -2051,6 +2156,7 @@ export declare const DEFAULT_AUTOMATION_HOURS: {
2051
2156
  readonly tasks: readonly [11];
2052
2157
  readonly streak: readonly [12];
2053
2158
  readonly travel: readonly [9, 21];
2159
+ readonly compensation: readonly [13];
2054
2160
  };
2055
2161
  //#endregion
2056
2162
  //#region src/catalog.d.ts
@@ -2197,9 +2303,26 @@ interface ProviderSetting {
2197
2303
  apiKey?: string;
2198
2304
  /** User override for the base URL, for providers whose host is per-deployment. */
2199
2305
  baseUrl?: string;
2200
- /** Model ids the user chose to expose, when narrower than the registry's. */
2306
+ /**
2307
+ * Model ids the user chose to expose, when narrower than the whole roster.
2308
+ *
2309
+ * This is the CHOICE and nothing else. It deliberately does not hold what a
2310
+ * listing round returned: a vendor that advertises eighty-five models and whose
2311
+ * user ticks two must be able to press "Fetch models" again next month and
2312
+ * still be choosing from eighty-five, not from the two they kept. Keeping both
2313
+ * in one field made the fetch overwrite the choice and left no way back.
2314
+ *
2315
+ * An empty or absent value means "expose everything the provider offers" — see
2316
+ * `modelIdsFor`.
2317
+ */
2201
2318
  models?: readonly string[];
2202
- /** Model ids a listing round discovered, kept so a later save is not a guess. */
2319
+ /**
2320
+ * The full roster a listing round last returned, kept as the universe the
2321
+ * choice is drawn from.
2322
+ *
2323
+ * Never surfaced as the exposed set on its own; it exists so the card can show
2324
+ * "2 of 85 chosen" and re-widen a narrowed set after a refetch.
2325
+ */
2203
2326
  discovered?: readonly string[];
2204
2327
  addedAt?: string;
2205
2328
  }
@@ -2771,6 +2894,8 @@ interface AutomationOptions {
2771
2894
  streakHours?: readonly number[];
2772
2895
  /** Hour list for the buddy travel job. */
2773
2896
  travelHours?: readonly number[];
2897
+ /** Hour list for the outage-compensation claim. */
2898
+ compensationHours?: readonly number[];
2774
2899
  /** Per-account serial delay, in milliseconds. */
2775
2900
  accountDelayMs?: number;
2776
2901
  /** Override the gap between expert chains, in milliseconds (tests use 0). */
@@ -2896,6 +3021,14 @@ interface AutomationAccountEarnings {
2896
3021
  bonusCredit: number;
2897
3022
  /** Credits from the buddy adoption / travel loop today. */
2898
3023
  travelCredit: number;
3024
+ /**
3025
+ * Credits collected from the outage-compensation offer today.
3026
+ *
3027
+ * Its own column for the same reason as `checkinCredit`: a 500-credit
3028
+ * outage refund is a different thing from a 100-credit daily check-in, and
3029
+ * the card lists what earned what.
3030
+ */
3031
+ compensationCredit: number;
2899
3032
  /** Local date the counters belong to. */
2900
3033
  date: string;
2901
3034
  }
@@ -2907,6 +3040,7 @@ interface AutomationAccountGain {
2907
3040
  checkinCredit: number;
2908
3041
  bonusCredit: number;
2909
3042
  travelCredit: number;
3043
+ compensationCredit: number;
2910
3044
  }
2911
3045
  /** Totals from running the whole ordered pass at once. */
2912
3046
  interface AutomationRunSummary {
@@ -2935,12 +3069,14 @@ interface AutomationStatus {
2935
3069
  reportHours: readonly number[];
2936
3070
  streakHours: readonly number[];
2937
3071
  travelHours: readonly number[];
3072
+ compensationHours: readonly number[];
2938
3073
  jobs: {
2939
3074
  checkin: AutomationJobState;
2940
3075
  report: AutomationJobState;
2941
3076
  tasks: AutomationJobState;
2942
3077
  streak: AutomationJobState;
2943
3078
  travel: AutomationJobState;
3079
+ compensation: AutomationJobState;
2944
3080
  };
2945
3081
  /** Claimable tasks seen on the most recent task pass, across accounts. */
2946
3082
  claimableSeen: number;
@@ -2960,8 +3096,8 @@ interface AutomationStatus {
2960
3096
  runInProgress: boolean;
2961
3097
  }
2962
3098
  /** The three plus one job kinds, in a stable order. */
2963
- type AutomationJobKind = 'checkin' | 'tasks' | 'report' | 'streak' | 'travel';
2964
- /** The four jobs in the order a tick runs them: report before tasks, always. */
3099
+ type AutomationJobKind = 'checkin' | 'tasks' | 'report' | 'streak' | 'travel' | 'compensation';
3100
+ /** The jobs in the order a tick runs them: report before tasks, always. */
2965
3101
  export declare const AUTOMATION_JOB_KINDS: readonly AutomationJobKind[];
2966
3102
  /** Reject anything that is not a job kind, so a route cannot name an unknown job. */
2967
3103
  export declare function isAutomationJobKind(value: unknown): value is AutomationJobKind;
@@ -3005,6 +3141,7 @@ export declare class WorkBuddyScheduler {
3005
3141
  private reportHours;
3006
3142
  private streakHours;
3007
3143
  private travelHours;
3144
+ private compensationHours;
3008
3145
  private timer;
3009
3146
  private running;
3010
3147
  /** Guards against a slow run overlapping the next tick. */
@@ -3262,6 +3399,18 @@ export declare class WorkBuddyScheduler {
3262
3399
  * bookkeeping.
3263
3400
  */
3264
3401
  private runTravel;
3402
+ /**
3403
+ * Collect the running service-outage compensation offer, if any.
3404
+ *
3405
+ * Read-then-claim, rather than claim-blind: a claim costs one mutation the
3406
+ * upstream may reject, and the status call is a free read that also tells us
3407
+ * the size on offer so the ledger records the real number instead of
3408
+ * assuming the usual 500.
3409
+ *
3410
+ * Returns the credits collected — 0 when there was nothing to collect, which
3411
+ * is the normal case for most of the year.
3412
+ */
3413
+ private runCompensation;
3265
3414
  }
3266
3415
  //#endregion
3267
3416
  //#region src/status.d.ts
@@ -3595,7 +3744,7 @@ interface PoolStatusRouteOptions {
3595
3744
  * Providers the host cannot answer for are omitted from the returned record;
3596
3745
  * see {@link PoolWebChannelModels} for why that distinction is load-bearing.
3597
3746
  */
3598
- channelModels?: (providers: readonly string[]) => Promise<Readonly<Record<string, readonly PoolWebChannelModel[]>>>;
3747
+ channelModels?: (providers: readonly string[], ids?: Readonly<Record<string, readonly string[]>>) => Promise<Readonly<Record<string, readonly PoolWebChannelModel[]>>>;
3599
3748
  /**
3600
3749
  * Fetch one provider's live model list, write it back as its discovered set,
3601
3750
  * and refresh the catalog.
@@ -3779,6 +3928,8 @@ export interface AutomationConfig {
3779
3928
  streakHours?: number[];
3780
3929
  /** Hours at which the buddy travel loop runs. */
3781
3930
  travelHours?: number[];
3931
+ /** Hours at which the outage-compensation claim runs. */
3932
+ compensationHours?: number[];
3782
3933
  /** How long an account rests after its credits run out, in milliseconds. */
3783
3934
  exhaustCooldownMs?: number;
3784
3935
  }