@mars-sea/dsh-commandcode-provider 0.10.0-alpha.5 → 0.10.0-alpha.6

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.js CHANGED
@@ -235,27 +235,27 @@ var CommandCodeAccountPool = class {
235
235
  }
236
236
  };
237
237
  //#endregion
238
- //#region src/adapter.ts
238
+ //#region src/capabilities.ts
239
239
  /**
240
- * DeepSeek Harness LLM adapter for the Command Code Provider API.
240
+ * Static capability snapshot for the Command Code provider: model →
241
+ * reasoning-effort levels, vision/thinking flags, model → minimum plan tier,
242
+ * subscription-plan labels, deals, and hourly (peak/off-peak) pricing.
241
243
  *
242
- * Ported from pi-commandcode-provider@0.5.1 (MIT). This is an unofficial,
243
- * community-maintained integration; you need your own Command Code account
244
- * and API key or subscription, and Command Code's terms apply.
244
+ * Everything in this module is synced from official sources (the command-code
245
+ * CLI bundle's model table and the official plan/pricing/model docs — see the
246
+ * dsh-commandcode-upstream skill for the exact extraction procedures), and
247
+ * changes whenever an upstream CLI release reshuffles models/plans/prices.
248
+ * Keeping the snapshot in its own module confines those frequent sync diffs
249
+ * here: src/adapter.ts holds only the stable wire/runtime logic and imports
250
+ * these tables + read helpers.
245
251
  *
246
- * Wire protocol (reverse-engineered by the pi plugin, command-code@1.28.4;
247
- * re-verified against command-code@1.40.1 — endpoints, request shape, and
248
- * stream events unchanged):
249
- * POST {apiBase}/alpha/generate
250
- * body: { config, memory, taste, skills, params: { model, messages, tools,
251
- * system, max_tokens, temperature, stream, reasoning_effort? }, threadId }
252
- * SSE-ish JSONL events: text-delta | reasoning-start/delta/end | tool-call
253
- * | tool-result | finish | error
254
- * Model catalog: GET {apiBase}/provider/v1/models -> { object: 'list', data: [...] }
252
+ * Snapshot read helpers (planLabel, dealLabel, formatContext,
253
+ * capabilityDescription, peakPricing*, compareByPlan, modelVisibleInPlan,
254
+ * subscriptionPlanInfo, isFreeModel) live here too — they exist only to read
255
+ * the tables, so a sync never has to touch src/adapter.ts.
255
256
  *
256
- * The adapter is deliberately free of cordis/schemastery: it receives a
257
- * per-request options thunk and an API-key resolver from the plugin entry
258
- * (src/index.ts), so a settings change reaches the very next request.
257
+ * Ported from pi-commandcode-provider (MIT); originally part of src/adapter.ts
258
+ * and split out so upstream syncs stay reviewable.
259
259
  */
260
260
  const KNOWN_EFFORTS = {
261
261
  "Qwen/Qwen3.8-Max": [
@@ -263,6 +263,11 @@ const KNOWN_EFFORTS = {
263
263
  "medium",
264
264
  "xhigh"
265
265
  ],
266
+ "Qwen/Qwen3.8-Max-0902": [
267
+ "low",
268
+ "medium",
269
+ "xhigh"
270
+ ],
266
271
  "Qwen/Qwen3.8-27B": [
267
272
  "low",
268
273
  "medium",
@@ -273,6 +278,13 @@ const KNOWN_EFFORTS = {
273
278
  "medium",
274
279
  "xhigh"
275
280
  ],
281
+ "claude-fable-5-1": [
282
+ "low",
283
+ "medium",
284
+ "high",
285
+ "xhigh",
286
+ "max"
287
+ ],
276
288
  "claude-fable-5": [
277
289
  "low",
278
290
  "medium",
@@ -397,6 +409,11 @@ const KNOWN_EFFORTS = {
397
409
  "high",
398
410
  "max"
399
411
  ],
412
+ "google/gemini-3.8-flash": [
413
+ "low",
414
+ "medium",
415
+ "high"
416
+ ],
400
417
  "sakana/fugu-ultra": ["high", "xhigh"],
401
418
  "tencent/hy4-preview": [
402
419
  "low",
@@ -449,6 +466,8 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
449
466
  "Qwen/Qwen3.8-27B",
450
467
  "Qwen/Qwen3.8-Flash",
451
468
  "Qwen/Qwen3.8-Max",
469
+ "Qwen/Qwen3.8-Max-0902",
470
+ "claude-fable-5-1",
452
471
  "claude-fable-5",
453
472
  "claude-haiku-4-5-20251001",
454
473
  "claude-opus-4-7",
@@ -462,6 +481,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
462
481
  "google/gemini-3.5-flash-lite",
463
482
  "google/gemini-3.6-flash",
464
483
  "google/gemini-3.7-flash",
484
+ "google/gemini-3.8-flash",
465
485
  "gpt-5.3-codex",
466
486
  "gpt-5.4",
467
487
  "gpt-5.4-mini",
@@ -472,6 +492,8 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
472
492
  "meta/muse-spark-1.1",
473
493
  "meta/muse-spark-1.2",
474
494
  "meta/muse-spark-1.2-contributor",
495
+ "meta/muse-spark-1.3",
496
+ "meta/muse-spark-1.3-contributor",
475
497
  "minimax/minimax-m3-free",
476
498
  "moonshotai/Kimi-K2.5",
477
499
  "moonshotai/Kimi-K2.6",
@@ -487,7 +509,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
487
509
  "z-ai/glm-5.3-flash"
488
510
  ]);
489
511
  /**
490
- * Models the official CLI's model table (command-code@1.40.1) marks
512
+ * Models the official CLI's model table (command-code@1.44.0) marks
491
513
  * `reasoning:!0` but defines no selectable `reasoning_effort` levels — they
492
514
  * think automatically, with Command Code driving the depth. This is the
493
515
  * authoritative "thinks, effort not adjustable" set: `KNOWN_EFFORTS` (which
@@ -495,7 +517,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
495
517
  * effort levels, and this snapshot is not surfaced in the picker's compact
496
518
  * description — it exists for programmatic consumers.
497
519
  *
498
- * Source: the command-code@1.40.1 bundled model table (dist/cli.mjs),
520
+ * Source: the command-code@1.44.0 bundled model table (dist/cli.mjs),
499
521
  * cross-checked with https://commandcode.ai/docs/reference/cli/models.
500
522
  * (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
501
523
  * selectable `['low', 'high', 'max']` efforts; the preview then ended in
@@ -505,7 +527,10 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
505
527
  * `['low', 'medium', 'high']` efforts in command-code@1.38.0 and moved to
506
528
  * `KNOWN_EFFORTS`. `moonshotai/Kimi-K3` followed the same path in
507
529
  * command-code@1.39.3 — it gained `['low', 'high', 'max']` efforts and moved
508
- * to `KNOWN_EFFORTS`.)
530
+ * to `KNOWN_EFFORTS`. command-code@1.42.0 added `meituan/LongCat-2.0:free`
531
+ * (reasoning:!0, no efforts) and command-code@1.44.0 added both
532
+ * `meta/muse-spark-1.3` variants — all think automatically with no
533
+ * selectable levels.)
509
534
  * Keep in sync via the dsh-commandcode-upstream skill.
510
535
  */
511
536
  const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
@@ -525,9 +550,12 @@ const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
525
550
  "thinkingmachines/inkling",
526
551
  "thinkingmachines/inkling-small",
527
552
  "poolside/laguna-s-2.1-free",
553
+ "meituan/LongCat-2.0:free",
528
554
  "meta/muse-spark-1.1",
529
555
  "meta/muse-spark-1.2",
530
- "meta/muse-spark-1.2-contributor"
556
+ "meta/muse-spark-1.2-contributor",
557
+ "meta/muse-spark-1.3",
558
+ "meta/muse-spark-1.3-contributor"
531
559
  ]);
532
560
  /**
533
561
  * The minimum subscription plan a model is included in, per the official plan
@@ -535,6 +563,14 @@ const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
535
563
  * and `/docs/resources/pricing-limits`). Each plan's model list is a superset of
536
564
  * the one below it: Go ⊂ GOAT ⊂ Pro ⊂ Provider/Max. Models absent from every
537
565
  * plan list (Claude Opus/Fable, Fugu Ultra) are Provider-tier.
566
+ * `claude-fable-5-1` (Claude Fable 5.1, added in command-code@1.40.0) is
567
+ * Provider/Max-tier exactly like `claude-fable-5` — its availability matrix on
568
+ * the official plan/pricing pages grants individual-provider/max/ultra and
569
+ * teams-pro only, and the CLI's plan-access map blocks it on Go/GOAT/Pro.
570
+ * command-code@1.41.0 added `Qwen/Qwen3.8-Max-0902` (Go) and 1.42.0 added
571
+ * `meituan/LongCat-2.0:free` (Go, free promo); command-code@1.43.0 added
572
+ * `google/gemini-3.8-flash` (GOAT) and 1.44.0 added `meta/muse-spark-1.3`
573
+ * (GOAT) plus its Contributor sibling (Go).
538
574
  *
539
575
  * The Provider API exposes no plan metadata, so this snapshot is the source of
540
576
  * truth for the picker's plan annotation — it answers "which plan do I need to
@@ -556,13 +592,16 @@ const KNOWN_PLANS = {
556
592
  "Qwen/Qwen3.8-27B": "go",
557
593
  "Qwen/Qwen3.8-Flash": "go",
558
594
  "Qwen/Qwen3.8-Max": "go",
595
+ "Qwen/Qwen3.8-Max-0902": "go",
559
596
  "deepseek/deepseek-v4-flash-fast": "go",
560
597
  "deepseek/deepseek-v4-flash": "go",
561
598
  "deepseek/deepseek-v4-flash-vision-exp": "go",
562
599
  "deepseek/deepseek-v4-pro": "go",
563
600
  "gpt-5.6-luna": "go",
564
601
  "inclusionai/ling-3.0-flash-free": "go",
602
+ "meituan/LongCat-2.0:free": "go",
565
603
  "meta/muse-spark-1.2-contributor": "go",
604
+ "meta/muse-spark-1.3-contributor": "go",
566
605
  "minimax/minimax-m2.7-free": "go",
567
606
  "minimax/minimax-m3-free": "go",
568
607
  "moonshotai/Kimi-K2.5": "go",
@@ -589,8 +628,10 @@ const KNOWN_PLANS = {
589
628
  "zai-org/GLM-5.2-Fast": "go",
590
629
  "zai-org/GLM-5.3": "go",
591
630
  "google/gemini-3.7-flash": "goat",
631
+ "google/gemini-3.8-flash": "goat",
592
632
  "gpt-5.6-sol": "goat",
593
633
  "meta/muse-spark-1.2": "goat",
634
+ "meta/muse-spark-1.3": "goat",
594
635
  "xai/grok-4.6": "goat",
595
636
  "claude-haiku-4-5-20251001": "pro",
596
637
  "claude-sonnet-4-6": "pro",
@@ -605,6 +646,7 @@ const KNOWN_PLANS = {
605
646
  "gpt-5.5": "pro",
606
647
  "gpt-5.6-terra": "pro",
607
648
  "meta/muse-spark-1.1": "pro",
649
+ "claude-fable-5-1": "provider",
608
650
  "claude-fable-5": "provider",
609
651
  "claude-opus-4-7": "provider",
610
652
  "claude-opus-4-8": "provider",
@@ -745,6 +787,10 @@ const KNOWN_DEALS = {
745
787
  "poolside/laguna-s-2.1-free": {
746
788
  label: "FREE",
747
789
  free: true
790
+ },
791
+ "meituan/LongCat-2.0:free": {
792
+ label: "FREE",
793
+ free: true
748
794
  }
749
795
  };
750
796
  /**
@@ -798,30 +844,6 @@ function peakPricingLabel(modelId, now = Date.now()) {
798
844
  if (state === void 0) return void 0;
799
845
  return state === "peak" ? "Peak" : "Half";
800
846
  }
801
- const COMMAND_CODE_CLI_VERSION = "1.40.1";
802
- const DEFAULT_API_BASE = "https://api.commandcode.ai";
803
- const DEFAULT_GENERATE_MAX_TOKENS = 64e3;
804
- const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
805
- const MODELS_TIMEOUT_MS = 1e4;
806
- /** How long the picker's plan-filter billing facts stay cached before refetching. */
807
- const BILLING_ACCESS_TTL_MS = 3e5;
808
- /**
809
- * Subscription statuses the CLI treats as live (`Mr` in command-code's
810
- * cli.mjs): the plan gate applies only under one of these.
811
- */
812
- const ACTIVE_SUBSCRIPTION_STATUSES = /* @__PURE__ */ new Set([
813
- "active",
814
- "trialing",
815
- "past_due"
816
- ]);
817
- /** Head-of-request timeout: how long to wait for the first response byte. */
818
- const DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
819
- /** Stream idle timeout: a generation that stalls this long is a dead connection. */
820
- const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
821
- const MODEL_CACHE_VERSION = 1;
822
- function isRecord(value) {
823
- return typeof value === "object" && value !== null && !Array.isArray(value);
824
- }
825
847
  /**
826
848
  * Official display label for a model's minimum plan, or undefined for models
827
849
  * outside the snapshot (e.g. future catalog additions).
@@ -877,6 +899,53 @@ function capabilityDescription(modelId, contextWindow, now = Date.now()) {
877
899
  if (ctx !== void 0) parts.push(ctx);
878
900
  return parts.join(" · ");
879
901
  }
902
+ //#endregion
903
+ //#region src/adapter.ts
904
+ /**
905
+ * DeepSeek Harness LLM adapter for the Command Code Provider API.
906
+ *
907
+ * Ported from pi-commandcode-provider@0.5.1 (MIT). This is an unofficial,
908
+ * community-maintained integration; you need your own Command Code account
909
+ * and API key or subscription, and Command Code's terms apply.
910
+ *
911
+ * Wire protocol (reverse-engineered by the pi plugin, command-code@1.28.4;
912
+ * re-verified against command-code@1.44.0 — endpoints, request shape, and
913
+ * stream events unchanged):
914
+ * POST {apiBase}/alpha/generate
915
+ * body: { config, memory, taste, skills, params: { model, messages, tools,
916
+ * system, max_tokens, temperature, stream, reasoning_effort? }, threadId }
917
+ * SSE-ish JSONL events: text-delta | reasoning-start/delta/end | tool-call
918
+ * | tool-result | finish | error
919
+ * Model catalog: GET {apiBase}/provider/v1/models -> { object: 'list', data: [...] }
920
+ *
921
+ * The adapter is deliberately free of cordis/schemastery: it receives a
922
+ * per-request options thunk and an API-key resolver from the plugin entry
923
+ * (src/index.ts), so a settings change reaches the very next request.
924
+ */
925
+ const COMMAND_CODE_CLI_VERSION = "1.44.0";
926
+ const DEFAULT_API_BASE = "https://api.commandcode.ai";
927
+ const DEFAULT_GENERATE_MAX_TOKENS = 64e3;
928
+ const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
929
+ const MODELS_TIMEOUT_MS = 1e4;
930
+ /** How long the picker's plan-filter billing facts stay cached before refetching. */
931
+ const BILLING_ACCESS_TTL_MS = 3e5;
932
+ /**
933
+ * Subscription statuses the CLI treats as live (`Mr` in command-code's
934
+ * cli.mjs): the plan gate applies only under one of these.
935
+ */
936
+ const ACTIVE_SUBSCRIPTION_STATUSES = /* @__PURE__ */ new Set([
937
+ "active",
938
+ "trialing",
939
+ "past_due"
940
+ ]);
941
+ /** Head-of-request timeout: how long to wait for the first response byte. */
942
+ const DEFAULT_REQUEST_TIMEOUT_MS = 6e4;
943
+ /** Stream idle timeout: a generation that stalls this long is a dead connection. */
944
+ const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
945
+ const MODEL_CACHE_VERSION = 1;
946
+ function isRecord(value) {
947
+ return typeof value === "object" && value !== null && !Array.isArray(value);
948
+ }
880
949
  function stringValue(value) {
881
950
  return typeof value === "string" ? value : void 0;
882
951
  }
@@ -2026,38 +2095,75 @@ function applyCommands(ctx, deps) {
2026
2095
  ctx.commands.register(commandDefinition(deps));
2027
2096
  }
2028
2097
  //#endregion
2098
+ //#region src/wire-shared.ts
2099
+ /** The npm package identity every contribution and descriptor claims. */
2100
+ const REMOTE_PACKAGE = "@mars-sea/dsh-commandcode-provider";
2101
+ /** The Cordis service key the Gateway resolves every Command Code Remote from. */
2102
+ const REMOTE_SERVICE = "commandcodeUsage";
2103
+ /** The wire namespace all Command Code endpoints share. */
2104
+ const REMOTE_NAMESPACE = "commandcode";
2105
+ /**
2106
+ * Build the validator helpers one endpoint uses Sequence. `prefix` names the
2107
+ * endpoint in the rejection message (e.g. `commandcode/report result:`), so
2108
+ * each wire file keeps its own diagnostic phrasing while sharing the helper
2109
+ * bodies.
2110
+ *
2111
+ * The helpers return the reject call directly in the failure branch: since
2112
+ * `reject` is typed `never`, the ternary's union collapses to the success type
2113
+ * without relying on TypeScript's control-flow analysis of a never-returning
2114
+ * call (which only recognizes function declarations, not the destructured
2115
+ * arrow `reject` callers receive from this factory).
2116
+ */
2117
+ function makeBoundaryValidator(prefix) {
2118
+ const reject = (field) => {
2119
+ throw new TypeError(`${prefix} invalid ${field}`);
2120
+ };
2121
+ const record = (value, field) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : reject(field);
2122
+ const stringField = (source, key, field) => typeof source[key] === "string" ? source[key] : reject(field);
2123
+ const numberField = (source, key, field) => typeof source[key] === "number" && Number.isFinite(source[key]) ? source[key] : reject(field);
2124
+ const booleanField = (source, key, field) => typeof source[key] === "boolean" ? source[key] : reject(field);
2125
+ return {
2126
+ reject,
2127
+ record,
2128
+ stringField,
2129
+ numberField,
2130
+ booleanField
2131
+ };
2132
+ }
2133
+ /**
2134
+ * Build one strict invocation descriptor. Every Command Code Remote shares the
2135
+ * `commandcode` namespace, the `commandcodeUsage` service, and a strict
2136
+ * `mode: 'strict'` result — only the endpoint, method, result type symbol, and
2137
+ * schema differ — so the boilerplate lives here once and each endpoint supplies
2138
+ * only its own facts.
2139
+ */
2140
+ function makeRemoteDescriptor(endpoint, method, typeSymbol, schema) {
2141
+ return {
2142
+ id: `${REMOTE_PACKAGE}#${endpoint}`,
2143
+ service: REMOTE_SERVICE,
2144
+ namespace: REMOTE_NAMESPACE,
2145
+ method,
2146
+ invocation: { kind: "direct" },
2147
+ parameters: [],
2148
+ result: {
2149
+ mode: "strict",
2150
+ typeSymbol,
2151
+ schema
2152
+ }
2153
+ };
2154
+ }
2155
+ //#endregion
2029
2156
  //#region src/usage-wire.ts
2030
2157
  /** The npm package identity both contribution registrations claim. */
2031
- const USAGE_REMOTE_PACKAGE = "@mars-sea/dsh-commandcode-provider";
2158
+ const USAGE_REMOTE_PACKAGE = REMOTE_PACKAGE;
2032
2159
  /** Canonical `<namespace>/<method>` endpoint of the usage report Remote. */
2033
2160
  const USAGE_REPORT_ENDPOINT = "commandcode/report";
2034
- /** Reject one boundary value with a field-naming error. */
2035
- function reject$1(field) {
2036
- throw new TypeError(`commandcode/report result: invalid ${field}`);
2037
- }
2038
- /** Read one required finite number field (`field` is the dotted error label). */
2039
- function numberField(source, key, field) {
2040
- const value = source[key];
2041
- if (typeof value !== "number" || !Number.isFinite(value)) reject$1(field);
2042
- return value;
2043
- }
2044
- /** Read one required string field (`field` is the dotted error label). */
2045
- function stringField(source, key, field) {
2046
- const value = source[key];
2047
- if (typeof value !== "string") reject$1(field);
2048
- return value;
2049
- }
2050
- /** Read one required boolean field (`field` is the dotted error label). */
2051
- function booleanField(source, key, field) {
2052
- const value = source[key];
2053
- if (typeof value !== "boolean") reject$1(field);
2054
- return value;
2055
- }
2056
- /** Narrow an unknown value to a plain record, or reject. */
2057
- function record(value, field) {
2058
- if (typeof value !== "object" || value === null || Array.isArray(value)) reject$1(field);
2059
- return value;
2060
- }
2161
+ /**
2162
+ * The shared read/validate helpers, prefixed with the report endpoint so
2163
+ * rejection messages name the offending boundary (the catalog endpoint below
2164
+ * shares this prefix, matching the historical behavior).
2165
+ */
2166
+ const { reject: reject$1, record, stringField, numberField, booleanField } = makeBoundaryValidator("commandcode/report result:");
2061
2167
  /** Validate one window-limit block (`fiveHour` / `weekly`). */
2062
2168
  function windowLimit(value, field) {
2063
2169
  const source = record(value, field);
@@ -2080,8 +2186,8 @@ function parseUsageReport(value) {
2080
2186
  const report = { failures };
2081
2187
  if (source.blocked !== void 0) {
2082
2188
  const blocked = source.blocked;
2083
- if (blocked !== "invalid-key" && blocked !== "service-unavailable" && blocked !== "network") reject$1("blocked");
2084
- report.blocked = blocked;
2189
+ if (blocked === "invalid-key" || blocked === "service-unavailable" || blocked === "network") report.blocked = blocked;
2190
+ else reject$1("blocked");
2085
2191
  }
2086
2192
  if (source.account !== void 0) {
2087
2193
  const account = record(source.account, "account");
@@ -2145,8 +2251,8 @@ function parseAccountUsage(value) {
2145
2251
  /** Parse the wire result into a {@link CommandCodeAccountsReport}. */
2146
2252
  function parseAccountsReport(value) {
2147
2253
  const accounts = record(value, "result").accounts;
2148
- if (!Array.isArray(accounts)) reject$1("accounts");
2149
- return { accounts: accounts.map(parseAccountUsage) };
2254
+ if (Array.isArray(accounts)) return { accounts: accounts.map(parseAccountUsage) };
2255
+ return reject$1("accounts");
2150
2256
  }
2151
2257
  /**
2152
2258
  * The strict result codec both halves attach to the descriptor. Hand-rolled:
@@ -2164,19 +2270,7 @@ const USAGE_HOST_CONTRIBUTION = {
2164
2270
  events: [],
2165
2271
  objects: []
2166
2272
  },
2167
- invocations: [{
2168
- id: `${USAGE_REMOTE_PACKAGE}#${USAGE_REPORT_ENDPOINT}`,
2169
- service: "commandcodeUsage",
2170
- namespace: "commandcode",
2171
- method: "report",
2172
- invocation: { kind: "direct" },
2173
- parameters: [],
2174
- result: {
2175
- mode: "strict",
2176
- typeSymbol: `${USAGE_REMOTE_PACKAGE}#CommandCodeAccountsReport`,
2177
- schema: usageReportSchema
2178
- }
2179
- }]
2273
+ invocations: [makeRemoteDescriptor(USAGE_REPORT_ENDPOINT, "report", `${USAGE_REMOTE_PACKAGE}#CommandCodeAccountsReport`, usageReportSchema)]
2180
2274
  };
2181
2275
  /** Canonical `<namespace>/<method>` endpoint of the model-catalog Remote. */
2182
2276
  const MODELS_ENDPOINT = "commandcode/models";
@@ -2191,26 +2285,14 @@ function parseCatalogModel(value) {
2191
2285
  /** Parse the wire result into a {@link CommandCodeCatalog}. */
2192
2286
  function parseCatalog(value) {
2193
2287
  const models = record(value, "result").models;
2194
- if (!Array.isArray(models)) reject$1("models");
2195
- return { models: models.map(parseCatalogModel) };
2288
+ if (Array.isArray(models)) return { models: models.map(parseCatalogModel) };
2289
+ return reject$1("models");
2196
2290
  }
2197
2291
  /**
2198
2292
  * The model-catalog invocation descriptor, sharing the same `commandcodeUsage`
2199
2293
  * service and `commandcode` namespace as the usage report.
2200
2294
  */
2201
- const MODELS_DESCRIPTOR = {
2202
- id: `${USAGE_REMOTE_PACKAGE}#${MODELS_ENDPOINT}`,
2203
- service: "commandcodeUsage",
2204
- namespace: "commandcode",
2205
- method: "models",
2206
- invocation: { kind: "direct" },
2207
- parameters: [],
2208
- result: {
2209
- mode: "strict",
2210
- typeSymbol: `${USAGE_REMOTE_PACKAGE}#CommandCodeCatalog`,
2211
- schema: { parse: parseCatalog }
2212
- }
2213
- };
2295
+ const MODELS_DESCRIPTOR = makeRemoteDescriptor(MODELS_ENDPOINT, "models", `${USAGE_REMOTE_PACKAGE}#CommandCodeCatalog`, { parse: parseCatalog });
2214
2296
  //#endregion
2215
2297
  //#region src/login-wire.ts
2216
2298
  /** The canonical endpoint paths of the three login Remotes. */
@@ -2226,7 +2308,12 @@ const REASONS = [
2226
2308
  "cancelled",
2227
2309
  "error"
2228
2310
  ];
2229
- /** Reject one boundary value with a field-naming error. */
2311
+ /** The shared read/validate helpers, prefixed with the login endpoint so
2312
+ * rejection messages name the offending boundary. */
2313
+ /** Reject one boundary value with a field-naming error. A module-level
2314
+ * function declaration (not the factory's destructured arrow) so TypeScript's
2315
+ * control-flow analysis recognizes it as never-returning and narrows `state`
2316
+ * after the guard below. */
2230
2317
  function reject(field) {
2231
2318
  throw new TypeError(`commandcode/login result: invalid ${field}`);
2232
2319
  }
@@ -2267,19 +2354,7 @@ function parseLoginStatus(value) {
2267
2354
  const loginStatusSchema = { parse: parseLoginStatus };
2268
2355
  /** Build one login invocation descriptor (uniform result, no parameters). */
2269
2356
  function loginDescriptor(endpoint, method) {
2270
- return {
2271
- id: `${USAGE_REMOTE_PACKAGE}#${endpoint}`,
2272
- service: "commandcodeUsage",
2273
- namespace: "commandcode",
2274
- method,
2275
- invocation: { kind: "direct" },
2276
- parameters: [],
2277
- result: {
2278
- mode: "strict",
2279
- typeSymbol: `${USAGE_REMOTE_PACKAGE}#CommandCodeLoginStatus`,
2280
- schema: loginStatusSchema
2281
- }
2282
- };
2357
+ return makeRemoteDescriptor(endpoint, method, `${REMOTE_PACKAGE}#CommandCodeLoginStatus`, loginStatusSchema);
2283
2358
  }
2284
2359
  /** The three login descriptors, shared verbatim by Host registration and Client mount. */
2285
2360
  const LOGIN_DESCRIPTORS = [