@jeffreyjyz/opencode-command-code 0.5.0 → 0.5.3
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/index.js +1 -1
- package/dist/sidebar/rows.d.ts +18 -0
- package/dist/sidebar/usageDb.d.ts +15 -0
- package/dist/sidebar/zen.d.ts +29 -3
- package/dist/tui.js +127 -38
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2414,7 +2414,7 @@ function superRefine(fn) {
|
|
|
2414
2414
|
// package.json
|
|
2415
2415
|
var package_default = {
|
|
2416
2416
|
name: "@jeffreyjyz/opencode-command-code",
|
|
2417
|
-
version: "0.5.
|
|
2417
|
+
version: "0.5.3",
|
|
2418
2418
|
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. Requires the cmduse CLI for usage rendering.",
|
|
2419
2419
|
type: "module",
|
|
2420
2420
|
main: "dist/index.js",
|
package/dist/sidebar/rows.d.ts
CHANGED
|
@@ -130,6 +130,24 @@ export declare function rate(value: number): string;
|
|
|
130
130
|
export declare function count(value: number): string;
|
|
131
131
|
/** "3h 12m" / "1d 20h" / "<1m" for a reset epoch. */
|
|
132
132
|
export declare function until(epoch: number | undefined, now?: number): string;
|
|
133
|
+
/** A rolling window as two or three rows: the use line, then resets plus whatever
|
|
134
|
+
* needs flagging, then an optional `extra` continuation. The lead segment follows
|
|
135
|
+
* cmduse's importance order — over-cap flag, then the cap ETA, then the
|
|
136
|
+
* informational elapsed share — because the 37-column budget fits exactly one of
|
|
137
|
+
* them beside the reset countdown.
|
|
138
|
+
*
|
|
139
|
+
* Shared by both panels: CommandCode passes four arguments (output unchanged),
|
|
140
|
+
* the OpenCode Go/Zen side adds the window's request count as `extra`, so
|
|
141
|
+
* `LIMIT EXCEEDED`, the tone, `cap in …`, `elapsed` and `resets` all have one
|
|
142
|
+
* implementation. */
|
|
143
|
+
export declare function windowRows(label: string, w: WindowUsage | undefined, now: number, durSecs: number, extra?: string): SidebarRow[];
|
|
144
|
+
/**
|
|
145
|
+
* The two store-backed rows for the active model — its requests under `Usage
|
|
146
|
+
* (this model)`, then this conversation's own totals under `Session`. They need
|
|
147
|
+
* no network, so both panels keep them when the catalog is missing, and both
|
|
148
|
+
* families build them here rather than in two places.
|
|
149
|
+
*/
|
|
150
|
+
export declare function localUsageRows(usage?: ModelUsage, session?: ModelUsage): SidebarRow[];
|
|
133
151
|
/** Plan + rolling windows + period totals, from a cmduse snapshot. */
|
|
134
152
|
export declare function usageRows(usage: Usage | undefined, now?: number): SidebarRow[];
|
|
135
153
|
/** Active model's allowance, rates and benchmarks, from mpc's catalog; its
|
|
@@ -24,6 +24,21 @@ export declare function periodStart(usage: {
|
|
|
24
24
|
* while the session said 2.7K).
|
|
25
25
|
*/
|
|
26
26
|
export declare function loadModelUsage(modelID: string, sinceMs: number, path?: string, sessionID?: string): ModelUsage | null;
|
|
27
|
+
/**
|
|
28
|
+
* The oldest in-window assistant turn for one model, as epoch ms — the start of
|
|
29
|
+
* the rolling window the Go/Zen panel needs. A rolling 5-hour/weekly window has
|
|
30
|
+
* no service-reported reset (Go has no usage API), but its clock does have a
|
|
31
|
+
* real start: the oldest request still inside it ages out at `start + window`,
|
|
32
|
+
* which is that window's honest reset. Null when the model has no turn in the
|
|
33
|
+
* window, or the store is missing/unreadable, so callers then omit the
|
|
34
|
+
* continuation exactly as before.
|
|
35
|
+
*
|
|
36
|
+
* Account-wide like ocuse's per-model window totals, so it is *not* scoped to a
|
|
37
|
+
* session: a rolling window counts the model's spend across every conversation.
|
|
38
|
+
* Matching is on the canonical key, the same normalisation `loadModelUsage` uses
|
|
39
|
+
* (the session id and the stored `modelID` differ by vendor prefix/punctuation).
|
|
40
|
+
*/
|
|
41
|
+
export declare function loadModelWindowStart(modelID: string, sinceMs: number, path?: string): number | null;
|
|
27
42
|
/**
|
|
28
43
|
* Requests and cost for one session, so the panel can show what this
|
|
29
44
|
* conversation has spent rather than only the period-to-date figure. Null when
|
package/dist/sidebar/zen.d.ts
CHANGED
|
@@ -14,7 +14,15 @@ export interface ZenModel {
|
|
|
14
14
|
month: ZenTotals;
|
|
15
15
|
}
|
|
16
16
|
export interface ZenUsage {
|
|
17
|
+
/**
|
|
18
|
+
* Billing period start, epoch ms: `periodStart` on current ocuse, or
|
|
19
|
+
* `periodStartAt` once it publishes the bounds (the same instants cmduse
|
|
20
|
+
* 0.7.2+ carries).
|
|
21
|
+
*/
|
|
17
22
|
periodStart?: number;
|
|
23
|
+
/** Billing period end, epoch ms. Optional: older ocuse does not publish it
|
|
24
|
+
* and the Monthly row must then degrade to spend alone. */
|
|
25
|
+
periodEndAt?: number;
|
|
18
26
|
source?: string;
|
|
19
27
|
totals: {
|
|
20
28
|
fiveHour: ZenTotals;
|
|
@@ -26,8 +34,26 @@ export interface ZenUsage {
|
|
|
26
34
|
}
|
|
27
35
|
/** Parse `ocuse -1 --json`. Anything malformed reads as "no usage". */
|
|
28
36
|
export declare function parseZenJson(text: string): ZenUsage;
|
|
37
|
+
/**
|
|
38
|
+
* The starts of the active model's rolling windows, epoch ms: the oldest request
|
|
39
|
+
* still inside each one, from opencode's own store. The Go/Zen panel turns each
|
|
40
|
+
* into a reset via `rollingReset`; absent when no such request exists.
|
|
41
|
+
*/
|
|
42
|
+
export interface ZenWindowStarts {
|
|
43
|
+
fiveHour?: number;
|
|
44
|
+
weekly?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A rolling window's reset, derived from the oldest request still inside it:
|
|
48
|
+
* that request leaves the window at `oldest + durSecs`, which is an honest reset
|
|
49
|
+
* epoch — unlike `now + durSecs`, a constant that would be noise in a usage
|
|
50
|
+
* panel. Undefined when there is no oldest request (an empty window), so the row
|
|
51
|
+
* keeps the same spend-only degrade it had before.
|
|
52
|
+
*/
|
|
53
|
+
export declare function rollingReset(startMs: number | undefined, durSecs: number): number | undefined;
|
|
29
54
|
/** The OpenCode Go / Zen panel: period windows, a rule, then the active model.
|
|
30
55
|
* Like `modelRows`, `fallbackName` (the session's own id) keeps the model block
|
|
31
|
-
* — and the local `
|
|
32
|
-
* unreachable; only the catalog-derived rows
|
|
33
|
-
|
|
56
|
+
* — and the local `Usage (this model)` / `Session` figures, which need no network
|
|
57
|
+
* — on screen when mpc's catalog is unreachable; only the catalog-derived rows
|
|
58
|
+
* then drop out. */
|
|
59
|
+
export declare function zenRows(usage: ZenUsage | undefined, meta: ModelMeta | undefined, modelUsage?: ModelUsage, session?: ModelUsage, fallbackName?: string, windows?: ZenWindowStarts): SidebarRow[];
|
package/dist/tui.js
CHANGED
|
@@ -621,7 +621,7 @@ function until(epoch, now = Date.now()) {
|
|
|
621
621
|
const days = Math.floor(hours / 24);
|
|
622
622
|
return hours % 24 ? `${days}d ${hours % 24}h` : `${days}d`;
|
|
623
623
|
}
|
|
624
|
-
function windowRows(label, w, now, durSecs) {
|
|
624
|
+
function windowRows(label, w, now, durSecs, extra) {
|
|
625
625
|
if (!w || typeof w.cap !== "number" || w.cap <= 0)
|
|
626
626
|
return [];
|
|
627
627
|
const used = typeof w.used === "number" ? w.used : 0;
|
|
@@ -632,7 +632,23 @@ function windowRows(label, w, now, durSecs) {
|
|
|
632
632
|
const reset = until(w.resetAt, now);
|
|
633
633
|
const lead = w.exceeded ? "LIMIT EXCEEDED" : eta === undefined ? elapsed === undefined ? "" : `${elapsed} elapsed` : `cap in ${until(now + eta * 1000, now)}`;
|
|
634
634
|
const detail = [lead, reset ? `resets ${reset}` : ""].filter(Boolean).join(" \xB7 ");
|
|
635
|
-
return [[label, `${money(used)}/${money(w.cap)} (${pct.toFixed(1)}%)`, w.exceeded ? "crit" : pctTone(pct)], ...detail ? [["", detail, "muted"]] : []];
|
|
635
|
+
return [[label, `${money(used)}/${money(w.cap)} (${pct.toFixed(1)}%)`, w.exceeded ? "crit" : pctTone(pct)], ...detail ? [["", detail, "muted"]] : [], ...extra ? [["", extra, "muted"]] : []];
|
|
636
|
+
}
|
|
637
|
+
function localUsageRows(usage, session) {
|
|
638
|
+
const rows = [];
|
|
639
|
+
if (usage) {
|
|
640
|
+
rows.push(["Usage (this model)", `${count(usage.requests)} req`, "base"]);
|
|
641
|
+
const spend = usage.cost > 0 ? money(usage.cost) : "";
|
|
642
|
+
const share = usage.cost > 0 && session && session.cost > 0 ? `${Math.min(100, Math.round(usage.cost / session.cost * 100))}% of session` : "";
|
|
643
|
+
const detail = [spend, share].filter(Boolean).join(" \xB7 ");
|
|
644
|
+
if (detail)
|
|
645
|
+
rows.push(["", detail, "muted"]);
|
|
646
|
+
}
|
|
647
|
+
if (session) {
|
|
648
|
+
const spent = session.cost > 0 ? ` \xB7 ${money(session.cost)}` : "";
|
|
649
|
+
rows.push(["Session", `${count(session.requests)} req${spent}`, "base"]);
|
|
650
|
+
}
|
|
651
|
+
return rows;
|
|
636
652
|
}
|
|
637
653
|
function monthlyDetail(usage, now) {
|
|
638
654
|
const {
|
|
@@ -681,19 +697,7 @@ function modelRows(meta, usage, session, fallbackName) {
|
|
|
681
697
|
const name = meta?.name ?? fallbackName;
|
|
682
698
|
if (!name)
|
|
683
699
|
return [];
|
|
684
|
-
const rows = [["Model", clip(name, valueWidth("Model")), "strong", true]];
|
|
685
|
-
if (usage) {
|
|
686
|
-
rows.push(["Usage (this model)", `${count(usage.requests)} req`, "base"]);
|
|
687
|
-
const spend = usage.cost > 0 ? money(usage.cost) : "";
|
|
688
|
-
const share = usage.cost > 0 && session && session.cost > 0 ? `${Math.min(100, Math.round(usage.cost / session.cost * 100))}% of session` : "";
|
|
689
|
-
const detail = [spend, share].filter(Boolean).join(" \xB7 ");
|
|
690
|
-
if (detail)
|
|
691
|
-
rows.push(["", detail, "muted"]);
|
|
692
|
-
}
|
|
693
|
-
if (session) {
|
|
694
|
-
const spent = session.cost > 0 ? ` \xB7 ${money(session.cost)}` : "";
|
|
695
|
-
rows.push(["Session", `${count(session.requests)} req${spent}`, "base"]);
|
|
696
|
-
}
|
|
700
|
+
const rows = [["Model", clip(name, valueWidth("Model")), "strong", true], ...localUsageRows(usage, session)];
|
|
697
701
|
if (!meta)
|
|
698
702
|
return rows;
|
|
699
703
|
if (meta.tier)
|
|
@@ -2060,7 +2064,8 @@ function parseZenJson(text) {
|
|
|
2060
2064
|
}
|
|
2061
2065
|
const top = body.totals ?? {};
|
|
2062
2066
|
return {
|
|
2063
|
-
periodStart: typeof body.periodStart === "number" ? body.periodStart : undefined,
|
|
2067
|
+
periodStart: typeof body.periodStartAt === "number" ? body.periodStartAt : typeof body.periodStart === "number" ? body.periodStart : undefined,
|
|
2068
|
+
periodEndAt: typeof body.periodEndAt === "number" ? body.periodEndAt : undefined,
|
|
2064
2069
|
source: typeof body.source === "string" ? body.source : undefined,
|
|
2065
2070
|
totals: {
|
|
2066
2071
|
fiveHour: totals(top.fiveHour),
|
|
@@ -2070,43 +2075,63 @@ function parseZenJson(text) {
|
|
|
2070
2075
|
models
|
|
2071
2076
|
};
|
|
2072
2077
|
}
|
|
2073
|
-
function
|
|
2074
|
-
|
|
2078
|
+
function monthPeriod(usage) {
|
|
2079
|
+
const {
|
|
2080
|
+
periodStart,
|
|
2081
|
+
periodEndAt
|
|
2082
|
+
} = usage;
|
|
2083
|
+
if (typeof periodStart !== "number" || typeof periodEndAt !== "number")
|
|
2084
|
+
return;
|
|
2085
|
+
const durSecs = Math.round((periodEndAt - periodStart) / 1000);
|
|
2086
|
+
if (durSecs <= 0)
|
|
2087
|
+
return;
|
|
2088
|
+
return {
|
|
2089
|
+
resetAt: periodEndAt,
|
|
2090
|
+
durSecs
|
|
2091
|
+
};
|
|
2092
|
+
}
|
|
2093
|
+
function rollingReset(startMs, durSecs) {
|
|
2094
|
+
if (typeof startMs !== "number" || !Number.isFinite(startMs))
|
|
2095
|
+
return;
|
|
2096
|
+
return startMs + durSecs * 1000;
|
|
2097
|
+
}
|
|
2098
|
+
function zenWindow(label, spent, limit, share, now, durSecs, resetAt) {
|
|
2099
|
+
const cap = typeof limit === "number" && limit > 0 ? limit * share : undefined;
|
|
2100
|
+
if (cap === undefined) {
|
|
2075
2101
|
return [[label, `${money(spent.cost)} \xB7 ${count(spent.requests)} req`, "base"]];
|
|
2076
2102
|
}
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
}
|
|
2084
|
-
function zenRows(usage, meta, session, fallbackName) {
|
|
2103
|
+
return windowRows(label, {
|
|
2104
|
+
cap,
|
|
2105
|
+
used: spent.cost,
|
|
2106
|
+
resetAt,
|
|
2107
|
+
exceeded: spent.cost >= cap
|
|
2108
|
+
}, now, durSecs, spent.requests > 0 ? `${count(spent.requests)} req` : undefined);
|
|
2109
|
+
}
|
|
2110
|
+
function zenRows(usage, meta, modelUsage, session, fallbackName, windows) {
|
|
2085
2111
|
if (!usage)
|
|
2086
2112
|
return [];
|
|
2113
|
+
const now = Date.now();
|
|
2087
2114
|
const oc = meta?.oc;
|
|
2088
2115
|
const rows = [["Plan", `${oc?.plan ?? "Go"} \xB7 limits per model`, "base"]];
|
|
2089
|
-
const mine = meta ? usage.models.get(modelKey(meta.name)) : undefined;
|
|
2116
|
+
const mine = usage.models.get(modelKey(fallbackName ?? "")) ?? (meta ? usage.models.get(modelKey(meta.name)) : undefined);
|
|
2090
2117
|
const limit = oc?.allowance ?? mine?.limit;
|
|
2091
2118
|
const cap = mine ? limit : undefined;
|
|
2092
|
-
rows.push(...
|
|
2093
|
-
rows.push(...
|
|
2094
|
-
|
|
2119
|
+
rows.push(...zenWindow("5-hour", mine?.fiveHour ?? usage.totals.fiveHour, cap, GO_WINDOW_SHARE.fiveHour, now, FIVE_HOUR_SECS, rollingReset(windows?.fiveHour, FIVE_HOUR_SECS)));
|
|
2120
|
+
rows.push(...zenWindow("Weekly", mine?.weekly ?? usage.totals.weekly, cap, GO_WINDOW_SHARE.weekly, now, WEEKLY_SECS, rollingReset(windows?.weekly, WEEKLY_SECS)));
|
|
2121
|
+
const period = monthPeriod(usage);
|
|
2122
|
+
rows.push(...zenWindow("Monthly", mine?.month ?? usage.totals.month, cap, GO_WINDOW_SHARE.month, now, period?.durSecs ?? 0, period?.resetAt));
|
|
2095
2123
|
rows.push(["Period", `${count(usage.totals.month.requests)} requests \xB7 ${money(usage.totals.month.cost)}`, "base"]);
|
|
2096
2124
|
rows.push(separator());
|
|
2097
2125
|
const name = meta?.name ?? fallbackName;
|
|
2098
2126
|
if (!name)
|
|
2099
2127
|
return rows;
|
|
2100
2128
|
rows.push(["Model", clip(name, valueWidth("Model")), "strong", true]);
|
|
2101
|
-
|
|
2102
|
-
const spent = session.cost > 0 ? ` \xB7 ${money(session.cost)}` : "";
|
|
2103
|
-
rows.push(["Session", `${count(session.requests)} req${spent}`, "base"]);
|
|
2104
|
-
}
|
|
2105
|
-
if (!meta)
|
|
2106
|
-
return rows;
|
|
2129
|
+
rows.push(...localUsageRows(modelUsage, session));
|
|
2107
2130
|
if (typeof limit === "number") {
|
|
2108
2131
|
rows.push(["Allowance", allowanceLabel(limit, oc?.free), "base"]);
|
|
2109
2132
|
}
|
|
2133
|
+
if (!meta)
|
|
2134
|
+
return rows;
|
|
2110
2135
|
if (oc?.rates) {
|
|
2111
2136
|
const cache = [`cache read ${rate(oc.rates.cacheRead)}`];
|
|
2112
2137
|
if (typeof oc.rates.cacheWrite === "number" && oc.rates.cacheWrite > 0) {
|
|
@@ -2355,6 +2380,53 @@ function loadModelUsage(modelID, sinceMs, path = usageDbPath(), sessionID) {
|
|
|
2355
2380
|
db.close();
|
|
2356
2381
|
}
|
|
2357
2382
|
}
|
|
2383
|
+
function loadModelWindowStart(modelID, sinceMs, path = usageDbPath()) {
|
|
2384
|
+
let db;
|
|
2385
|
+
try {
|
|
2386
|
+
db = new Database(path, {
|
|
2387
|
+
readonly: true
|
|
2388
|
+
});
|
|
2389
|
+
} catch {
|
|
2390
|
+
return null;
|
|
2391
|
+
}
|
|
2392
|
+
try {
|
|
2393
|
+
const key = modelKey(modelID);
|
|
2394
|
+
if (hasV2(db)) {
|
|
2395
|
+
const rows = db.query(`SELECT json_extract(data, '$.model.id') AS model,
|
|
2396
|
+
min(time_created) AS start
|
|
2397
|
+
FROM session_message
|
|
2398
|
+
WHERE type = 'assistant' AND time_created >= ?
|
|
2399
|
+
GROUP BY model`).all(sinceMs);
|
|
2400
|
+
for (const row of rows) {
|
|
2401
|
+
if (row.model && modelKey(row.model) === key)
|
|
2402
|
+
return row.start;
|
|
2403
|
+
}
|
|
2404
|
+
return null;
|
|
2405
|
+
}
|
|
2406
|
+
const rows = db.query(`SELECT data, time_created FROM message
|
|
2407
|
+
WHERE data LIKE '%"tokens"%' AND time_created >= ?`).all(sinceMs);
|
|
2408
|
+
let oldest = null;
|
|
2409
|
+
for (const row of rows) {
|
|
2410
|
+
let data;
|
|
2411
|
+
try {
|
|
2412
|
+
data = JSON.parse(row.data);
|
|
2413
|
+
} catch {
|
|
2414
|
+
continue;
|
|
2415
|
+
}
|
|
2416
|
+
if (data.role !== "assistant" || !data.tokens || !data.modelID)
|
|
2417
|
+
continue;
|
|
2418
|
+
if (modelKey(data.modelID) !== key)
|
|
2419
|
+
continue;
|
|
2420
|
+
if (oldest === null || row.time_created < oldest)
|
|
2421
|
+
oldest = row.time_created;
|
|
2422
|
+
}
|
|
2423
|
+
return oldest;
|
|
2424
|
+
} catch {
|
|
2425
|
+
return null;
|
|
2426
|
+
} finally {
|
|
2427
|
+
db.close();
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2358
2430
|
function loadSessionUsage(sessionID, path = usageDbPath()) {
|
|
2359
2431
|
let db;
|
|
2360
2432
|
try {
|
|
@@ -2465,6 +2537,7 @@ function useRows(activeModelId, providerID, sessionID) {
|
|
|
2465
2537
|
const [meta, setMeta] = createSignal(seededMeta());
|
|
2466
2538
|
const [modelUsage, setModelUsage] = createSignal(lastModelUsage);
|
|
2467
2539
|
const [sessionUsage, setSessionUsage] = createSignal();
|
|
2540
|
+
const [modelWindows, setModelWindows] = createSignal();
|
|
2468
2541
|
const [wasOurs, setWasOurs] = createSignal(false);
|
|
2469
2542
|
const refreshMeta = () => {
|
|
2470
2543
|
loadMeta(loadPrefs().ocPlan).then((next) => {
|
|
@@ -2485,6 +2558,15 @@ function useRows(activeModelId, providerID, sessionID) {
|
|
|
2485
2558
|
rememberModelUsage(id, fresh, session);
|
|
2486
2559
|
setModelUsage(lastModelUsage);
|
|
2487
2560
|
};
|
|
2561
|
+
const refreshModelWindows = (id) => {
|
|
2562
|
+
if (!id)
|
|
2563
|
+
return;
|
|
2564
|
+
const now = Date.now();
|
|
2565
|
+
setModelWindows({
|
|
2566
|
+
fiveHour: loadModelWindowStart(id, now - FIVE_HOUR_SECS * 1000) ?? undefined,
|
|
2567
|
+
weekly: loadModelWindowStart(id, now - WEEKLY_SECS * 1000) ?? undefined
|
|
2568
|
+
});
|
|
2569
|
+
};
|
|
2488
2570
|
let inFlight = false;
|
|
2489
2571
|
const refresh = async () => {
|
|
2490
2572
|
if (inFlight)
|
|
@@ -2503,6 +2585,8 @@ function useRows(activeModelId, providerID, sessionID) {
|
|
|
2503
2585
|
refreshModelUsage(activeModelId());
|
|
2504
2586
|
} else if (kind === "go" || kind === "zen") {
|
|
2505
2587
|
setZen(await loadZen(loadPrefs().ocPlan));
|
|
2588
|
+
refreshModelUsage(activeModelId());
|
|
2589
|
+
refreshModelWindows(activeModelId());
|
|
2506
2590
|
}
|
|
2507
2591
|
} catch {} finally {
|
|
2508
2592
|
inFlight = false;
|
|
@@ -2520,7 +2604,12 @@ function useRows(activeModelId, providerID, sessionID) {
|
|
|
2520
2604
|
createEffect(() => {
|
|
2521
2605
|
const id = activeModelId();
|
|
2522
2606
|
const session = sessionID();
|
|
2523
|
-
|
|
2607
|
+
const kind = sessionKind(providerID());
|
|
2608
|
+
if (!shows(kind) || !id)
|
|
2609
|
+
return;
|
|
2610
|
+
if (kind === "go" || kind === "zen")
|
|
2611
|
+
refreshModelWindows(id);
|
|
2612
|
+
if (!session)
|
|
2524
2613
|
return;
|
|
2525
2614
|
refreshModelUsage(id);
|
|
2526
2615
|
});
|
|
@@ -2540,7 +2629,7 @@ function useRows(activeModelId, providerID, sessionID) {
|
|
|
2540
2629
|
const found = id ? meta().get(modelKey(id)) ?? meta().get(id) : undefined;
|
|
2541
2630
|
const fallbackName = id ? id.split("/").pop() ?? id : undefined;
|
|
2542
2631
|
if (kind === "go" || kind === "zen") {
|
|
2543
|
-
return zenRows(zen(), found, sessionUsage(), fallbackName);
|
|
2632
|
+
return zenRows(zen(), found, usageFor(id), sessionUsage(), fallbackName, modelWindows());
|
|
2544
2633
|
}
|
|
2545
2634
|
const model = found ? {
|
|
2546
2635
|
...found,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jeffreyjyz/opencode-command-code",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
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. Requires the cmduse CLI for usage rendering.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|