@aliyunrds/ctxdb 0.0.8-beta.1 → 0.0.8-beta.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/dist/{chunk-KEQMJ6IO.js → chunk-52IAVJRK.js} +1 -1
- package/dist/{chunk-C62I23HL.js → chunk-73OY44GY.js} +2 -2
- package/dist/{chunk-U3T5O6NX.js → chunk-BWPFGTF7.js} +14 -6
- package/dist/cli/main.js +40 -24
- package/dist/hooks/session-start.js +3 -3
- package/dist/hooks/stop.js +161 -11
- package/dist/hooks/user-prompt-submit.js +3 -3
- package/dist/setup/skills/contextdb-knowledge/SKILL.md +14 -12
- package/dist/setup/skills/contextdb-memory/SKILL.md +12 -10
- package/package.json +1 -1
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
isConnectionError,
|
|
7
7
|
resetCircuit,
|
|
8
8
|
tripCircuit
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-52IAVJRK.js";
|
|
10
10
|
import {
|
|
11
11
|
CtxdbError
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-BWPFGTF7.js";
|
|
13
13
|
|
|
14
14
|
// src/lib/recall-orchestrator.ts
|
|
15
15
|
import {
|
|
@@ -39,23 +39,27 @@ ${s}`;
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
// src/lib/
|
|
42
|
+
// src/lib/package-version.ts
|
|
43
43
|
import { readFileSync } from "fs";
|
|
44
|
-
import { fileURLToPath } from "url";
|
|
45
44
|
import { dirname as dirname2, join as join2 } from "path";
|
|
45
|
+
import { fileURLToPath } from "url";
|
|
46
46
|
function findPackageVersion() {
|
|
47
47
|
let dir = dirname2(fileURLToPath(import.meta.url));
|
|
48
48
|
for (let i = 0; i < 5; i++) {
|
|
49
49
|
try {
|
|
50
50
|
const pkg = JSON.parse(readFileSync(join2(dir, "package.json"), "utf-8"));
|
|
51
|
-
if (pkg.name === "@aliyunrds/ctxdb"
|
|
51
|
+
if (pkg.name === "@aliyunrds/ctxdb" && typeof pkg.version === "string") {
|
|
52
|
+
return pkg.version;
|
|
53
|
+
}
|
|
52
54
|
} catch {
|
|
53
55
|
}
|
|
54
56
|
dir = dirname2(dir);
|
|
55
57
|
}
|
|
56
58
|
return "0.0.0";
|
|
57
59
|
}
|
|
58
|
-
var
|
|
60
|
+
var PACKAGE_VERSION = findPackageVersion();
|
|
61
|
+
|
|
62
|
+
// src/lib/http-client.ts
|
|
59
63
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
60
64
|
var CtxdbError = class extends Error {
|
|
61
65
|
constructor(message) {
|
|
@@ -108,7 +112,7 @@ var HttpClient = class {
|
|
|
108
112
|
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
109
113
|
this.apiKey = opts.apiKey;
|
|
110
114
|
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
111
|
-
this.userAgent = opts.userAgent ?? `ctxdb-cli/${
|
|
115
|
+
this.userAgent = opts.userAgent ?? `ctxdb-cli/${PACKAGE_VERSION}`;
|
|
112
116
|
this.extraHeaders = { ...opts.extraHeaders ?? {} };
|
|
113
117
|
const f = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
114
118
|
this.fetchImpl = f;
|
|
@@ -257,7 +261,7 @@ function extractErrorDetail(text, fallback) {
|
|
|
257
261
|
// src/lib/agents.ts
|
|
258
262
|
import { homedir as homedir2 } from "os";
|
|
259
263
|
import { join as join3 } from "path";
|
|
260
|
-
var SUPPORTED_AGENTS = ["qoder", "codex", "claude"];
|
|
264
|
+
var SUPPORTED_AGENTS = ["qoder", "qoderwork", "codex", "claude"];
|
|
261
265
|
function isBuiltinAgent(v) {
|
|
262
266
|
return typeof v === "string" && SUPPORTED_AGENTS.includes(v);
|
|
263
267
|
}
|
|
@@ -269,6 +273,8 @@ function agentHomeDir(agent) {
|
|
|
269
273
|
switch (agent) {
|
|
270
274
|
case "qoder":
|
|
271
275
|
return join3(homedir2(), ".qoder");
|
|
276
|
+
case "qoderwork":
|
|
277
|
+
return join3(homedir2(), ".qoderwork");
|
|
272
278
|
case "codex":
|
|
273
279
|
return join3(homedir2(), ".codex");
|
|
274
280
|
case "claude":
|
|
@@ -490,7 +496,9 @@ function writeInstalledPkgVersion(version, path) {
|
|
|
490
496
|
|
|
491
497
|
export {
|
|
492
498
|
setDebug,
|
|
499
|
+
isDebug,
|
|
493
500
|
debug,
|
|
501
|
+
PACKAGE_VERSION,
|
|
494
502
|
CtxdbError,
|
|
495
503
|
HttpClient,
|
|
496
504
|
SUPPORTED_AGENTS,
|
package/dist/cli/main.js
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
DEFAULT_BASE_URL,
|
|
19
19
|
DEFAULT_USER_ID,
|
|
20
20
|
HttpClient,
|
|
21
|
+
PACKAGE_VERSION,
|
|
21
22
|
SUPPORTED_AGENTS,
|
|
22
23
|
agentFromEnv,
|
|
23
24
|
agentHomeDir,
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
removeAgent,
|
|
30
31
|
save,
|
|
31
32
|
writeInstalledPkgVersion
|
|
32
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-BWPFGTF7.js";
|
|
33
34
|
|
|
34
35
|
// src/cli/util.ts
|
|
35
36
|
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
@@ -216,7 +217,6 @@ function fail(message, code = 1) {
|
|
|
216
217
|
`);
|
|
217
218
|
process.exit(code);
|
|
218
219
|
}
|
|
219
|
-
var PACKAGE_VERSION = "0.0.7";
|
|
220
220
|
|
|
221
221
|
// src/setup/installer.ts
|
|
222
222
|
import {
|
|
@@ -242,6 +242,8 @@ function skillInstallRoot(agent) {
|
|
|
242
242
|
switch (agent) {
|
|
243
243
|
case "qoder":
|
|
244
244
|
return join(homedir(), ".qoder", "skills");
|
|
245
|
+
case "qoderwork":
|
|
246
|
+
return join(homedir(), ".qoderwork", "skills");
|
|
245
247
|
case "codex":
|
|
246
248
|
return join(homedir(), ".codex", "skills");
|
|
247
249
|
case "claude":
|
|
@@ -257,6 +259,8 @@ function hookConfigPath(agent) {
|
|
|
257
259
|
switch (agent) {
|
|
258
260
|
case "qoder":
|
|
259
261
|
return join(homedir(), ".qoder", "settings.json");
|
|
262
|
+
case "qoderwork":
|
|
263
|
+
return join(homedir(), ".qoderwork", "settings.json");
|
|
260
264
|
case "codex":
|
|
261
265
|
return join(homedir(), ".codex", "hooks.json");
|
|
262
266
|
case "claude":
|
|
@@ -306,6 +310,14 @@ async function runSetup(options) {
|
|
|
306
310
|
ok: true,
|
|
307
311
|
detail: `${agent}: ${cfg.baseUrl} (user_id=${cfg.userId})`
|
|
308
312
|
});
|
|
313
|
+
if (isBuiltinAgent(agent) && !configuredAgents().includes("default")) {
|
|
314
|
+
save(cfg, void 0, { agent: "default" });
|
|
315
|
+
steps.push({
|
|
316
|
+
step: "write-default-config",
|
|
317
|
+
ok: true,
|
|
318
|
+
detail: `default: copied from ${agent}`
|
|
319
|
+
});
|
|
320
|
+
}
|
|
309
321
|
if (installSkill && isBuiltinAgent(agent)) {
|
|
310
322
|
const installRoot = skillInstallRoot(agent);
|
|
311
323
|
const skillResult = installSkillsTo(installRoot, agent);
|
|
@@ -628,11 +640,9 @@ function checkHookNodePaths(agent) {
|
|
|
628
640
|
nodePaths.add(h.command);
|
|
629
641
|
} else {
|
|
630
642
|
const cmd = h.command;
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
nodePaths.add(parts[0]);
|
|
635
|
-
}
|
|
643
|
+
const parts = cmd.split(" ");
|
|
644
|
+
if (parts.length >= 2 && !parts[0].endsWith(".js") && !parts[0].endsWith(".ts")) {
|
|
645
|
+
nodePaths.add(parts[0]);
|
|
636
646
|
}
|
|
637
647
|
}
|
|
638
648
|
}
|
|
@@ -808,6 +818,7 @@ function copySkillDir(src, dest, agent) {
|
|
|
808
818
|
}
|
|
809
819
|
var SKILL_INSTALL_TARGETS = {
|
|
810
820
|
qoder: join(homedir(), ".qoder", "skills"),
|
|
821
|
+
qoderwork: join(homedir(), ".qoderwork", "skills"),
|
|
811
822
|
codex: join(homedir(), ".codex", "skills"),
|
|
812
823
|
claude: join(homedir(), ".claude", "skills"),
|
|
813
824
|
openclaw: join(homedir(), ".openclaw", "skills"),
|
|
@@ -870,14 +881,17 @@ var LEGACY_MARKER_VALUES = ["@aliyunrds/ctxdb-qoder"];
|
|
|
870
881
|
var TOOL_SCOPED_EVENTS = /* @__PURE__ */ new Set(["PreToolUse", "PostToolUse"]);
|
|
871
882
|
function appendOne(hooks, event, command, agent) {
|
|
872
883
|
if (!Array.isArray(hooks[event])) hooks[event] = [];
|
|
884
|
+
const useExecForm = agent === "claude";
|
|
885
|
+
const shellCmd = `${process.execPath} ${command} --agent=${agent}`;
|
|
873
886
|
const dup = hooks[event].some(
|
|
874
887
|
(entry2) => Array.isArray(entry2?.hooks) && entry2.hooks.some(
|
|
875
|
-
(h) => h?.type === "command" && Array.isArray(h.args) && h.args[0] === command
|
|
888
|
+
(h) => h?.type === "command" && (Array.isArray(h.args) && h.args[0] === command || typeof h.command === "string" && h.command.includes(command))
|
|
876
889
|
)
|
|
877
890
|
);
|
|
878
891
|
if (dup) return;
|
|
892
|
+
const inner = useExecForm ? { type: "command", command: process.execPath, args: [command, `--agent=${agent}`], timeout: 60 } : { type: "command", command: shellCmd, timeout: 60 };
|
|
879
893
|
const entry = {
|
|
880
|
-
hooks: [
|
|
894
|
+
hooks: [inner],
|
|
881
895
|
[ENTRY_MARKER_KEY]: ENTRY_MARKER_VALUE,
|
|
882
896
|
[ENTRY_AGENT_KEY]: agent
|
|
883
897
|
};
|
|
@@ -1240,7 +1254,7 @@ async function ping(args) {
|
|
|
1240
1254
|
var HELP = `ctxdb setup \u2014 configure an agent
|
|
1241
1255
|
|
|
1242
1256
|
USAGE
|
|
1243
|
-
ctxdb setup [--agent <qoder|codex|claude>]
|
|
1257
|
+
ctxdb setup [--agent <qoder|qoderwork|codex|claude>]
|
|
1244
1258
|
[--api-key=K] [--base-url=URL] [--user-id=ID]
|
|
1245
1259
|
[--no-install-skill] [--no-validate] [--json]
|
|
1246
1260
|
|
|
@@ -1251,7 +1265,7 @@ BEHAVIOR
|
|
|
1251
1265
|
specified agent harness.
|
|
1252
1266
|
|
|
1253
1267
|
FLAGS
|
|
1254
|
-
--agent <name> Target agent (qoder|codex|claude)
|
|
1268
|
+
--agent <name> Target agent (qoder|qoderwork|codex|claude)
|
|
1255
1269
|
--api-key <key> API key (required on first setup)
|
|
1256
1270
|
--base-url <url> Server URL (default: https://context-database.aliyuncs.com)
|
|
1257
1271
|
--user-id <id> User bucket (default: "default")
|
|
@@ -1278,7 +1292,7 @@ async function setup(args) {
|
|
|
1278
1292
|
const json = !!args.flags.json;
|
|
1279
1293
|
if (agent === "default" && !json && !configuredAgents().includes("default")) {
|
|
1280
1294
|
process.stderr.write(
|
|
1281
|
-
`hint: creating CLI-only "default" agent (no hooks/skills). Use --agent <claude|qoder|codex> for full setup.
|
|
1295
|
+
`hint: creating CLI-only "default" agent (no hooks/skills). Use --agent <claude|qoder|qoderwork|codex> for full setup.
|
|
1282
1296
|
`
|
|
1283
1297
|
);
|
|
1284
1298
|
}
|
|
@@ -1303,11 +1317,11 @@ ${h}
|
|
|
1303
1317
|
var HELP2 = `ctxdb uninstall \u2014 remove hooks + skills
|
|
1304
1318
|
|
|
1305
1319
|
USAGE
|
|
1306
|
-
ctxdb uninstall [--agent <qoder|codex|claude>] [--purge-config] [--purge-logs] [--purge-all] [--json]
|
|
1320
|
+
ctxdb uninstall [--agent <qoder|qoderwork|codex|claude>] [--purge-config] [--purge-logs] [--purge-all] [--json]
|
|
1307
1321
|
|
|
1308
1322
|
DEFAULT BEHAVIOR (no --agent, no purge flags)
|
|
1309
1323
|
Strips ctxdb hook entries and skill directories for ALL agents (qoder,
|
|
1310
|
-
codex, claude). Keeps ~/.ctxdb/ctxdb.json (credentials) and ~/.ctxdb/logs/
|
|
1324
|
+
qoderwork, codex, claude). Keeps ~/.ctxdb/ctxdb.json (credentials) and ~/.ctxdb/logs/
|
|
1311
1325
|
so you can re-run \`ctxdb setup\` later without losing configuration.
|
|
1312
1326
|
|
|
1313
1327
|
WITH --agent <name>
|
|
@@ -1315,7 +1329,7 @@ WITH --agent <name>
|
|
|
1315
1329
|
Other agents remain untouched.
|
|
1316
1330
|
|
|
1317
1331
|
FLAGS
|
|
1318
|
-
--agent <name> Target a single agent (qoder|codex|claude)
|
|
1332
|
+
--agent <name> Target a single agent (qoder|qoderwork|codex|claude)
|
|
1319
1333
|
--purge-config Also delete ~/.ctxdb/ctxdb.json
|
|
1320
1334
|
--purge-logs Also delete ~/.ctxdb/logs/
|
|
1321
1335
|
--purge-all Delete everything under ~/.ctxdb/
|
|
@@ -1457,7 +1471,7 @@ function runSelfUpdate(currentVersion, passthroughArgs = []) {
|
|
|
1457
1471
|
var HELP3 = `ctxdb upgrade \u2014 refresh skills + hooks
|
|
1458
1472
|
|
|
1459
1473
|
USAGE
|
|
1460
|
-
ctxdb upgrade [--agent <qoder|codex|claude>] [--self-update] [--json]
|
|
1474
|
+
ctxdb upgrade [--agent <qoder|qoderwork|codex|claude>] [--self-update] [--json]
|
|
1461
1475
|
|
|
1462
1476
|
BEHAVIOR
|
|
1463
1477
|
Refreshes skill files and hook entries for configured agents without
|
|
@@ -1467,7 +1481,7 @@ BEHAVIOR
|
|
|
1467
1481
|
With --agent: upgrades only the specified agent.
|
|
1468
1482
|
|
|
1469
1483
|
FLAGS
|
|
1470
|
-
--agent <name> Target a single agent (qoder|codex|claude)
|
|
1484
|
+
--agent <name> Target a single agent (qoder|qoderwork|codex|claude)
|
|
1471
1485
|
--self-update Also pull latest package from npm before upgrading
|
|
1472
1486
|
--json Machine-readable JSON output
|
|
1473
1487
|
`;
|
|
@@ -1573,7 +1587,8 @@ function skillInstall(args) {
|
|
|
1573
1587
|
}
|
|
1574
1588
|
targetRoot = resolved;
|
|
1575
1589
|
}
|
|
1576
|
-
const
|
|
1590
|
+
const templateAgent = target && isBuiltinAgent(target) ? target : "default";
|
|
1591
|
+
const result = installSkillsTo(targetRoot, templateAgent);
|
|
1577
1592
|
const ok = result.ok;
|
|
1578
1593
|
const output = {
|
|
1579
1594
|
ok,
|
|
@@ -1829,13 +1844,14 @@ USAGE
|
|
|
1829
1844
|
ctxdb <command> [args] [--flags]
|
|
1830
1845
|
|
|
1831
1846
|
COMMANDS
|
|
1832
|
-
setup [--agent <qoder|codex|claude>]
|
|
1847
|
+
setup [--agent <qoder|qoderwork|codex|claude>]
|
|
1833
1848
|
[--api-key=K] [--base-url=URL] [--user-id=ID]
|
|
1834
1849
|
[--no-install-skill] [--no-validate] [--json]
|
|
1835
1850
|
Without --agent \u2192 writes agents.default (CLI-only, no hooks/skills)
|
|
1836
|
-
Qoder
|
|
1837
|
-
|
|
1838
|
-
|
|
1851
|
+
Qoder \u2192 writes agents.qoder config + ~/.qoder/settings.json hooks + skill
|
|
1852
|
+
QoderWork \u2192 writes agents.qoderwork config + ~/.qoderwork/settings.json hooks + skill
|
|
1853
|
+
Codex \u2192 writes agents.codex config + ~/.codex/hooks.json hooks + skill
|
|
1854
|
+
Claude \u2192 writes agents.claude config + ~/.claude/settings.json hooks + skill
|
|
1839
1855
|
status [--agent <name>] [--json]
|
|
1840
1856
|
ping [--agent <name>] [--json]
|
|
1841
1857
|
uninstall [--agent <name>] [--purge-config] [--purge-logs] [--purge-all] [--json]
|
|
@@ -1878,7 +1894,7 @@ COMMANDS
|
|
|
1878
1894
|
doc_id?/tags? for citation.
|
|
1879
1895
|
--raw: server response verbatim (curl parity).
|
|
1880
1896
|
|
|
1881
|
-
skill install --target <qoder|codex|claude|openclaw|hermes> [--json]
|
|
1897
|
+
skill install --target <qoder|qoderwork|codex|claude|openclaw|hermes> [--json]
|
|
1882
1898
|
skill install --path <dir> [--json]
|
|
1883
1899
|
Install skill files (contextdb-memory,
|
|
1884
1900
|
contextdb-knowledge) to an agent's skill directory.
|
|
@@ -1891,7 +1907,7 @@ AGENT RESOLUTION (when --agent is omitted):
|
|
|
1891
1907
|
ENV VARS (override selected ~/.ctxdb/ctxdb.json agent config):
|
|
1892
1908
|
CTXDB_AGENT CTXDB_API_KEY CTXDB_BASE_URL CTXDB_USER_ID
|
|
1893
1909
|
|
|
1894
|
-
CONFIG: ~/.ctxdb/ctxdb.json (agents.default / agents.qoder / agents.codex / agents.claude)
|
|
1910
|
+
CONFIG: ~/.ctxdb/ctxdb.json (agents.default / agents.qoder / agents.qoderwork / agents.codex / agents.claude)
|
|
1895
1911
|
LOGS: ~/.ctxdb/logs/ctxdb.log
|
|
1896
1912
|
`;
|
|
1897
1913
|
var ROUTES = {
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
fetchKbCatalogBlock,
|
|
4
4
|
recallTurn
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-73OY44GY.js";
|
|
6
6
|
import "../chunk-6S5RJYBC.js";
|
|
7
7
|
import {
|
|
8
8
|
isCircuitOpen
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-52IAVJRK.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-BWPFGTF7.js";
|
|
18
18
|
|
|
19
19
|
// src/hooks/session-start.ts
|
|
20
20
|
import { pathToFileURL } from "url";
|
package/dist/hooks/stop.js
CHANGED
|
@@ -4,15 +4,16 @@ import {
|
|
|
4
4
|
isConnectionError,
|
|
5
5
|
resetCircuit,
|
|
6
6
|
tripCircuit
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-52IAVJRK.js";
|
|
8
8
|
import {
|
|
9
9
|
CtxdbError,
|
|
10
10
|
HttpClient,
|
|
11
11
|
agentFromArgvWithFallback,
|
|
12
12
|
debug,
|
|
13
|
+
isDebug,
|
|
13
14
|
load,
|
|
14
15
|
setDebug
|
|
15
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-BWPFGTF7.js";
|
|
16
17
|
|
|
17
18
|
// src/lib/capture-orchestrator.ts
|
|
18
19
|
import {
|
|
@@ -122,6 +123,48 @@ function toKbDetectionMessages(rows) {
|
|
|
122
123
|
}
|
|
123
124
|
return out;
|
|
124
125
|
}
|
|
126
|
+
function selectTurnRows(rows) {
|
|
127
|
+
let turnStart = -1;
|
|
128
|
+
for (let ri = rows.length - 1; ri >= 0; ri--) {
|
|
129
|
+
if (hasExtractableUserText(rows[ri])) {
|
|
130
|
+
turnStart = ri;
|
|
131
|
+
while (turnStart > 0 && hasExtractableUserText(rows[turnStart - 1])) {
|
|
132
|
+
turnStart--;
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return turnStart >= 0 ? rows.slice(turnStart) : [];
|
|
138
|
+
}
|
|
139
|
+
function hasExtractableUserText(row) {
|
|
140
|
+
if (!row || typeof row !== "object") return false;
|
|
141
|
+
if (row.type === CODEX_RESPONSE_ITEM) {
|
|
142
|
+
const p = row.payload;
|
|
143
|
+
if (!p || typeof p !== "object") return false;
|
|
144
|
+
if (p.type !== "message" || p.role !== "user") return false;
|
|
145
|
+
const content2 = p.content;
|
|
146
|
+
if (!Array.isArray(content2)) return false;
|
|
147
|
+
return content2.some((block) => {
|
|
148
|
+
if (!block || typeof block !== "object") return false;
|
|
149
|
+
if (block.type !== "input_text") return false;
|
|
150
|
+
const text = block.text;
|
|
151
|
+
return typeof text === "string" && text.trim() && !isCodexScaffoldingText(text);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (row.isMeta === true) return false;
|
|
155
|
+
const msg = row.message;
|
|
156
|
+
if (!msg || typeof msg !== "object") return false;
|
|
157
|
+
if (msg.role !== "user") return false;
|
|
158
|
+
const content = msg.content;
|
|
159
|
+
if (typeof content === "string") return Boolean(content.trim());
|
|
160
|
+
if (!Array.isArray(content)) return false;
|
|
161
|
+
return content.some((block) => {
|
|
162
|
+
if (!block || typeof block !== "object") return false;
|
|
163
|
+
if (block.type !== "text") return false;
|
|
164
|
+
const text = block.text;
|
|
165
|
+
return typeof text === "string" && Boolean(text.trim());
|
|
166
|
+
});
|
|
167
|
+
}
|
|
125
168
|
function parseArgs(raw) {
|
|
126
169
|
if (typeof raw !== "string") return {};
|
|
127
170
|
try {
|
|
@@ -275,15 +318,10 @@ async function captureTurn(transcriptPath, cfg, client, agent = "default") {
|
|
|
275
318
|
if (rows.length === 0) {
|
|
276
319
|
return { captured: false, reason: "empty_transcript", messageCount: 0 };
|
|
277
320
|
}
|
|
278
|
-
const
|
|
279
|
-
if (
|
|
280
|
-
return {
|
|
281
|
-
captured: false,
|
|
282
|
-
reason: `b3c_skip: ${kb.reason ?? "(no reason)"}`,
|
|
283
|
-
messageCount: 0
|
|
284
|
-
};
|
|
285
|
-
}
|
|
321
|
+
const dbg = isDebug();
|
|
322
|
+
if (dbg) debug("capture", "transcript rows", summarizeTranscriptRows(rows));
|
|
286
323
|
const parsed = toParsedMessages(rows);
|
|
324
|
+
if (dbg) debug("capture", "parsed messages", summarizeTextMessages(parsed));
|
|
287
325
|
if (parsed.length === 0) {
|
|
288
326
|
return {
|
|
289
327
|
captured: false,
|
|
@@ -292,14 +330,26 @@ async function captureTurn(transcriptPath, cfg, client, agent = "default") {
|
|
|
292
330
|
};
|
|
293
331
|
}
|
|
294
332
|
const turn = selectTurnMessages(parsed);
|
|
333
|
+
if (dbg) debug("capture", "selected turn", summarizeTextMessages(turn));
|
|
295
334
|
if (turn.length === 0) {
|
|
296
335
|
return { captured: false, reason: "empty_turn_slice", messageCount: 0 };
|
|
297
336
|
}
|
|
298
337
|
if (!turn.some((m) => m.role === "user")) {
|
|
299
338
|
return { captured: false, reason: "no_user_in_turn", messageCount: 0 };
|
|
300
339
|
}
|
|
340
|
+
const turnRows = selectTurnRows(rows);
|
|
341
|
+
if (dbg) debug("capture", "current turn rows", summarizeTranscriptRows(turnRows));
|
|
342
|
+
const kb = isKnowledgeBaseUploadTurn(toKbDetectionMessages(turnRows));
|
|
343
|
+
if (kb.detected) {
|
|
344
|
+
return {
|
|
345
|
+
captured: false,
|
|
346
|
+
reason: `b3c_skip: ${kb.reason ?? "(no reason)"}`,
|
|
347
|
+
messageCount: 0
|
|
348
|
+
};
|
|
349
|
+
}
|
|
301
350
|
const rawMessages = turn.map((m) => ({ role: m.role, content: m.content }));
|
|
302
351
|
const filtered = filterMessagesForExtraction(rawMessages);
|
|
352
|
+
if (dbg) debug("capture", "filtered messages", summarizeTextMessages(filtered));
|
|
303
353
|
if (filtered.length === 0) {
|
|
304
354
|
return { captured: false, reason: "all_filtered", messageCount: 0 };
|
|
305
355
|
}
|
|
@@ -310,7 +360,9 @@ async function captureTurn(transcriptPath, cfg, client, agent = "default") {
|
|
|
310
360
|
if (skills.length > 0) bg.skills = skills.map(
|
|
311
361
|
({ skill, trigger, args }) => args ? { skill, trigger, args } : { skill, trigger }
|
|
312
362
|
);
|
|
313
|
-
const
|
|
363
|
+
const hasBackground = Boolean(bg.git || bg.skills);
|
|
364
|
+
if (hasBackground) debug("capture", "background", bg);
|
|
365
|
+
const messages = hasBackground ? [{ role: "background", content: JSON.stringify(bg) }, ...filtered] : filtered;
|
|
314
366
|
const payload = {
|
|
315
367
|
messages,
|
|
316
368
|
user_id: cfg.userId,
|
|
@@ -336,6 +388,104 @@ async function captureTurn(transcriptPath, cfg, client, agent = "default") {
|
|
|
336
388
|
messageCount: filtered.length
|
|
337
389
|
};
|
|
338
390
|
}
|
|
391
|
+
var DEBUG_TAIL_LIMIT = 25;
|
|
392
|
+
var DEBUG_TEXT_LIMIT = 240;
|
|
393
|
+
var DEBUG_BLOCK_LIMIT = 8;
|
|
394
|
+
function summarizeTextMessages(messages) {
|
|
395
|
+
return {
|
|
396
|
+
count: messages.length,
|
|
397
|
+
roles: countRoles(messages),
|
|
398
|
+
tail: tailWithIndex(messages).map(({ index, item }) => ({
|
|
399
|
+
index,
|
|
400
|
+
parsedIndex: typeof item.index === "number" ? item.index : void 0,
|
|
401
|
+
role: item.role ?? "(unknown)",
|
|
402
|
+
content: summarizeText(item.content)
|
|
403
|
+
}))
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function summarizeTranscriptRows(rows) {
|
|
407
|
+
return {
|
|
408
|
+
count: rows.length,
|
|
409
|
+
tail: tailWithIndex(rows).map(({ index, item: row }) => ({
|
|
410
|
+
index,
|
|
411
|
+
type: row.type,
|
|
412
|
+
role: rowRole(row),
|
|
413
|
+
isMeta: row.isMeta === true || void 0,
|
|
414
|
+
payloadType: row.payload?.type,
|
|
415
|
+
content: summarizeRowContent(row)
|
|
416
|
+
}))
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
function tailWithIndex(items) {
|
|
420
|
+
const start = Math.max(0, items.length - DEBUG_TAIL_LIMIT);
|
|
421
|
+
return items.slice(start).map((item, offset) => ({ index: start + offset, item }));
|
|
422
|
+
}
|
|
423
|
+
function countRoles(messages) {
|
|
424
|
+
const counts = {};
|
|
425
|
+
for (const msg of messages) {
|
|
426
|
+
const role = msg.role ?? "(unknown)";
|
|
427
|
+
counts[role] = (counts[role] ?? 0) + 1;
|
|
428
|
+
}
|
|
429
|
+
return counts;
|
|
430
|
+
}
|
|
431
|
+
function rowRole(row) {
|
|
432
|
+
const msgRole = row.message && typeof row.message === "object" ? row.message.role : void 0;
|
|
433
|
+
if (typeof msgRole === "string") return msgRole;
|
|
434
|
+
const payloadRole = row.payload && typeof row.payload === "object" ? row.payload.role : void 0;
|
|
435
|
+
return typeof payloadRole === "string" ? payloadRole : void 0;
|
|
436
|
+
}
|
|
437
|
+
function summarizeRowContent(row) {
|
|
438
|
+
if (row.type === "response_item") {
|
|
439
|
+
const p = row.payload;
|
|
440
|
+
if (!p || typeof p !== "object") return { kind: "missing" };
|
|
441
|
+
if (p.type === "function_call") {
|
|
442
|
+
return {
|
|
443
|
+
kind: "function_call",
|
|
444
|
+
name: p.name,
|
|
445
|
+
arguments: summarizeText(p.arguments)
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
return summarizeContent(p.content);
|
|
449
|
+
}
|
|
450
|
+
return summarizeContent(row.message?.content);
|
|
451
|
+
}
|
|
452
|
+
function summarizeContent(content) {
|
|
453
|
+
if (typeof content === "string") return summarizeText(content);
|
|
454
|
+
if (!Array.isArray(content)) {
|
|
455
|
+
return { kind: content === void 0 ? "missing" : typeof content };
|
|
456
|
+
}
|
|
457
|
+
return {
|
|
458
|
+
kind: "blocks",
|
|
459
|
+
count: content.length,
|
|
460
|
+
blocks: content.slice(0, DEBUG_BLOCK_LIMIT).map((block) => summarizeBlock(block)),
|
|
461
|
+
truncated: content.length > DEBUG_BLOCK_LIMIT || void 0
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
function summarizeBlock(block) {
|
|
465
|
+
if (!block || typeof block !== "object") return { kind: typeof block };
|
|
466
|
+
const b = block;
|
|
467
|
+
const summary = { type: b.type };
|
|
468
|
+
if (typeof b.name === "string") summary.name = b.name;
|
|
469
|
+
if (typeof b.text === "string") summary.text = summarizeText(b.text);
|
|
470
|
+
if (typeof b.thinking === "string") summary.thinking = summarizeText(b.thinking);
|
|
471
|
+
if (typeof b.content === "string") summary.content = summarizeText(b.content);
|
|
472
|
+
const input = b.input;
|
|
473
|
+
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
474
|
+
const i = input;
|
|
475
|
+
summary.inputKeys = Object.keys(i).sort();
|
|
476
|
+
if (typeof i.command === "string") summary.command = summarizeText(i.command);
|
|
477
|
+
}
|
|
478
|
+
return summary;
|
|
479
|
+
}
|
|
480
|
+
function summarizeText(text) {
|
|
481
|
+
if (typeof text !== "string") return { kind: text === void 0 ? "missing" : typeof text };
|
|
482
|
+
const normalized = text.replace(/\s+/g, " ").trim();
|
|
483
|
+
return {
|
|
484
|
+
kind: "text",
|
|
485
|
+
length: text.length,
|
|
486
|
+
snippet: normalized.length > DEBUG_TEXT_LIMIT ? `${normalized.slice(0, DEBUG_TEXT_LIMIT)}...` : normalized
|
|
487
|
+
};
|
|
488
|
+
}
|
|
339
489
|
|
|
340
490
|
// src/hooks/stop.ts
|
|
341
491
|
async function readStdinJson() {
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
fetchKbCatalogBlock,
|
|
4
4
|
recallTurn
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-73OY44GY.js";
|
|
6
6
|
import "../chunk-6S5RJYBC.js";
|
|
7
7
|
import {
|
|
8
8
|
isCircuitOpen
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-52IAVJRK.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-BWPFGTF7.js";
|
|
18
18
|
|
|
19
19
|
// src/hooks/user-prompt-submit.ts
|
|
20
20
|
import { pathToFileURL } from "url";
|
|
@@ -18,14 +18,14 @@ description: contextdb 知识库高频操作(查询 / 浏览 KB / 上传文档
|
|
|
18
18
|
|
|
19
19
|
## 2. 高频 recipes
|
|
20
20
|
|
|
21
|
-
>
|
|
21
|
+
> 命令里的 `--agent={{agent}}` 是当前 skill 安装目标。不要把示例改成 `qoder`;如果读到未替换的双花括号 agent 模板,先按 §6 判定真实 agent,再替换成 `qoder` / `qoderwork` / `codex` / `claude` / `default`。
|
|
22
22
|
|
|
23
23
|
### Recipe 1:在已知 KB 中查内容(最常见)
|
|
24
24
|
|
|
25
25
|
**场景**:用户问"X KB 里关于 Y 的内容"、"在知识库 Z 查一下 W"。
|
|
26
26
|
|
|
27
27
|
```sh
|
|
28
|
-
ctxdb kb search "<query>" --kb=<kb-name> --top-k=6 --agent=
|
|
28
|
+
ctxdb kb search "<query>" --kb=<kb-name> --top-k=6 --agent={{agent}}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
返回 `chunks` 数组,按 `score` 倒序判断相关性;默认 threshold 0.4,空结果时见 §5 注意事项 4。
|
|
@@ -37,7 +37,7 @@ ctxdb kb search "<query>" --kb=<kb-name> --top-k=6 --agent=qoder
|
|
|
37
37
|
**场景**:用户问"有哪些知识库"、"列一下 KB",或本身在写 recipe 1 之前需要确认 KB 名。
|
|
38
38
|
|
|
39
39
|
```sh
|
|
40
|
-
ctxdb kb list --agent=
|
|
40
|
+
ctxdb kb list --agent={{agent}}
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
返回 `knowledge_bases` 数组,每项含 `name` / `id` / `document_count`。跨多 KB 查 chunk 时把 `name` 拼起来:`--kb=a,b,c`。
|
|
@@ -49,7 +49,7 @@ ctxdb kb list --agent=qoder
|
|
|
49
49
|
**场景**:用户问"X KB 收了哪些文档"、"X KB 里有几篇"。
|
|
50
50
|
|
|
51
51
|
```sh
|
|
52
|
-
ctxdb kb documents-list <kb-name> --agent=
|
|
52
|
+
ctxdb kb documents-list <kb-name> --agent={{agent}}
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
返回 `documents` 数组,每项含 `name` / `id` / `size`。
|
|
@@ -61,7 +61,7 @@ ctxdb kb documents-list <kb-name> --agent=qoder
|
|
|
61
61
|
**场景**:用户说"把这段记进 X KB"、"上传这段文字到知识库 Y"。
|
|
62
62
|
|
|
63
63
|
```sh
|
|
64
|
-
ctxdb kb upload-text <kb-name> <doc-name> --text="<body>" --agent=
|
|
64
|
+
ctxdb kb upload-text <kb-name> <doc-name> --text="<body>" --agent={{agent}}
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
副作用操作。**用户没明示 KB 名前先 recipe 2 列出来确认**(见 §5 注意事项 3)。KB 不存在会直接报错,不自动创建。
|
|
@@ -73,7 +73,7 @@ ctxdb kb upload-text <kb-name> <doc-name> --text="<body>" --agent=qoder
|
|
|
73
73
|
**场景**:用户说"把 X.pdf 上传到 Y KB"、"灌这个文件进知识库 Z"。
|
|
74
74
|
|
|
75
75
|
```sh
|
|
76
|
-
ctxdb kb upload-file <kb-name> <local-path> --agent=
|
|
76
|
+
ctxdb kb upload-file <kb-name> <local-path> --agent={{agent}}
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
支持格式:PDF / DOCX / MD / TXT。默认等待 chunking 完成;想立即返回加 `--no-wait`(见 §6)。
|
|
@@ -118,7 +118,7 @@ ctxdb kb upload-file <kb-name> <local-path> --agent=qoder
|
|
|
118
118
|
|
|
119
119
|
- **现象**:在 shell 里写 `ctxdb kb list | python3 -c "import json,sys; ..."` 经常因为单/双引号嵌套 escape 失败
|
|
120
120
|
- **根因**:shell + python -c 的引号是两层独立 escape,组合时极容易漏
|
|
121
|
-
- **正确做法**:`ctxdb kb list --agent=
|
|
121
|
+
- **正确做法**:`ctxdb kb list --agent={{agent}} | jq '.knowledge_bases[].name'`;jq 表达式在单引号里不需要 escape
|
|
122
122
|
|
|
123
123
|
### 注意事项 3:`upload-*` / `create` 是副作用,没明示 KB 名前必须先确认
|
|
124
124
|
|
|
@@ -136,7 +136,7 @@ ctxdb kb upload-file <kb-name> <local-path> --agent=qoder
|
|
|
136
136
|
|
|
137
137
|
- **现象**:`kb upload-text foo bar --text=...` 报错 "kb 'foo' not found"
|
|
138
138
|
- **根因**:上传命令只写已有 KB,**不会**为了你 implicit 建一个
|
|
139
|
-
- **正确做法**:先 `ctxdb kb create foo --agent=
|
|
139
|
+
- **正确做法**:先 `ctxdb kb create foo --agent={{agent}}`,再 upload
|
|
140
140
|
|
|
141
141
|
## 6. 高级参数
|
|
142
142
|
|
|
@@ -172,18 +172,20 @@ ctxdb kb upload-file <kb-name> <local-path> --agent=qoder
|
|
|
172
172
|
|
|
173
173
|
| 参数 | 说明 |
|
|
174
174
|
|------|------|
|
|
175
|
-
| `--agent=<name>` | **必填**。指定操作哪个 agent 的配置桶(`qoder` / `codex` / `claude` / `default`) |
|
|
175
|
+
| `--agent=<name>` | **必填**。指定操作哪个 agent 的配置桶(`qoder` / `qoderwork` / `codex` / `claude` / `default`) |
|
|
176
176
|
|
|
177
177
|
`--agent` 解析顺序:
|
|
178
178
|
1. 命令行显式 `--agent=<name>` → 用它
|
|
179
179
|
2. 缺省 → 读 `CTXDB_AGENT` 环境变量
|
|
180
180
|
3. env 也没有 → 落到 `"default"` 桶
|
|
181
|
-
4.
|
|
181
|
+
4. 新版本 `ctxdb setup --agent <qoder|qoderwork|codex|claude>` 会在 `agents.default` 缺失时复制当前 agent 配置作为兜底
|
|
182
|
+
5. 若 `"default"` 桶仍不存在或未配置完整 → exit 2 "config incomplete for agent default"
|
|
182
183
|
|
|
183
184
|
## 7. 配置
|
|
184
185
|
|
|
185
|
-
- 配置文件:`~/.ctxdb/ctxdb.json`,分 `agents.<name>` 段(`qoder` / `codex` / `claude` / `default`),互不复用
|
|
186
|
+
- 配置文件:`~/.ctxdb/ctxdb.json`,分 `agents.<name>` 段(`qoder` / `qoderwork` / `codex` / `claude` / `default`),互不复用
|
|
186
187
|
- 配置命令:`ctxdb setup --agent <name> --api-key=<key> --base-url=<url> [--user-id=<id>]`
|
|
187
|
-
- 带 `--agent` 时还会装 hooks + skill
|
|
188
|
+
- 带 `--agent` 时还会装 hooks + skill;若 `agents.default` 缺失,会复制当前 agent 配置作为 CLI 兜底
|
|
189
|
+
- `--agent default` 只写 `agents.default` 段(仅 CLI 用,不装 hooks / skill)
|
|
188
190
|
- 连接检查:`ctxdb ping --agent=<name>`
|
|
189
191
|
- 状态查看:`ctxdb status --agent=<name>`
|
|
@@ -18,14 +18,14 @@ description: contextdb 长期记忆高频操作(主动记忆 / 搜索过往 /
|
|
|
18
18
|
|
|
19
19
|
## 2. 高频 recipes
|
|
20
20
|
|
|
21
|
-
>
|
|
21
|
+
> 命令里的 `--agent={{agent}}` 是当前 skill 安装目标。不要把示例改成 `qoder`;如果读到未替换的双花括号 agent 模板,先按 §6 判定真实 agent,再替换成 `qoder` / `qoderwork` / `codex` / `claude` / `default`。
|
|
22
22
|
|
|
23
23
|
### Recipe 1:主动记忆("记住 X")
|
|
24
24
|
|
|
25
25
|
**场景**:用户明确说"记住"、"帮我记一下"、"把这条写进记忆"。
|
|
26
26
|
|
|
27
27
|
```sh
|
|
28
|
-
ctxdb memory add "<text>" --agent=
|
|
28
|
+
ctxdb memory add "<text>" --agent={{agent}}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
默认走 LLM fact-extraction(同步等结果)。想原文存(项目代号 / 精确数值)加 `--no-infer`(见 §6)。
|
|
@@ -39,7 +39,7 @@ ctxdb memory add "<text>" --agent=qoder
|
|
|
39
39
|
**场景**:用户问"之前我们讨论过 X 吗"、"上次怎么说的"、"我之前提过 Y 没"。
|
|
40
40
|
|
|
41
41
|
```sh
|
|
42
|
-
ctxdb memory search "<query>" --agent=
|
|
42
|
+
ctxdb memory search "<query>" --agent={{agent}}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
返回 `results` 数组,每项含 `id` / `memory` / `score`,按 score 倒序。top-5 默认。想同时搜知识库 chunks 加 `--knowledge`(见 §6)。
|
|
@@ -51,7 +51,7 @@ ctxdb memory search "<query>" --agent=qoder
|
|
|
51
51
|
**场景**:排查"刚才那条记进去没"、用户想看"系统记了我什么"。
|
|
52
52
|
|
|
53
53
|
```sh
|
|
54
|
-
ctxdb memory list --page-size=20 --agent=
|
|
54
|
+
ctxdb memory list --page-size=20 --agent={{agent}}
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
返回 `results` 数组(含 `total` 计数)。按 category 过滤加 `--category=<cat>`(见 §6)。
|
|
@@ -64,10 +64,10 @@ ctxdb memory list --page-size=20 --agent=qoder
|
|
|
64
64
|
|
|
65
65
|
```sh
|
|
66
66
|
# 改
|
|
67
|
-
ctxdb memory update <memory-id> --text="<new-text>" --agent=
|
|
67
|
+
ctxdb memory update <memory-id> --text="<new-text>" --agent={{agent}}
|
|
68
68
|
|
|
69
69
|
# 删单条
|
|
70
|
-
ctxdb memory delete <memory-id> --agent=
|
|
70
|
+
ctxdb memory delete <memory-id> --agent={{agent}}
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
`<memory-id>` 必须先用 recipe 2 或 recipe 3 拿到。
|
|
@@ -165,18 +165,20 @@ ctxdb memory delete <memory-id> --agent=qoder
|
|
|
165
165
|
|
|
166
166
|
| 参数 | 说明 |
|
|
167
167
|
|------|------|
|
|
168
|
-
| `--agent=<name>` | **必填**。指定操作哪个 agent 的配置桶(`qoder` / `codex` / `claude` / `default`) |
|
|
168
|
+
| `--agent=<name>` | **必填**。指定操作哪个 agent 的配置桶(`qoder` / `qoderwork` / `codex` / `claude` / `default`) |
|
|
169
169
|
|
|
170
170
|
`--agent` 解析顺序:
|
|
171
171
|
1. 命令行显式 `--agent=<name>` → 用它
|
|
172
172
|
2. 缺省 → 读 `CTXDB_AGENT` 环境变量
|
|
173
173
|
3. env 也没有 → 落到 `"default"` 桶
|
|
174
|
-
4.
|
|
174
|
+
4. 新版本 `ctxdb setup --agent <qoder|qoderwork|codex|claude>` 会在 `agents.default` 缺失时复制当前 agent 配置作为兜底
|
|
175
|
+
5. 若 `"default"` 桶仍不存在或未配置完整 → exit 2 "config incomplete for agent default"
|
|
175
176
|
|
|
176
177
|
## 7. 配置
|
|
177
178
|
|
|
178
|
-
- 配置文件:`~/.ctxdb/ctxdb.json`,分 `agents.<name>` 段(`qoder` / `codex` / `claude` / `default`),互不复用
|
|
179
|
+
- 配置文件:`~/.ctxdb/ctxdb.json`,分 `agents.<name>` 段(`qoder` / `qoderwork` / `codex` / `claude` / `default`),互不复用
|
|
179
180
|
- 配置命令:`ctxdb setup --agent <name> --api-key=<key> --base-url=<url> [--user-id=<id>]`
|
|
180
|
-
- 带 `--agent` 时还会装 hooks + skill
|
|
181
|
+
- 带 `--agent` 时还会装 hooks + skill;若 `agents.default` 缺失,会复制当前 agent 配置作为 CLI 兜底
|
|
182
|
+
- `--agent default` 只写 `agents.default` 段(仅 CLI 用,不装 hooks / skill)
|
|
181
183
|
- 连接检查:`ctxdb ping --agent=<name>`
|
|
182
184
|
- 状态查看:`ctxdb status --agent=<name>`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aliyunrds/ctxdb",
|
|
3
|
-
"version": "0.0.8-beta.
|
|
3
|
+
"version": "0.0.8-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Unified access layer for RDS ContextDatabase: `ctxdb` CLI (memory + KB ops), one-shot `setup --agent <qoder|codex|claude>` installer, per-agent config, hooks, and SKILL.md.",
|
|
6
6
|
"license": "Apache-2.0",
|