@omercnet/paseo-context-mode 3.1.4-next.382.1 → 3.1.4-next.434.1
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/OVERVIEW.md +3 -3
- package/README.md +13 -15
- package/client/analytics-dashboard.tsx +745 -613
- package/client/controls.tsx +295 -0
- package/client/diagnostics-section.tsx +178 -0
- package/client/{context-mode-footer.tsx → footer.tsx} +22 -20
- package/client/knowledge-section.tsx +725 -697
- package/client/{context-mode-pill.tsx → pill.tsx} +5 -5
- package/client/scoped-knowledge-section.tsx +14 -20
- package/client/screen-scope.ts +12 -6
- package/client/settings-screen.tsx +94 -97
- package/client/surface.tsx +377 -0
- package/index.client.tsx +3 -3
- package/index.server.ts +18 -27
- package/npm-shrinkwrap.json +6 -1745
- package/package.json +3 -3
- package/server/actions.ts +91 -102
- package/server/analytics.ts +257 -308
- package/server/binary.ts +119 -94
- package/server/database.ts +463 -0
- package/server/handlers.ts +40 -95
- package/server/integration.ts +230 -361
- package/server/knowledge.ts +65 -137
- package/server/mcp-process.ts +135 -86
- package/server/storage-discovery.ts +46 -199
- package/shared/actions.ts +2 -27
- package/shared/analytics.ts +60 -33
- package/shared/contracts.ts +16 -47
- package/shared/knowledge.ts +62 -65
- package/shared/providers.ts +62 -0
- package/shared/settings.ts +33 -18
- package/client/actions-section.tsx +0 -621
- package/client/context-mode-surface.tsx +0 -444
- package/server/context-mode-db.ts +0 -481
- package/shared/index.ts +0 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omercnet/paseo-context-mode",
|
|
3
|
-
"version": "3.1.4-next.
|
|
3
|
+
"version": "3.1.4-next.434.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Provider-aware Context Mode health, savings, and MCP activation for Paseo.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"packageManager": "bun@1.4.4",
|
|
21
21
|
"engines": {
|
|
22
|
-
"node": ">=24"
|
|
22
|
+
"node": ">=24.15.0"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"paseo",
|
|
@@ -68,6 +68,6 @@
|
|
|
68
68
|
"zod": "4.6.7"
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"context-mode": "1.
|
|
71
|
+
"context-mode": "2.1.4"
|
|
72
72
|
}
|
|
73
73
|
}
|
package/server/actions.ts
CHANGED
|
@@ -1,78 +1,117 @@
|
|
|
1
|
+
import { rm } from "node:fs/promises";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
1
3
|
import type { PluginSettings } from "@getpaseo/plugin/server";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type ContextModeAction,
|
|
5
|
-
type ContextModeActionInput,
|
|
6
|
-
type DoctorReport,
|
|
7
|
-
type DoctorStatusRow,
|
|
8
|
-
} from "../shared/actions";
|
|
4
|
+
import type { ContextModeActionInput, DoctorReport, DoctorStatusRow } from "../shared/actions";
|
|
5
|
+
import { contextModePlatformFor } from "../shared/providers";
|
|
9
6
|
import type { contextModeSettings } from "../shared/settings";
|
|
10
|
-
import { type BinaryResolution,
|
|
7
|
+
import { type BinaryResolution, resolveContextModeBinary } from "./binary";
|
|
8
|
+
import { contextModeProbeOptions } from "./handlers";
|
|
11
9
|
import type { ProviderConfigSource } from "./integration";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
callContextModeTool,
|
|
15
|
-
inspectContextMode,
|
|
16
|
-
type McpInspection,
|
|
17
|
-
type McpProcessDependencies,
|
|
18
|
-
type McpToolArguments,
|
|
19
|
-
} from "./mcp-process";
|
|
10
|
+
import { callContextModeTool } from "./mcp-process";
|
|
20
11
|
|
|
21
|
-
type
|
|
12
|
+
type BinarySource = Extract<BinaryResolution, { state: "found" }>["source"];
|
|
22
13
|
|
|
23
|
-
type
|
|
24
|
-
launch: LaunchDescriptor,
|
|
25
|
-
name: "ctx_doctor",
|
|
26
|
-
arguments_: McpToolArguments,
|
|
27
|
-
dependencies: McpProcessDependencies,
|
|
28
|
-
) => Promise<string>;
|
|
14
|
+
type SettingsHandle = PluginSettings<typeof contextModeSettings.schema>;
|
|
29
15
|
|
|
30
16
|
export interface ActionHandlerDependencies {
|
|
31
|
-
osPlatform?: NodeJS.Platform;
|
|
32
17
|
resolveBinary?: typeof resolveContextModeBinary;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
dependencies?: McpProcessDependencies,
|
|
36
|
-
) => Promise<McpInspection>;
|
|
37
|
-
callTool?: ActionToolCaller;
|
|
18
|
+
callTool?: typeof callContextModeTool;
|
|
19
|
+
probeOptions?: typeof contextModeProbeOptions;
|
|
38
20
|
}
|
|
39
21
|
|
|
40
22
|
type ActionContext = { paseo?: ProviderConfigSource };
|
|
41
23
|
|
|
42
24
|
export interface ContextModeActionHandlers {
|
|
43
25
|
doctor(input: ContextModeActionInput, context?: ActionContext): Promise<DoctorReport>;
|
|
44
|
-
install(input: ContextModeActionInput, context?: ActionContext): Promise<ContextModeAction>;
|
|
45
|
-
upgrade(input: ContextModeActionInput, context?: ActionContext): Promise<ContextModeAction>;
|
|
46
26
|
}
|
|
47
27
|
|
|
48
|
-
|
|
28
|
+
const DOCTOR_STATUS: Readonly<Record<string, DoctorStatusRow["status"]>> = {
|
|
29
|
+
PASS: "ok",
|
|
30
|
+
WARN: "warning",
|
|
31
|
+
FAIL: "error",
|
|
32
|
+
UNKNOWN: "error",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* D3 compares the agent's own host config with Context Mode's setup and D5 exercises its hooks.
|
|
37
|
+
* Paseo injects only the MCP server, so both fail for every injected agent: advice, not a fault,
|
|
38
|
+
* and their `context-mode setup` fix would replace Paseo's injection with a native install.
|
|
39
|
+
*/
|
|
40
|
+
const INFORMATIONAL_CHECK = /^D(3|5b?)\b/;
|
|
41
|
+
|
|
42
|
+
/** Upstream's fix for an outdated runtime; the plugin offers no in-place upgrade. */
|
|
43
|
+
const UPGRADE_FIX = "run ctx_upgrade";
|
|
44
|
+
|
|
45
|
+
const UPGRADE_ADVICE: Readonly<Record<BinarySource, string>> = {
|
|
46
|
+
bundled: "Update the Context Mode plugin in Paseo",
|
|
47
|
+
settings: "Upgrade the Context Mode install configured in settings",
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function doctorRow(
|
|
51
|
+
check: string,
|
|
52
|
+
status: DoctorStatusRow["status"],
|
|
53
|
+
detail: string,
|
|
54
|
+
upstreamFix: string,
|
|
55
|
+
runtime: BinarySource,
|
|
56
|
+
): DoctorStatusRow {
|
|
57
|
+
const row = { check: check.slice(0, 256), detail: detail.slice(0, 4_096) };
|
|
58
|
+
if (INFORMATIONAL_CHECK.test(check)) {
|
|
59
|
+
return { ...row, status: status === "ok" ? "ok" : "warning" };
|
|
60
|
+
}
|
|
61
|
+
if (upstreamFix === UPGRADE_FIX) {
|
|
62
|
+
// A bundled runtime that trails npm is expected until the next plugin release.
|
|
63
|
+
const upgradeStatus = runtime === "bundled" ? "warning" : status;
|
|
64
|
+
return { ...row, status: upgradeStatus, fix: UPGRADE_ADVICE[runtime] };
|
|
65
|
+
}
|
|
66
|
+
return upstreamFix ? { ...row, status, fix: upstreamFix.slice(0, 4_096) } : { ...row, status };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parses the `| Check | Status | Detail | Fix |` table that `ctx_doctor` prints. Upstream does not
|
|
71
|
+
* escape pipes, so the first two cells are check and status, the last is the fix, and whatever is
|
|
72
|
+
* between them is the detail. The fix cell leads with a restatement; only the command after the
|
|
73
|
+
* last `Fix:` is kept, and advice the plugin cannot act on is rewritten for `runtime`.
|
|
74
|
+
*/
|
|
75
|
+
export function parseContextModeDoctorOutput(
|
|
76
|
+
rawOutput: string,
|
|
77
|
+
runtime: BinarySource,
|
|
78
|
+
): DoctorStatusRow[] {
|
|
49
79
|
const rows: DoctorStatusRow[] = [];
|
|
50
80
|
for (const line of rawOutput.split(/\r?\n/)) {
|
|
51
|
-
const
|
|
52
|
-
if (!
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
81
|
+
const trimmed = line.trim();
|
|
82
|
+
if (!trimmed.startsWith("|") || !trimmed.endsWith("|")) continue;
|
|
83
|
+
const cells = trimmed
|
|
84
|
+
.slice(1, -1)
|
|
85
|
+
.split("|")
|
|
86
|
+
.map((cell) => cell.trim());
|
|
87
|
+
const [check = "", statusCell = ""] = cells;
|
|
88
|
+
const status = Object.hasOwn(DOCTOR_STATUS, statusCell) ? DOCTOR_STATUS[statusCell] : null;
|
|
89
|
+
if (cells.length < 4 || !check || !status) continue;
|
|
90
|
+
const detail = cells.slice(2, -1).join(" | ");
|
|
91
|
+
const fix = (cells.at(-1) ?? "").split("Fix:").at(-1)?.trim() ?? "";
|
|
92
|
+
rows.push(doctorRow(check, status, detail, fix, runtime));
|
|
63
93
|
if (rows.length === 64) break;
|
|
64
94
|
}
|
|
65
95
|
return rows;
|
|
66
96
|
}
|
|
67
97
|
|
|
98
|
+
/** Upstream's report file name; the shown path may be `~`-abbreviated, so only the name is trusted. */
|
|
99
|
+
const DOCTOR_REPORT_NAME = /^doctor-[\w-]+\.md$/;
|
|
100
|
+
|
|
101
|
+
/** ctx_doctor writes a report file per failing check and nothing prunes them; the panel keeps none. */
|
|
102
|
+
async function discardDoctorReport(output: string, dataDir: string): Promise<void> {
|
|
103
|
+
const reported = /^Report file: (.+)$/m.exec(output)?.[1]?.trim();
|
|
104
|
+
const name = reported ? basename(reported) : "";
|
|
105
|
+
if (DOCTOR_REPORT_NAME.test(name)) await rm(join(dataDir, "reports", name), { force: true });
|
|
106
|
+
}
|
|
107
|
+
|
|
68
108
|
export function createContextModeActionHandlers(
|
|
69
109
|
settingsHandle: SettingsHandle,
|
|
70
110
|
dependencies: ActionHandlerDependencies = {},
|
|
71
111
|
): ContextModeActionHandlers {
|
|
72
112
|
const resolveBinary = dependencies.resolveBinary ?? resolveContextModeBinary;
|
|
73
|
-
const inspect = dependencies.inspect ?? inspectContextMode;
|
|
74
113
|
const callTool = dependencies.callTool ?? callContextModeTool;
|
|
75
|
-
const
|
|
114
|
+
const probeOptions = dependencies.probeOptions ?? contextModeProbeOptions;
|
|
76
115
|
|
|
77
116
|
async function resolvedBinary(
|
|
78
117
|
paseo: ProviderConfigSource | undefined,
|
|
@@ -86,68 +125,18 @@ export function createContextModeActionHandlers(
|
|
|
86
125
|
return binary;
|
|
87
126
|
}
|
|
88
127
|
|
|
89
|
-
async function currentVersion(
|
|
90
|
-
input: ContextModeActionInput,
|
|
91
|
-
paseo: ProviderConfigSource | undefined,
|
|
92
|
-
): Promise<string | null> {
|
|
93
|
-
try {
|
|
94
|
-
const binary = await resolvedBinary(paseo);
|
|
95
|
-
const inspection = await inspect(binary.launch, {
|
|
96
|
-
env: contextModeEnvironmentFor(input.provider),
|
|
97
|
-
});
|
|
98
|
-
return inspection.version?.slice(0, 128) ?? null;
|
|
99
|
-
} catch {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
128
|
return {
|
|
105
129
|
async doctor(input, context) {
|
|
106
|
-
const binary = await resolvedBinary(context?.paseo);
|
|
107
|
-
const rawOutput = await callTool(
|
|
108
|
-
binary.launch,
|
|
109
|
-
"ctx_doctor",
|
|
110
|
-
{},
|
|
111
|
-
{
|
|
112
|
-
env: contextModeEnvironmentFor(input.provider),
|
|
113
|
-
},
|
|
114
|
-
);
|
|
115
|
-
return {
|
|
116
|
-
platform: contextModePlatformFor(input.provider),
|
|
117
|
-
rows: parseContextModeDoctorOutput(rawOutput),
|
|
118
|
-
rawOutput,
|
|
119
|
-
};
|
|
120
|
-
},
|
|
121
|
-
async install(input, context) {
|
|
122
|
-
const platform = contextModePlatformFor(input.provider);
|
|
123
|
-
return {
|
|
124
|
-
program: osPlatform === "win32" ? "npm.cmd" : "npm",
|
|
125
|
-
args: [
|
|
126
|
-
"install",
|
|
127
|
-
"-g",
|
|
128
|
-
`context-mode@${CONTEXT_MODE_TARGET_VERSION}`,
|
|
129
|
-
"--no-audit",
|
|
130
|
-
"--no-fund",
|
|
131
|
-
],
|
|
132
|
-
currentVersion: await currentVersion(input, context?.paseo),
|
|
133
|
-
targetVersion: CONTEXT_MODE_TARGET_VERSION,
|
|
134
|
-
platform,
|
|
135
|
-
requiresRestart: true,
|
|
136
|
-
};
|
|
137
|
-
},
|
|
138
|
-
async upgrade(input, context) {
|
|
139
130
|
const platform = contextModePlatformFor(input.provider);
|
|
140
131
|
const binary = await resolvedBinary(context?.paseo);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
});
|
|
132
|
+
// ctx_doctor writes a report and index rows, so it runs against the plugin-owned probe store.
|
|
133
|
+
const options = await probeOptions(platform);
|
|
134
|
+
const rawOutput = await callTool(binary.launch, "ctx_doctor", {}, {}, options);
|
|
135
|
+
await discardDoctorReport(rawOutput, options.dataDir);
|
|
144
136
|
return {
|
|
145
|
-
program: binary.launch.program,
|
|
146
|
-
args: [...binary.launch.args, "upgrade", "--platform", platform],
|
|
147
|
-
currentVersion: inspection.version?.slice(0, 128) ?? null,
|
|
148
|
-
targetVersion: "latest",
|
|
149
137
|
platform,
|
|
150
|
-
|
|
138
|
+
rows: parseContextModeDoctorOutput(rawOutput, binary.source),
|
|
139
|
+
rawOutput,
|
|
151
140
|
};
|
|
152
141
|
},
|
|
153
142
|
};
|