@jeffreyjyz/opencode-command-code 0.5.20 → 0.5.22
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/README.md +7 -7
- package/dist/index.js +50 -67
- package/dist/sidebar/rows.d.ts +1 -6
- package/dist/tui.js +28 -38
- package/dist/v2.d.ts +0 -6
- package/package.json +3 -3
- package/tui.js +0 -5
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Add the plugin to `opencode.json` (v2 hosts use `plugins`; v1's singular `plugin
|
|
|
25
25
|
|
|
26
26
|
```json
|
|
27
27
|
{
|
|
28
|
-
|
|
28
|
+
"plugins": ["@jeffreyjyz/opencode-command-code"]
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -67,12 +67,12 @@ Usage comes from `cmduse` polled every 5 seconds, read from opencode's message s
|
|
|
67
67
|
|
|
68
68
|
Each command passes its arguments through to the CLI that owns it, and each has an agent-facing tool of the same name, so the model can fetch the same text without you typing a slash command.
|
|
69
69
|
|
|
70
|
-
| Command
|
|
71
|
-
|
|
72
|
-
| `/cmd-usage`
|
|
73
|
-
| `/ocuse-usage`
|
|
74
|
-
| `/arkuse-usage` | `arkuse_usage` | `arkuse` — Volcengine ARK Agent Plan meters in AFP; empty args mean `-1`
|
|
75
|
-
| —
|
|
70
|
+
| Command | Tool | Spawns |
|
|
71
|
+
| --------------- | -------------- | ----------------------------------------------------------------------------- |
|
|
72
|
+
| `/cmd-usage` | `cmd_usage` | `cmduse` — plan, credits, windows, billing period; `plans` for the plan table |
|
|
73
|
+
| `/ocuse-usage` | `ocuse_usage` | `ocuse` — OpenCode Go/Zen meters and per-model spend; empty args mean `-1` |
|
|
74
|
+
| `/arkuse-usage` | `arkuse_usage` | `arkuse` — Volcengine ARK Agent Plan meters in AFP; empty args mean `-1` |
|
|
75
|
+
| — | `mpc_prices` | `mpc` — per-model price comparison across Command Code and OpenCode Go plans |
|
|
76
76
|
|
|
77
77
|
A bare `ocuse` or `arkuse` is a live watch loop that would never return to the dialog, so an empty argument means the one-shot dashboard.
|
|
78
78
|
|
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.22",
|
|
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",
|
|
@@ -2426,7 +2426,8 @@ var package_default = {
|
|
|
2426
2426
|
scripts: {
|
|
2427
2427
|
build: "rm -rf dist && bun build src/index.ts --outdir dist --target bun --external @opencode-ai/plugin --external @opencode/plugin --external @opencode/plugin/tui && bun scripts/build-tui.ts && tsc -p tsconfig.build.json",
|
|
2428
2428
|
test: "bun test",
|
|
2429
|
-
|
|
2429
|
+
lint: "biome lint --write .",
|
|
2430
|
+
typecheck: "bun check",
|
|
2430
2431
|
"build:tui": "bun scripts/build-tui.ts",
|
|
2431
2432
|
"extract:catalog": "bun scripts/extract-catalog.ts"
|
|
2432
2433
|
},
|
|
@@ -2445,7 +2446,6 @@ var package_default = {
|
|
|
2445
2446
|
},
|
|
2446
2447
|
files: [
|
|
2447
2448
|
"dist",
|
|
2448
|
-
"tui.js",
|
|
2449
2449
|
"LICENSE"
|
|
2450
2450
|
],
|
|
2451
2451
|
keywords: [
|
|
@@ -3361,7 +3361,13 @@ function runOnce(bin, args, opts, name = "cmduse") {
|
|
|
3361
3361
|
if (settled)
|
|
3362
3362
|
return;
|
|
3363
3363
|
settled = true;
|
|
3364
|
-
child.
|
|
3364
|
+
child.stdout.removeAllListeners("data");
|
|
3365
|
+
child.stderr.removeAllListeners("data");
|
|
3366
|
+
child.removeAllListeners("error");
|
|
3367
|
+
child.removeAllListeners("close");
|
|
3368
|
+
child.kill("SIGTERM");
|
|
3369
|
+
const killTimer = setTimeout(() => child.kill("SIGKILL"), 3000);
|
|
3370
|
+
killTimer.unref();
|
|
3365
3371
|
reject(new Error(`${name} ${args.join(" ")}: timed out after ${opts.timeoutMs}ms`));
|
|
3366
3372
|
}, opts.timeoutMs);
|
|
3367
3373
|
const onAbort = () => child.kill("SIGTERM");
|
|
@@ -3373,6 +3379,10 @@ function runOnce(bin, args, opts, name = "cmduse") {
|
|
|
3373
3379
|
if (timer)
|
|
3374
3380
|
clearTimeout(timer);
|
|
3375
3381
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
3382
|
+
child.stdout.removeAllListeners("data");
|
|
3383
|
+
child.stderr.removeAllListeners("data");
|
|
3384
|
+
child.removeAllListeners("error");
|
|
3385
|
+
child.removeAllListeners("close");
|
|
3376
3386
|
fn();
|
|
3377
3387
|
};
|
|
3378
3388
|
child.stdout.on("data", (d) => out.push(d));
|
|
@@ -3615,9 +3625,7 @@ var gating_default = {
|
|
|
3615
3625
|
},
|
|
3616
3626
|
plans: {
|
|
3617
3627
|
"individual-go": {
|
|
3618
|
-
allowedCategories: [
|
|
3619
|
-
"opensource"
|
|
3620
|
-
],
|
|
3628
|
+
allowedCategories: ["opensource"],
|
|
3621
3629
|
blockedModels: [
|
|
3622
3630
|
"vercel-ai-gateway:meta/muse-spark-1.2",
|
|
3623
3631
|
"vercel-ai-gateway:meta/muse-spark-1.3",
|
|
@@ -3631,9 +3639,7 @@ var gating_default = {
|
|
|
3631
3639
|
]
|
|
3632
3640
|
},
|
|
3633
3641
|
"individual-go-v1": {
|
|
3634
|
-
allowedCategories: [
|
|
3635
|
-
"opensource"
|
|
3636
|
-
],
|
|
3642
|
+
allowedCategories: ["opensource"],
|
|
3637
3643
|
blockedModels: [
|
|
3638
3644
|
"vercel-ai-gateway:meta/muse-spark-1.2",
|
|
3639
3645
|
"vercel-ai-gateway:meta/muse-spark-1.3",
|
|
@@ -3647,16 +3653,11 @@ var gating_default = {
|
|
|
3647
3653
|
]
|
|
3648
3654
|
},
|
|
3649
3655
|
"individual-goat": {
|
|
3650
|
-
allowedCategories: [
|
|
3651
|
-
"opensource"
|
|
3652
|
-
],
|
|
3656
|
+
allowedCategories: ["opensource"],
|
|
3653
3657
|
blockedModels: []
|
|
3654
3658
|
},
|
|
3655
3659
|
"individual-pro": {
|
|
3656
|
-
allowedCategories: [
|
|
3657
|
-
"premium",
|
|
3658
|
-
"opensource"
|
|
3659
|
-
],
|
|
3660
|
+
allowedCategories: ["premium", "opensource"],
|
|
3660
3661
|
blockedModels: [
|
|
3661
3662
|
"anthropic:claude-fable-5-1",
|
|
3662
3663
|
"anthropic:claude-fable-5",
|
|
@@ -3672,10 +3673,7 @@ var gating_default = {
|
|
|
3672
3673
|
]
|
|
3673
3674
|
},
|
|
3674
3675
|
"individual-pro-v1": {
|
|
3675
|
-
allowedCategories: [
|
|
3676
|
-
"premium",
|
|
3677
|
-
"opensource"
|
|
3678
|
-
],
|
|
3676
|
+
allowedCategories: ["premium", "opensource"],
|
|
3679
3677
|
blockedModels: [
|
|
3680
3678
|
"anthropic:claude-fable-5-1",
|
|
3681
3679
|
"anthropic:claude-fable-5",
|
|
@@ -3691,33 +3689,19 @@ var gating_default = {
|
|
|
3691
3689
|
]
|
|
3692
3690
|
},
|
|
3693
3691
|
"individual-provider": {
|
|
3694
|
-
allowedCategories: [
|
|
3695
|
-
|
|
3696
|
-
"opensource"
|
|
3697
|
-
],
|
|
3698
|
-
blockedModels: [
|
|
3699
|
-
"openai:gpt-6.1-sol"
|
|
3700
|
-
]
|
|
3692
|
+
allowedCategories: ["premium", "opensource"],
|
|
3693
|
+
blockedModels: ["openai:gpt-6.1-sol"]
|
|
3701
3694
|
},
|
|
3702
3695
|
"individual-max": {
|
|
3703
|
-
allowedCategories: [
|
|
3704
|
-
"premium",
|
|
3705
|
-
"opensource"
|
|
3706
|
-
],
|
|
3696
|
+
allowedCategories: ["premium", "opensource"],
|
|
3707
3697
|
blockedModels: []
|
|
3708
3698
|
},
|
|
3709
3699
|
"individual-ultra": {
|
|
3710
|
-
allowedCategories: [
|
|
3711
|
-
"premium",
|
|
3712
|
-
"opensource"
|
|
3713
|
-
],
|
|
3700
|
+
allowedCategories: ["premium", "opensource"],
|
|
3714
3701
|
blockedModels: []
|
|
3715
3702
|
},
|
|
3716
3703
|
"teams-pro": {
|
|
3717
|
-
allowedCategories: [
|
|
3718
|
-
"premium",
|
|
3719
|
-
"opensource"
|
|
3720
|
-
],
|
|
3704
|
+
allowedCategories: ["premium", "opensource"],
|
|
3721
3705
|
blockedModels: []
|
|
3722
3706
|
}
|
|
3723
3707
|
},
|
|
@@ -4046,12 +4030,7 @@ function sseDecoder(onEvent) {
|
|
|
4046
4030
|
var text = (v) => typeof v === "string" ? v : "";
|
|
4047
4031
|
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
4048
4032
|
var rec = (v) => v && typeof v === "object" ? v : {};
|
|
4049
|
-
var TOOL_FINISH = new Set([
|
|
4050
|
-
"tool_use",
|
|
4051
|
-
"tool_calls",
|
|
4052
|
-
"tool-call",
|
|
4053
|
-
"function_call"
|
|
4054
|
-
]);
|
|
4033
|
+
var TOOL_FINISH = new Set(["tool_use", "tool_calls", "tool-call", "function_call"]);
|
|
4055
4034
|
var LENGTH_FINISH = new Set([
|
|
4056
4035
|
"length",
|
|
4057
4036
|
"max_tokens",
|
|
@@ -4100,9 +4079,7 @@ function anthropicReducer() {
|
|
|
4100
4079
|
const open = (index, kind) => {
|
|
4101
4080
|
const id = `${kind === "text" ? "text" : "reasoning"}-${index}`;
|
|
4102
4081
|
blocks.set(index, { type: kind, id });
|
|
4103
|
-
return [
|
|
4104
|
-
{ type: kind === "text" ? "text-start" : "reasoning-start", id }
|
|
4105
|
-
];
|
|
4082
|
+
return [{ type: kind === "text" ? "text-start" : "reasoning-start", id }];
|
|
4106
4083
|
};
|
|
4107
4084
|
return {
|
|
4108
4085
|
feed(event) {
|
|
@@ -4143,19 +4120,13 @@ function anthropicReducer() {
|
|
|
4143
4120
|
if (textDelta) {
|
|
4144
4121
|
const parts = block?.type === "text" ? [] : open(index, "text");
|
|
4145
4122
|
const id = blocks.get(index)?.id ?? `text-${index}`;
|
|
4146
|
-
return [
|
|
4147
|
-
...parts,
|
|
4148
|
-
{ type: "text-delta", id, delta: textDelta }
|
|
4149
|
-
];
|
|
4123
|
+
return [...parts, { type: "text-delta", id, delta: textDelta }];
|
|
4150
4124
|
}
|
|
4151
4125
|
const thinking = text(delta.thinking);
|
|
4152
4126
|
if (thinking) {
|
|
4153
4127
|
const parts = block?.type === "thinking" ? [] : open(index, "thinking");
|
|
4154
4128
|
const id = blocks.get(index)?.id ?? `reasoning-${index}`;
|
|
4155
|
-
return [
|
|
4156
|
-
...parts,
|
|
4157
|
-
{ type: "reasoning-delta", id, delta: thinking }
|
|
4158
|
-
];
|
|
4129
|
+
return [...parts, { type: "reasoning-delta", id, delta: thinking }];
|
|
4159
4130
|
}
|
|
4160
4131
|
const partial = text(delta.partial_json);
|
|
4161
4132
|
if (partial && block?.type === "tool_use") {
|
|
@@ -4382,11 +4353,7 @@ function openaiReducer() {
|
|
|
4382
4353
|
return parts;
|
|
4383
4354
|
},
|
|
4384
4355
|
close() {
|
|
4385
|
-
const parts = [
|
|
4386
|
-
...closeReasoning(),
|
|
4387
|
-
...closeText(),
|
|
4388
|
-
...flushTools()
|
|
4389
|
-
];
|
|
4356
|
+
const parts = [...closeReasoning(), ...closeText(), ...flushTools()];
|
|
4390
4357
|
if (pending && !finished) {
|
|
4391
4358
|
finished = true;
|
|
4392
4359
|
parts.push({
|
|
@@ -4914,6 +4881,9 @@ async function credentialKey(ctx) {
|
|
|
4914
4881
|
return;
|
|
4915
4882
|
}
|
|
4916
4883
|
}
|
|
4884
|
+
var v2Controller;
|
|
4885
|
+
var v2FirstRefresh;
|
|
4886
|
+
var v2Timer;
|
|
4917
4887
|
var commandCodeV2 = {
|
|
4918
4888
|
id: PLUGIN_ID,
|
|
4919
4889
|
async setup(ctx) {
|
|
@@ -4953,7 +4923,7 @@ var commandCodeV2 = {
|
|
|
4953
4923
|
}
|
|
4954
4924
|
const seed = staticSeedModels();
|
|
4955
4925
|
const cached = await readModelsCache();
|
|
4956
|
-
if (cached) {
|
|
4926
|
+
if (cached && typeof cached.fetchedAt === "number" && Date.now() - cached.fetchedAt < MODELS_CACHE_TTL_MS) {
|
|
4957
4927
|
seed["command-code-anthropic"] = mergeModels(seed["command-code-anthropic"], cached.claude.map((m) => toV2Model(m, LANES[0])));
|
|
4958
4928
|
seed["command-code-openai"] = mergeModels(seed["command-code-openai"], cached.open.map((m) => toV2Model(m, LANES[1])));
|
|
4959
4929
|
}
|
|
@@ -5085,7 +5055,14 @@ var commandCodeV2 = {
|
|
|
5085
5055
|
if (!localKey && !hasConnection) {
|
|
5086
5056
|
console.warn(`[command-code] no API key found. Run /connect and choose "${INTEGRATION_NAME}", or \`cmd login\` (~/.commandcode/auth.json), or set CMD_API_KEY.`);
|
|
5087
5057
|
}
|
|
5058
|
+
if (v2Controller)
|
|
5059
|
+
v2Controller.abort();
|
|
5060
|
+
if (v2FirstRefresh)
|
|
5061
|
+
clearTimeout(v2FirstRefresh);
|
|
5062
|
+
if (v2Timer)
|
|
5063
|
+
clearInterval(v2Timer);
|
|
5088
5064
|
const controller = new AbortController;
|
|
5065
|
+
v2Controller = controller;
|
|
5089
5066
|
let refreshing = false;
|
|
5090
5067
|
let appliedClaude = cached?.claude ?? [];
|
|
5091
5068
|
let appliedOpen = cached?.open ?? [];
|
|
@@ -5137,12 +5114,18 @@ var commandCodeV2 = {
|
|
|
5137
5114
|
canTransform = true;
|
|
5138
5115
|
}
|
|
5139
5116
|
};
|
|
5140
|
-
|
|
5141
|
-
|
|
5117
|
+
v2FirstRefresh = setTimeout(() => void refresh(), 3000);
|
|
5118
|
+
v2Timer = setInterval(() => void refresh(), 30 * 60 * 1000);
|
|
5142
5119
|
return () => {
|
|
5143
5120
|
controller.abort();
|
|
5144
|
-
|
|
5145
|
-
|
|
5121
|
+
if (v2FirstRefresh)
|
|
5122
|
+
clearTimeout(v2FirstRefresh);
|
|
5123
|
+
if (v2Timer)
|
|
5124
|
+
clearInterval(v2Timer);
|
|
5125
|
+
if (v2Controller === controller)
|
|
5126
|
+
v2Controller = undefined;
|
|
5127
|
+
v2FirstRefresh = undefined;
|
|
5128
|
+
v2Timer = undefined;
|
|
5146
5129
|
};
|
|
5147
5130
|
}
|
|
5148
5131
|
};
|
package/dist/sidebar/rows.d.ts
CHANGED
|
@@ -11,12 +11,7 @@ export type Tone = "base" | "muted" | "strong" | "ok" | "warn" | "crit";
|
|
|
11
11
|
* A row. `headline` marks the two rows whose label names the thing the panel is
|
|
12
12
|
* about (the plan, the active model); the panel colours their labels apart.
|
|
13
13
|
*/
|
|
14
|
-
export type SidebarRow = [
|
|
15
|
-
label: string,
|
|
16
|
-
value: string,
|
|
17
|
-
tone?: Tone,
|
|
18
|
-
headline?: true
|
|
19
|
-
];
|
|
14
|
+
export type SidebarRow = [label: string, value: string, tone?: Tone, headline?: true];
|
|
20
15
|
/** Headroom severity: comfortable to 70%, tight to 90%, over after that. */
|
|
21
16
|
export declare function pctTone(pct: number): Tone;
|
|
22
17
|
/**
|
package/dist/tui.js
CHANGED
|
@@ -124,7 +124,13 @@ function runOnce(bin, args, opts, name = "cmduse") {
|
|
|
124
124
|
if (settled)
|
|
125
125
|
return;
|
|
126
126
|
settled = true;
|
|
127
|
-
child.
|
|
127
|
+
child.stdout.removeAllListeners("data");
|
|
128
|
+
child.stderr.removeAllListeners("data");
|
|
129
|
+
child.removeAllListeners("error");
|
|
130
|
+
child.removeAllListeners("close");
|
|
131
|
+
child.kill("SIGTERM");
|
|
132
|
+
const killTimer = setTimeout(() => child.kill("SIGKILL"), 3000);
|
|
133
|
+
killTimer.unref();
|
|
128
134
|
reject(new Error(`${name} ${args.join(" ")}: timed out after ${opts.timeoutMs}ms`));
|
|
129
135
|
}, opts.timeoutMs);
|
|
130
136
|
const onAbort = () => child.kill("SIGTERM");
|
|
@@ -138,6 +144,10 @@ function runOnce(bin, args, opts, name = "cmduse") {
|
|
|
138
144
|
if (timer)
|
|
139
145
|
clearTimeout(timer);
|
|
140
146
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
147
|
+
child.stdout.removeAllListeners("data");
|
|
148
|
+
child.stderr.removeAllListeners("data");
|
|
149
|
+
child.removeAllListeners("error");
|
|
150
|
+
child.removeAllListeners("close");
|
|
141
151
|
fn();
|
|
142
152
|
};
|
|
143
153
|
child.stdout.on("data", (d) => out.push(d));
|
|
@@ -345,9 +355,7 @@ var gating_default = {
|
|
|
345
355
|
},
|
|
346
356
|
plans: {
|
|
347
357
|
"individual-go": {
|
|
348
|
-
allowedCategories: [
|
|
349
|
-
"opensource"
|
|
350
|
-
],
|
|
358
|
+
allowedCategories: ["opensource"],
|
|
351
359
|
blockedModels: [
|
|
352
360
|
"vercel-ai-gateway:meta/muse-spark-1.2",
|
|
353
361
|
"vercel-ai-gateway:meta/muse-spark-1.3",
|
|
@@ -361,9 +369,7 @@ var gating_default = {
|
|
|
361
369
|
]
|
|
362
370
|
},
|
|
363
371
|
"individual-go-v1": {
|
|
364
|
-
allowedCategories: [
|
|
365
|
-
"opensource"
|
|
366
|
-
],
|
|
372
|
+
allowedCategories: ["opensource"],
|
|
367
373
|
blockedModels: [
|
|
368
374
|
"vercel-ai-gateway:meta/muse-spark-1.2",
|
|
369
375
|
"vercel-ai-gateway:meta/muse-spark-1.3",
|
|
@@ -377,16 +383,11 @@ var gating_default = {
|
|
|
377
383
|
]
|
|
378
384
|
},
|
|
379
385
|
"individual-goat": {
|
|
380
|
-
allowedCategories: [
|
|
381
|
-
"opensource"
|
|
382
|
-
],
|
|
386
|
+
allowedCategories: ["opensource"],
|
|
383
387
|
blockedModels: []
|
|
384
388
|
},
|
|
385
389
|
"individual-pro": {
|
|
386
|
-
allowedCategories: [
|
|
387
|
-
"premium",
|
|
388
|
-
"opensource"
|
|
389
|
-
],
|
|
390
|
+
allowedCategories: ["premium", "opensource"],
|
|
390
391
|
blockedModels: [
|
|
391
392
|
"anthropic:claude-fable-5-1",
|
|
392
393
|
"anthropic:claude-fable-5",
|
|
@@ -402,10 +403,7 @@ var gating_default = {
|
|
|
402
403
|
]
|
|
403
404
|
},
|
|
404
405
|
"individual-pro-v1": {
|
|
405
|
-
allowedCategories: [
|
|
406
|
-
"premium",
|
|
407
|
-
"opensource"
|
|
408
|
-
],
|
|
406
|
+
allowedCategories: ["premium", "opensource"],
|
|
409
407
|
blockedModels: [
|
|
410
408
|
"anthropic:claude-fable-5-1",
|
|
411
409
|
"anthropic:claude-fable-5",
|
|
@@ -421,33 +419,19 @@ var gating_default = {
|
|
|
421
419
|
]
|
|
422
420
|
},
|
|
423
421
|
"individual-provider": {
|
|
424
|
-
allowedCategories: [
|
|
425
|
-
|
|
426
|
-
"opensource"
|
|
427
|
-
],
|
|
428
|
-
blockedModels: [
|
|
429
|
-
"openai:gpt-6.1-sol"
|
|
430
|
-
]
|
|
422
|
+
allowedCategories: ["premium", "opensource"],
|
|
423
|
+
blockedModels: ["openai:gpt-6.1-sol"]
|
|
431
424
|
},
|
|
432
425
|
"individual-max": {
|
|
433
|
-
allowedCategories: [
|
|
434
|
-
"premium",
|
|
435
|
-
"opensource"
|
|
436
|
-
],
|
|
426
|
+
allowedCategories: ["premium", "opensource"],
|
|
437
427
|
blockedModels: []
|
|
438
428
|
},
|
|
439
429
|
"individual-ultra": {
|
|
440
|
-
allowedCategories: [
|
|
441
|
-
"premium",
|
|
442
|
-
"opensource"
|
|
443
|
-
],
|
|
430
|
+
allowedCategories: ["premium", "opensource"],
|
|
444
431
|
blockedModels: []
|
|
445
432
|
},
|
|
446
433
|
"teams-pro": {
|
|
447
|
-
allowedCategories: [
|
|
448
|
-
"premium",
|
|
449
|
-
"opensource"
|
|
450
|
-
],
|
|
434
|
+
allowedCategories: ["premium", "opensource"],
|
|
451
435
|
blockedModels: []
|
|
452
436
|
}
|
|
453
437
|
},
|
|
@@ -2589,12 +2573,14 @@ async function loadZen(plan = OC_PLAN_DEFAULT) {
|
|
|
2589
2573
|
}
|
|
2590
2574
|
var arkCache;
|
|
2591
2575
|
async function loadArk() {
|
|
2576
|
+
const key = "default";
|
|
2592
2577
|
const now = Date.now();
|
|
2593
|
-
if (arkCache && now - arkCache.at < ARK_SNAPSHOT_TTL_MS) {
|
|
2578
|
+
if (arkCache && arkCache.key === key && now - arkCache.at < ARK_SNAPSHOT_TTL_MS) {
|
|
2594
2579
|
return arkCache.usage;
|
|
2595
2580
|
}
|
|
2596
2581
|
const usage = parseArkJson(await runArkuse("-1 --json", SIDEBAR_OPTS));
|
|
2597
2582
|
arkCache = {
|
|
2583
|
+
key,
|
|
2598
2584
|
at: now,
|
|
2599
2585
|
usage
|
|
2600
2586
|
};
|
|
@@ -3022,9 +3008,13 @@ function PanelV2(props) {
|
|
|
3022
3008
|
colors: () => themed(hostColors(ctx.theme))
|
|
3023
3009
|
});
|
|
3024
3010
|
}
|
|
3011
|
+
var tuiSetupSeen = new WeakSet;
|
|
3025
3012
|
var commandCodeTui = {
|
|
3026
3013
|
id: TUI_ID,
|
|
3027
3014
|
setup(ctx) {
|
|
3015
|
+
if (tuiSetupSeen.has(ctx))
|
|
3016
|
+
return;
|
|
3017
|
+
tuiSetupSeen.add(ctx);
|
|
3028
3018
|
ctx.ui.slot({
|
|
3029
3019
|
append: "sidebar.content",
|
|
3030
3020
|
render: (input) => _$createComponent2(PanelV2, {
|
package/dist/v2.d.ts
CHANGED
|
@@ -29,11 +29,5 @@ type CredentialContext = {
|
|
|
29
29
|
* back to CMD_API_KEY / ~/.commandcode/auth.json. Resolved per call — a
|
|
30
30
|
* /connect mid-session must be picked up. */
|
|
31
31
|
export declare function credentialKey(ctx: CredentialContext): Promise<string | undefined>;
|
|
32
|
-
/**
|
|
33
|
-
* opencode validates the plugin *by decoding* the default export against its
|
|
34
|
-
* own `Plugin` interface (identity `define` on both sides), so the package is
|
|
35
|
-
* only needed for types. Keeps the runtime dependency surface to opencode's
|
|
36
|
-
* own rewrite list (@opentui/*, solid-js).
|
|
37
|
-
*/
|
|
38
32
|
export declare const commandCodeV2: PluginNs.Plugin;
|
|
39
33
|
export {};
|
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.22",
|
|
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",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "rm -rf dist && bun build src/index.ts --outdir dist --target bun --external @opencode-ai/plugin --external @opencode/plugin --external @opencode/plugin/tui && bun scripts/build-tui.ts && tsc -p tsconfig.build.json",
|
|
14
14
|
"test": "bun test",
|
|
15
|
-
"
|
|
15
|
+
"lint": "biome lint --write .",
|
|
16
|
+
"typecheck": "bun check",
|
|
16
17
|
"build:tui": "bun scripts/build-tui.ts",
|
|
17
18
|
"extract:catalog": "bun scripts/extract-catalog.ts"
|
|
18
19
|
},
|
|
@@ -31,7 +32,6 @@
|
|
|
31
32
|
},
|
|
32
33
|
"files": [
|
|
33
34
|
"dist",
|
|
34
|
-
"tui.js",
|
|
35
35
|
"LICENSE"
|
|
36
36
|
],
|
|
37
37
|
"keywords": [
|
package/tui.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
// Entry shim for local/directory plugin loading: opencode resolves the TUI
|
|
2
|
-
// half as a literal `tui.js` beside the package root (package `exports`
|
|
3
|
-
// are only consulted for npm-installed plugins). Keep this file in sync with
|
|
4
|
-
// the built ./tui output.
|
|
5
|
-
export { default } from "./dist/tui.js";
|