@aliyunrds/ctxdb 0.0.9 → 0.0.10

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 CHANGED
@@ -5,10 +5,12 @@ Unified access layer for RDS ContextDatabase. One `ctxdb` CLI (memory + KB ops),
5
5
  | Agent | Hooks | Skill install path | Skill style |
6
6
  |---|---|---|---|
7
7
  | **qoder** | ✅ UserPromptSubmit + Stop + SessionStart | `~/.qoder/skills/ctxdb/` | hooks-driven (auto capture/recall) |
8
+ | **qoderwork** | ✅ UserPromptSubmit + Stop + SessionStart | `~/.qoderwork/skills/ctxdb/` | hooks-driven (auto capture/recall) |
8
9
  | **codex** | ✅ UserPromptSubmit + Stop + SessionStart | `~/.codex/skills/ctxdb/` | hooks-driven (auto capture/recall) |
9
10
  | **claude** | ✅ UserPromptSubmit + Stop + SessionStart | `~/.claude/skills/ctxdb/` | hooks-driven (auto capture/recall) |
11
+ | **opencode** | Plugin shim (`~/.config/opencode/plugins/ctxdb.ts`) | `~/.config/opencode/skills/` | in-process plugin (auto capture/recall + KB catalog injection) |
10
12
 
11
- Config and logs live under `~/.ctxdb/`. `~/.ctxdb/ctxdb.json` is one file, but runtime config is isolated per agent under `agents.qoder`, `agents.codex`, and `agents.claude`. (Pre-2026-05-23 installs used `~/.ctxdb.json` at the home root; running `ctxdb setup --agent <name>` migrates the file into the selected agent section.)
13
+ Config and logs live under `~/.ctxdb/`. `~/.ctxdb/ctxdb.json` is one file, but runtime config is isolated per agent under `agents.qoder`, `agents.qoderwork`, `agents.codex`, `agents.claude`, and `agents.opencode`. (Pre-2026-05-23 installs used `~/.ctxdb.json` at the home root; running `ctxdb setup --agent <name>` migrates the file into the selected agent section.)
12
14
 
13
15
  ## Install
14
16
 
@@ -17,10 +19,14 @@ npm install -g @aliyunrds/ctxdb
17
19
 
18
20
  # Qoder (hooks + skill)
19
21
  ctxdb setup --agent qoder --api-key ctxdb-...
22
+ # QoderWork (hooks + skill)
23
+ ctxdb setup --agent qoderwork --api-key ctxdb-...
20
24
  # Codex (hooks + skill)
21
25
  ctxdb setup --agent codex --api-key ctxdb-...
22
26
  # Claude Code (hooks + skill)
23
27
  ctxdb setup --agent claude --api-key ctxdb-...
28
+ # OpenCode (plugin shim + skill)
29
+ ctxdb setup --agent opencode --api-key ctxdb-...
24
30
 
25
31
  # --base-url defaults to https://context-database.aliyuncs.com (public prod).
26
32
  # Pass --base-url <host> only if you target a different deployment
@@ -33,13 +39,13 @@ ctxdb setup --agent claude --api-key ctxdb-...
33
39
  ctxdb status --json
34
40
  ```
35
41
 
36
- Setup first checks that the target agent home exists (`~/.qoder`, `~/.codex`, or `~/.claude`). If the directory is missing, install or start that agent once before running `ctxdb setup --agent <name>`.
42
+ Setup first checks that the target agent home exists (`~/.qoder`, `~/.qoderwork`, `~/.codex`, or `~/.claude`). If the directory is missing, install or start that agent once before running `ctxdb setup --agent <name>`. OpenCode is XDG-style: setup creates `~/.config/opencode` and `~/.config/opencode/plugins` when they are missing.
37
43
 
38
- For **qoder**, **codex**, and **claude**, restart the harness (CLI: just exit + restart; app: Cmd+R or quit/relaunch) so it picks up the new hooks/skill. For **codex**, setup also writes `[features].hooks = true` into `~/.codex/config.toml` (creating the file if missing) — Codex won't fire any hook entries without it. On first use Codex may prompt you to trust the new hook commands.
44
+ For **qoder**, **qoderwork**, **codex**, and **claude**, restart the harness (CLI: just exit + restart; app: Cmd+R or quit/relaunch) so it picks up the new hooks/skill. For **codex**, setup also writes `[features].hooks = true` into `~/.codex/config.toml` (creating the file if missing) — Codex won't fire any hook entries without it. On first use Codex may prompt you to trust the new hook commands. For **opencode**, restart OpenCode so it loads `~/.config/opencode/plugins/ctxdb.ts`.
39
45
 
40
46
  ## What it does
41
47
 
42
- For **qoder**, **codex**, and **claude**, hooks fire automatically:
48
+ For **qoder**, **qoderwork**, **codex**, and **claude**, hooks fire automatically:
43
49
 
44
50
  | Trigger | Hook | What runs |
45
51
  |---|---|---|
@@ -49,6 +55,8 @@ For **qoder**, **codex**, and **claude**, hooks fire automatically:
49
55
 
50
56
  Implementation note: qoder/Claude consume the JSON `hookSpecificOutput.additionalContext` shape; Codex has been verified on this machine through `~/.codex/hooks.json`, `[features].hooks = true`, and hook audit logs, where non-empty stdout from `UserPromptSubmit`/`SessionStart` is treated as injected context. The same hook core is shared; setup passes `--agent=<name>` so each hook reads its own config section.
51
57
 
58
+ For **opencode**, `ctxdb setup --agent opencode` writes a small re-export shim at `~/.config/opencode/plugins/ctxdb.ts`. The shim points into this package's bundled `dist/opencode/src/index.ts`, so `npm update -g @aliyunrds/ctxdb` updates the plugin implementation without copying source into the user config directory. `ctxdb upgrade --agent opencode` refreshes the absolute shim target after package moves.
59
+
52
60
  ## CLI
53
61
 
54
62
  `ctxdb` ships 18 subcommands:
@@ -59,7 +67,7 @@ Implementation note: qoder/Claude consume the JSON `hookSpecificOutput.additiona
59
67
 
60
68
  See `ctxdb --help`.
61
69
 
62
- `setup` without `--agent` writes `agents.default` in `~/.ctxdb/ctxdb.json` (CLI-only, no hooks or skills); with `--agent <qoder|codex|claude>` it writes agent config and installs hooks + skills for that harness. Memory and KB commands also accept `--agent <name>` so agents use their own config section; when omitted, `CTXDB_AGENT` env wins, otherwise `agents.default` is used. `uninstall` without `--agent` loops every supported agent; with `--agent <name>` it targets just that one. `teardown` is an alias for `uninstall`.
70
+ `setup` without `--agent` writes `agents.default` in `~/.ctxdb/ctxdb.json` (CLI-only, no hooks or skills); with `--agent <qoder|qoderwork|codex|claude|opencode>` it writes agent config and installs hooks/plugins + skills for that harness. Memory and KB commands also accept `--agent <name>` so agents use their own config section; when omitted, `CTXDB_AGENT` env wins, otherwise `agents.default` is used. `uninstall` without `--agent` loops every supported agent; with `--agent <name>` it targets just that one. `teardown` is an alias for `uninstall`.
63
71
 
64
72
  `memory add … --no-infer` stores the text verbatim (skips server-side LLM
65
73
  fact-extraction). Use it when the user explicitly asks for a verbatim
@@ -94,13 +102,15 @@ Lives at `~/.ctxdb/ctxdb.json` (co-located with logs at `~/.ctxdb/logs/`). Schem
94
102
  "knowledge_top_k": 6,
95
103
  "debug": false
96
104
  },
105
+ "qoderwork": { "...": "same schema, independent values" },
97
106
  "codex": { "...": "same schema, independent values" },
98
- "claude": { "...": "same schema, independent values" }
107
+ "claude": { "...": "same schema, independent values" },
108
+ "opencode": { "...": "same schema, independent values" }
99
109
  }
100
110
  }
101
111
  ```
102
112
 
103
- Agent selection is driven by `--agent <qoder|codex|claude|default>` on every CLI invocation, falling back to `CTXDB_AGENT` env, then to `default`. There is no `default_agent` field — older installs that have one written get it dropped on the next save.
113
+ Agent selection is driven by `--agent <qoder|qoderwork|codex|claude|opencode|default>` on every CLI invocation, falling back to `CTXDB_AGENT` env, then to `default`. There is no `default_agent` field — older installs that have one written get it dropped on the next save.
104
114
 
105
115
  Field reference:
106
116
 
@@ -121,6 +131,8 @@ Env-var overrides apply to the selected agent config (env wins): `CTXDB_AGENT` /
121
131
 
122
132
  ```
123
133
  @aliyunrds/ctxdb ← this package (CLI + setup + hooks + skills)
134
+
135
+ ├─ bundles OpenCode plugin source in dist/opencode/src
124
136
 
125
137
  └─ depends on @aliyunrds/ctxdb-shared ← input sanitation,
126
138
  prompt-injection defenses,
@@ -155,8 +167,10 @@ After step 1, `ctxdb uninstall` prints the exact `npm uninstall` command to run
155
167
  # itself is unlinked so a future `ctxdb setup --agent <X>` runs through the
156
168
  # first-time install path cleanly.
157
169
  ctxdb uninstall --agent qoder
170
+ ctxdb uninstall --agent qoderwork
158
171
  ctxdb uninstall --agent codex
159
172
  ctxdb uninstall --agent claude
173
+ ctxdb uninstall --agent opencode
160
174
 
161
175
  # Wholesale across all agents, but keep config + logs for re-setup later:
162
176
  ctxdb uninstall # all agents, keeps ~/.ctxdb/{ctxdb.json,logs/}
@@ -262,7 +262,7 @@ function extractErrorDetail(text, fallback) {
262
262
  // src/lib/agents.ts
263
263
  import { homedir as homedir2 } from "os";
264
264
  import { join as join3 } from "path";
265
- var SUPPORTED_AGENTS = ["qoder", "qoderwork", "codex", "claude"];
265
+ var SUPPORTED_AGENTS = ["qoder", "qoderwork", "codex", "claude", "opencode"];
266
266
  function isBuiltinAgent(v) {
267
267
  return typeof v === "string" && SUPPORTED_AGENTS.includes(v);
268
268
  }
@@ -280,6 +280,8 @@ function agentHomeDir(agent) {
280
280
  return join3(homedir2(), ".codex");
281
281
  case "claude":
282
282
  return join3(homedir2(), ".claude");
283
+ case "opencode":
284
+ return join3(homedir2(), ".config", "opencode");
283
285
  }
284
286
  }
285
287
  var AGENT_VARIANT_HOMES = {
@@ -6,10 +6,10 @@ import {
6
6
  isConnectionError,
7
7
  resetCircuit,
8
8
  tripCircuit
9
- } from "./chunk-PZJZ5O62.js";
9
+ } from "./chunk-XWPTIFUK.js";
10
10
  import {
11
11
  CtxdbError
12
- } from "./chunk-TOXXGL5L.js";
12
+ } from "./chunk-F25Q3WM4.js";
13
13
 
14
14
  // src/lib/recall-orchestrator.ts
15
15
  import {
@@ -165,7 +165,7 @@ async function fetchKbCatalogBlock(client, agent) {
165
165
  });
166
166
  return [
167
167
  "<available-knowledge-bases>",
168
- `When you identify that relevant information may exist in the knowledge bases below, you MUST run \`ctxdb kb search "<query>" --kb=<name> --agent=${agent}\` with targeted keywords after initial analysis to supplement and correct your approach. Knowledge bases:`,
168
+ `When you identify that relevant information may exist in the knowledge bases below, you MUST run \`ctxdb kb search "<query>" --kb=<name> --agent=${agent}\` with targeted keywords after initial analysis to supplement and correct your approach. For keyword-based KB search, keep each single query focused: use at most 5 keywords or short phrases; run multiple targeted searches if more are needed. Knowledge bases:`,
169
169
  ...lines,
170
170
  "</available-knowledge-bases>"
171
171
  ].join("\n");
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  configDir
4
- } from "./chunk-TOXXGL5L.js";
4
+ } from "./chunk-F25Q3WM4.js";
5
5
 
6
6
  // src/lib/circuit.ts
7
7
  import { statSync, writeFileSync, unlinkSync, mkdirSync, readdirSync, readFileSync } from "fs";
package/dist/cli/main.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  removeAgent,
32
32
  save,
33
33
  writeInstalledPkgVersion
34
- } from "../chunk-TOXXGL5L.js";
34
+ } from "../chunk-F25Q3WM4.js";
35
35
 
36
36
  // src/cli/util.ts
37
37
  var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
@@ -249,11 +249,14 @@ function skillInstallRoot(agent) {
249
249
  return join(homedir(), ".codex", "skills");
250
250
  case "claude":
251
251
  return join(homedir(), ".claude", "skills");
252
+ case "opencode":
253
+ return join(homedir(), ".config", "opencode", "skills");
252
254
  }
253
255
  }
254
256
  var SKILL_DIRS = ["contextdb-memory", "contextdb-knowledge"];
255
257
  var LEGACY_SKILL_DIRS = ["ctxdb"];
256
258
  function agentSupportsHooks(agent) {
259
+ if (agent === "opencode") return false;
257
260
  return isBuiltinAgent(agent);
258
261
  }
259
262
  function hookConfigPath(agent) {
@@ -266,6 +269,8 @@ function hookConfigPath(agent) {
266
269
  return join(homedir(), ".codex", "hooks.json");
267
270
  case "claude":
268
271
  return join(homedir(), ".claude", "settings.json");
272
+ case "opencode":
273
+ return null;
269
274
  }
270
275
  }
271
276
  var LEGACY_QODER_SKILL_DIRS = [
@@ -407,6 +412,32 @@ async function runSetup(options) {
407
412
  }
408
413
  }
409
414
  }
415
+ if (agent === "opencode") {
416
+ const absEntry = resolveOpencodePluginEntry();
417
+ if (!absEntry) {
418
+ steps.push({
419
+ step: "install-opencode-shim",
420
+ ok: false,
421
+ detail: "could not resolve plugin entry under @aliyunrds/ctxdb/dist/opencode/src"
422
+ });
423
+ return { ok: false, steps };
424
+ }
425
+ try {
426
+ writeOpencodeShim(absEntry);
427
+ steps.push({
428
+ step: "install-opencode-shim",
429
+ ok: true,
430
+ detail: `${opencodeShimPath()} \u2192 ${absEntry}`
431
+ });
432
+ } catch (err) {
433
+ steps.push({
434
+ step: "install-opencode-shim",
435
+ ok: false,
436
+ detail: err?.message ?? String(err)
437
+ });
438
+ return { ok: false, steps };
439
+ }
440
+ }
410
441
  if (validate) {
411
442
  if (!cfg.apiKey || !cfg.baseUrl) {
412
443
  steps.push({
@@ -429,8 +460,14 @@ async function runSetup(options) {
429
460
  }
430
461
  }
431
462
  const ok = steps.every((s) => s.ok);
432
- const hints = ok ? [UNINSTALL_ORDER_HINT] : void 0;
433
- return { ok, steps, hints };
463
+ const hints = ok ? [UNINSTALL_ORDER_HINT] : [];
464
+ if (ok && agent === "opencode") {
465
+ hints.unshift(
466
+ `OpenCode plugin shim: ${opencodeShimPath()}`,
467
+ "Restart OpenCode to load the plugin. `ctxdb upgrade` auto-refreshes the shim after npm updates; only re-run setup if you move ctxdb's install dir."
468
+ );
469
+ }
470
+ return { ok, steps, hints: hints.length > 0 ? hints : void 0 };
434
471
  }
435
472
  function runRemove(agent, options = {}) {
436
473
  const steps = [];
@@ -537,6 +574,32 @@ function runRemove(agent, options = {}) {
537
574
  }
538
575
  }
539
576
  }
577
+ if (agent === "opencode") {
578
+ const removed = removeOpencodeShim();
579
+ steps.push({
580
+ step: "remove-opencode-shim",
581
+ ok: true,
582
+ detail: removed ? opencodeShimPath() : "nothing to remove"
583
+ });
584
+ const root = skillInstallRoot(agent);
585
+ const dirs = [
586
+ ...SKILL_DIRS.map((d) => join(root, d)),
587
+ ...LEGACY_SKILL_DIRS.map((d) => join(root, d))
588
+ ];
589
+ for (const p of dirs) {
590
+ if (!existsSync(p)) continue;
591
+ try {
592
+ rmSync(p, { recursive: true, force: true });
593
+ steps.push({ step: "remove-skill-dir", ok: true, detail: p });
594
+ } catch (err) {
595
+ steps.push({
596
+ step: "remove-skill-dir",
597
+ ok: false,
598
+ detail: `${p}: ${err?.message ?? String(err)}`
599
+ });
600
+ }
601
+ }
602
+ }
540
603
  try {
541
604
  const r = removeAgent(agent, void 0, {
542
605
  keepEmptyShell: !!options.keepConfigShell
@@ -570,6 +633,19 @@ function runRemove(agent, options = {}) {
570
633
  return { ok: steps.every((s) => s.ok), steps };
571
634
  }
572
635
  function checkAgentHome(agent) {
636
+ if (agent === "opencode") {
637
+ const primary = agentHomeDir(agent);
638
+ try {
639
+ mkdirSync(primary, { recursive: true });
640
+ return { step: "check-agent-home", ok: true, detail: primary };
641
+ } catch (err) {
642
+ return {
643
+ step: "check-agent-home",
644
+ ok: false,
645
+ detail: `${primary}: ${err?.message ?? String(err)}`
646
+ };
647
+ }
648
+ }
573
649
  const dirs = agentHomeDirs(agent).filter((d) => existsSync(d));
574
650
  if (dirs.length === 0) {
575
651
  const primary = agentHomeDir(agent);
@@ -679,6 +755,7 @@ function verifyNodeBinary(nodePath) {
679
755
  }
680
756
  }
681
757
  function checkHookNodePaths(agent) {
758
+ if (agent === "opencode") return checkOpencodeShimHealth();
682
759
  const empty = {
683
760
  installed: false,
684
761
  nodePaths: [],
@@ -742,6 +819,51 @@ function checkHookNodePaths(agent) {
742
819
  }
743
820
  return { installed: true, nodePaths: paths, nodeOk: true, detail: `${paths[0]} (${goodVersion})` };
744
821
  }
822
+ function checkOpencodeShimHealth() {
823
+ const path = opencodeShimPath();
824
+ if (!existsSync(path)) {
825
+ return {
826
+ installed: false,
827
+ nodePaths: [],
828
+ nodeOk: false,
829
+ detail: `opencode shim not installed \u2014 run \`ctxdb setup --agent opencode\``
830
+ };
831
+ }
832
+ let text = "";
833
+ try {
834
+ text = readFileSync(path, "utf-8");
835
+ } catch (err) {
836
+ return {
837
+ installed: true,
838
+ nodePaths: [],
839
+ nodeOk: false,
840
+ detail: `opencode shim unreadable: ${err?.message ?? String(err)}`
841
+ };
842
+ }
843
+ const target = text.match(/export\s+\{\s*default\s*\}\s+from\s+["']([^"']+)["'];/)?.[1];
844
+ if (!target) {
845
+ return {
846
+ installed: true,
847
+ nodePaths: [],
848
+ nodeOk: false,
849
+ detail: `opencode shim malformed: ${path} \u2014 re-run \`ctxdb setup --agent opencode\``
850
+ };
851
+ }
852
+ if (!existsSync(target)) {
853
+ return {
854
+ installed: true,
855
+ nodePaths: [target],
856
+ nodeOk: false,
857
+ detail: `opencode shim target missing: ${target} \u2014 re-run \`ctxdb setup --agent opencode\``
858
+ };
859
+ }
860
+ return {
861
+ installed: true,
862
+ nodePaths: [target],
863
+ nodeOk: true,
864
+ detail: `opencode shim: ${path} \u2192 ${target}`
865
+ };
866
+ }
745
867
  var SETTINGS_BACKUP_KEEP = 5;
746
868
  function backupSettingsFile(path) {
747
869
  if (!existsSync(path)) return;
@@ -903,6 +1025,7 @@ var SKILL_INSTALL_TARGETS = {
903
1025
  qoderworkcn: join(homedir(), ".qoderworkcn", "skills"),
904
1026
  codex: join(homedir(), ".codex", "skills"),
905
1027
  claude: join(homedir(), ".claude", "skills"),
1028
+ opencode: join(homedir(), ".config", "opencode", "skills"),
906
1029
  openclaw: join(homedir(), ".openclaw", "skills"),
907
1030
  hermes: join(homedir(), ".hermes", "skills")
908
1031
  };
@@ -958,6 +1081,39 @@ function appendHooks(agent, hookPaths) {
958
1081
  if (!path) return;
959
1082
  appendHooksToFile(path, agent, hookPaths);
960
1083
  }
1084
+ var OPENCODE_SHIM_FILENAME = "ctxdb.ts";
1085
+ function opencodeShimPath() {
1086
+ return join(homedir(), ".config", "opencode", "plugins", OPENCODE_SHIM_FILENAME);
1087
+ }
1088
+ function resolveOpencodePluginEntry() {
1089
+ const here = dirname(fileURLToPath(import.meta.url));
1090
+ const pkgRoot = walkUpToPackageJson(here, "@aliyunrds/ctxdb");
1091
+ if (!pkgRoot) return null;
1092
+ const candidates = [
1093
+ join(pkgRoot, "dist", "opencode", "src", "index.ts"),
1094
+ join(pkgRoot, "..", "opencode", "src", "index.ts")
1095
+ ];
1096
+ return candidates.find((candidate) => existsSync(candidate)) ?? null;
1097
+ }
1098
+ var OPENCODE_SHIM_HEADER = "// Generated by ctxdb setup --agent opencode. Do not edit by hand.\n// To refresh after moving ctxdb's install directory, run ctxdb upgrade --agent opencode or re-run setup.\n// To remove, run: ctxdb setup --remove --agent opencode\n";
1099
+ function writeOpencodeShim(absEntry) {
1100
+ const path = opencodeShimPath();
1101
+ mkdirSync(dirname(path), { recursive: true });
1102
+ const importSpec = absEntry.replace(/\\/g, "/");
1103
+ const body = `${OPENCODE_SHIM_HEADER}export { default } from ${JSON.stringify(importSpec)};
1104
+ `;
1105
+ writeFileSync(path, body, "utf-8");
1106
+ }
1107
+ function removeOpencodeShim() {
1108
+ const path = opencodeShimPath();
1109
+ if (!existsSync(path)) return false;
1110
+ try {
1111
+ unlinkSync(path);
1112
+ return true;
1113
+ } catch {
1114
+ return false;
1115
+ }
1116
+ }
961
1117
  var ENTRY_MARKER_KEY = "_ctxdb";
962
1118
  var ENTRY_MARKER_VALUE = "@aliyunrds/ctxdb";
963
1119
  var ENTRY_AGENT_KEY = "_ctxdbAgent";
@@ -1300,6 +1456,28 @@ function upgradeOneAgent(agent) {
1300
1456
  }
1301
1457
  }
1302
1458
  }
1459
+ if (agent === "opencode") {
1460
+ const absEntry = resolveOpencodePluginEntry();
1461
+ if (!absEntry) {
1462
+ steps.push({
1463
+ step: "refresh-opencode-shim",
1464
+ ok: false,
1465
+ detail: "could not resolve plugin entry under @aliyunrds/ctxdb/dist/opencode/src"
1466
+ });
1467
+ return { ok: false, steps };
1468
+ }
1469
+ try {
1470
+ writeOpencodeShim(absEntry);
1471
+ steps.push({
1472
+ step: "refresh-opencode-shim",
1473
+ ok: true,
1474
+ detail: `${opencodeShimPath()} \u2192 ${absEntry}`
1475
+ });
1476
+ } catch (err) {
1477
+ steps.push({ step: "refresh-opencode-shim", ok: false, detail: err?.message ?? String(err) });
1478
+ return { ok: false, steps };
1479
+ }
1480
+ }
1303
1481
  return { ok: steps.every((s) => s.ok), steps };
1304
1482
  }
1305
1483
 
@@ -1360,7 +1538,7 @@ async function ping(args) {
1360
1538
  var HELP = `ctxdb setup \u2014 configure an agent
1361
1539
 
1362
1540
  USAGE
1363
- ctxdb setup [--agent <qoder|qoderwork|codex|claude>]
1541
+ ctxdb setup [--agent <qoder|qoderwork|codex|claude|opencode>]
1364
1542
  [--api-key=K] [--base-url=URL] [--user-id=ID]
1365
1543
  [--no-install-skill] [--no-validate] [--json]
1366
1544
 
@@ -1371,7 +1549,7 @@ BEHAVIOR
1371
1549
  specified agent harness.
1372
1550
 
1373
1551
  FLAGS
1374
- --agent <name> Target agent (qoder|qoderwork|codex|claude)
1552
+ --agent <name> Target agent (qoder|qoderwork|codex|claude|opencode)
1375
1553
  --api-key <key> API key (required on first setup)
1376
1554
  --base-url <url> Server URL (default: https://context-database.aliyuncs.com)
1377
1555
  --user-id <id> User bucket (default: "default")
@@ -1398,7 +1576,7 @@ async function setup(args) {
1398
1576
  const json = !!args.flags.json;
1399
1577
  if (agent === "default" && !json && !configuredAgents().includes("default")) {
1400
1578
  process.stderr.write(
1401
- `hint: creating CLI-only "default" agent (no hooks/skills). Use --agent <claude|qoder|qoderwork|codex> for full setup.
1579
+ `hint: creating CLI-only "default" agent (no hooks/skills). Use --agent <claude|qoder|qoderwork|codex|opencode> for full setup.
1402
1580
  `
1403
1581
  );
1404
1582
  }
@@ -1423,11 +1601,11 @@ ${h}
1423
1601
  var HELP2 = `ctxdb uninstall \u2014 remove hooks + skills
1424
1602
 
1425
1603
  USAGE
1426
- ctxdb uninstall [--agent <qoder|qoderwork|codex|claude>] [--purge-config] [--purge-logs] [--purge-all] [--json]
1604
+ ctxdb uninstall [--agent <qoder|qoderwork|codex|claude|opencode>] [--purge-config] [--purge-logs] [--purge-all] [--json]
1427
1605
 
1428
1606
  DEFAULT BEHAVIOR (no --agent, no purge flags)
1429
1607
  Strips ctxdb hook entries and skill directories for ALL agents (qoder,
1430
- qoderwork, codex, claude). Keeps ~/.ctxdb/ctxdb.json (credentials) and ~/.ctxdb/logs/
1608
+ qoderwork, codex, claude, opencode). Keeps ~/.ctxdb/ctxdb.json (credentials) and ~/.ctxdb/logs/
1431
1609
  so you can re-run \`ctxdb setup\` later without losing configuration.
1432
1610
 
1433
1611
  WITH --agent <name>
@@ -1435,7 +1613,7 @@ WITH --agent <name>
1435
1613
  Other agents remain untouched.
1436
1614
 
1437
1615
  FLAGS
1438
- --agent <name> Target a single agent (qoder|qoderwork|codex|claude)
1616
+ --agent <name> Target a single agent (qoder|qoderwork|codex|claude|opencode)
1439
1617
  --purge-config Also delete ~/.ctxdb/ctxdb.json
1440
1618
  --purge-logs Also delete ~/.ctxdb/logs/
1441
1619
  --purge-all Delete everything under ~/.ctxdb/
@@ -1593,7 +1771,7 @@ function runSelfUpdate(currentVersion, passthroughArgs = []) {
1593
1771
  var HELP3 = `ctxdb upgrade \u2014 refresh skills + hooks
1594
1772
 
1595
1773
  USAGE
1596
- ctxdb upgrade [--agent <qoder|qoderwork|codex|claude>] [--self-update] [--json]
1774
+ ctxdb upgrade [--agent <qoder|qoderwork|codex|claude|opencode>] [--self-update] [--json]
1597
1775
 
1598
1776
  BEHAVIOR
1599
1777
  Refreshes skill files and hook entries for configured agents without
@@ -1603,7 +1781,7 @@ BEHAVIOR
1603
1781
  With --agent: upgrades only the specified agent.
1604
1782
 
1605
1783
  FLAGS
1606
- --agent <name> Target a single agent (qoder|qoderwork|codex|claude)
1784
+ --agent <name> Target a single agent (qoder|qoderwork|codex|claude|opencode)
1607
1785
  --self-update Also pull latest package from npm before upgrading
1608
1786
  --json Machine-readable JSON output
1609
1787
  `;
@@ -1966,7 +2144,7 @@ USAGE
1966
2144
  ctxdb <command> [args] [--flags]
1967
2145
 
1968
2146
  COMMANDS
1969
- setup [--agent <qoder|qoderwork|codex|claude>]
2147
+ setup [--agent <qoder|qoderwork|codex|claude|opencode>]
1970
2148
  [--api-key=K] [--base-url=URL] [--user-id=ID]
1971
2149
  [--no-install-skill] [--no-validate] [--json]
1972
2150
  Without --agent \u2192 writes agents.default (CLI-only, no hooks/skills)
@@ -1974,6 +2152,7 @@ COMMANDS
1974
2152
  QoderWork \u2192 writes agents.qoderwork config + ~/.qoderwork/settings.json hooks + skill
1975
2153
  Codex \u2192 writes agents.codex config + ~/.codex/hooks.json hooks + skill
1976
2154
  Claude \u2192 writes agents.claude config + ~/.claude/settings.json hooks + skill
2155
+ OpenCode \u2192 writes agents.opencode config + ~/.config/opencode/plugins/ctxdb.ts shim + skill
1977
2156
  status [--agent <name>] [--json]
1978
2157
  ping [--agent <name>] [--json]
1979
2158
  uninstall [--agent <name>] [--purge-config] [--purge-logs] [--purge-all] [--json]
@@ -2016,7 +2195,7 @@ COMMANDS
2016
2195
  doc_id?/tags? for citation.
2017
2196
  --raw: server response verbatim (curl parity).
2018
2197
 
2019
- skill install --target <qoder|qoderwork|codex|claude|openclaw|hermes> [--json]
2198
+ skill install --target <qoder|qoderwork|codex|claude|opencode|openclaw|hermes> [--json]
2020
2199
  skill install --path <dir> [--json]
2021
2200
  Install skill files (contextdb-memory,
2022
2201
  contextdb-knowledge) to an agent's skill directory.
@@ -2029,7 +2208,7 @@ AGENT RESOLUTION (when --agent is omitted):
2029
2208
  ENV VARS (override selected ~/.ctxdb/ctxdb.json agent config):
2030
2209
  CTXDB_AGENT CTXDB_API_KEY CTXDB_BASE_URL CTXDB_USER_ID
2031
2210
 
2032
- CONFIG: ~/.ctxdb/ctxdb.json (agents.default / agents.qoder / agents.qoderwork / agents.codex / agents.claude)
2211
+ CONFIG: ~/.ctxdb/ctxdb.json (agents.default / agents.qoder / agents.qoderwork / agents.codex / agents.claude / agents.opencode)
2033
2212
  LOGS: ~/.ctxdb/logs/ctxdb.log
2034
2213
  `;
2035
2214
  var ROUTES = {
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  fetchKbCatalogBlock,
4
4
  recallTurn
5
- } from "../chunk-RHWGDY6S.js";
5
+ } from "../chunk-I5HRGFZO.js";
6
6
  import "../chunk-6S5RJYBC.js";
7
7
  import {
8
8
  isCircuitOpen
9
- } from "../chunk-PZJZ5O62.js";
9
+ } from "../chunk-XWPTIFUK.js";
10
10
  import {
11
11
  HttpClient,
12
12
  agentFromArgvWithFallback,
@@ -14,7 +14,7 @@ import {
14
14
  isComplete,
15
15
  load,
16
16
  setDebug
17
- } from "../chunk-TOXXGL5L.js";
17
+ } from "../chunk-F25Q3WM4.js";
18
18
 
19
19
  // src/hooks/session-start.ts
20
20
  import { pathToFileURL } from "url";
@@ -4,7 +4,7 @@ import {
4
4
  isConnectionError,
5
5
  resetCircuit,
6
6
  tripCircuit
7
- } from "../chunk-PZJZ5O62.js";
7
+ } from "../chunk-XWPTIFUK.js";
8
8
  import {
9
9
  CtxdbError,
10
10
  HttpClient,
@@ -13,7 +13,7 @@ import {
13
13
  isDebug,
14
14
  load,
15
15
  setDebug
16
- } from "../chunk-TOXXGL5L.js";
16
+ } from "../chunk-F25Q3WM4.js";
17
17
 
18
18
  // src/lib/capture-orchestrator.ts
19
19
  import {
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  fetchKbCatalogBlock,
4
4
  recallTurn
5
- } from "../chunk-RHWGDY6S.js";
5
+ } from "../chunk-I5HRGFZO.js";
6
6
  import "../chunk-6S5RJYBC.js";
7
7
  import {
8
8
  isCircuitOpen
9
- } from "../chunk-PZJZ5O62.js";
9
+ } from "../chunk-XWPTIFUK.js";
10
10
  import {
11
11
  HttpClient,
12
12
  agentFromArgvWithFallback,
@@ -14,7 +14,7 @@ import {
14
14
  isComplete,
15
15
  load,
16
16
  setDebug
17
- } from "../chunk-TOXXGL5L.js";
17
+ } from "../chunk-F25Q3WM4.js";
18
18
 
19
19
  // src/hooks/user-prompt-submit.ts
20
20
  import { pathToFileURL } from "url";