opencode-usage-coach 0.13.1 → 0.13.2
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 +38 -12
- package/dist/cli.js +59 -2
- package/package.json +5 -13
package/README.md
CHANGED
|
@@ -25,32 +25,52 @@ See **[docs/architecture.md](docs/architecture.md)** for the full design.
|
|
|
25
25
|
|
|
26
26
|
## Quick Start
|
|
27
27
|
|
|
28
|
+
### 3 steps to get running
|
|
29
|
+
|
|
30
|
+
**Step 1 — Install globally (provides the `usage-coach` CLI):**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g opencode-usage-coach
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Step 2 — Add the server plugin to opencode:**
|
|
37
|
+
|
|
28
38
|
```jsonc
|
|
29
|
-
// ~/.config/opencode/opencode.json
|
|
39
|
+
// ~/.config/opencode/opencode.json
|
|
30
40
|
{ "plugin": ["opencode-usage-coach"] }
|
|
31
|
-
|
|
32
|
-
// ~/.config/opencode/tui.json — sidebar panel (point at built dist/tui.js)
|
|
33
|
-
{ "$schema": "https://opencode.ai/tui.json", "plugin": ["opencode-usage-coach/tui"] }
|
|
34
41
|
```
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
**Step 3 — Run setup (auto-configures everything else):**
|
|
37
44
|
|
|
38
45
|
```bash
|
|
39
|
-
usage-coach setup
|
|
40
|
-
usage-coach setup --json # machine-readable output (for scripts/CI)
|
|
46
|
+
usage-coach setup
|
|
41
47
|
```
|
|
42
48
|
|
|
43
|
-
This
|
|
49
|
+
This single command:
|
|
50
|
+
- Creates `~/.config/opencode-usage-coach/harness.config.json` (model config)
|
|
51
|
+
- Copies the harness agent file to `~/.config/opencode/agents/`
|
|
52
|
+
- **Auto-configures `~/.config/opencode/tui.json`** with the correct TUI plugin path
|
|
53
|
+
- Detects whether `codexbar` is installed
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
Restart opencode — you're done. The sidebar panel appears (toggle with `Alt+H`).
|
|
56
|
+
|
|
57
|
+
> **Without `npm install -g`:** The server plugin still works (opencode auto-installs it from npm), but `usage-coach setup` and the `usage-coach` CLI won't be available. You'd need to manually create `harness.config.json` and configure `tui.json` yourself.
|
|
58
|
+
|
|
59
|
+
### Quota sensing (optional but recommended)
|
|
60
|
+
|
|
61
|
+
The plugin works in **GO-only mode** out of the box (no quota sensing). To enable real-time quota monitoring, install [codexbar](https://github.com/nicepkg/codexbar):
|
|
46
62
|
|
|
47
63
|
```bash
|
|
64
|
+
# macOS / Linux
|
|
65
|
+
curl -fsSL https://raw.githubusercontent.com/nicepkg/codexbar/main/install.sh | bash
|
|
66
|
+
|
|
67
|
+
# Then configure your provider API key:
|
|
48
68
|
printf '%s' "$YOUR_PROVIDER_API_KEY" | codexbar config set-api-key --provider <id> --stdin
|
|
49
69
|
```
|
|
50
70
|
|
|
51
|
-
|
|
71
|
+
codexbar supports any provider with a usage API (OpenAI, Anthropic, Google, z.ai, etc.). Check `codexbar providers` for the full list.
|
|
52
72
|
|
|
53
|
-
|
|
73
|
+
Without codexbar, the plugin simply doesn't sense quota — all other features (harness loop, learning, domain knowledge) work normally.
|
|
54
74
|
|
|
55
75
|
## Configuration
|
|
56
76
|
|
|
@@ -89,7 +109,13 @@ See **[docs/architecture.md](docs/architecture.md)** for details on the loop, NE
|
|
|
89
109
|
|
|
90
110
|
## Troubleshooting
|
|
91
111
|
|
|
92
|
-
|
|
112
|
+
**opencode crashes on startup after adding the plugin** — Make sure you're on v0.13.1 or later. Earlier versions had a bug where opencode would crash due to named exports. Run `npm install -g opencode-usage-coach@latest`.
|
|
113
|
+
|
|
114
|
+
**TUI sidebar not showing** — Run `usage-coach setup` again. It auto-detects the TUI path and writes `tui.json`. If you installed via `npm install -g`, the path is `$(npm root -g)/opencode-usage-coach/dist/tui.js`. Never install `solid-js` in the opencode config directory.
|
|
115
|
+
|
|
116
|
+
**`usage-coach: command not found`** — You need `npm install -g opencode-usage-coach` for the CLI. The server plugin works without it, but setup and status commands require the global install.
|
|
117
|
+
|
|
118
|
+
**Model selection errors** — `generator` is required in `harness.config.json`. Run `usage-coach setup` to create it, then edit the model or use `/coach-config` at runtime.
|
|
93
119
|
|
|
94
120
|
See **[docs/troubleshooting.md](docs/troubleshooting.md)** for full diagnoses and fixes.
|
|
95
121
|
|
package/dist/cli.js
CHANGED
|
@@ -345,6 +345,7 @@ function formatDomain(r) {
|
|
|
345
345
|
}
|
|
346
346
|
var GLOBAL_CONFIG_DIR = join(homedir(), ".config", "opencode-usage-coach");
|
|
347
347
|
var OPENCODE_AGENTS_DIR = join(homedir(), ".config", "opencode", "agents");
|
|
348
|
+
var OPENCODE_TUI_CONFIG = join(homedir(), ".config", "opencode", "tui.json");
|
|
348
349
|
var DEFAULT_HARNESS_CONFIG = {
|
|
349
350
|
generator: "opencode/deepseek-v4-flash-free",
|
|
350
351
|
grader: "opencode/mimo-v2.5-free",
|
|
@@ -355,6 +356,42 @@ function resolveAgentSourceFile() {
|
|
|
355
356
|
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
356
357
|
return join(scriptDir, "..", "agents", "usage-coach-harness.md");
|
|
357
358
|
}
|
|
359
|
+
function resolveTuiPath(scriptDir) {
|
|
360
|
+
const dir = scriptDir ?? dirname(fileURLToPath(import.meta.url));
|
|
361
|
+
return join(dir, "tui.js");
|
|
362
|
+
}
|
|
363
|
+
function configureTui(tuiPath, tuiConfigPath) {
|
|
364
|
+
if (!existsSync(tuiPath)) {
|
|
365
|
+
return { action: "not-found", path: tuiPath };
|
|
366
|
+
}
|
|
367
|
+
let config = {};
|
|
368
|
+
if (existsSync(tuiConfigPath)) {
|
|
369
|
+
try {
|
|
370
|
+
config = JSON.parse(readFileSync(tuiConfigPath, "utf8"));
|
|
371
|
+
} catch {
|
|
372
|
+
config = {};
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
const plugins = Array.isArray(config["plugin"]) ? config["plugin"] : [];
|
|
376
|
+
if (plugins.includes(tuiPath)) {
|
|
377
|
+
return { action: "exists", path: tuiConfigPath };
|
|
378
|
+
}
|
|
379
|
+
const filtered = plugins.filter(
|
|
380
|
+
(p) => !p.includes("opencode-usage-coach")
|
|
381
|
+
);
|
|
382
|
+
filtered.push(tuiPath);
|
|
383
|
+
config["plugin"] = filtered;
|
|
384
|
+
if (!config["$schema"]) {
|
|
385
|
+
config["$schema"] = "https://opencode.ai/tui.json";
|
|
386
|
+
}
|
|
387
|
+
try {
|
|
388
|
+
mkdirSync(dirname(tuiConfigPath), { recursive: true });
|
|
389
|
+
writeFileSync(tuiConfigPath, JSON.stringify(config, null, 2) + "\n");
|
|
390
|
+
return { action: "configured", path: tuiConfigPath };
|
|
391
|
+
} catch {
|
|
392
|
+
return { action: "write-error", path: tuiConfigPath };
|
|
393
|
+
}
|
|
394
|
+
}
|
|
358
395
|
function detectCodexbar() {
|
|
359
396
|
try {
|
|
360
397
|
const r = spawnSync("codexbar", ["--version"], { timeout: 5e3 });
|
|
@@ -370,6 +407,7 @@ function doSetup(opts = {}) {
|
|
|
370
407
|
const configDir = opts.configDir ?? GLOBAL_CONFIG_DIR;
|
|
371
408
|
const agentsDir = opts.agentsDir ?? OPENCODE_AGENTS_DIR;
|
|
372
409
|
const agentSource = opts.agentSourceFile ?? resolveAgentSourceFile();
|
|
410
|
+
const tuiConfigPath = opts.tuiConfigPath ?? OPENCODE_TUI_CONFIG;
|
|
373
411
|
const configPath = join(configDir, "harness.config.json");
|
|
374
412
|
let configAction;
|
|
375
413
|
if (existsSync(configPath)) {
|
|
@@ -394,10 +432,13 @@ function doSetup(opts = {}) {
|
|
|
394
432
|
copyFileSync(agentSource, agentDestPath);
|
|
395
433
|
agentAction = "copied";
|
|
396
434
|
}
|
|
435
|
+
const tuiPath = resolveTuiPath(opts.scriptDir);
|
|
436
|
+
const tuiResult = configureTui(tuiPath, tuiConfigPath);
|
|
397
437
|
return {
|
|
398
438
|
harnessConfig: { action: configAction, path: configPath },
|
|
399
439
|
codexbar,
|
|
400
|
-
agentFile: { action: agentAction, path: agentDestPath }
|
|
440
|
+
agentFile: { action: agentAction, path: agentDestPath },
|
|
441
|
+
tuiConfig: tuiResult
|
|
401
442
|
};
|
|
402
443
|
}
|
|
403
444
|
function formatSetup(r) {
|
|
@@ -433,6 +474,20 @@ function formatSetup(r) {
|
|
|
433
474
|
lines.push(` Expected: ${r.agentFile.path}`);
|
|
434
475
|
}
|
|
435
476
|
lines.push("");
|
|
477
|
+
if (r.tuiConfig.action === "configured") {
|
|
478
|
+
lines.push(` \u2705 TUI plugin configured`);
|
|
479
|
+
lines.push(` ${r.tuiConfig.path}`);
|
|
480
|
+
} else if (r.tuiConfig.action === "exists") {
|
|
481
|
+
lines.push(` \u2705 TUI plugin already configured`);
|
|
482
|
+
lines.push(` ${r.tuiConfig.path}`);
|
|
483
|
+
} else if (r.tuiConfig.action === "not-found") {
|
|
484
|
+
lines.push(` \u26A0\uFE0F TUI plugin (dist/tui.js) not found`);
|
|
485
|
+
lines.push(` Run: npm install -g opencode-usage-coach`);
|
|
486
|
+
} else {
|
|
487
|
+
lines.push(` \u26A0\uFE0F Could not write TUI config`);
|
|
488
|
+
lines.push(` Manually add to ${r.tuiConfig.path}`);
|
|
489
|
+
}
|
|
490
|
+
lines.push("");
|
|
436
491
|
lines.push("Setup complete. Restart opencode to apply changes.");
|
|
437
492
|
return lines.join("\n");
|
|
438
493
|
}
|
|
@@ -551,6 +606,7 @@ if (isDirectRun) {
|
|
|
551
606
|
main();
|
|
552
607
|
}
|
|
553
608
|
export {
|
|
609
|
+
configureTui,
|
|
554
610
|
doSetup,
|
|
555
611
|
parseArgs,
|
|
556
612
|
projectStateDir,
|
|
@@ -560,5 +616,6 @@ export {
|
|
|
560
616
|
readRules,
|
|
561
617
|
readStatus,
|
|
562
618
|
resolveAgentSourceFile,
|
|
563
|
-
resolveStateDir
|
|
619
|
+
resolveStateDir,
|
|
620
|
+
resolveTuiPath
|
|
564
621
|
};
|
package/package.json
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-usage-coach",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "opencode closed-loop usage coach — quota SENSE -> coaching DECIDE -> loop ACT + TUI integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
8
8
|
"exports": {
|
|
9
|
-
".":
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
"./tui": {
|
|
14
|
-
"types": "./dist/tui.d.ts",
|
|
15
|
-
"import": "./dist/tui.js"
|
|
16
|
-
},
|
|
17
|
-
"./cli": {
|
|
18
|
-
"types": "./dist/cli.d.ts",
|
|
19
|
-
"import": "./dist/cli.js"
|
|
20
|
-
}
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./tui": "./dist/tui.js",
|
|
11
|
+
"./cli": "./dist/cli.js"
|
|
21
12
|
},
|
|
22
13
|
"bin": {
|
|
23
14
|
"usage-coach": "./dist/cli.js"
|
|
24
15
|
},
|
|
25
16
|
"scripts": {
|
|
26
17
|
"build": "tsup",
|
|
18
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm test",
|
|
27
19
|
"typecheck": "tsc --noEmit",
|
|
28
20
|
"lint": "eslint .",
|
|
29
21
|
"lint:fix": "eslint . --fix",
|