@aliyunrds/ctxdb 1.0.4 → 1.0.6
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 +66 -14
- package/dist/{chunk-SAQT6VL6.js → chunk-6BB65W5W.js} +2 -2
- package/dist/{chunk-BVCDRUU4.js → chunk-7EIJB5LA.js} +7 -3
- package/dist/{chunk-JFTKYEVN.js → chunk-ARZX2RLR.js} +55 -7
- package/dist/{chunk-USMJLDBD.js → chunk-B7JCQL4O.js} +1 -1
- package/dist/{chunk-CWGF5D52.js → chunk-BHRWAU3E.js} +13 -6
- package/dist/{chunk-3PFMHU3C.js → chunk-L4GVGVOP.js} +4 -3
- package/dist/{chunk-Q4JYST7K.js → chunk-VHNHVMCA.js} +137 -20
- package/dist/{chunk-BQA7YSXT.js → chunk-Z6OHSEF2.js} +20 -16
- package/dist/cli/main.js +291 -77
- package/dist/hooks/hermes-post-llm-call.js +3 -3
- package/dist/hooks/hermes-pre-llm-call.js +31 -9
- package/dist/hooks/session-start.js +14 -6
- package/dist/hooks/stop.js +3 -3
- package/dist/hooks/user-prompt-submit.js +13 -6
- package/dist/opencode/index.js +657 -208
- package/dist/setup/skills/contextdb-knowledge/SKILL.md +7 -5
- package/dist/setup/skills/contextdb-memory/SKILL.md +1 -1
- package/dist/workers/version-check.js +1 -1
- package/package.json +2 -2
package/dist/cli/main.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
pollIngest,
|
|
13
13
|
uploadFile,
|
|
14
14
|
uploadText
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-L4GVGVOP.js";
|
|
16
16
|
import {
|
|
17
17
|
DEFAULT_BASE_URL,
|
|
18
18
|
DEFAULT_USER_ID,
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
agentPlatformSupport,
|
|
26
26
|
configuredAgents,
|
|
27
27
|
detectInstalledAgents,
|
|
28
|
+
hasConfiguredAgent,
|
|
28
29
|
inspectAgentHomes,
|
|
29
30
|
isAgentSlug,
|
|
30
31
|
isBuiltinAgent,
|
|
@@ -32,13 +33,14 @@ import {
|
|
|
32
33
|
load,
|
|
33
34
|
removeAgent,
|
|
34
35
|
save,
|
|
36
|
+
updateConfiguredDebug,
|
|
35
37
|
writeInstalledPkgVersion
|
|
36
|
-
} from "../chunk-
|
|
38
|
+
} from "../chunk-ARZX2RLR.js";
|
|
37
39
|
import {
|
|
38
40
|
beginUpdateNotification,
|
|
39
41
|
completeUpdateNotification,
|
|
40
42
|
runSelfUpdate
|
|
41
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-Z6OHSEF2.js";
|
|
42
44
|
|
|
43
45
|
// src/cli/util.ts
|
|
44
46
|
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
@@ -70,8 +72,10 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
70
72
|
// kb upload-text / upload-file
|
|
71
73
|
"verbose",
|
|
72
74
|
// memory search / kb search (three-tier projection)
|
|
73
|
-
"raw"
|
|
75
|
+
"raw",
|
|
74
76
|
// kb search / memory search --knowledge (W3 compaction bypass)
|
|
77
|
+
"full"
|
|
78
|
+
// debug recall full-content human output
|
|
75
79
|
]);
|
|
76
80
|
function parseArgs(argv, booleanFlags = BOOLEAN_FLAGS) {
|
|
77
81
|
const positional = [];
|
|
@@ -202,6 +206,9 @@ function formatMultiAgentResult(r) {
|
|
|
202
206
|
}
|
|
203
207
|
lines.push(` ${DIM}config${RESET} ${result.ok ? "complete" : "incomplete"}`);
|
|
204
208
|
lines.push(` ${DIM}connected${RESET} ${result.connected ? "yes" : "no"}`);
|
|
209
|
+
lines.push(
|
|
210
|
+
` ${DIM}debug${RESET} ${result.debug ? "enabled" : "disabled"} (configured=${result.debug_configured ? "enabled" : "disabled"}, forced=${result.debug_forced ? "yes" : "no"}, reason=${result.debug_reason ?? "-"})`
|
|
211
|
+
);
|
|
205
212
|
if (result.hooks_node !== void 0) {
|
|
206
213
|
lines.push(` ${DIM}hooks${RESET} ${result.hooks_node}`);
|
|
207
214
|
}
|
|
@@ -233,6 +240,10 @@ function formatStatusResult(r) {
|
|
|
233
240
|
["top_k", r.top_k],
|
|
234
241
|
["threshold", r.threshold],
|
|
235
242
|
["knowledge_top_k", r.knowledge_top_k],
|
|
243
|
+
["debug", r.debug],
|
|
244
|
+
["debug_configured", r.debug_configured],
|
|
245
|
+
["debug_forced", r.debug_forced],
|
|
246
|
+
["debug_reason", r.debug_reason],
|
|
236
247
|
["connected", r.connected],
|
|
237
248
|
["version", r.version]
|
|
238
249
|
];
|
|
@@ -324,6 +335,8 @@ function skillInstallRoot(agent) {
|
|
|
324
335
|
return join(homedir(), ".qoder", "skills");
|
|
325
336
|
case "qoderwork":
|
|
326
337
|
return join(homedir(), ".qoderwork", "skills");
|
|
338
|
+
case "qwenwork":
|
|
339
|
+
return join(homedir(), ".qwenwork", "skills");
|
|
327
340
|
case "codex":
|
|
328
341
|
return join(homedir(), ".codex", "skills");
|
|
329
342
|
case "claude":
|
|
@@ -346,6 +359,8 @@ function hookConfigPath(agent) {
|
|
|
346
359
|
return join(homedir(), ".qoder", "settings.json");
|
|
347
360
|
case "qoderwork":
|
|
348
361
|
return join(homedir(), ".qoderwork", "settings.json");
|
|
362
|
+
case "qwenwork":
|
|
363
|
+
return join(homedir(), ".qwenwork", "settings.json");
|
|
349
364
|
case "codex":
|
|
350
365
|
return join(homedir(), ".codex", "hooks.json");
|
|
351
366
|
case "claude":
|
|
@@ -381,6 +396,7 @@ function checkCurrentNodeVersion() {
|
|
|
381
396
|
}
|
|
382
397
|
async function runSetup(options) {
|
|
383
398
|
const steps = [];
|
|
399
|
+
let existingAgentHomes = [];
|
|
384
400
|
if (!isAgentSlug(options.agent)) {
|
|
385
401
|
steps.push({
|
|
386
402
|
step: "validate-agent",
|
|
@@ -401,6 +417,7 @@ async function runSetup(options) {
|
|
|
401
417
|
const homeCheck = checkAgentHome(agent);
|
|
402
418
|
steps.push(homeCheck);
|
|
403
419
|
if (!homeCheck.ok) return { ok: false, steps };
|
|
420
|
+
existingAgentHomes = inspectAgentHomes(agent).existing;
|
|
404
421
|
}
|
|
405
422
|
const cfg = load({ agent });
|
|
406
423
|
if (options.apiKey) cfg.apiKey = options.apiKey;
|
|
@@ -429,7 +446,7 @@ async function runSetup(options) {
|
|
|
429
446
|
detail: `default: copied from ${agent}`
|
|
430
447
|
});
|
|
431
448
|
}
|
|
432
|
-
if (installSkill && isBuiltinAgent(agent)) {
|
|
449
|
+
if (installSkill && isBuiltinAgent(agent) && existingAgentHomes.includes(agentHomeDir(agent))) {
|
|
433
450
|
const installRoot = skillInstallRoot(agent);
|
|
434
451
|
for (const legacy of LEGACY_SKILL_DIRS) {
|
|
435
452
|
const legacyDir = join(installRoot, legacy);
|
|
@@ -451,6 +468,8 @@ async function runSetup(options) {
|
|
|
451
468
|
if (!skillResult.ok) return { ok: false, steps };
|
|
452
469
|
}
|
|
453
470
|
if (isBuiltinAgent(agent) && agentSupportsHooks(agent)) {
|
|
471
|
+
const primaryHome = agentHomeDir(agent);
|
|
472
|
+
const primaryHomeExists = existingAgentHomes.includes(primaryHome);
|
|
454
473
|
const hookPaths = locateHookPaths();
|
|
455
474
|
steps.push({
|
|
456
475
|
step: "locate-hooks",
|
|
@@ -466,26 +485,28 @@ async function runSetup(options) {
|
|
|
466
485
|
detail: nodeCheck.ok ? `${nodePath} (${nodeCheck.version})` : `node not executable: ${nodeCheck.error}`
|
|
467
486
|
});
|
|
468
487
|
if (!nodeCheck.ok) return { ok: false, steps };
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
488
|
+
if (primaryHomeExists) {
|
|
489
|
+
try {
|
|
490
|
+
backupSettingsJson(agent);
|
|
491
|
+
steps.push({ step: "backup-settings", ok: true });
|
|
492
|
+
const removed = stripCtxdbHooks(agent);
|
|
493
|
+
if (removed > 0) {
|
|
494
|
+
steps.push({
|
|
495
|
+
step: "clean-legacy-hooks",
|
|
496
|
+
ok: true,
|
|
497
|
+
detail: `removed ${removed} existing entries`
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
appendHooks(agent, hookPaths);
|
|
501
|
+
steps.push({ step: "append-hooks", ok: true });
|
|
502
|
+
} catch (err) {
|
|
474
503
|
steps.push({
|
|
475
|
-
step: "
|
|
476
|
-
ok:
|
|
477
|
-
detail:
|
|
504
|
+
step: "settings-update",
|
|
505
|
+
ok: false,
|
|
506
|
+
detail: err?.message ?? String(err)
|
|
478
507
|
});
|
|
508
|
+
return { ok: false, steps };
|
|
479
509
|
}
|
|
480
|
-
appendHooks(agent, hookPaths);
|
|
481
|
-
steps.push({ step: "append-hooks", ok: true });
|
|
482
|
-
} catch (err) {
|
|
483
|
-
steps.push({
|
|
484
|
-
step: "settings-update",
|
|
485
|
-
ok: false,
|
|
486
|
-
detail: err?.message ?? String(err)
|
|
487
|
-
});
|
|
488
|
-
return { ok: false, steps };
|
|
489
510
|
}
|
|
490
511
|
try {
|
|
491
512
|
chmodSync(hookPaths.userPromptSubmit, 493);
|
|
@@ -505,8 +526,7 @@ async function runSetup(options) {
|
|
|
505
526
|
if (agent === "codex") {
|
|
506
527
|
steps.push(enableCodexHooksFeature());
|
|
507
528
|
}
|
|
508
|
-
const
|
|
509
|
-
const variantHomes = agentHomeDirs(agent).filter((d) => d !== primaryHome && existsSync(d));
|
|
529
|
+
const variantHomes = existingAgentHomes.filter((d) => d !== primaryHome);
|
|
510
530
|
for (const vHome of variantHomes) {
|
|
511
531
|
const tag = vHome.split("/").pop() ?? vHome;
|
|
512
532
|
if (installSkill) {
|
|
@@ -1099,42 +1119,49 @@ function checkHookNodePaths(agent) {
|
|
|
1099
1119
|
nodeOk: true,
|
|
1100
1120
|
detail: "no hooks installed"
|
|
1101
1121
|
};
|
|
1102
|
-
const
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
} catch {
|
|
1108
|
-
return empty;
|
|
1109
|
-
}
|
|
1110
|
-
if (!data?.hooks || typeof data.hooks !== "object") return empty;
|
|
1122
|
+
const primaryHome = agentHomeDir(agent);
|
|
1123
|
+
const primaryPath = hookConfigPath(agent);
|
|
1124
|
+
const configPaths = agentHomeDirs(agent).filter((home) => existsSync(home)).map((home) => home === primaryHome ? primaryPath : join(home, "settings.json")).filter((path) => path !== null && existsSync(path));
|
|
1125
|
+
if (configPaths.length === 0) return empty;
|
|
1126
|
+
let foundHooksObject = false;
|
|
1111
1127
|
const nodePaths = /* @__PURE__ */ new Set();
|
|
1112
|
-
for (const
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1128
|
+
for (const configPath of configPaths) {
|
|
1129
|
+
let data;
|
|
1130
|
+
try {
|
|
1131
|
+
data = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
1132
|
+
} catch {
|
|
1133
|
+
continue;
|
|
1134
|
+
}
|
|
1135
|
+
if (!data?.hooks || typeof data.hooks !== "object") continue;
|
|
1136
|
+
foundHooksObject = true;
|
|
1137
|
+
for (const event of HOOK_EVENTS) {
|
|
1138
|
+
const entries = data.hooks[event];
|
|
1139
|
+
if (!Array.isArray(entries)) continue;
|
|
1140
|
+
for (const entry of entries) {
|
|
1141
|
+
if (!entryIsCtxdb(entry)) continue;
|
|
1142
|
+
for (const h of entry.hooks ?? []) {
|
|
1143
|
+
if (h?.type !== "command" || typeof h.command !== "string") continue;
|
|
1144
|
+
if (Array.isArray(h.args) && h.args.length > 0) {
|
|
1145
|
+
nodePaths.add(h.command);
|
|
1127
1146
|
} else {
|
|
1128
|
-
const
|
|
1129
|
-
|
|
1130
|
-
|
|
1147
|
+
const cmd = h.command;
|
|
1148
|
+
let nodePath;
|
|
1149
|
+
if (cmd.startsWith('"')) {
|
|
1150
|
+
const closeQuote = cmd.indexOf('"', 1);
|
|
1151
|
+
if (closeQuote > 1) nodePath = cmd.slice(1, closeQuote);
|
|
1152
|
+
} else {
|
|
1153
|
+
const parts = cmd.split(" ");
|
|
1154
|
+
if (parts.length >= 2 && !parts[0].endsWith(".js") && !parts[0].endsWith(".ts") && (parts[0].includes("/") || parts[0].includes("\\"))) {
|
|
1155
|
+
nodePath = parts[0];
|
|
1156
|
+
}
|
|
1131
1157
|
}
|
|
1158
|
+
if (nodePath) nodePaths.add(nodePath);
|
|
1132
1159
|
}
|
|
1133
|
-
if (nodePath) nodePaths.add(nodePath);
|
|
1134
1160
|
}
|
|
1135
1161
|
}
|
|
1136
1162
|
}
|
|
1137
1163
|
}
|
|
1164
|
+
if (!foundHooksObject) return empty;
|
|
1138
1165
|
if (nodePaths.size === 0) {
|
|
1139
1166
|
return { installed: true, nodePaths: [], nodeOk: true, detail: "hooks use shebang (no explicit node path)" };
|
|
1140
1167
|
}
|
|
@@ -1366,6 +1393,8 @@ var SKILL_INSTALL_TARGETS = {
|
|
|
1366
1393
|
qodercn: join(homedir(), ".qoder-cn", "skills"),
|
|
1367
1394
|
qoderwork: join(homedir(), ".qoderwork", "skills"),
|
|
1368
1395
|
qoderworkcn: join(homedir(), ".qoderworkcn", "skills"),
|
|
1396
|
+
qwenwork: join(homedir(), ".qwenwork", "skills"),
|
|
1397
|
+
qwenworkcn: join(homedir(), ".qwenworkcn", "skills"),
|
|
1369
1398
|
codex: join(homedir(), ".codex", "skills"),
|
|
1370
1399
|
claude: join(homedir(), ".claude", "skills"),
|
|
1371
1400
|
opencode: join(homedir(), ".config", "opencode", "skills"),
|
|
@@ -1977,7 +2006,7 @@ async function runUpgrade(options = {}) {
|
|
|
1977
2006
|
var STATUS_HELP = `ctxdb status \u2014 inspect configuration and connectivity
|
|
1978
2007
|
|
|
1979
2008
|
USAGE
|
|
1980
|
-
ctxdb status [--agent <qoder|qoderwork|codex|claude|opencode|hermes|default> | --all] [--json]
|
|
2009
|
+
ctxdb status [--agent <qoder|qoderwork|qwenwork|codex|claude|opencode|hermes|default> | --all] [--json]
|
|
1981
2010
|
|
|
1982
2011
|
FLAGS
|
|
1983
2012
|
--agent <name> Inspect exactly one Agent profile
|
|
@@ -2011,6 +2040,10 @@ async function inspectStatus(agent) {
|
|
|
2011
2040
|
top_k: cfg.topK,
|
|
2012
2041
|
threshold: cfg.threshold,
|
|
2013
2042
|
knowledge_top_k: cfg.knowledgeTopK,
|
|
2043
|
+
debug: cfg.debug,
|
|
2044
|
+
debug_configured: cfg.debugConfigured,
|
|
2045
|
+
debug_forced: cfg.debugForced,
|
|
2046
|
+
debug_reason: cfg.debugReason,
|
|
2014
2047
|
connected,
|
|
2015
2048
|
ping_error: pingError,
|
|
2016
2049
|
hooks_node: hookHealth.detail,
|
|
@@ -2099,7 +2132,7 @@ async function ping(args) {
|
|
|
2099
2132
|
var HELP = `ctxdb setup \u2014 configure an agent
|
|
2100
2133
|
|
|
2101
2134
|
USAGE
|
|
2102
|
-
ctxdb setup [--agent <qoder|qoderwork|codex|claude|opencode|hermes> | --all]
|
|
2135
|
+
ctxdb setup [--agent <qoder|qoderwork|qwenwork|codex|claude|opencode|hermes> | --all]
|
|
2103
2136
|
[--api-key=K] [--base-url=URL] [--user-id=ID]
|
|
2104
2137
|
[--no-install-skill] [--no-validate] [--json]
|
|
2105
2138
|
|
|
@@ -2120,7 +2153,7 @@ BEHAVIOR
|
|
|
2120
2153
|
any running Hermes CLI/gateway process to load the hooks.
|
|
2121
2154
|
|
|
2122
2155
|
FLAGS
|
|
2123
|
-
--agent <name> Target agent (qoder|qoderwork|codex|claude|opencode|hermes)
|
|
2156
|
+
--agent <name> Target agent (qoder|qoderwork|qwenwork|codex|claude|opencode|hermes)
|
|
2124
2157
|
--all Target every setup-compatible detected Agent
|
|
2125
2158
|
--api-key <key> API key (required on first setup)
|
|
2126
2159
|
--base-url <url> Server URL (default: https://context-database.aliyuncs.com)
|
|
@@ -2133,6 +2166,24 @@ var CODEX_HOOKS_TRUST_REMINDER = [
|
|
|
2133
2166
|
"codex hooks \u914D\u7F6E\u540E\uFF0C\u9700\u8981\u91CD\u542F Codex \u5BF9\u8BDD\uFF0C\u5728\u5F39\u51FA\u7684 hooks \u786E\u8BA4\u754C\u9762\u9009\u62E9`\u63A5\u6536\u6240\u6709 hooks(\u94A9\u5B50)`\u9009\u9879\u3002",
|
|
2134
2167
|
"\u5982\u679C\u4F7F\u7528\u7684\u662F Codex App \u684C\u9762\u7248\uFF0C\u64CD\u4F5C\u8DEF\u5F84\u662F\uFF1A\u5DE6\u4E0B\u89D2\u70B9\u51FB\u7528\u6237\u540D \u2192 \u70B9\u51FB\u8BBE\u7F6E \u2192 \u70B9\u51FB\u4FA7\u8FB9\u680F\u7684 `Hooks\uFF08\u94A9\u5B50\uFF09`\u2192 \u70B9\u51FB`\u7528\u6237\u914D\u7F6E`\uFF0C\u4FE1\u4EFB `UserPromptSubmit`\u3001`SessionStart` \u548C `Stop` \u91CC\u7684 `aliyunrds/ctxdb` \u94A9\u5B50\u3002"
|
|
2135
2168
|
].join("\n");
|
|
2169
|
+
var FULL_APP_RESTART_REMINDERS = {
|
|
2170
|
+
qoder: "Next action: \u8BF7\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u65B0\u542F\u52A8 Qoder\uFF08\u4E0D\u662F\u53EA\u5173\u95ED\u5F53\u524D\u5BF9\u8BDD\uFF09\uFF0C\u4F7F\u65B0\u7684 hooks \u548C skill \u751F\u6548\u3002",
|
|
2171
|
+
qoderwork: "Next action: \u8BF7\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u65B0\u542F\u52A8 QoderWork\uFF08\u4E0D\u662F\u53EA\u5173\u95ED\u5F53\u524D\u5BF9\u8BDD\uFF09\uFF0C\u4F7F\u65B0\u7684 hooks \u548C skill \u751F\u6548\u3002",
|
|
2172
|
+
qwenwork: "Next action: \u8BF7\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u65B0\u542F\u52A8 QwenWork\uFF08\u4E0D\u662F\u53EA\u5173\u95ED\u5F53\u524D\u5BF9\u8BDD\uFF09\uFF0C\u4F7F\u65B0\u7684 hooks \u548C skill \u751F\u6548\u3002"
|
|
2173
|
+
};
|
|
2174
|
+
function printPostSetupReminder(agent) {
|
|
2175
|
+
const restartReminder = FULL_APP_RESTART_REMINDERS[agent];
|
|
2176
|
+
if (restartReminder) {
|
|
2177
|
+
process.stderr.write(`
|
|
2178
|
+
${dim(restartReminder)}
|
|
2179
|
+
`);
|
|
2180
|
+
}
|
|
2181
|
+
if (agent === "codex") {
|
|
2182
|
+
process.stderr.write(`
|
|
2183
|
+
${dim(CODEX_HOOKS_TRUST_REMINDER)}
|
|
2184
|
+
`);
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2136
2187
|
function parseAgent(args) {
|
|
2137
2188
|
const raw = args.flags.agent;
|
|
2138
2189
|
if (raw === void 0) return "default";
|
|
@@ -2170,19 +2221,19 @@ ${highlightInlineCode(hint)}
|
|
|
2170
2221
|
`);
|
|
2171
2222
|
}
|
|
2172
2223
|
}
|
|
2173
|
-
if (!json
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2224
|
+
if (!json) {
|
|
2225
|
+
for (const agent2 of ["qoder", "qoderwork", "qwenwork", "codex"]) {
|
|
2226
|
+
if (result2.agents[agent2]?.ok) {
|
|
2227
|
+
printPostSetupReminder(agent2);
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2179
2230
|
}
|
|
2180
2231
|
return result2.ok ? 0 : 1;
|
|
2181
2232
|
}
|
|
2182
2233
|
const agent = parseAgent(args);
|
|
2183
2234
|
if (agent === "default" && !json && !configuredAgents().includes("default")) {
|
|
2184
2235
|
process.stderr.write(
|
|
2185
|
-
`hint: creating CLI-only "default" agent (no hooks/skills). Use --agent <claude|qoder|qoderwork|codex|opencode|hermes> for full setup.
|
|
2236
|
+
`hint: creating CLI-only "default" agent (no hooks/skills). Use --agent <claude|qoder|qoderwork|qwenwork|codex|opencode|hermes> for full setup.
|
|
2186
2237
|
`
|
|
2187
2238
|
);
|
|
2188
2239
|
}
|
|
@@ -2202,12 +2253,8 @@ ${highlightInlineCode(h)}
|
|
|
2202
2253
|
`);
|
|
2203
2254
|
}
|
|
2204
2255
|
}
|
|
2205
|
-
if (!json &&
|
|
2206
|
-
|
|
2207
|
-
`
|
|
2208
|
-
${dim(CODEX_HOOKS_TRUST_REMINDER)}
|
|
2209
|
-
`
|
|
2210
|
-
);
|
|
2256
|
+
if (!json && result.ok) {
|
|
2257
|
+
printPostSetupReminder(agent);
|
|
2211
2258
|
}
|
|
2212
2259
|
return result.ok ? 0 : 1;
|
|
2213
2260
|
}
|
|
@@ -2216,11 +2263,11 @@ ${dim(CODEX_HOOKS_TRUST_REMINDER)}
|
|
|
2216
2263
|
var HELP2 = `ctxdb uninstall \u2014 remove hooks + skills
|
|
2217
2264
|
|
|
2218
2265
|
USAGE
|
|
2219
|
-
ctxdb uninstall [--agent <qoder|qoderwork|codex|claude|opencode|hermes>] [--purge-config] [--purge-logs] [--purge-all] [--json]
|
|
2266
|
+
ctxdb uninstall [--agent <qoder|qoderwork|qwenwork|codex|claude|opencode|hermes>] [--purge-config] [--purge-logs] [--purge-all] [--json]
|
|
2220
2267
|
|
|
2221
2268
|
DEFAULT BEHAVIOR (no --agent, no purge flags)
|
|
2222
2269
|
Strips ctxdb hook entries and skill directories for ALL agents (qoder,
|
|
2223
|
-
qoderwork, codex, claude, opencode, hermes). Keeps ~/.ctxdb/ctxdb.json (credentials) and ~/.ctxdb/logs/
|
|
2270
|
+
qoderwork, qwenwork, codex, claude, opencode, hermes). Keeps ~/.ctxdb/ctxdb.json (credentials) and ~/.ctxdb/logs/
|
|
2224
2271
|
so you can re-run \`ctxdb setup\` later without losing configuration.
|
|
2225
2272
|
|
|
2226
2273
|
WITH --agent <name>
|
|
@@ -2228,7 +2275,7 @@ WITH --agent <name>
|
|
|
2228
2275
|
Other agents remain untouched.
|
|
2229
2276
|
|
|
2230
2277
|
FLAGS
|
|
2231
|
-
--agent <name> Target a single agent (qoder|qoderwork|codex|claude|opencode|hermes)
|
|
2278
|
+
--agent <name> Target a single agent (qoder|qoderwork|qwenwork|codex|claude|opencode|hermes)
|
|
2232
2279
|
--purge-config Also delete ~/.ctxdb/ctxdb.json
|
|
2233
2280
|
--purge-logs Also delete ~/.ctxdb/logs/
|
|
2234
2281
|
--purge-all Delete everything under ~/.ctxdb/
|
|
@@ -2280,7 +2327,7 @@ ${h}
|
|
|
2280
2327
|
var HELP3 = `ctxdb upgrade \u2014 refresh skills + hooks
|
|
2281
2328
|
|
|
2282
2329
|
USAGE
|
|
2283
|
-
ctxdb upgrade [--agent <qoder|qoderwork|codex|claude|opencode|hermes>] [--no-self-update] [--json]
|
|
2330
|
+
ctxdb upgrade [--agent <qoder|qoderwork|qwenwork|codex|claude|opencode|hermes>] [--no-self-update] [--json]
|
|
2284
2331
|
|
|
2285
2332
|
BEHAVIOR
|
|
2286
2333
|
Pulls the latest @aliyunrds/ctxdb package from npm, then re-runs setup
|
|
@@ -2290,7 +2337,7 @@ BEHAVIOR
|
|
|
2290
2337
|
With --agent: sets up only the specified agent.
|
|
2291
2338
|
|
|
2292
2339
|
FLAGS
|
|
2293
|
-
--agent <name> Target a single agent (qoder|qoderwork|codex|claude|opencode|hermes)
|
|
2340
|
+
--agent <name> Target a single agent (qoder|qoderwork|qwenwork|codex|claude|opencode|hermes)
|
|
2294
2341
|
--self-update Pull latest package from npm (enabled by default)
|
|
2295
2342
|
--no-self-update Skip the npm package update and only re-run setup
|
|
2296
2343
|
--json Machine-readable JSON output
|
|
@@ -2418,7 +2465,8 @@ function skillInstall(args) {
|
|
|
2418
2465
|
}
|
|
2419
2466
|
const TARGET_TEMPLATE_AGENT = {
|
|
2420
2467
|
qodercn: "qoder",
|
|
2421
|
-
qoderworkcn: "qoderwork"
|
|
2468
|
+
qoderworkcn: "qoderwork",
|
|
2469
|
+
qwenworkcn: "qwenwork"
|
|
2422
2470
|
};
|
|
2423
2471
|
const templateAgent = TARGET_TEMPLATE_AGENT[target] ?? (target && isBuiltinAgent(target) ? target : "default");
|
|
2424
2472
|
const result = installSkillsTo(targetRoot, templateAgent);
|
|
@@ -2680,6 +2728,163 @@ async function kbSearch(args) {
|
|
|
2680
2728
|
return 0;
|
|
2681
2729
|
}
|
|
2682
2730
|
|
|
2731
|
+
// src/cli/debug-cli.ts
|
|
2732
|
+
import {
|
|
2733
|
+
readRecallTraces
|
|
2734
|
+
} from "@aliyunrds/ctxdb-shared";
|
|
2735
|
+
var CONTROL_HELP = `ctxdb debug enable|disable \u2014 control local recall tracing
|
|
2736
|
+
|
|
2737
|
+
USAGE
|
|
2738
|
+
ctxdb debug enable [--agent=<name>] [--json]
|
|
2739
|
+
ctxdb debug disable [--agent=<name>] [--json]
|
|
2740
|
+
|
|
2741
|
+
Debug is forced on when the final CTXDB base URL is not the official
|
|
2742
|
+
production URL. A forced profile cannot be disabled until its endpoint changes.
|
|
2743
|
+
`;
|
|
2744
|
+
var RECALL_HELP = `ctxdb debug recall \u2014 replay local recall traces
|
|
2745
|
+
|
|
2746
|
+
USAGE
|
|
2747
|
+
ctxdb debug recall (--session=<id> | --event=<id>) [--full] [--json]
|
|
2748
|
+
|
|
2749
|
+
Reads ~/.ctxdb/logs/recall-trace.jsonl and its rotated generations.
|
|
2750
|
+
An unmatched recall.start means the hook was interrupted or terminated before
|
|
2751
|
+
recall.finish; it is not a completed timeout outcome.
|
|
2752
|
+
`;
|
|
2753
|
+
function resultFor(agent, changed) {
|
|
2754
|
+
const cfg = load({ agent });
|
|
2755
|
+
return {
|
|
2756
|
+
ok: true,
|
|
2757
|
+
agent,
|
|
2758
|
+
debug: cfg.debug,
|
|
2759
|
+
debug_configured: cfg.debugConfigured,
|
|
2760
|
+
debug_forced: cfg.debugForced,
|
|
2761
|
+
debug_reason: cfg.debugReason,
|
|
2762
|
+
changed
|
|
2763
|
+
};
|
|
2764
|
+
}
|
|
2765
|
+
function printControlResult(result, json) {
|
|
2766
|
+
if (json) {
|
|
2767
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
2768
|
+
`);
|
|
2769
|
+
return;
|
|
2770
|
+
}
|
|
2771
|
+
const configured = result.debug_configured ? "enabled" : "disabled";
|
|
2772
|
+
const effective = result.debug ? "enabled" : "disabled";
|
|
2773
|
+
const forced = result.debug_forced ? "yes" : "no";
|
|
2774
|
+
process.stdout.write(
|
|
2775
|
+
`ctxdb debug (${result.agent}): ${effective}
|
|
2776
|
+
configured: ${configured}
|
|
2777
|
+
forced: ${forced}
|
|
2778
|
+
reason: ${result.debug_reason ?? "-"}
|
|
2779
|
+
`
|
|
2780
|
+
);
|
|
2781
|
+
}
|
|
2782
|
+
async function controlDebug(args, configured) {
|
|
2783
|
+
if (args.flags.help || args.flags.h) {
|
|
2784
|
+
process.stdout.write(CONTROL_HELP);
|
|
2785
|
+
return 0;
|
|
2786
|
+
}
|
|
2787
|
+
const agent = agentFromFlags(args.flags);
|
|
2788
|
+
const current = load({ agent });
|
|
2789
|
+
if (!hasConfiguredAgent(agent)) {
|
|
2790
|
+
const hint = agent === "default" ? "run `ctxdb setup --api-key=<key>` or select a configured --agent" : `run \`ctxdb setup --agent ${agent}\` first`;
|
|
2791
|
+
process.stderr.write(`no configured profile for agent ${agent}; ${hint}
|
|
2792
|
+
`);
|
|
2793
|
+
return 1;
|
|
2794
|
+
}
|
|
2795
|
+
if (!configured && current.debugForced) {
|
|
2796
|
+
const result2 = {
|
|
2797
|
+
ok: false,
|
|
2798
|
+
agent,
|
|
2799
|
+
debug: current.debug,
|
|
2800
|
+
debug_configured: current.debugConfigured,
|
|
2801
|
+
debug_forced: current.debugForced,
|
|
2802
|
+
debug_reason: current.debugReason,
|
|
2803
|
+
changed: false
|
|
2804
|
+
};
|
|
2805
|
+
if (args.flags.json) {
|
|
2806
|
+
process.stdout.write(`${JSON.stringify(result2, null, 2)}
|
|
2807
|
+
`);
|
|
2808
|
+
} else {
|
|
2809
|
+
process.stderr.write(
|
|
2810
|
+
`cannot disable debug for ${agent}: debug is forced by non-production base_url (reason: ${current.debugReason})
|
|
2811
|
+
`
|
|
2812
|
+
);
|
|
2813
|
+
printControlResult(result2, false);
|
|
2814
|
+
}
|
|
2815
|
+
return 1;
|
|
2816
|
+
}
|
|
2817
|
+
const changed = current.debugConfigured !== configured;
|
|
2818
|
+
if (!updateConfiguredDebug(agent, configured)) {
|
|
2819
|
+
process.stderr.write(`failed to update debug for agent ${agent}
|
|
2820
|
+
`);
|
|
2821
|
+
return 1;
|
|
2822
|
+
}
|
|
2823
|
+
const result = resultFor(agent, changed);
|
|
2824
|
+
printControlResult(result, Boolean(args.flags.json));
|
|
2825
|
+
return 0;
|
|
2826
|
+
}
|
|
2827
|
+
function debugEnable(args) {
|
|
2828
|
+
return controlDebug(args, true);
|
|
2829
|
+
}
|
|
2830
|
+
function debugDisable(args) {
|
|
2831
|
+
return controlDebug(args, false);
|
|
2832
|
+
}
|
|
2833
|
+
function compactRecord(record) {
|
|
2834
|
+
const base = `${record.timestamp} ${record.agent}/${record.kind} ${record.type} event=${record.recall_event_id} session=${record.session_id ?? "-"}`;
|
|
2835
|
+
if (record.type === "recall.start") {
|
|
2836
|
+
return `${base} query_chars=${record.query.length}`;
|
|
2837
|
+
}
|
|
2838
|
+
return `${base} outcome=${record.outcome} duration_ms=${record.duration_ms} returned=${record.returned_memories.length} selected=${record.selection.selected.length} knowledge=${record.returned_knowledge.length}`;
|
|
2839
|
+
}
|
|
2840
|
+
async function debugRecall(args) {
|
|
2841
|
+
if (args.flags.help || args.flags.h) {
|
|
2842
|
+
process.stdout.write(RECALL_HELP);
|
|
2843
|
+
return 0;
|
|
2844
|
+
}
|
|
2845
|
+
const session = typeof args.flags.session === "string" && args.flags.session ? args.flags.session : null;
|
|
2846
|
+
const event = typeof args.flags.event === "string" && args.flags.event ? args.flags.event : null;
|
|
2847
|
+
if (session && event || !session && !event) {
|
|
2848
|
+
process.stderr.write(
|
|
2849
|
+
"exactly one of --session=<id> or --event=<id> is required\n"
|
|
2850
|
+
);
|
|
2851
|
+
return 2;
|
|
2852
|
+
}
|
|
2853
|
+
const result = readRecallTraces({
|
|
2854
|
+
...session ? { sessionId: session } : { recallEventId: event }
|
|
2855
|
+
});
|
|
2856
|
+
const output = {
|
|
2857
|
+
ok: true,
|
|
2858
|
+
selector: session ? { session } : { event },
|
|
2859
|
+
count: result.records.length,
|
|
2860
|
+
malformed_lines: result.malformedLines,
|
|
2861
|
+
records: result.records
|
|
2862
|
+
};
|
|
2863
|
+
if (args.flags.json) {
|
|
2864
|
+
process.stdout.write(`${JSON.stringify(output, null, 2)}
|
|
2865
|
+
`);
|
|
2866
|
+
return 0;
|
|
2867
|
+
}
|
|
2868
|
+
if (result.records.length === 0) {
|
|
2869
|
+
process.stdout.write("No matching recall traces.\n");
|
|
2870
|
+
return 0;
|
|
2871
|
+
}
|
|
2872
|
+
if (args.flags.full) {
|
|
2873
|
+
process.stdout.write(`${JSON.stringify(result.records, null, 2)}
|
|
2874
|
+
`);
|
|
2875
|
+
} else {
|
|
2876
|
+
process.stdout.write(`${result.records.map(compactRecord).join("\n")}
|
|
2877
|
+
`);
|
|
2878
|
+
}
|
|
2879
|
+
if (result.malformedLines > 0) {
|
|
2880
|
+
process.stderr.write(
|
|
2881
|
+
`skipped ${result.malformedLines} malformed recall trace line(s)
|
|
2882
|
+
`
|
|
2883
|
+
);
|
|
2884
|
+
}
|
|
2885
|
+
return 0;
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2683
2888
|
// src/cli/main.ts
|
|
2684
2889
|
var HELP5 = `ctxdb v${PACKAGE_VERSION} \u2014 RDS ContextDatabase CLI (multi-agent)
|
|
2685
2890
|
|
|
@@ -2687,7 +2892,7 @@ USAGE
|
|
|
2687
2892
|
ctxdb <command> [args] [--flags]
|
|
2688
2893
|
|
|
2689
2894
|
COMMANDS
|
|
2690
|
-
setup [--agent <qoder|qoderwork|codex|claude|opencode|hermes> | --all]
|
|
2895
|
+
setup [--agent <qoder|qoderwork|qwenwork|codex|claude|opencode|hermes> | --all]
|
|
2691
2896
|
[--api-key=K] [--base-url=URL] [--user-id=ID]
|
|
2692
2897
|
[--no-install-skill] [--no-validate] [--json]
|
|
2693
2898
|
Without --agent \u2192 writes agents.default (CLI-only, no hooks/skills)
|
|
@@ -2716,6 +2921,10 @@ COMMANDS
|
|
|
2716
2921
|
upgrade|update [--agent <name>] [--no-self-update] [--json]
|
|
2717
2922
|
Pull latest package from npm, then re-run
|
|
2718
2923
|
setup. Self-update is enabled by default.
|
|
2924
|
+
debug enable|disable [--agent <name>] [--json]
|
|
2925
|
+
Control configured debug for an existing profile.
|
|
2926
|
+
debug recall (--session=<id> | --event=<id>) [--full] [--json]
|
|
2927
|
+
Replay local full-fidelity recall traces.
|
|
2719
2928
|
|
|
2720
2929
|
memory add <text> [--agent=<name>] [--user-id=...] [--metadata=K1=V1,K2=V2] [--no-infer]
|
|
2721
2930
|
memory search <query> [--agent=<name>] [--top-k=10] [--threshold=0.4] [--knowledge]
|
|
@@ -2750,7 +2959,7 @@ COMMANDS
|
|
|
2750
2959
|
doc_id?/tags? for citation.
|
|
2751
2960
|
--raw: server response verbatim (curl parity).
|
|
2752
2961
|
|
|
2753
|
-
skill install --target <qoder|qoderwork|codex|claude|opencode|openclaw|hermes> [--json]
|
|
2962
|
+
skill install --target <qoder|qoderwork|qwenwork|codex|claude|opencode|openclaw|hermes> [--json]
|
|
2754
2963
|
skill install --path <dir> [--json]
|
|
2755
2964
|
Install skill files (contextdb-memory,
|
|
2756
2965
|
contextdb-knowledge) to an agent's skill directory.
|
|
@@ -2773,7 +2982,7 @@ HOOK ENV VARS:
|
|
|
2773
2982
|
Direct ctxdb CLI commands are unchanged.
|
|
2774
2983
|
|
|
2775
2984
|
CONFIG: ~/.ctxdb/ctxdb.json (agents.default / agents.qoder / agents.qoderwork / agents.codex / agents.claude / agents.opencode / agents.hermes)
|
|
2776
|
-
LOGS: ~/.ctxdb/logs/ctxdb.log
|
|
2985
|
+
LOGS: ~/.ctxdb/logs/ctxdb.log, ~/.ctxdb/logs/recall-trace.jsonl
|
|
2777
2986
|
`;
|
|
2778
2987
|
var ROUTES = {
|
|
2779
2988
|
setup,
|
|
@@ -2783,6 +2992,11 @@ var ROUTES = {
|
|
|
2783
2992
|
teardown: uninstall,
|
|
2784
2993
|
upgrade,
|
|
2785
2994
|
update: upgrade,
|
|
2995
|
+
debug: {
|
|
2996
|
+
enable: debugEnable,
|
|
2997
|
+
disable: debugDisable,
|
|
2998
|
+
recall: debugRecall
|
|
2999
|
+
},
|
|
2786
3000
|
skill: {
|
|
2787
3001
|
install: skillInstall
|
|
2788
3002
|
},
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
captureParsedMessages
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-6BB65W5W.js";
|
|
5
|
+
import "../chunk-B7JCQL4O.js";
|
|
6
6
|
import {
|
|
7
7
|
HttpClient,
|
|
8
8
|
agentFromArgvWithFallback,
|
|
9
9
|
debug,
|
|
10
10
|
load,
|
|
11
11
|
setDebug
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-ARZX2RLR.js";
|
|
13
13
|
import {
|
|
14
14
|
shouldSkipHooks
|
|
15
15
|
} from "../chunk-UEKR2Z3S.js";
|