context-mode 1.0.146 → 1.0.147
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +26 -23
- package/bin/statusline.mjs +22 -9
- package/build/adapters/base.d.ts +9 -4
- package/build/adapters/base.js +16 -7
- package/build/adapters/codex/index.d.ts +1 -1
- package/build/adapters/codex/index.js +10 -4
- package/build/adapters/openclaw/index.d.ts +11 -2
- package/build/adapters/openclaw/index.js +12 -3
- package/build/adapters/pi/mcp-bridge.d.ts +8 -0
- package/build/adapters/pi/mcp-bridge.js +118 -15
- package/build/adapters/types.d.ts +7 -1
- package/build/cli.d.ts +2 -0
- package/build/cli.js +82 -19
- package/build/search/auto-memory.d.ts +6 -1
- package/build/search/auto-memory.js +11 -2
- package/build/server.js +305 -105
- package/build/session/db.d.ts +37 -0
- package/build/session/db.js +197 -2
- package/build/session/extract.js +16 -0
- package/build/truncate.d.ts +15 -0
- package/build/truncate.js +28 -0
- package/cli.bundle.mjs +424 -350
- package/hooks/core/routing.mjs +4 -4
- package/hooks/routing-block.mjs +18 -23
- package/hooks/session-db.bundle.mjs +21 -19
- package/hooks/session-extract.bundle.mjs +2 -2
- package/hooks/session-helpers.mjs +13 -2
- package/hooks/session-snapshot.bundle.mjs +7 -7
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -2
- package/server.bundle.mjs +372 -300
package/build/cli.js
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* context-mode doctor → Diagnose runtime issues, hooks, FTS5, version
|
|
8
8
|
* context-mode upgrade → Fix hooks, permissions, and settings
|
|
9
9
|
* context-mode hook <platform> <event> → Dispatch a hook script (used by platform hook configs)
|
|
10
|
+
* CONTEXT_MODE_DIR=/abs/path context-mode → Override sessions/content storage root
|
|
11
|
+
* Empty/whitespace is ignored; non-empty values must be absolute.
|
|
10
12
|
*
|
|
11
13
|
* Platform auto-detection: CLI detects which platform is running
|
|
12
14
|
* (Claude Code, Gemini CLI, OpenCode, etc.) and uses the appropriate adapter.
|
|
@@ -22,6 +24,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
22
24
|
import { detectRuntimes, getRuntimeSummary, hasBunRuntime, getAvailableLanguages, } from "./runtime.js";
|
|
23
25
|
import { getHookScriptPaths } from "./util/hook-config.js";
|
|
24
26
|
import { resolveClaudeConfigDir } from "./util/claude-config.js";
|
|
27
|
+
import { ensureWritableStorageDir, formatStorageDirectoryError, resolveContentStorageDir, resolveSessionStorageDir, resolveStatsStorageDir, StorageDirectoryError, } from "./session/db.js";
|
|
25
28
|
// v1.0.128 — Issue #559 sibling MCP kill helpers (see PR-559-560-FIX-DESIGN.md).
|
|
26
29
|
import { discoverSiblingMcpPids, killSiblingMcpServers } from "./util/sibling-mcp.js";
|
|
27
30
|
// v1.0.119 — Issue #523 Layer 5 heal: post-bump assertion on .claude-plugin/plugin.json
|
|
@@ -125,8 +128,26 @@ async function hookDispatch(platform, event) {
|
|
|
125
128
|
/* -------------------------------------------------------
|
|
126
129
|
* Entry point
|
|
127
130
|
* ------------------------------------------------------- */
|
|
131
|
+
const IN_PROCESS_PLUGIN_PLATFORMS = new Set(["opencode", "kilo"]);
|
|
132
|
+
const isInProcessPluginPlatform = (p) => p ? IN_PROCESS_PLUGIN_PLATFORMS.has(p) : false;
|
|
128
133
|
const args = process.argv.slice(2);
|
|
129
|
-
|
|
134
|
+
function printHelp() {
|
|
135
|
+
console.log([
|
|
136
|
+
"Usage:",
|
|
137
|
+
" context-mode Start MCP server (stdio)",
|
|
138
|
+
" context-mode doctor Diagnose runtime issues, hooks, FTS5, version",
|
|
139
|
+
" context-mode upgrade Fix hooks, permissions, and settings",
|
|
140
|
+
" context-mode hook <platform> <event> Dispatch a configured hook script",
|
|
141
|
+
" context-mode statusline Print Claude Code status line",
|
|
142
|
+
"",
|
|
143
|
+
"Environment:",
|
|
144
|
+
" CONTEXT_MODE_DIR=/absolute/path Override sessions/content storage root; empty is ignored, non-empty must be absolute",
|
|
145
|
+
].join("\n"));
|
|
146
|
+
}
|
|
147
|
+
if (args[0] === "--help" || args[0] === "-h" || args[0] === "help") {
|
|
148
|
+
printHelp();
|
|
149
|
+
}
|
|
150
|
+
else if (args[0] === "doctor") {
|
|
130
151
|
doctor().then((code) => process.exit(code));
|
|
131
152
|
}
|
|
132
153
|
else if (args[0] === "upgrade") {
|
|
@@ -236,7 +257,7 @@ function cachePluginRoot(platform) {
|
|
|
236
257
|
}
|
|
237
258
|
function getPluginRoot() {
|
|
238
259
|
const platform = detectPlatform().platform;
|
|
239
|
-
if (platform
|
|
260
|
+
if (isInProcessPluginPlatform(platform)) {
|
|
240
261
|
return cachePluginRoot(platform);
|
|
241
262
|
}
|
|
242
263
|
return defaultPluginRoot();
|
|
@@ -276,6 +297,25 @@ async function fetchLatestVersion() {
|
|
|
276
297
|
/* -------------------------------------------------------
|
|
277
298
|
* Doctor — adapter-aware diagnostics
|
|
278
299
|
* ------------------------------------------------------- */
|
|
300
|
+
function describeStorageSource(dir) {
|
|
301
|
+
return dir.envVar ? dir.envVar : "adapter default";
|
|
302
|
+
}
|
|
303
|
+
function logStorageDir(dir) {
|
|
304
|
+
try {
|
|
305
|
+
ensureWritableStorageDir(dir);
|
|
306
|
+
p.log.success(color.green(`Storage ${dir.kind}: PASS`) +
|
|
307
|
+
color.dim(` — ${dir.path} (${describeStorageSource(dir)})`));
|
|
308
|
+
return 0;
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
if (err instanceof StorageDirectoryError) {
|
|
312
|
+
p.log.error(color.red(`Storage ${dir.kind}: FAIL`) +
|
|
313
|
+
color.dim(` — ${formatStorageDirectoryError(err)}`));
|
|
314
|
+
return 1;
|
|
315
|
+
}
|
|
316
|
+
throw err;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
279
319
|
async function doctor() {
|
|
280
320
|
if (process.stdout.isTTY)
|
|
281
321
|
console.clear();
|
|
@@ -286,6 +326,29 @@ async function doctor() {
|
|
|
286
326
|
p.log.info(`Platform: ${color.cyan(adapter.name)}` +
|
|
287
327
|
color.dim(` (${detection.confidence} confidence — ${detection.reason})`));
|
|
288
328
|
let criticalFails = 0;
|
|
329
|
+
try {
|
|
330
|
+
const sessionDir = resolveSessionStorageDir(() => adapter.getSessionDir());
|
|
331
|
+
const contentDir = resolveContentStorageDir(() => sessionDir.path);
|
|
332
|
+
const statsDir = resolveStatsStorageDir(() => sessionDir.path);
|
|
333
|
+
p.note([
|
|
334
|
+
`sessions: ${sessionDir.path} (${describeStorageSource(sessionDir)})`,
|
|
335
|
+
`content: ${contentDir.path} (${describeStorageSource(contentDir)})`,
|
|
336
|
+
`stats: ${statsDir.path} (${describeStorageSource(statsDir)})`,
|
|
337
|
+
].join("\n"), "Storage paths");
|
|
338
|
+
criticalFails += logStorageDir(sessionDir);
|
|
339
|
+
criticalFails += logStorageDir(contentDir);
|
|
340
|
+
criticalFails += logStorageDir(statsDir);
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
if (err instanceof StorageDirectoryError) {
|
|
344
|
+
criticalFails++;
|
|
345
|
+
p.log.error(color.red(`Storage ${err.kind}: FAIL`) +
|
|
346
|
+
color.dim(` — ${formatStorageDirectoryError(err)}`));
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
throw err;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
289
352
|
const s = p.spinner();
|
|
290
353
|
s.start("Running diagnostics");
|
|
291
354
|
let runtimes;
|
|
@@ -738,8 +801,8 @@ async function insight(port) {
|
|
|
738
801
|
// Detect platform + adapter for correct session/content paths
|
|
739
802
|
const detection = detectPlatform();
|
|
740
803
|
const adapter = await getAdapter(detection.platform);
|
|
741
|
-
const sessDir = adapter.getSessionDir();
|
|
742
|
-
const contentDir =
|
|
804
|
+
const sessDir = ensureWritableStorageDir(resolveSessionStorageDir(() => adapter.getSessionDir()));
|
|
805
|
+
const contentDir = ensureWritableStorageDir(resolveContentStorageDir(() => sessDir));
|
|
743
806
|
const cacheDir = join(dirname(sessDir), "insight-cache");
|
|
744
807
|
if (!existsSync(join(insightSource, "server.mjs"))) {
|
|
745
808
|
console.error("Error: Insight source not found. Try upgrading context-mode.");
|
|
@@ -1141,7 +1204,7 @@ async function upgrade(opts) {
|
|
|
1141
1204
|
timeout: 60000,
|
|
1142
1205
|
});
|
|
1143
1206
|
s.stop("Dependencies ready");
|
|
1144
|
-
if (detection.platform
|
|
1207
|
+
if (!isInProcessPluginPlatform(detection.platform)) {
|
|
1145
1208
|
// Verify native addons through the same bootstrap start.mjs imports.
|
|
1146
1209
|
// On modern Node, the ABI-specific cache file is the compatibility marker;
|
|
1147
1210
|
// the active binding alone may be stale from a previous Node ABI.
|
|
@@ -1203,20 +1266,20 @@ async function upgrade(opts) {
|
|
|
1203
1266
|
color.dim(`\n Try (primary): cd "${pluginRoot}" && npm install better-sqlite3 --no-optional`) +
|
|
1204
1267
|
color.dim("\n Try (fallback): /context-mode:ctx-doctor"));
|
|
1205
1268
|
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1269
|
+
// Update global npm
|
|
1270
|
+
s.start("Updating npm global package");
|
|
1271
|
+
try {
|
|
1272
|
+
npmExecFile(["install", "-g", pluginRoot, "--no-audit", "--no-fund"], {
|
|
1273
|
+
stdio: "pipe",
|
|
1274
|
+
timeout: 30000,
|
|
1275
|
+
});
|
|
1276
|
+
s.stop(color.green("npm global updated"));
|
|
1277
|
+
changes.push("Updated npm global package");
|
|
1278
|
+
}
|
|
1279
|
+
catch {
|
|
1280
|
+
s.stop(color.yellow("npm global update skipped"));
|
|
1281
|
+
p.log.info(color.dim(" Could not update global npm — may need sudo or standalone install"));
|
|
1282
|
+
}
|
|
1220
1283
|
}
|
|
1221
1284
|
// Cleanup
|
|
1222
1285
|
rmSync(tmpDir, { recursive: true, force: true });
|
|
@@ -19,7 +19,12 @@ export interface AutoMemoryResult {
|
|
|
19
19
|
export interface AutoMemoryAdapter {
|
|
20
20
|
getConfigDir(): string;
|
|
21
21
|
getInstructionFiles(): string[];
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* `projectDir` is optional for backwards compatibility with legacy
|
|
24
|
+
* callers — when supplied, adapters MUST return a project-scoped path
|
|
25
|
+
* (see HookAdapter.getMemoryDir contract, issue #663).
|
|
26
|
+
*/
|
|
27
|
+
getMemoryDir(projectDir?: string): string;
|
|
23
28
|
}
|
|
24
29
|
/**
|
|
25
30
|
* Search auto-memory files for content matching any of the given queries.
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
9
9
|
import { join, isAbsolute } from "node:path";
|
|
10
10
|
import { resolveClaudeConfigDir } from "../util/claude-config.js";
|
|
11
|
+
import { hashProjectDirCanonical } from "../session/db.js";
|
|
11
12
|
const DEBUG = process.env.DEBUG?.includes("context-mode");
|
|
12
13
|
/**
|
|
13
14
|
* Search auto-memory files for content matching any of the given queries.
|
|
@@ -38,10 +39,18 @@ export function searchAutoMemory(queries, limit = 5, projectDir, configDir, adap
|
|
|
38
39
|
// CC config trees (and empty/whitespace env doesn't poison the path).
|
|
39
40
|
const adapterRelative = adapterConfigDir ? resolveAgainst(projectDir, adapterConfigDir) : null;
|
|
40
41
|
const effectiveConfigDir = adapterRelative ?? configDir ?? resolveClaudeConfigDir();
|
|
41
|
-
|
|
42
|
+
// Issue #663: scope memory dir by projectDir so parallel projects can't
|
|
43
|
+
// read each other's auto-memory. Adapter-aware path delegates the
|
|
44
|
+
// scoping to the adapter; legacy adapterless fallback applies the same
|
|
45
|
+
// hash directly so the contract holds at both call sites.
|
|
46
|
+
const adapterMemoryDir = adapter?.getMemoryDir(projectDir);
|
|
47
|
+
const fallbackMemoryBase = join(effectiveConfigDir, "memory");
|
|
48
|
+
const fallbackMemoryDir = projectDir
|
|
49
|
+
? join(fallbackMemoryBase, hashProjectDirCanonical(projectDir))
|
|
50
|
+
: fallbackMemoryBase;
|
|
42
51
|
const memoryDir = adapterMemoryDir
|
|
43
52
|
? resolveAgainst(projectDir, adapterMemoryDir)
|
|
44
|
-
:
|
|
53
|
+
: fallbackMemoryDir;
|
|
45
54
|
// Collect candidate files
|
|
46
55
|
const candidates = [];
|
|
47
56
|
// 1. Project-level instruction files
|