@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.
@@ -6,32 +6,29 @@ const MAX_PATH_LENGTH = 4_096;
6
6
  const MAX_LABEL_LENGTH = 512;
7
7
  const MAX_QUERY_LENGTH = 1_024;
8
8
 
9
- export const ContextModeProviderSchema = z.enum([
10
- "claude",
11
- "codex",
12
- "copilot",
13
- "cursor",
14
- "opencode",
15
- "pi",
16
- "omp",
17
- "omp-plugin",
18
- ]);
19
-
20
- export const ContextModePlatformSchema = z.enum([
21
- "claude-code",
22
- "codex",
23
- "copilot-cli",
24
- "cursor",
25
- "opencode",
26
- "pi",
27
- "omp",
28
- ]);
29
-
30
9
  /** A Paseo provider id: a built-in or one configured in `agents.providers`. */
31
10
  export const KnowledgeProviderSchema = z.string().trim().min(1).max(128);
32
11
 
12
+ /** The project store a knowledge action writes to, and the agent it is recorded as. */
13
+ export interface KnowledgeDestination {
14
+ provider: string;
15
+ projectPath: string;
16
+ }
17
+
18
+ /** A finished action's result belongs to the destination it ran against, not to a later one. */
19
+ export function sameDestination(
20
+ ran: KnowledgeDestination | undefined,
21
+ current: KnowledgeDestination | null,
22
+ ): boolean {
23
+ return (
24
+ ran !== undefined &&
25
+ current !== null &&
26
+ ran.provider === current.provider &&
27
+ ran.projectPath === current.projectPath
28
+ );
29
+ }
30
+
33
31
  const boundedLabel = z.string().trim().min(1).max(MAX_LABEL_LENGTH);
34
- const boundedPattern = z.string().trim().min(1).max(256);
35
32
  const absoluteLocalPath = z
36
33
  .string()
37
34
  .trim()
@@ -64,65 +61,64 @@ export const KnowledgeToolResultSchema = z
64
61
  })
65
62
  .strict();
66
63
 
64
+ const pageCursor = z.number().int().nonnegative();
65
+
66
+ /** Where the next page starts: `offset` for relevance order, `after` (epoch ms) for timeline. */
67
+ export const SearchPageSchema = z.union([
68
+ z.object({ offset: pageCursor }).strict(),
69
+ z.object({ after: pageCursor }).strict(),
70
+ ]);
71
+
72
+ export const SearchKnowledgeResultSchema = KnowledgeToolResultSchema.extend({
73
+ next: SearchPageSchema.nullable(),
74
+ }).strict();
75
+
67
76
  export const SearchKnowledgeInputSchema = providerScope
68
77
  .extend({
69
78
  queries: z.array(z.string().trim().min(1).max(MAX_QUERY_LENGTH)).min(1).max(8),
70
- limit: z.number().int().min(1).max(10).default(3),
79
+ scope: z.enum(["worktree", "project"]).default("worktree"),
71
80
  source: boundedLabel.optional(),
72
- contentType: z.enum(["code", "prose"]).optional(),
73
81
  sort: z.enum(["relevance", "timeline"]).default("relevance"),
82
+ page: SearchPageSchema.optional(),
74
83
  })
75
84
  .strict();
76
85
 
77
- export const IndexPathInputSchema = providerScope
78
- .extend({
79
- path: absoluteLocalPath,
80
- source: boundedLabel.optional(),
81
- include: z.array(boundedPattern).max(32).optional(),
82
- exclude: z.array(boundedPattern).max(32).optional(),
83
- maxDepth: z.number().int().min(0).max(20).optional(),
84
- maxFiles: z.number().int().min(1).max(1_000).optional(),
85
- extensions: z.array(boundedPattern).max(32).optional(),
86
- respectGitignore: z.boolean().optional(),
87
- followSymlinks: z.boolean().optional(),
88
- })
89
- .strict();
86
+ export const IndexPathInputSchema = providerScope.extend({ path: absoluteLocalPath }).strict();
90
87
 
91
- export const FetchAndIndexInputSchema = providerScope
92
- .extend({
93
- url: httpUrl,
94
- source: boundedLabel.optional(),
95
- force: z.boolean().default(false),
96
- ttl: z.number().int().min(0).max(1_209_600_000).optional(),
97
- })
98
- .strict();
88
+ export const FetchAndIndexInputSchema = providerScope.extend({ url: httpUrl }).strict();
99
89
 
100
- const projectPurge = z
101
- .object({
102
- provider: KnowledgeProviderSchema,
103
- projectPath: absoluteLocalPath,
104
- confirm: z.literal(true),
105
- scope: z.literal("project"),
106
- })
107
- .strict();
108
- const sessionPurge = z
109
- .object({
110
- provider: KnowledgeProviderSchema,
111
- projectPath: absoluteLocalPath,
112
- confirm: z.literal(true),
113
- scope: z.literal("session"),
114
- sessionId: z.string().trim().min(1).max(256),
115
- })
90
+ export const ResumeSessionInputSchema = providerScope
91
+ .extend({ sessionId: z.string().trim().min(1).max(256) })
116
92
  .strict();
117
93
 
94
+ const purgeBase = {
95
+ provider: KnowledgeProviderSchema,
96
+ projectPath: absoluteLocalPath,
97
+ confirm: z.literal(true),
98
+ };
99
+
118
100
  export const PurgeKnowledgeInputSchema = z.discriminatedUnion("scope", [
119
- projectPurge,
120
- sessionPurge,
101
+ z.object({ ...purgeBase, scope: z.literal("project") }).strict(),
102
+ z
103
+ .object({
104
+ ...purgeBase,
105
+ scope: z.literal("session"),
106
+ sessionId: z.string().trim().min(1).max(256),
107
+ })
108
+ .strict(),
109
+ z.object({ ...purgeBase, scope: z.literal("source"), source: boundedLabel }).strict(),
121
110
  ]);
122
111
 
123
112
  export const searchContextModeKnowledge = defineRpc({
124
113
  name: "context-mode.knowledge.search",
125
114
  input: SearchKnowledgeInputSchema,
115
+ output: SearchKnowledgeResultSchema,
116
+ });
117
+
118
+ /** `ctx_resume` for one recorded session: the state block an agent gets after a compact or restart. */
119
+ export const resumeContextModeSession = defineRpc({
120
+ name: "context-mode.knowledge.resume",
121
+ input: ResumeSessionInputSchema,
126
122
  output: KnowledgeToolResultSchema,
127
123
  });
128
124
 
@@ -144,10 +140,11 @@ export const purgeContextModeKnowledge = defineRpc({
144
140
  output: KnowledgeToolResultSchema,
145
141
  });
146
142
 
147
- export type ContextModeProvider = z.infer<typeof ContextModeProviderSchema>;
148
- export type ContextModePlatform = z.infer<typeof ContextModePlatformSchema>;
149
143
  export type KnowledgeToolResult = z.infer<typeof KnowledgeToolResultSchema>;
144
+ export type SearchPage = z.infer<typeof SearchPageSchema>;
145
+ export type SearchKnowledgeResult = z.infer<typeof SearchKnowledgeResultSchema>;
150
146
  export type SearchKnowledgeInput = z.infer<typeof SearchKnowledgeInputSchema>;
151
147
  export type IndexPathInput = z.infer<typeof IndexPathInputSchema>;
152
148
  export type FetchAndIndexInput = z.infer<typeof FetchAndIndexInputSchema>;
149
+ export type ResumeSessionInput = z.infer<typeof ResumeSessionInputSchema>;
153
150
  export type PurgeKnowledgeInput = z.infer<typeof PurgeKnowledgeInputSchema>;
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+
3
+ /** Paseo providers Context Mode 2 serves over MCP. */
4
+ export const ContextModeProviderSchema = z.enum(["claude", "codex", "copilot", "opencode"]);
5
+
6
+ /** Context Mode 2 `--agent` ids for those providers. */
7
+ export const ContextModePlatformSchema = z.enum([
8
+ "claude-code",
9
+ "codex",
10
+ "copilot-cli",
11
+ "opencode",
12
+ ]);
13
+
14
+ export type ContextModeProvider = z.infer<typeof ContextModeProviderSchema>;
15
+ export type ContextModePlatform = z.infer<typeof ContextModePlatformSchema>;
16
+
17
+ interface ProviderEntry {
18
+ provider: ContextModeProvider;
19
+ platform: ContextModePlatform;
20
+ label: string;
21
+ }
22
+
23
+ /** The one mapping between Paseo providers, Context Mode agent ids, and display labels. */
24
+ export const CONTEXT_MODE_PROVIDERS: readonly ProviderEntry[] = [
25
+ { provider: "claude", platform: "claude-code", label: "Claude" },
26
+ { provider: "codex", platform: "codex", label: "Codex" },
27
+ { provider: "copilot", platform: "copilot-cli", label: "Copilot" },
28
+ { provider: "opencode", platform: "opencode", label: "OpenCode" },
29
+ ];
30
+
31
+ export function contextModePlatformFor(provider: ContextModeProvider): ContextModePlatform {
32
+ const entry = CONTEXT_MODE_PROVIDERS.find((candidate) => candidate.provider === provider);
33
+ if (!entry) throw new Error(`No Context Mode agent id for provider ${provider}.`);
34
+ return entry.platform;
35
+ }
36
+
37
+ interface InProcessEntry {
38
+ provider: string;
39
+ agent: string;
40
+ label: string;
41
+ }
42
+
43
+ /**
44
+ * Context Mode runs inside these hosts as an extension, so Paseo cannot inject it, but they record
45
+ * sessions in the same store under their own agent id.
46
+ */
47
+ export const IN_PROCESS_PROVIDERS: readonly InProcessEntry[] = [
48
+ { provider: "pi", agent: "pi", label: "Pi" },
49
+ ];
50
+
51
+ /**
52
+ * Agent id of the panel's own Context Mode process when no injectable agent applies: `--agent pi`
53
+ * cannot resolve a project over MCP, and the panel's calls are its own session anyway.
54
+ */
55
+ export const PANEL_PLATFORM: ContextModePlatform = "claude-code";
56
+
57
+ /** The Paseo provider that owns a Context Mode agent id recorded in a database, if any. */
58
+ export function providerForPlatform(platform: string): { provider: string; label: string } | null {
59
+ const injected = CONTEXT_MODE_PROVIDERS.find((candidate) => candidate.platform === platform);
60
+ if (injected) return injected;
61
+ return IN_PROCESS_PROVIDERS.find((candidate) => candidate.agent === platform) ?? null;
62
+ }
@@ -4,10 +4,8 @@ import { z } from "zod";
4
4
  export const REFRESH_INTERVALS = [5_000, 15_000, 30_000, 60_000] as const;
5
5
 
6
6
  export const DEFAULT_CONTEXT_MODE_SETTINGS = {
7
- binaryMode: "path",
8
- binaryPath: "",
7
+ binaryPath: null,
9
8
  refreshIntervalMs: 15_000,
10
- showDoctorByDefault: false,
11
9
  autoInject: true,
12
10
  preferNativeIntegrations: true,
13
11
  } as const;
@@ -18,34 +16,51 @@ function isAbsolutePath(value: string): boolean {
18
16
 
19
17
  export const ContextModeSettingsSchema = z
20
18
  .object({
21
- binaryMode: z.enum(["path", "automatic"]).default(DEFAULT_CONTEXT_MODE_SETTINGS.binaryMode),
22
- binaryPath: z.string().trim().max(4_096).default(DEFAULT_CONTEXT_MODE_SETTINGS.binaryPath),
19
+ /** Your own Context Mode executable; null runs the runtime bundled with the plugin. */
20
+ binaryPath: z
21
+ .string()
22
+ .trim()
23
+ .min(1)
24
+ .max(4_096)
25
+ .refine(isAbsolutePath, "The Context Mode binary path must be absolute.")
26
+ .nullable()
27
+ .default(DEFAULT_CONTEXT_MODE_SETTINGS.binaryPath),
23
28
  refreshIntervalMs: z
24
29
  .union([z.literal(5_000), z.literal(15_000), z.literal(30_000), z.literal(60_000)])
25
30
  .default(DEFAULT_CONTEXT_MODE_SETTINGS.refreshIntervalMs),
26
- showDoctorByDefault: z.boolean().default(DEFAULT_CONTEXT_MODE_SETTINGS.showDoctorByDefault),
27
31
  autoInject: z.boolean().default(DEFAULT_CONTEXT_MODE_SETTINGS.autoInject),
28
32
  preferNativeIntegrations: z
29
33
  .boolean()
30
34
  .default(DEFAULT_CONTEXT_MODE_SETTINGS.preferNativeIntegrations),
31
35
  })
32
- .strict()
33
- .superRefine((settings, context) => {
34
- if (settings.binaryMode !== "path" || settings.binaryPath.length === 0) return;
35
- if (!isAbsolutePath(settings.binaryPath)) {
36
- context.addIssue({
37
- code: "custom",
38
- path: ["binaryPath"],
39
- message: "The Context Mode binary path must be absolute.",
40
- });
41
- }
42
- });
36
+ .strict();
43
37
 
44
38
  export type ContextModeSettings = z.infer<typeof ContextModeSettingsSchema>;
45
39
 
40
+ const VersionOneSettingsSchema = z.looseObject({
41
+ binaryMode: z.string().optional(),
42
+ binaryPath: z.string().optional(),
43
+ });
44
+
45
+ /**
46
+ * Version 1 searched PATH when no path was set and kept a `showDoctorByDefault` flag nothing read.
47
+ * Only an explicitly configured absolute path survives as the user's own binary.
48
+ */
49
+ function migrate(values: unknown): unknown {
50
+ const {
51
+ binaryMode,
52
+ binaryPath,
53
+ showDoctorByDefault: _unused,
54
+ ...rest
55
+ } = VersionOneSettingsSchema.parse(values ?? {});
56
+ const configured = binaryMode !== "automatic" ? binaryPath?.trim() : undefined;
57
+ return { ...rest, binaryPath: configured || null };
58
+ }
59
+
46
60
  export const contextModeSettings = defineSettings({
47
61
  id: "context-mode",
48
62
  scope: "host",
49
- version: 1,
63
+ version: 2,
50
64
  schema: ContextModeSettingsSchema,
65
+ migrate,
51
66
  });