@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 +21 -7
- package/dist/{chunk-TOXXGL5L.js → chunk-F25Q3WM4.js} +3 -1
- package/dist/{chunk-RHWGDY6S.js → chunk-I5HRGFZO.js} +3 -3
- package/dist/{chunk-PZJZ5O62.js → chunk-XWPTIFUK.js} +1 -1
- package/dist/cli/main.js +193 -14
- package/dist/hooks/session-start.js +3 -3
- package/dist/hooks/stop.js +2 -2
- package/dist/hooks/user-prompt-submit.js +3 -3
- package/dist/opencode/src/capture.ts +187 -0
- package/dist/opencode/src/config.ts +160 -0
- package/dist/opencode/src/hooks.ts +252 -0
- package/dist/opencode/src/http-client.ts +147 -0
- package/dist/opencode/src/index.ts +9 -0
- package/dist/opencode/src/kb-catalog.ts +64 -0
- package/dist/opencode/src/recall.ts +87 -0
- package/dist/opencode/src/warmup.ts +51 -0
- package/dist/setup/skills/contextdb-knowledge/SKILL.md +4 -4
- package/dist/setup/skills/contextdb-memory/SKILL.md +4 -4
- package/package.json +4 -3
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.
|
|
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-
|
|
9
|
+
} from "./chunk-XWPTIFUK.js";
|
|
10
10
|
import {
|
|
11
11
|
CtxdbError
|
|
12
|
-
} from "./chunk-
|
|
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");
|
package/dist/cli/main.js
CHANGED
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
removeAgent,
|
|
32
32
|
save,
|
|
33
33
|
writeInstalledPkgVersion
|
|
34
|
-
} from "../chunk-
|
|
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] :
|
|
433
|
-
|
|
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-
|
|
5
|
+
} from "../chunk-I5HRGFZO.js";
|
|
6
6
|
import "../chunk-6S5RJYBC.js";
|
|
7
7
|
import {
|
|
8
8
|
isCircuitOpen
|
|
9
|
-
} from "../chunk-
|
|
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-
|
|
17
|
+
} from "../chunk-F25Q3WM4.js";
|
|
18
18
|
|
|
19
19
|
// src/hooks/session-start.ts
|
|
20
20
|
import { pathToFileURL } from "url";
|
package/dist/hooks/stop.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
isConnectionError,
|
|
5
5
|
resetCircuit,
|
|
6
6
|
tripCircuit
|
|
7
|
-
} from "../chunk-
|
|
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-
|
|
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-
|
|
5
|
+
} from "../chunk-I5HRGFZO.js";
|
|
6
6
|
import "../chunk-6S5RJYBC.js";
|
|
7
7
|
import {
|
|
8
8
|
isCircuitOpen
|
|
9
|
-
} from "../chunk-
|
|
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-
|
|
17
|
+
} from "../chunk-F25Q3WM4.js";
|
|
18
18
|
|
|
19
19
|
// src/hooks/user-prompt-submit.ts
|
|
20
20
|
import { pathToFileURL } from "url";
|