@getpaseo/server 0.1.90 → 0.1.91-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.
@@ -12,6 +12,11 @@ export interface McpStdioServerConfig {
12
12
  command: string;
13
13
  args?: string[];
14
14
  env?: Record<string, string>;
15
+ /**
16
+ * When true, all tools from this server are always included in the prompt
17
+ * and never deferred behind tool search. Honored by the Claude provider.
18
+ */
19
+ alwaysLoad?: boolean;
15
20
  }
16
21
  /**
17
22
  * HTTP-based MCP server.
@@ -20,6 +25,11 @@ export interface McpHttpServerConfig {
20
25
  type: "http";
21
26
  url: string;
22
27
  headers?: Record<string, string>;
28
+ /**
29
+ * When true, all tools from this server are always included in the prompt
30
+ * and never deferred behind tool search. Honored by the Claude provider.
31
+ */
32
+ alwaysLoad?: boolean;
23
33
  }
24
34
  /**
25
35
  * SSE-based MCP server (Server-Sent Events over HTTP).
@@ -28,6 +38,11 @@ export interface McpSseServerConfig {
28
38
  type: "sse";
29
39
  url: string;
30
40
  headers?: Record<string, string>;
41
+ /**
42
+ * When true, all tools from this server are always included in the prompt
43
+ * and never deferred behind tool search. Honored by the Claude provider.
44
+ */
45
+ alwaysLoad?: boolean;
31
46
  }
32
47
  /**
33
48
  * Canonical MCP server configuration.
@@ -292,7 +292,7 @@ function buildResolvedBuiltinProviders(providerOverrides, runtimeSettings, optio
292
292
  runtimeSettings: mergedRuntimeSettings,
293
293
  profileModels: override?.models ?? [],
294
294
  additionalModels: override?.additionalModels ?? [],
295
- profileModelsAreAdditive: definition.id === "claude",
295
+ profileModelsAreAdditive: false,
296
296
  enabled: override?.enabled !== false,
297
297
  derivedFromProviderId: null,
298
298
  createBaseClient: (logger) => factory(logger, mergedRuntimeSettings, {
@@ -6,6 +6,24 @@ import { withTimeout } from "../../utils/promise-timeout.js";
6
6
  import { buildProviderRegistry, shutdownAgentClients, } from "./provider-registry.js";
7
7
  import { applyMutableProviderConfigToOverrides } from "../daemon-config-store.js";
8
8
  const DEFAULT_REFRESH_TIMEOUT_MS = 30000;
9
+ const REFRESH_TIMEOUT_ENV_VAR = "PASEO_PROVIDER_REFRESH_TIMEOUT_MS";
10
+ // Provider refresh probes can be slow on cold starts (e.g. Copilot's first
11
+ // `copilot --acp` invocation, OpenCode workspace probes with many MCP servers).
12
+ // Allow operators to bump the ceiling via env var without rebuilding.
13
+ function resolveRefreshTimeoutMs(option) {
14
+ if (typeof option === "number" && Number.isFinite(option) && option > 0) {
15
+ return option;
16
+ }
17
+ const fromEnv = process.env[REFRESH_TIMEOUT_ENV_VAR];
18
+ if (fromEnv) {
19
+ // Number() handles scientific notation (e.g. "6e4") which parseInt would silently truncate.
20
+ const parsed = Number(fromEnv);
21
+ if (Number.isFinite(parsed) && parsed > 0) {
22
+ return parsed;
23
+ }
24
+ }
25
+ return DEFAULT_REFRESH_TIMEOUT_MS;
26
+ }
9
27
  export class ProviderSnapshotManager {
10
28
  constructor(options) {
11
29
  this.snapshots = new Map();
@@ -19,7 +37,7 @@ export class ProviderSnapshotManager {
19
37
  this.runtimeSettings = options.runtimeSettings;
20
38
  this.providerOverrides = options.providerOverrides;
21
39
  this.baseProviderOverrides = options.providerOverrides;
22
- this.refreshTimeoutMs = options.refreshTimeoutMs ?? DEFAULT_REFRESH_TIMEOUT_MS;
40
+ this.refreshTimeoutMs = resolveRefreshTimeoutMs(options.refreshTimeoutMs);
23
41
  this.providerRegistry = this.buildRegistry();
24
42
  this.providerClients = { ...this.extraClients };
25
43
  }
@@ -1,7 +1,7 @@
1
- import { type AgentDefinition, type SDKMessage } from "@anthropic-ai/claude-agent-sdk";
1
+ import { type AgentDefinition, type McpServerConfig as ClaudeSdkMcpServerConfig, type SDKMessage } from "@anthropic-ai/claude-agent-sdk";
2
2
  import type { Logger } from "pino";
3
3
  import { type ClaudeQueryFactory } from "./query.js";
4
- import { type AgentCapabilityFlags, type AgentClient, type AgentCreateSessionOptions, type AgentFeature, type AgentLaunchContext, type AgentMetadata, type AgentModelDefinition, type AgentPersistenceHandle, type AgentSession, type AgentSessionConfig, type AgentTimelineItem, type ListModelsOptions, type ListPersistedAgentsOptions, type PersistedAgentDescriptor } from "../../agent-sdk-types.js";
4
+ import { type AgentCapabilityFlags, type AgentClient, type AgentCreateSessionOptions, type AgentFeature, type AgentLaunchContext, type AgentMetadata, type AgentModelDefinition, type AgentPersistenceHandle, type AgentSession, type AgentSessionConfig, type AgentTimelineItem, type ListModelsOptions, type ListPersistedAgentsOptions, type McpServerConfig, type PersistedAgentDescriptor } from "../../agent-sdk-types.js";
5
5
  import { type ProviderRuntimeSettings } from "../../provider-launch-config.js";
6
6
  export declare function normalizeClaudeAskUserQuestionUpdatedInput(updatedInput: AgentMetadata | undefined, fallbackInput: AgentMetadata | undefined): AgentMetadata;
7
7
  interface EventIdentifiers {
@@ -21,8 +21,10 @@ interface ClaudeAgentClientOptions {
21
21
  runtimeSettings?: ProviderRuntimeSettings;
22
22
  queryFactory?: ClaudeQueryFactory;
23
23
  resolveBinary?: () => Promise<string>;
24
+ configDir?: string;
24
25
  }
25
26
  export declare function extractUserMessageText(content: unknown): string | null;
27
+ export declare function toClaudeSdkMcpConfig(config: McpServerConfig): ClaudeSdkMcpServerConfig;
26
28
  export declare function readEventIdentifiers(message: SDKMessage): EventIdentifiers;
27
29
  export declare class ClaudeAgentClient implements AgentClient {
28
30
  readonly provider: "claude";
@@ -32,6 +34,7 @@ export declare class ClaudeAgentClient implements AgentClient {
32
34
  private readonly runtimeSettings?;
33
35
  private readonly queryFactory?;
34
36
  private readonly resolveBinary;
37
+ private readonly configDir?;
35
38
  constructor(options: ClaudeAgentClientOptions);
36
39
  createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext, options?: AgentCreateSessionOptions): Promise<AgentSession>;
37
40
  resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, launchContext?: AgentLaunchContext): Promise<AgentSession>;
@@ -15,6 +15,7 @@ import { renderPromptAttachmentAsText } from "../../prompt-attachments.js";
15
15
  import { claudeQuery } from "./query.js";
16
16
  import { realClaudeRewindSdk, revertClaudeConversation, revertClaudeFiles } from "./rewind.js";
17
17
  import { normalizeProviderReplayTimestamp } from "../../provider-history-timestamps.js";
18
+ import { claudeProjectDirSync } from "./project-dir.js";
18
19
  import { getAgentStreamEventTurnId, } from "../../agent-sdk-types.js";
19
20
  import { checkProviderLaunchAvailable, createProviderEnv, createProviderEnvSpec, resolveProviderLaunch, } from "../../provider-launch-config.js";
20
21
  import { withTimeout } from "../../../../utils/promise-timeout.js";
@@ -171,9 +172,6 @@ function isClaudeThinkingEffort(value) {
171
172
  value === "xhigh" ||
172
173
  value === "max");
173
174
  }
174
- function sanitizeClaudeProjectPath(cwd) {
175
- return cwd.replace(/[\\/._:]/g, "-");
176
- }
177
175
  const MAX_RECENT_STDERR_CHARS = 4000;
178
176
  const STDERR_FLUSH_WAIT_MS = 150;
179
177
  const STDERR_FLUSH_POLL_INTERVAL_MS = 10;
@@ -541,7 +539,7 @@ function coerceSessionMetadata(metadata) {
541
539
  }
542
540
  return result;
543
541
  }
544
- function toClaudeSdkMcpConfig(config) {
542
+ export function toClaudeSdkMcpConfig(config) {
545
543
  switch (config.type) {
546
544
  case "stdio":
547
545
  return {
@@ -549,18 +547,21 @@ function toClaudeSdkMcpConfig(config) {
549
547
  command: config.command,
550
548
  args: config.args,
551
549
  env: config.env,
550
+ alwaysLoad: config.alwaysLoad,
552
551
  };
553
552
  case "http":
554
553
  return {
555
554
  type: "http",
556
555
  url: config.url,
557
556
  headers: config.headers,
557
+ alwaysLoad: config.alwaysLoad,
558
558
  };
559
559
  case "sse":
560
560
  return {
561
561
  type: "sse",
562
562
  url: config.url,
563
563
  headers: config.headers,
564
+ alwaysLoad: config.alwaysLoad,
564
565
  };
565
566
  }
566
567
  throw new Error("Unhandled MCP server config type");
@@ -924,6 +925,7 @@ export class ClaudeAgentClient {
924
925
  this.runtimeSettings = options.runtimeSettings;
925
926
  this.queryFactory = options.queryFactory;
926
927
  this.resolveBinary = options.resolveBinary ?? (() => resolveClaudeBinary(this.runtimeSettings));
928
+ this.configDir = options.configDir;
927
929
  }
928
930
  async createSession(config, launchContext, options) {
929
931
  const claudeConfig = this.assertConfig(config);
@@ -963,7 +965,7 @@ export class ClaudeAgentClient {
963
965
  }
964
966
  async listModels(_options) {
965
967
  // Claude exposes a global catalog here; cwd/force are intentionally irrelevant.
966
- return await getClaudeModelsWithSettings(this.logger);
968
+ return await getClaudeModelsWithSettings(this.logger, this.configDir);
967
969
  }
968
970
  async listFeatures(config) {
969
971
  const claudeConfig = this.assertConfig(config);
@@ -3188,14 +3190,12 @@ class ClaudeAgentSession {
3188
3190
  // Fall back to the configured cwd when the path has already disappeared.
3189
3191
  }
3190
3192
  for (const candidate of candidates) {
3191
- const sanitized = sanitizeClaudeProjectPath(candidate);
3192
- const historyPath = path.join(configDir, "projects", sanitized, `${sessionId}.jsonl`);
3193
+ const historyPath = path.join(claudeProjectDirSync(candidate, { configDir }), `${sessionId}.jsonl`);
3193
3194
  if (fs.existsSync(historyPath)) {
3194
3195
  return historyPath;
3195
3196
  }
3196
3197
  }
3197
- const sanitized = sanitizeClaudeProjectPath(cwd);
3198
- return path.join(configDir, "projects", sanitized, `${sessionId}.jsonl`);
3198
+ return path.join(claudeProjectDirSync(cwd, { configDir }), `${sessionId}.jsonl`);
3199
3199
  }
3200
3200
  convertHistoryEntry(entry) {
3201
3201
  return convertClaudeHistoryEntry(entry, (content) => this.mapBlocksToTimeline(content));
@@ -1,7 +1,7 @@
1
1
  import type { Logger } from "pino";
2
2
  import type { AgentModelDefinition } from "../../agent-sdk-types.js";
3
3
  export declare function getClaudeModels(): AgentModelDefinition[];
4
- export declare function getClaudeModelsWithSettings(logger: Logger): Promise<AgentModelDefinition[]>;
4
+ export declare function getClaudeModelsWithSettings(logger: Logger, configDir?: string): Promise<AgentModelDefinition[]>;
5
5
  /**
6
6
  * Normalize a runtime model string (from SDK init message) to a known model ID.
7
7
  * Handles the `[1m]` suffix that the SDK appends for 1M context sessions.
@@ -89,9 +89,9 @@ const CLAUDE_SETTINGS_MODEL_ENV_KEYS = [
89
89
  export function getClaudeModels() {
90
90
  return CLAUDE_MODELS.map((model) => ({ ...model }));
91
91
  }
92
- export async function getClaudeModelsWithSettings(logger) {
92
+ export async function getClaudeModelsWithSettings(logger, configDir) {
93
93
  const hardcodedModels = getClaudeModels();
94
- const settingsModels = await readClaudeSettingsModels(logger);
94
+ const settingsModels = await readClaudeSettingsModels(logger, configDir);
95
95
  if (settingsModels.length === 0) {
96
96
  return hardcodedModels;
97
97
  }
@@ -106,8 +106,8 @@ export async function getClaudeModelsWithSettings(logger) {
106
106
  }
107
107
  return models;
108
108
  }
109
- async function readClaudeSettingsModels(logger) {
110
- const settingsPath = path.join(resolveClaudeConfigDir(), "settings.json");
109
+ async function readClaudeSettingsModels(logger, configDir) {
110
+ const settingsPath = path.join(resolveClaudeConfigDir(configDir), "settings.json");
111
111
  let parsed;
112
112
  try {
113
113
  const rawSettings = await fs.readFile(settingsPath, "utf8");
@@ -136,8 +136,8 @@ async function readClaudeSettingsModels(logger) {
136
136
  }
137
137
  return models;
138
138
  }
139
- function resolveClaudeConfigDir() {
140
- return process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
139
+ function resolveClaudeConfigDir(configDir) {
140
+ return configDir ?? process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
141
141
  }
142
142
  function addSettingsModel(models, value, settingsKey) {
143
143
  if (typeof value !== "string") {
@@ -2,4 +2,5 @@ export interface ClaudeProjectDirOptions {
2
2
  configDir?: string;
3
3
  }
4
4
  export declare function claudeProjectDir(cwd: string, options?: ClaudeProjectDirOptions): Promise<string>;
5
+ export declare function claudeProjectDirSync(cwd: string, options?: ClaudeProjectDirOptions): string;
5
6
  //# sourceMappingURL=project-dir.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { realpathSync } from "node:fs";
1
2
  import { realpath } from "node:fs/promises";
2
3
  import { homedir } from "node:os";
3
4
  import { join } from "node:path";
@@ -12,6 +13,11 @@ export async function claudeProjectDir(cwd, options) {
12
13
  const projectsRoot = join(resolveConfigDir(options), "projects");
13
14
  return join(projectsRoot, encode(canonical));
14
15
  }
16
+ export function claudeProjectDirSync(cwd, options) {
17
+ const canonical = canonicalizeSync(cwd);
18
+ const projectsRoot = join(resolveConfigDir(options), "projects");
19
+ return join(projectsRoot, encode(canonical));
20
+ }
15
21
  async function canonicalize(input) {
16
22
  try {
17
23
  return (await realpath(input)).normalize("NFC");
@@ -20,6 +26,14 @@ async function canonicalize(input) {
20
26
  return input.normalize("NFC");
21
27
  }
22
28
  }
29
+ function canonicalizeSync(input) {
30
+ try {
31
+ return realpathSync.native(input).normalize("NFC");
32
+ }
33
+ catch {
34
+ return input.normalize("NFC");
35
+ }
36
+ }
23
37
  function encode(input) {
24
38
  const replaced = input.replace(/[^a-zA-Z0-9]/g, "-");
25
39
  if (replaced.length <= PROJECT_DIR_LENGTH_CAP) {
@@ -84,10 +84,25 @@ export function createRequireBearerMiddleware(auth, onReject) {
84
84
  })();
85
85
  };
86
86
  }
87
+ // Routes that authenticate via their own capability and therefore must not be
88
+ // gated a second time behind the daemon password.
89
+ const BEARER_AUTH_BYPASS_PATHS = new Set([
90
+ // Unauthenticated liveness probe.
91
+ "/api/health",
92
+ // Guarded by a single-use download token (crypto-random UUID, 60s TTL,
93
+ // consumed on first use) that is only ever issued over the
94
+ // already-authenticated WebSocket. The token IS the capability for this
95
+ // route. Requiring the daemon password on top of it breaks browser and
96
+ // Electron downloads: those trigger the download via an anchor navigation,
97
+ // which cannot attach an `Authorization` header. The download endpoint still
98
+ // rejects requests without a valid token (400/403), so dropping the bearer
99
+ // here does not make the route unauthenticated.
100
+ "/api/files/download",
101
+ ]);
87
102
  export function shouldBypassBearerAuth(method, path) {
88
103
  if (method === "OPTIONS") {
89
104
  return true;
90
105
  }
91
- return path === "/api/health";
106
+ return BEARER_AUTH_BYPASS_PATHS.has(path);
92
107
  }
93
108
  //# sourceMappingURL=auth.js.map
@@ -3,6 +3,7 @@ import type { AgentProviderRuntimeSettingsMap } from "./agent/provider-launch-co
3
3
  export declare const LogLevelSchema: z.ZodEnum<["trace", "debug", "info", "warn", "error", "fatal"]>;
4
4
  export declare const LogFormatSchema: z.ZodEnum<["pretty", "json"]>;
5
5
  export declare const PersistedConfigSchema: z.ZodObject<{
6
+ $schema: z.ZodOptional<z.ZodString>;
6
7
  version: z.ZodOptional<z.ZodLiteral<1>>;
7
8
  daemon: z.ZodOptional<z.ZodEffects<z.ZodObject<{
8
9
  listen: z.ZodOptional<z.ZodString>;
@@ -957,6 +958,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
957
958
  order?: number | undefined;
958
959
  }> | undefined;
959
960
  } | undefined;
961
+ $schema?: string | undefined;
960
962
  app?: {
961
963
  baseUrl?: string | undefined;
962
964
  } | undefined;
@@ -1061,6 +1063,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
1061
1063
  } | undefined;
1062
1064
  providers?: unknown;
1063
1065
  } | undefined;
1066
+ $schema?: string | undefined;
1064
1067
  app?: {
1065
1068
  baseUrl?: string | undefined;
1066
1069
  } | undefined;
@@ -169,6 +169,7 @@ function normalizeAgentProviders(value) {
169
169
  }
170
170
  export const PersistedConfigSchema = z
171
171
  .object({
172
+ $schema: z.string().optional(),
172
173
  // v1 schema marker
173
174
  version: z.literal(1).optional(),
174
175
  // v1 config layout
@@ -12,8 +12,11 @@ const NO_SEGMENT_INDEX = Number.MAX_SAFE_INTEGER;
12
12
  const NO_MATCH_OFFSET = Number.MAX_SAFE_INTEGER;
13
13
  const NO_FUZZY_SCORE = Number.MAX_SAFE_INTEGER;
14
14
  const NO_WORKSPACE_MATCH_TIER = 5;
15
- const WORKSPACE_IGNORED_DIRECTORY_NAMES = new Set([
15
+ const IGNORED_SUGGESTION_DIRECTORY_NAMES = new Set([
16
16
  "node_modules",
17
+ "venv",
18
+ "env",
19
+ "virtualenv",
17
20
  "dist",
18
21
  "build",
19
22
  "target",
@@ -589,7 +592,9 @@ async function listChildDirectories(input) {
589
592
  return cached.entries;
590
593
  }
591
594
  const dirents = await readdir(input.directory, { withFileTypes: true }).catch(() => []);
592
- const candidates = dirents.filter((dirent) => !isHiddenDirectoryName(dirent.name) && (dirent.isDirectory() || dirent.isSymbolicLink()));
595
+ const candidates = dirents.filter((dirent) => !isHiddenDirectoryName(dirent.name) &&
596
+ !isIgnoredSuggestionDirectoryName(dirent.name) &&
597
+ (dirent.isDirectory() || dirent.isSymbolicLink()));
593
598
  const resolved = await Promise.all(candidates.map(async (dirent) => {
594
599
  const candidatePath = path.join(input.directory, dirent.name);
595
600
  const absolutePath = await resolveDirectoryCandidate({
@@ -613,7 +618,7 @@ async function listWorkspaceChildEntries(input) {
613
618
  return cached.entries;
614
619
  }
615
620
  const dirents = await readdir(input.directory, { withFileTypes: true }).catch(() => []);
616
- const candidates = dirents.filter((dirent) => !isHiddenDirectoryName(dirent.name) && !isIgnoredWorkspaceDirectoryName(dirent.name));
621
+ const candidates = dirents.filter((dirent) => !isHiddenDirectoryName(dirent.name) && !isIgnoredSuggestionDirectoryName(dirent.name));
617
622
  const resolved = await Promise.all(candidates.map(async (dirent) => {
618
623
  const candidatePath = path.join(input.directory, dirent.name);
619
624
  const entry = await resolveWorkspaceCandidate({
@@ -682,8 +687,8 @@ async function resolveWorkspaceCandidate(input) {
682
687
  function isHiddenDirectoryName(name) {
683
688
  return name.startsWith(".");
684
689
  }
685
- function isIgnoredWorkspaceDirectoryName(name) {
686
- return WORKSPACE_IGNORED_DIRECTORY_NAMES.has(name);
690
+ function isIgnoredSuggestionDirectoryName(name) {
691
+ return IGNORED_SUGGESTION_DIRECTORY_NAMES.has(name);
687
692
  }
688
693
  function setDirectoryListCache(cacheKey, entry) {
689
694
  directoryListCache.set(cacheKey, entry);
@@ -128,6 +128,10 @@ export declare class UnknownBranchError extends Error {
128
128
  cwd: string;
129
129
  });
130
130
  }
131
+ export declare class InvalidGitBranchNameError extends Error {
132
+ readonly branchName: string;
133
+ constructor(branchName: string);
134
+ }
131
135
  export type ReadPaseoConfigResult = {
132
136
  ok: true;
133
137
  config: PaseoConfig | null;
@@ -55,6 +55,13 @@ export class UnknownBranchError extends Error {
55
55
  this.cwd = params.cwd;
56
56
  }
57
57
  }
58
+ export class InvalidGitBranchNameError extends Error {
59
+ constructor(branchName) {
60
+ super(`Invalid branch name: Git rejected ref name '${branchName}'`);
61
+ this.name = "InvalidGitBranchNameError";
62
+ this.branchName = branchName;
63
+ }
64
+ }
58
65
  export function readPaseoConfig(repoRoot) {
59
66
  try {
60
67
  const json = readPaseoConfigJson(repoRoot);
@@ -898,7 +905,7 @@ async function resolveWorktreeSourcePlan({ cwd, source, desiredSlug, }) {
898
905
  };
899
906
  }
900
907
  case "checkout-branch": {
901
- validateWorktreeBranchName(source.branchName);
908
+ await validateExistingWorktreeBranchName(cwd, source.branchName);
902
909
  if (!(await localBranchExists(cwd, source.branchName))) {
903
910
  try {
904
911
  await runGitCommand(["fetch", "origin", `${source.branchName}:${source.branchName}`], {
@@ -921,7 +928,7 @@ async function resolveWorktreeSourcePlan({ cwd, source, desiredSlug, }) {
921
928
  }
922
929
  case "checkout-github-pr": {
923
930
  const localBranchCandidate = source.localBranchName ?? source.headRef;
924
- validateWorktreeBranchName(localBranchCandidate);
931
+ await validateExistingWorktreeBranchName(cwd, localBranchCandidate);
925
932
  const localBranchName = await resolveUniqueLocalBranchName(cwd, localBranchCandidate);
926
933
  const normalizedBaseRefName = normalizeRequiredBaseBranch(source.baseRefName);
927
934
  await runGitCommand([
@@ -966,6 +973,16 @@ function validateWorktreeBranchName(branchName) {
966
973
  throw new Error(`Invalid branch name: ${validation.error}`);
967
974
  }
968
975
  }
976
+ async function validateExistingWorktreeBranchName(cwd, branchName) {
977
+ const result = await runGitCommand(["check-ref-format", "--branch", branchName], {
978
+ cwd,
979
+ timeout: 30000,
980
+ acceptExitCodes: [0, 1, 128],
981
+ });
982
+ if (result.exitCode !== 0) {
983
+ throw new InvalidGitBranchNameError(branchName);
984
+ }
985
+ }
969
986
  function normalizeRequiredBaseBranch(baseBranch) {
970
987
  const normalizedBaseBranch = normalizeBaseRefName(baseBranch);
971
988
  if (!normalizedBaseBranch) {
@@ -169,6 +169,7 @@ function normalizeAgentProviders(value) {
169
169
  }
170
170
  export const PersistedConfigSchema = z
171
171
  .object({
172
+ $schema: z.string().optional(),
172
173
  // v1 schema marker
173
174
  version: z.literal(1).optional(),
174
175
  // v1 config layout
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpaseo/server",
3
- "version": "0.1.90",
3
+ "version": "0.1.91-beta.2",
4
4
  "description": "Paseo backend server",
5
5
  "files": [
6
6
  "dist/server",
@@ -59,10 +59,10 @@
59
59
  "dependencies": {
60
60
  "@agentclientprotocol/sdk": "^0.17.1",
61
61
  "@anthropic-ai/claude-agent-sdk": "^0.2.133",
62
- "@getpaseo/client": "0.1.90",
63
- "@getpaseo/highlight": "0.1.90",
64
- "@getpaseo/protocol": "0.1.90",
65
- "@getpaseo/relay": "0.1.90",
62
+ "@getpaseo/client": "0.1.91-beta.2",
63
+ "@getpaseo/highlight": "0.1.91-beta.2",
64
+ "@getpaseo/protocol": "0.1.91-beta.2",
65
+ "@getpaseo/relay": "0.1.91-beta.2",
66
66
  "@isaacs/ttlcache": "^2.1.4",
67
67
  "@modelcontextprotocol/sdk": "^1.20.1",
68
68
  "@opencode-ai/sdk": "1.14.46",