@omercnet/paseo-context-mode 3.1.3 → 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.
@@ -1,239 +1,86 @@
1
1
  import type { Dirent } from "node:fs";
2
- import { lstat, readdir, realpath } from "node:fs/promises";
3
- import { homedir } from "node:os";
4
- import { basename, isAbsolute, join, resolve } from "node:path";
2
+ import { lstat, readdir } from "node:fs/promises";
3
+ import { isAbsolute, join, resolve } from "node:path";
5
4
  import type { AnalyticsWarning } from "../shared/analytics";
6
- import { contextModeStorageRootFor, type ProviderOverrides, resolveProvider } from "./integration";
7
5
 
8
- const MAX_DATABASES_PER_DIRECTORY = 512;
9
- const MAX_LOCAL_DISCOVERY_WARNINGS = 10;
6
+ const MAX_PROJECTS = 256;
7
+ const MAX_DISCOVERY_WARNINGS = 10;
10
8
 
11
- export interface ProviderStorageRoot {
12
- provider: string;
13
- root: string;
14
- sessionsDir: string;
15
- contentDir: string;
9
+ export interface ContextModeProjectDatabase {
10
+ /** Project key directory name, `sha256(projectPath).slice(0, 16)` upstream. */
11
+ project: string;
12
+ path: string;
16
13
  }
17
14
 
18
15
  export interface StorageDiscoveryResult {
19
- roots: ProviderStorageRoot[];
16
+ databases: ContextModeProjectDatabase[];
20
17
  warnings: AnalyticsWarning[];
21
18
  }
22
19
 
23
- export interface StorageDiscoveryOptions {
24
- home?: string;
25
- env?: NodeJS.ProcessEnv;
26
- platform?: NodeJS.Platform;
27
- /** Paseo `agents.providers`; each one contributes the storage its own env resolves to. */
28
- providers?: ProviderOverrides;
20
+ /** Context Mode 2.x data dir: absolute `CONTEXT_MODE_DATA_DIR`, else `~/.context-mode`. */
21
+ export function resolveContextModeDataDir(env: NodeJS.ProcessEnv, home: string): string {
22
+ const configured = env.CONTEXT_MODE_DATA_DIR?.trim();
23
+ return configured && isAbsolute(configured) ? resolve(configured) : join(home, ".context-mode");
29
24
  }
30
25
 
31
- interface ProviderLocation {
32
- provider: string;
33
- root: string;
34
- }
35
-
36
- function configuredDirectory(
37
- value: string | undefined,
38
- home: string,
39
- envVar: string,
40
- warnings: AnalyticsWarning[],
41
- ): string | null {
42
- const trimmed = value?.trim();
43
- if (!trimmed) return null;
44
- if (trimmed === "~" || trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
45
- return resolve(home, trimmed.slice(2));
46
- }
47
- if (isAbsolute(trimmed)) return resolve(trimmed);
48
- warnings.push({
49
- code: "invalid-storage-root",
50
- message: `${envVar} was ignored because it is not an absolute path.`,
51
- });
52
- return null;
53
- }
54
-
55
- function providerLocations(
56
- home: string,
57
- env: NodeJS.ProcessEnv,
58
- warnings: AnalyticsWarning[],
59
- platform: NodeJS.Platform,
60
- providers: ProviderOverrides,
61
- ): ProviderLocation[] {
62
- const configuredRoot = configuredDirectory(
63
- env.CONTEXT_MODE_DIR,
64
- home,
65
- "CONTEXT_MODE_DIR",
66
- warnings,
67
- );
68
- const configuredDataRoot = configuredDirectory(
69
- env.CONTEXT_MODE_DATA_DIR,
70
- home,
71
- "CONTEXT_MODE_DATA_DIR",
72
- warnings,
73
- );
74
- const claudeRoot =
75
- configuredDirectory(env.CLAUDE_CONFIG_DIR, home, "CLAUDE_CONFIG_DIR", warnings) ??
76
- join(home, ".claude");
77
- const codexRoot =
78
- configuredDirectory(env.CODEX_HOME, home, "CODEX_HOME", warnings) ?? join(home, ".codex");
79
- const kimiRoot =
80
- configuredDirectory(env.KIMI_CODE_HOME, home, "KIMI_CODE_HOME", warnings) ??
81
- join(home, ".kimi-code");
82
- const xdgRoot =
83
- platform === "win32"
84
- ? (configuredDirectory(env.APPDATA, home, "APPDATA", warnings) ??
85
- join(home, "AppData", "Roaming"))
86
- : (configuredDirectory(env.XDG_CONFIG_HOME, home, "XDG_CONFIG_HOME", warnings) ??
87
- join(home, ".config"));
88
-
89
- const configured = Object.keys(providers).flatMap((id) => {
90
- const { base, policy, env: providerEnv } = resolveProvider(id, providers);
91
- const root = policy
92
- ? contextModeStorageRootFor(base, { home, env: { ...env, ...providerEnv } })
93
- : null;
94
- return root ? [{ provider: id, root }] : [];
95
- });
96
-
97
- return [
98
- ...(configuredRoot ? [{ provider: "custom", root: configuredRoot }] : []),
99
- ...(configuredDataRoot
100
- ? [{ provider: "custom-data", root: join(configuredDataRoot, "context-mode") }]
101
- : []),
102
- { provider: "claude-code", root: join(claudeRoot, "context-mode") },
103
- { provider: "gemini-cli", root: join(home, ".gemini", "context-mode") },
104
- { provider: "openclaw", root: join(home, ".openclaw", "context-mode") },
105
- { provider: "codex", root: join(codexRoot, "context-mode") },
106
- { provider: "cursor", root: join(home, ".cursor", "context-mode") },
107
- { provider: "vscode-copilot", root: join(home, ".vscode", "context-mode") },
108
- { provider: "copilot-cli", root: join(home, ".copilot", "context-mode") },
109
- { provider: "kiro", root: join(home, ".kiro", "context-mode") },
110
- { provider: "pi", root: join(home, ".pi", "context-mode") },
111
- { provider: "omp", root: join(home, ".omp", "context-mode") },
112
- { provider: "qwen-code", root: join(home, ".qwen", "context-mode") },
113
- { provider: "kimi", root: join(kimiRoot, "context-mode") },
114
- { provider: "kilo", root: join(xdgRoot, "kilo", "context-mode") },
115
- { provider: "opencode", root: join(xdgRoot, "opencode", "context-mode") },
116
- { provider: "zed", root: join(home, ".config", "zed", "context-mode") },
117
- {
118
- provider: "jetbrains-copilot",
119
- root: join(home, ".config", "JetBrains", "context-mode"),
120
- },
121
- ...configured,
122
- ];
123
- }
124
-
125
- function storageWarning(provider: string, message: string, database?: string): AnalyticsWarning {
126
- return {
127
- code: "storage-unavailable",
128
- provider,
129
- ...(database ? { database } : {}),
130
- message,
131
- };
132
- }
133
-
134
- export async function discoverContextModeStorageRoots(
135
- options: StorageDiscoveryOptions = {},
26
+ /** Lists `<dataDir>/projects/<key>/context.db`, skipping project directories without a database. */
27
+ export async function discoverContextModeDatabases(
28
+ dataDir: string,
136
29
  ): Promise<StorageDiscoveryResult> {
137
- const home = resolve(options.home ?? homedir());
138
- const env = options.env ?? process.env;
139
- const warnings: AnalyticsWarning[] = [];
140
- const roots: ProviderStorageRoot[] = [];
141
- const seen = new Set<string>();
142
-
143
- for (const location of providerLocations(
144
- home,
145
- env,
146
- warnings,
147
- options.platform ?? process.platform,
148
- options.providers ?? {},
149
- )) {
150
- try {
151
- const info = await lstat(location.root);
152
- if (info.isSymbolicLink() || !info.isDirectory()) {
153
- warnings.push(
154
- storageWarning(
155
- location.provider,
156
- "The Context Mode storage root is not a regular directory.",
157
- ),
158
- );
159
- continue;
160
- }
161
- const canonical = await realpath(location.root);
162
- if (seen.has(canonical)) continue;
163
- seen.add(canonical);
164
- roots.push({
165
- provider: location.provider,
166
- root: canonical,
167
- sessionsDir: join(canonical, "sessions"),
168
- contentDir: join(canonical, "content"),
169
- });
170
- } catch (error) {
171
- if ((error as NodeJS.ErrnoException).code === "ENOENT") continue;
172
- warnings.push(
173
- storageWarning(location.provider, "The Context Mode storage root could not be inspected."),
174
- );
175
- }
176
- }
177
-
178
- return { roots, warnings };
179
- }
180
-
181
- export async function listRegularContextModeDatabases(
182
- provider: string,
183
- directory: string,
184
- ): Promise<{ files: string[]; warnings: AnalyticsWarning[] }> {
30
+ const projectsDir = join(dataDir, "projects");
185
31
  let entries: Dirent[];
186
32
  try {
187
- entries = await readdir(directory, { withFileTypes: true });
33
+ entries = await readdir(projectsDir, { withFileTypes: true });
188
34
  } catch (error) {
189
- if ((error as NodeJS.ErrnoException).code === "ENOENT") return { files: [], warnings: [] };
35
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") return { databases: [], warnings: [] };
190
36
  return {
191
- files: [],
37
+ databases: [],
192
38
  warnings: [
193
- storageWarning(
194
- provider,
195
- `The ${basename(directory)} database directory could not be read.`,
196
- ),
39
+ {
40
+ code: "storage-unavailable",
41
+ message: "The Context Mode projects directory could not be read.",
42
+ },
197
43
  ],
198
44
  };
199
45
  }
200
46
 
201
- const candidates = entries
202
- .filter((entry) => entry.name.endsWith(".db"))
203
- .sort((left, right) => left.name.localeCompare(right.name));
204
- const files: string[] = [];
47
+ const projects = entries
48
+ .filter((entry) => entry.isDirectory())
49
+ .map((entry) => entry.name)
50
+ .sort();
51
+ const databases: ContextModeProjectDatabase[] = [];
205
52
  const warnings: AnalyticsWarning[] = [];
206
53
 
207
- for (const entry of candidates.slice(0, MAX_DATABASES_PER_DIRECTORY)) {
208
- const path = join(directory, entry.name);
54
+ for (const project of projects.slice(0, MAX_PROJECTS)) {
55
+ const path = join(projectsDir, project, "context.db");
209
56
  try {
210
57
  const info = await lstat(path);
211
- if (entry.isFile() && info.isFile()) {
212
- files.push(path);
213
- } else if (warnings.length < MAX_LOCAL_DISCOVERY_WARNINGS) {
58
+ if (info.isFile()) databases.push({ project, path });
59
+ else if (warnings.length < MAX_DISCOVERY_WARNINGS) {
214
60
  warnings.push({
215
61
  code: "not-regular-database",
216
- provider,
217
- database: entry.name,
218
- message: "Skipped a .db entry that is not a regular file.",
62
+ project,
63
+ message: "Skipped a context.db entry that is not a regular file.",
219
64
  });
220
65
  }
221
- } catch {
222
- if (warnings.length < MAX_LOCAL_DISCOVERY_WARNINGS) {
223
- warnings.push(
224
- storageWarning(provider, "A database disappeared during discovery.", entry.name),
225
- );
66
+ } catch (error) {
67
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") continue;
68
+ if (warnings.length < MAX_DISCOVERY_WARNINGS) {
69
+ warnings.push({
70
+ code: "storage-unavailable",
71
+ project,
72
+ message: "The project database could not be inspected.",
73
+ });
226
74
  }
227
75
  }
228
76
  }
229
77
 
230
- if (candidates.length > MAX_DATABASES_PER_DIRECTORY) {
78
+ if (projects.length > MAX_PROJECTS) {
231
79
  warnings.push({
232
80
  code: "result-truncated",
233
- provider,
234
- message: `Only the first ${MAX_DATABASES_PER_DIRECTORY} database files in ${basename(directory)} were inspected.`,
81
+ message: `Only the first ${MAX_PROJECTS} of ${projects.length} Context Mode projects were inspected.`,
235
82
  });
236
83
  }
237
84
 
238
- return { files, warnings };
85
+ return { databases, warnings };
239
86
  }
package/shared/actions.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import { defineRpc } from "@getpaseo/plugin";
2
2
  import { z } from "zod";
3
- import { ContextModePlatformSchema, ContextModeProviderSchema } from "./knowledge";
4
-
5
- export const CONTEXT_MODE_TARGET_VERSION = "1.0.169" as const;
3
+ import { ContextModePlatformSchema, ContextModeProviderSchema } from "./providers";
6
4
 
7
5
  const providerInput = z.object({ provider: ContextModeProviderSchema }).strict();
8
6
 
@@ -11,6 +9,7 @@ export const DoctorStatusRowSchema = z
11
9
  status: z.enum(["ok", "warning", "error"]),
12
10
  check: z.string().trim().min(1).max(256),
13
11
  detail: z.string().max(4_096),
12
+ fix: z.string().max(4_096).optional(),
14
13
  })
15
14
  .strict();
16
15
 
@@ -22,36 +21,12 @@ export const DoctorReportSchema = z
22
21
  })
23
22
  .strict();
24
23
 
25
- export const ContextModeActionSchema = z
26
- .object({
27
- program: z.string().trim().min(1).max(4_096),
28
- args: z.array(z.string().max(4_096)).max(32),
29
- currentVersion: z.string().trim().min(1).max(128).nullable(),
30
- targetVersion: z.union([z.literal(CONTEXT_MODE_TARGET_VERSION), z.literal("latest")]),
31
- platform: ContextModePlatformSchema,
32
- requiresRestart: z.boolean(),
33
- })
34
- .strict();
35
-
36
24
  export const getContextModeDoctorReport = defineRpc({
37
25
  name: "context-mode.actions.doctor",
38
26
  input: providerInput,
39
27
  output: DoctorReportSchema,
40
28
  });
41
29
 
42
- export const getContextModeInstallAction = defineRpc({
43
- name: "context-mode.actions.install",
44
- input: providerInput,
45
- output: ContextModeActionSchema,
46
- });
47
-
48
- export const getContextModeUpgradeAction = defineRpc({
49
- name: "context-mode.actions.upgrade",
50
- input: providerInput,
51
- output: ContextModeActionSchema,
52
- });
53
-
54
30
  export type DoctorStatusRow = z.infer<typeof DoctorStatusRowSchema>;
55
31
  export type DoctorReport = z.infer<typeof DoctorReportSchema>;
56
- export type ContextModeAction = z.infer<typeof ContextModeActionSchema>;
57
32
  export type ContextModeActionInput = z.infer<typeof providerInput>;
@@ -1,27 +1,32 @@
1
1
  import { defineRpc } from "@getpaseo/plugin";
2
2
  import { z } from "zod";
3
3
 
4
- export const CONTEXT_MODE_ANALYTICS_SCHEMA_VERSION = 1 as const;
5
- export const SUPPORTED_CONTEXT_MODE_DATABASE_VERSION = "1.0.169" as const;
4
+ export const CONTEXT_MODE_ANALYTICS_SCHEMA_VERSION = 2 as const;
5
+ export const SUPPORTED_CONTEXT_MODE_DATABASE_USER_VERSION = 6 as const;
6
6
 
7
7
  const nonNegativeInteger = z.number().int().nonnegative();
8
8
  const nonNegativeNumber = z.number().finite().nonnegative();
9
+ const timestamp = z.string().datetime().nullable();
9
10
 
11
+ /** Byte totals of Context Mode tool calls: produced in the sandbox, returned to the agent, kept out. */
10
12
  export const AnalyticsByteAccountingSchema = z
11
13
  .object({
12
- eventDataBytes: nonNegativeInteger,
13
- avoidedBytes: nonNegativeInteger,
14
+ producedBytes: nonNegativeInteger,
14
15
  returnedBytes: nonNegativeInteger,
15
- snapshotBytes: nonNegativeInteger,
16
- indexedBytes: nonNegativeInteger,
17
16
  savedBytes: nonNegativeInteger,
17
+ indexedBytes: nonNegativeInteger,
18
18
  })
19
19
  .strict();
20
20
 
21
+ const savingsFields = {
22
+ savedTokens: nonNegativeInteger,
23
+ savingsPercent: nonNegativeNumber.max(100),
24
+ byteAccounting: AnalyticsByteAccountingSchema,
25
+ };
26
+
21
27
  export const AnalyticsTotalsSchema = z
22
28
  .object({
23
- providers: nonNegativeInteger,
24
- databases: nonNegativeInteger,
29
+ agents: nonNegativeInteger,
25
30
  projects: nonNegativeInteger,
26
31
  sessions: nonNegativeInteger,
27
32
  events: nonNegativeInteger,
@@ -30,27 +35,47 @@ export const AnalyticsTotalsSchema = z
30
35
  indexedChunks: nonNegativeInteger,
31
36
  inputTokens: nonNegativeInteger,
32
37
  outputTokens: nonNegativeInteger,
33
- savedTokens: nonNegativeInteger,
34
- savingsPercent: nonNegativeNumber.max(100),
35
- byteAccounting: AnalyticsByteAccountingSchema,
38
+ ...savingsFields,
39
+ lastActivityAt: timestamp,
36
40
  })
37
41
  .strict();
38
42
 
39
- export const ProviderAnalyticsSchema = z
43
+ /** One row per Context Mode `--agent` id recorded in the databases (claude-code, codex, ...). */
44
+ export const AgentAnalyticsSchema = z
40
45
  .object({
41
- provider: z.string().min(1).max(128),
42
- databases: nonNegativeInteger,
46
+ agent: z.string().min(1).max(128),
43
47
  projects: nonNegativeInteger,
44
48
  sessions: nonNegativeInteger,
45
- events: nonNegativeInteger,
46
49
  toolCalls: nonNegativeInteger,
47
50
  indexedSources: nonNegativeInteger,
48
- indexedChunks: nonNegativeInteger,
49
- inputTokens: nonNegativeInteger,
50
- outputTokens: nonNegativeInteger,
51
- savedTokens: nonNegativeInteger,
52
- savingsPercent: nonNegativeNumber.max(100),
53
- byteAccounting: AnalyticsByteAccountingSchema,
51
+ ...savingsFields,
52
+ })
53
+ .strict();
54
+
55
+ export const ProjectAnalyticsSchema = z
56
+ .object({
57
+ path: z.string().min(1).max(4_096),
58
+ worktrees: nonNegativeInteger,
59
+ sessions: nonNegativeInteger,
60
+ toolCalls: nonNegativeInteger,
61
+ indexedSources: nonNegativeInteger,
62
+ ...savingsFields,
63
+ lastActivityAt: timestamp,
64
+ })
65
+ .strict();
66
+
67
+ /** Paseo provider whose Context Mode store holds the row, for Resume and Forget; null when none reaches it. */
68
+ const storeProvider = z.string().min(1).max(128).nullable();
69
+
70
+ /** One recorded agent session, newest first; the plugin's own `paseo-context-mode` calls are excluded. */
71
+ export const SessionAnalyticsSchema = z
72
+ .object({
73
+ sessionId: z.string().min(1).max(256),
74
+ agent: z.string().min(1).max(128),
75
+ projectPath: z.string().min(1).max(4_096),
76
+ events: nonNegativeInteger,
77
+ lastActivityAt: timestamp,
78
+ provider: storeProvider,
54
79
  })
55
80
  .strict();
56
81
 
@@ -72,32 +97,30 @@ export const DailyAnalyticsSchema = z
72
97
 
73
98
  export const IndexedSourceAnalyticsSchema = z
74
99
  .object({
75
- provider: z.string().min(1).max(128),
100
+ agent: z.string().min(1).max(128),
101
+ projectPath: z.string().min(1).max(4_096),
76
102
  source: z.string().min(1).max(4_096),
103
+ kind: z.enum(["path", "content", "url"]),
77
104
  chunks: nonNegativeInteger,
78
- codeChunks: nonNegativeInteger,
79
105
  indexedBytes: nonNegativeInteger,
80
- indexedAt: z.string().nullable(),
81
- state: z.enum(["ready", "empty", "unavailable"]),
82
- detail: z.string().max(512).optional(),
106
+ indexedAt: timestamp,
107
+ provider: storeProvider,
83
108
  })
84
109
  .strict();
85
110
 
86
111
  export const AnalyticsWarningSchema = z
87
112
  .object({
88
113
  code: z.enum([
89
- "invalid-storage-root",
90
114
  "storage-unavailable",
91
115
  "not-regular-database",
92
116
  "database-open-failed",
117
+ "database-locked",
93
118
  "unsupported-schema",
94
119
  "database-query-failed",
95
- "inconsistent-index",
96
120
  "result-truncated",
97
121
  "warning-limit",
98
122
  ]),
99
- provider: z.string().min(1).max(128).optional(),
100
- database: z.string().min(1).max(512).optional(),
123
+ project: z.string().min(1).max(128).optional(),
101
124
  message: z.string().min(1).max(512),
102
125
  })
103
126
  .strict();
@@ -105,11 +128,13 @@ export const AnalyticsWarningSchema = z
105
128
  export const ContextModeAnalyticsDashboardSchema = z
106
129
  .object({
107
130
  schemaVersion: z.literal(CONTEXT_MODE_ANALYTICS_SCHEMA_VERSION),
108
- contextModeVersion: z.literal(SUPPORTED_CONTEXT_MODE_DATABASE_VERSION),
131
+ contextModeVersion: z.string().min(1).max(64).nullable(),
109
132
  completeness: z.enum(["complete", "partial", "unsupported"]),
110
133
  warnings: z.array(AnalyticsWarningSchema).max(20),
111
134
  totals: AnalyticsTotalsSchema,
112
- byProvider: z.array(ProviderAnalyticsSchema).max(32),
135
+ byAgent: z.array(AgentAnalyticsSchema).max(32),
136
+ byProject: z.array(ProjectAnalyticsSchema).max(50),
137
+ recentSessions: z.array(SessionAnalyticsSchema).max(20),
113
138
  byCategory: z.array(CategoryAnalyticsSchema).max(128),
114
139
  byDay: z.array(DailyAnalyticsSchema).max(400),
115
140
  sources: z.array(IndexedSourceAnalyticsSchema).max(2_000),
@@ -125,7 +150,9 @@ export const getContextModeAnalyticsDashboard = defineRpc({
125
150
 
126
151
  export type AnalyticsByteAccounting = z.infer<typeof AnalyticsByteAccountingSchema>;
127
152
  export type AnalyticsTotals = z.infer<typeof AnalyticsTotalsSchema>;
128
- export type ProviderAnalytics = z.infer<typeof ProviderAnalyticsSchema>;
153
+ export type AgentAnalytics = z.infer<typeof AgentAnalyticsSchema>;
154
+ export type ProjectAnalytics = z.infer<typeof ProjectAnalyticsSchema>;
155
+ export type SessionAnalytics = z.infer<typeof SessionAnalyticsSchema>;
129
156
  export type CategoryAnalytics = z.infer<typeof CategoryAnalyticsSchema>;
130
157
  export type DailyAnalytics = z.infer<typeof DailyAnalyticsSchema>;
131
158
  export type IndexedSourceAnalytics = z.infer<typeof IndexedSourceAnalyticsSchema>;
@@ -1,8 +1,10 @@
1
1
  import { defineRpc } from "@getpaseo/plugin";
2
2
  import { z } from "zod";
3
+ import { ContextModePlatformSchema } from "./providers";
3
4
 
4
5
  const refreshInput = z.object({ fresh: z.boolean().default(false) }).strict();
5
- const binarySource = z.enum(["settings", "path", "bundled"]);
6
+ /** `settings`: the user's own binary; `bundled`: the runtime shipped with the plugin. */
7
+ const binarySource = z.enum(["settings", "bundled"]);
6
8
  const failureCode = z.enum([
7
9
  "not-installed",
8
10
  "invalid-settings",
@@ -20,8 +22,6 @@ export const BinaryStatusSchema = z.discriminatedUnion("state", [
20
22
  binaryPath: z.string(),
21
23
  source: binarySource,
22
24
  version: z.string().nullable(),
23
- supportsDoctor: z.boolean(),
24
- supportsStats: z.boolean(),
25
25
  checkedAt: z.string().datetime(),
26
26
  }),
27
27
  z.object({
@@ -32,37 +32,19 @@ export const BinaryStatusSchema = z.discriminatedUnion("state", [
32
32
  }),
33
33
  ]);
34
34
 
35
- export const CommandReportSchema = z.discriminatedUnion("state", [
36
- z.object({
37
- state: z.literal("ready"),
38
- binaryPath: z.string(),
39
- output: z.string().max(196_608),
40
- checkedAt: z.string().datetime(),
41
- }),
42
- z.object({
43
- state: z.literal("unavailable"),
44
- code: failureCode,
45
- message: z.string().max(4_096),
46
- checkedAt: z.string().datetime(),
47
- }),
48
- ]);
49
-
50
- export const ProviderIntegrationSchema = z.object({
51
- provider: z.string(),
52
- platform: z.string(),
53
- activation: z.enum(["native", "mcp", "disabled"]),
54
- storageRoot: z.string(),
55
- reusesExistingStorage: z.boolean(),
56
- detail: z.string().max(4_096),
57
- });
35
+ export const ProviderIntegrationSchema = z
36
+ .object({
37
+ provider: z.string(),
38
+ /** `--agent` id, or null when Context Mode 2.x cannot serve this provider over MCP. */
39
+ platform: ContextModePlatformSchema.nullable(),
40
+ activation: z.enum(["native", "mcp", "disabled"]),
41
+ detail: z.string().max(4_096),
42
+ })
43
+ .strict();
58
44
 
59
- export const IntegrationAuditSchema = z.object({
60
- runtimePath: z.string(),
61
- runtimeVersion: z.string().nullable(),
62
- injectionEnabled: z.boolean(),
63
- providers: z.array(ProviderIntegrationSchema),
64
- checkedAt: z.string().datetime(),
65
- });
45
+ export const IntegrationAuditSchema = z
46
+ .object({ providers: z.array(ProviderIntegrationSchema) })
47
+ .strict();
66
48
 
67
49
  export const getContextModeStatus = defineRpc({
68
50
  name: "context-mode.status",
@@ -70,26 +52,13 @@ export const getContextModeStatus = defineRpc({
70
52
  output: BinaryStatusSchema,
71
53
  });
72
54
 
73
- export const getContextModeDoctor = defineRpc({
74
- name: "context-mode.doctor",
75
- input: refreshInput,
76
- output: CommandReportSchema,
77
- });
78
-
79
- export const getContextModeStats = defineRpc({
80
- name: "context-mode.stats",
81
- input: refreshInput,
82
- output: CommandReportSchema,
83
- });
84
-
85
55
  export const getContextModeIntegrationAudit = defineRpc({
86
56
  name: "context-mode.integration-audit",
87
- input: refreshInput,
57
+ input: z.object({}).strict(),
88
58
  output: IntegrationAuditSchema,
89
59
  });
90
60
 
91
61
  export type BinaryStatus = z.infer<typeof BinaryStatusSchema>;
92
- export type CommandReport = z.infer<typeof CommandReportSchema>;
93
62
  export type IntegrationAudit = z.infer<typeof IntegrationAuditSchema>;
94
63
  export type ProviderIntegration = z.infer<typeof ProviderIntegrationSchema>;
95
64
  export type ContextModeRefreshInput = z.infer<typeof refreshInput>;