@jeffreyjyz/opencode-command-code 0.1.4 → 0.1.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/dist/gating.d.ts CHANGED
@@ -10,6 +10,12 @@ export declare const PLAN_RULES: Record<string, {
10
10
  * category rules. Empirically probed — the CLI bundle misses these because it
11
11
  * tracks category via serving lane, not per-model plan entitlements. */
12
12
  export declare const HARD_BLOCKED: Record<string, string[]>;
13
+ /** ISO timestamp the snapshot was extracted (absent on pre-metadata files). */
14
+ export declare const GATE_EXTRACTED_AT: string | undefined;
15
+ /** Command Code CLI version the snapshot was scraped from. */
16
+ export declare const GATE_CLI_VERSION: string | undefined;
17
+ /** Warn once per process when gating.json is older than 30 days. */
18
+ export declare function warnIfGatingStale(): void;
13
19
  export declare function canonicalizeModelId(model: string): string;
14
20
  /** Bare model id with any provider qualifier stripped: everything after the
15
21
  * FIRST colon ("anthropic:claude-opus-5" → "claude-opus-5"). Matches
package/dist/index.js CHANGED
@@ -71,6 +71,8 @@ async function resolveKey(getAuth) {
71
71
  }
72
72
  // ../core/gating.json
73
73
  var gating_default = {
74
+ extractedAt: "2026-09-12T06:01:01.385Z",
75
+ cliVersion: "1.38.2",
74
76
  categories: {
75
77
  "claude-sonnet-5": "premium",
76
78
  "claude-sonnet-4-6": "premium",
@@ -311,6 +313,19 @@ var PLAN_RULES = gating_default.plans;
311
313
  var HARD_BLOCKED = gating_default.hardBlocked;
312
314
  var KNOWN_MODELS = gating_default.knownModels;
313
315
  var MODEL_ALIASES = gating_default.aliases;
316
+ var GATE_EXTRACTED_AT = gating_default.extractedAt;
317
+ var GATE_CLI_VERSION = gating_default.cliVersion;
318
+ var GATE_STALE_DAYS = 30;
319
+ var staleWarned = false;
320
+ function warnIfGatingStale() {
321
+ if (staleWarned || !GATE_EXTRACTED_AT)
322
+ return;
323
+ const days = Math.floor((Date.now() - Date.parse(GATE_EXTRACTED_AT)) / 86400000);
324
+ if (days > GATE_STALE_DAYS) {
325
+ staleWarned = true;
326
+ console.warn(`[command-code] gating snapshot is ${days}d old (CLI ${GATE_CLI_VERSION ?? "?"}) \u2014 run \`bun run extract\` from the repo root`);
327
+ }
328
+ }
314
329
  function findKnown(s) {
315
330
  const k = s.toLowerCase();
316
331
  return KNOWN_MODELS.find((m) => m.toLowerCase() === k);
@@ -382,6 +397,7 @@ function splitModels(models) {
382
397
  return { claude, open };
383
398
  }
384
399
  async function loadModels(key) {
400
+ warnIfGatingStale();
385
401
  let models;
386
402
  if (cache && Date.now() - cache.at < CACHE_TTL_MS) {
387
403
  models = cache.models;
@@ -549,6 +565,13 @@ function parseIsoUtc(s) {
549
565
  }
550
566
  return Date.UTC(+y, +mo - 1, +d, +h, +mi, Math.floor(+sec)) - offsetMs;
551
567
  }
568
+ function monthlyWindow(cap, remaining, periodStart, periodEnd) {
569
+ const used = Math.min(Math.max(cap - remaining, 0), cap);
570
+ const resetAt = periodEnd ? parseIsoUtc(periodEnd) : undefined;
571
+ const start = periodStart ? parseIsoUtc(periodStart) : undefined;
572
+ const durSecs = start !== undefined && resetAt !== undefined ? Math.max(Math.floor((resetAt - start) / 1000), 1) : undefined;
573
+ return { window: { used, cap, resetAt }, durSecs };
574
+ }
552
575
  var NAME_RULES = plans_default.nameRules;
553
576
  var DEFAULT_NAME = plans_default.defaultName;
554
577
  var CAPS = plans_default.caps;
@@ -556,6 +579,17 @@ var PLANS = plans_default.plans;
556
579
  function planMonthlyCap(planId) {
557
580
  return CAPS[planName(planId)] ?? undefined;
558
581
  }
582
+ function planRuleMatched(planId) {
583
+ const id = planId.toLowerCase();
584
+ return NAME_RULES.some((rule) => rule.needles.every((n) => id.includes(n)));
585
+ }
586
+ var unknownPlanWarned = false;
587
+ function warnUnknownPlanOnce(planId) {
588
+ if (unknownPlanWarned)
589
+ return;
590
+ unknownPlanWarned = true;
591
+ console.warn(`[command-code] unknown plan id '${planId}' \u2014 showing Free; update core/plans.json`);
592
+ }
559
593
  function planName(planId) {
560
594
  const id = planId.toLowerCase();
561
595
  for (const rule of NAME_RULES) {
@@ -595,6 +629,9 @@ async function renderUsage(key) {
595
629
  return;
596
630
  })
597
631
  ]);
632
+ if (sub.planId && sub.planId !== "free" && !planRuleMatched(sub.planId)) {
633
+ warnUnknownPlanOnce(sub.planId);
634
+ }
598
635
  const lines = [];
599
636
  lines.push(`## Command Code \u2014 ${planName(sub.planId)} (${sub.status})
600
637
  `);
@@ -611,11 +648,8 @@ async function renderUsage(key) {
611
648
  }
612
649
  lines.push("### Usage windows");
613
650
  if (cap) {
614
- const used = Math.min(Math.max(cap - cr.credits.monthlyCredits, 0), cap);
615
- const resetAt = sub.currentPeriodEnd ? parseIsoUtc(sub.currentPeriodEnd) : undefined;
616
- const start = sub.currentPeriodStart ? parseIsoUtc(sub.currentPeriodStart) : undefined;
617
- const dur = start !== undefined && resetAt !== undefined ? Math.max(Math.floor((resetAt - start) / 1000), 1) : undefined;
618
- lines.push(windowLine("Monthly", { used, cap, resetAt }, nowSecs, dur));
651
+ const { window, durSecs } = monthlyWindow(cap, cr.credits.monthlyCredits, sub.currentPeriodStart, sub.currentPeriodEnd);
652
+ lines.push(windowLine("Monthly", { ...window, exceeded: false }, nowSecs, durSecs));
619
653
  }
620
654
  const five = cr.windowLimits?.fiveHour;
621
655
  const weekly = cr.windowLimits?.weekly;
package/dist/usage.d.ts CHANGED
@@ -18,7 +18,21 @@ export declare function elapsedPct(resetAtMs: number | undefined, durSecs: numbe
18
18
  export declare function paceEta(resetAtMs: number | undefined, durSecs: number, used: number, cap: number, nowSecs: number): number | undefined;
19
19
  /** ISO 8601 → epoch ms. Handles trailing Z or a ±HH:MM / ±HHMM offset. */
20
20
  export declare function parseIsoUtc(s: string): number | undefined;
21
+ /** Assemble the monthly window from the plan cap + subscription period:
22
+ * used = cap − remaining (clamped), reset = period end, durSecs = period
23
+ * length. Mirrors cmduse_core::monthly_window (conformance-pinned). */
24
+ export declare function monthlyWindow(cap: number, remaining: number, periodStart?: string, periodEnd?: string): {
25
+ window: {
26
+ used: number;
27
+ cap: number;
28
+ resetAt?: number;
29
+ };
30
+ durSecs?: number;
31
+ };
21
32
  export declare function planMonthlyCap(planId: string): number | undefined;
33
+ /** True when `planId` matched a NAME_RULES entry (not the DEFAULT_NAME
34
+ * fallback). Mirrors cmduse_core::plan_rule_matched. */
35
+ export declare function planRuleMatched(planId: string): boolean;
22
36
  export declare function planName(planId: string): string;
23
37
  export declare function windowLine(label: string, w: Window, nowSecs: number, durSecs?: number): string;
24
38
  export declare function plansTable(current: string): string;
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "@jeffreyjyz/opencode-command-code",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Command Code provider + usage dashboard for opencode: two providers (Anthropic wire for Claude, OpenAI wire for everything else) against api.commandcode.ai, live model list, plan gating, /cmd-usage.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
- "build": "bun build src/index.ts --outdir dist --target bun --external @opencode-ai/plugin --external @opencode-ai/sdk && tsc -p tsconfig.build.json",
9
+ "build": "bun build src/index.ts --outdir dist --target bun --external @opencode-ai/plugin && tsc -p tsconfig.build.json",
10
10
  "test": "bun test",
11
- "extract": "bun run scripts/extract-gating.ts",
12
11
  "typecheck": "tsc --noEmit"
13
12
  },
14
13
  "dependencies": {