@jeffreyjyz/opencode-command-code 0.3.9 → 0.3.11

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 CHANGED
@@ -4063,7 +4063,7 @@ var commandCodeV2 = {
4063
4063
  // package.json
4064
4064
  var package_default = {
4065
4065
  name: "@jeffreyjyz/opencode-command-code",
4066
- version: "0.3.9",
4066
+ version: "0.3.11",
4067
4067
  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.",
4068
4068
  type: "module",
4069
4069
  main: "dist/index.js",
@@ -1 +1,25 @@
1
- export declare function useRows(activeModelId: () => string | undefined, active: () => boolean): import("solid-js").Accessor<import("./rows").SidebarRow[]>;
1
+ import { type ModelUsage, type SidebarRow, type Usage } from "./rows";
2
+ /** Which provider a session is on, as far as this panel is concerned. */
3
+ export type SessionKind = "ours" | "other" | "unknown";
4
+ /**
5
+ * `unknown` is the frame during a session switch, before the host has resolved
6
+ * the new session's model. It must not be read as "another provider", or the
7
+ * panel blanks and refetches on every tab change.
8
+ */
9
+ export declare function sessionKind(providerID: string | undefined): SessionKind;
10
+ /** Keep an account snapshot for the next panel that needs it. */
11
+ export declare function rememberSnapshot(snapshot: Usage): void;
12
+ /** Rows to paint before this panel's first fetch of the session completes. */
13
+ export declare function seededRows(): SidebarRow[];
14
+ /**
15
+ * Keep the last figure for a model. Keyed canonically because the session's id
16
+ * and the stored `modelID` differ by vendor prefix and punctuation.
17
+ */
18
+ export declare function rememberModelUsage(id: string, usage: ModelUsage): void;
19
+ /**
20
+ * The remembered figure for `id`, or undefined when that model is unseen. An
21
+ * undefined id is the frame during a session switch: keeping the previous row up
22
+ * beats blanking it, the same call `wasOurs` makes for the account block.
23
+ */
24
+ export declare function seededModelUsage(id: string | undefined): ModelUsage | undefined;
25
+ export declare function useRows(activeModelId: () => string | undefined, providerID: () => string | undefined): import("solid-js").Accessor<SidebarRow[]>;
package/dist/tui.js CHANGED
@@ -2009,28 +2009,81 @@ function loadModelUsage(modelID, sinceMs, path = usageDbPath()) {
2009
2009
 
2010
2010
  // src/sidebar/useRows.ts
2011
2011
  var POLL_MS = 60000;
2012
- function useRows(activeModelId, active) {
2013
- const [usage, setUsage] = createSignal([]);
2012
+ function sessionKind(providerID) {
2013
+ if (!providerID)
2014
+ return "unknown";
2015
+ return providerID.startsWith("command-code") ? "ours" : "other";
2016
+ }
2017
+ var lastSnapshot;
2018
+ function rememberSnapshot(snapshot) {
2019
+ lastSnapshot = snapshot;
2020
+ }
2021
+ function seededRows() {
2022
+ return lastSnapshot ? usageRows(lastSnapshot) : [];
2023
+ }
2024
+ var lastModelUsage;
2025
+ function rememberModelUsage(id, usage) {
2026
+ lastModelUsage = {
2027
+ key: modelKey(id),
2028
+ usage
2029
+ };
2030
+ }
2031
+ function seededModelUsage(id) {
2032
+ if (!lastModelUsage)
2033
+ return;
2034
+ if (id === undefined)
2035
+ return lastModelUsage.usage;
2036
+ return lastModelUsage.key === modelKey(id) ? lastModelUsage.usage : undefined;
2037
+ }
2038
+ function useRows(activeModelId, providerID) {
2039
+ const [usage, setUsage] = createSignal(seededRows());
2014
2040
  const [meta, setMeta] = createSignal(new Map);
2015
- const [modelUsage, setModelUsage] = createSignal();
2041
+ const [modelUsage, setModelUsage] = createSignal(lastModelUsage);
2042
+ const [wasOurs, setWasOurs] = createSignal(false);
2016
2043
  loadMeta().then(setMeta).catch(() => {});
2044
+ const refreshModelUsage = (id, sinceMs) => {
2045
+ if (!id)
2046
+ return;
2047
+ const fresh = loadModelUsage(id, sinceMs);
2048
+ if (fresh)
2049
+ rememberModelUsage(id, fresh);
2050
+ setModelUsage(lastModelUsage);
2051
+ };
2017
2052
  const refresh = async () => {
2018
2053
  try {
2019
2054
  const snapshot = await loadUsage();
2055
+ rememberSnapshot(snapshot);
2020
2056
  setUsage(usageRows(snapshot));
2021
- const id = activeModelId();
2022
- setModelUsage(id ? loadModelUsage(id, periodStart(snapshot)) ?? undefined : undefined);
2057
+ refreshModelUsage(activeModelId(), periodStart(snapshot));
2023
2058
  } catch {}
2024
2059
  };
2025
2060
  createEffect(() => {
2026
- if (!active())
2061
+ const kind = sessionKind(providerID());
2062
+ if (kind !== "ours")
2027
2063
  return;
2064
+ setWasOurs(true);
2028
2065
  refresh();
2029
2066
  const timer = setInterval(() => void refresh(), POLL_MS);
2030
2067
  onCleanup(() => clearInterval(timer));
2031
2068
  });
2069
+ createEffect(() => {
2070
+ const id = activeModelId();
2071
+ if (sessionKind(providerID()) !== "ours" || !id)
2072
+ return;
2073
+ refreshModelUsage(id, periodStart(lastSnapshot ?? {}));
2074
+ });
2075
+ const usageFor = (id) => {
2076
+ const seen = modelUsage();
2077
+ if (seen && (id === undefined || seen.key === modelKey(id))) {
2078
+ return seen.usage;
2079
+ }
2080
+ return seededModelUsage(id);
2081
+ };
2032
2082
  return createMemo(() => {
2033
- if (!active())
2083
+ const kind = sessionKind(providerID());
2084
+ if (kind === "other")
2085
+ return [];
2086
+ if (kind === "unknown" && !wasOurs())
2034
2087
  return [];
2035
2088
  const id = activeModelId();
2036
2089
  const found = id ? meta().get(modelKey(id)) ?? meta().get(id) : undefined;
@@ -2039,17 +2092,16 @@ function useRows(activeModelId, active) {
2039
2092
  tier: found.tier ?? (id ? tierFor(id) : undefined),
2040
2093
  minPlan: id ? minPlan(id) : undefined
2041
2094
  } : undefined;
2042
- return [...usage(), separator(), ...modelRows(model, modelUsage())];
2095
+ return [...usage(), separator(), ...modelRows(model, usageFor(id))];
2043
2096
  });
2044
2097
  }
2045
2098
 
2046
2099
  // src/tui.tsx
2047
2100
  var ID = "command-code.tui";
2048
- var isOurs = (providerID) => Boolean(providerID?.startsWith("command-code"));
2049
2101
  var themed = (colors) => loadPrefs().colors ? colors : mono(colors);
2050
2102
  function PanelV1(props) {
2051
2103
  const current = () => props.api.state.session.get(props.sessionID)?.model;
2052
- const rows = useRows(() => current()?.id, () => isOurs(current()?.providerID));
2104
+ const rows = useRows(() => current()?.id, () => current()?.providerID);
2053
2105
  return _$createComponent2(Panel, {
2054
2106
  rows,
2055
2107
  colors: () => themed(legacyColors(props.api.theme.current))
@@ -2075,7 +2127,7 @@ function PanelV2(props) {
2075
2127
  ctx
2076
2128
  } = props;
2077
2129
  const current = () => ctx.data.session.get(props.sessionID)?.model;
2078
- const rows = useRows(() => current()?.id, () => isOurs(current()?.providerID));
2130
+ const rows = useRows(() => current()?.id, () => current()?.providerID);
2079
2131
  return _$createComponent2(Panel, {
2080
2132
  rows,
2081
2133
  colors: () => themed(hostColors(ctx.theme))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeffreyjyz/opencode-command-code",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
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",