@getpaseo/server 0.1.97 → 0.1.99

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.
Files changed (101) hide show
  1. package/dist/server/server/agent/agent-manager.d.ts +11 -3
  2. package/dist/server/server/agent/agent-manager.js +96 -24
  3. package/dist/server/server/agent/agent-prompt.d.ts +1 -1
  4. package/dist/server/server/agent/agent-prompt.js +3 -10
  5. package/dist/server/server/agent/agent-sdk-types.d.ts +20 -9
  6. package/dist/server/server/agent/create-agent/create.d.ts +2 -0
  7. package/dist/server/server/agent/create-agent/create.js +8 -7
  8. package/dist/server/server/agent/lifecycle-command.d.ts +15 -1
  9. package/dist/server/server/agent/lifecycle-command.js +9 -2
  10. package/dist/server/server/agent/mcp-server.js +254 -115
  11. package/dist/server/server/agent/provider-notices.d.ts +3 -0
  12. package/dist/server/server/agent/provider-notices.js +5 -0
  13. package/dist/server/server/agent/provider-registry.d.ts +8 -3
  14. package/dist/server/server/agent/provider-registry.js +58 -25
  15. package/dist/server/server/agent/provider-snapshot-manager.d.ts +3 -0
  16. package/dist/server/server/agent/provider-snapshot-manager.js +37 -16
  17. package/dist/server/server/agent/providers/acp-agent.d.ts +5 -3
  18. package/dist/server/server/agent/providers/acp-agent.js +32 -19
  19. package/dist/server/server/agent/providers/claude/agent.d.ts +2 -2
  20. package/dist/server/server/agent/providers/claude/agent.js +261 -167
  21. package/dist/server/server/agent/providers/claude/models.js +7 -3
  22. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +6 -4
  23. package/dist/server/server/agent/providers/codex-app-server-agent.js +48 -25
  24. package/dist/server/server/agent/providers/copilot-acp-agent.js +4 -31
  25. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +9 -0
  26. package/dist/server/server/agent/providers/diagnostic-utils.js +188 -0
  27. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +0 -1
  28. package/dist/server/server/agent/providers/generic-acp-agent.js +2 -108
  29. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -3
  30. package/dist/server/server/agent/providers/mock-load-test-agent.js +5 -5
  31. package/dist/server/server/agent/providers/mock-slow-provider.d.ts +2 -3
  32. package/dist/server/server/agent/providers/mock-slow-provider.js +3 -6
  33. package/dist/server/server/agent/providers/opencode/server-manager.d.ts +29 -2
  34. package/dist/server/server/agent/providers/opencode/server-manager.js +83 -17
  35. package/dist/server/server/agent/providers/opencode-agent.d.ts +6 -3
  36. package/dist/server/server/agent/providers/opencode-agent.js +61 -107
  37. package/dist/server/server/agent/providers/pi/agent.d.ts +2 -3
  38. package/dist/server/server/agent/providers/pi/agent.js +11 -63
  39. package/dist/server/server/agent/providers/pi/cli-runtime.js +2 -2
  40. package/dist/server/server/agent/providers/pi/runtime.d.ts +1 -1
  41. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts +1 -1
  42. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js +1 -1
  43. package/dist/server/server/bootstrap.d.ts +2 -0
  44. package/dist/server/server/bootstrap.js +32 -2
  45. package/dist/server/server/managed-processes/managed-processes.d.ts +76 -0
  46. package/dist/server/server/managed-processes/managed-processes.js +326 -0
  47. package/dist/server/server/resolve-worktree-creation-intent.d.ts +3 -0
  48. package/dist/server/server/resolve-worktree-creation-intent.js +3 -3
  49. package/dist/server/server/session/agent-config/agent-config-session.d.ts +50 -0
  50. package/dist/server/server/session/agent-config/agent-config-session.js +98 -0
  51. package/dist/server/server/session/chat/chat-schedule-loop-session.d.ts +120 -0
  52. package/dist/server/server/session/chat/chat-schedule-loop-session.js +489 -0
  53. package/dist/server/server/session/checkout/checkout-session.d.ts +142 -0
  54. package/dist/server/server/session/checkout/checkout-session.js +925 -0
  55. package/dist/server/server/session/daemon/daemon-session.d.ts +50 -0
  56. package/dist/server/server/session/daemon/daemon-session.js +98 -0
  57. package/dist/server/server/session/files/workspace-files-session.d.ts +43 -0
  58. package/dist/server/server/session/files/workspace-files-session.js +218 -0
  59. package/dist/server/server/session/project-config/project-config-session.d.ts +34 -0
  60. package/dist/server/server/session/project-config/project-config-session.js +125 -0
  61. package/dist/server/server/session/provider/provider-catalog-session.d.ts +74 -0
  62. package/dist/server/server/session/provider/provider-catalog-session.js +339 -0
  63. package/dist/server/server/session/voice/voice-session.d.ts +166 -0
  64. package/dist/server/server/session/voice/voice-session.js +893 -0
  65. package/dist/server/server/{voice → session/voice}/voice-turn-controller.d.ts +2 -2
  66. package/dist/server/server/{voice → session/voice}/voice-turn-controller.js +2 -2
  67. package/dist/server/server/session.d.ts +23 -207
  68. package/dist/server/server/session.js +2319 -5102
  69. package/dist/server/server/speech/providers/openai/runtime.js +3 -4
  70. package/dist/server/server/websocket-server.d.ts +1 -0
  71. package/dist/server/server/websocket-server.js +11 -0
  72. package/dist/server/server/workspace-archive-service.js +2 -3
  73. package/dist/server/server/workspace-directory.js +5 -5
  74. package/dist/server/server/workspace-reconciliation-service.js +2 -2
  75. package/dist/server/server/worktree-core.d.ts +1 -0
  76. package/dist/server/server/worktree-core.js +5 -1
  77. package/dist/server/services/quota-fetcher/manifest.d.ts +4 -0
  78. package/dist/server/services/quota-fetcher/manifest.js +47 -0
  79. package/dist/server/services/quota-fetcher/provider.d.ts +17 -0
  80. package/dist/server/services/quota-fetcher/provider.js +2 -0
  81. package/dist/server/services/quota-fetcher/providers/claude.d.ts +26 -0
  82. package/dist/server/services/quota-fetcher/providers/claude.js +217 -0
  83. package/dist/server/services/quota-fetcher/providers/codex.d.ts +23 -0
  84. package/dist/server/services/quota-fetcher/providers/codex.js +211 -0
  85. package/dist/server/services/quota-fetcher/providers/copilot.d.ts +17 -0
  86. package/dist/server/services/quota-fetcher/providers/copilot.js +75 -0
  87. package/dist/server/services/quota-fetcher/providers/cursor.d.ts +17 -0
  88. package/dist/server/services/quota-fetcher/providers/cursor.js +123 -0
  89. package/dist/server/services/quota-fetcher/providers/grok.d.ts +18 -0
  90. package/dist/server/services/quota-fetcher/providers/grok.js +89 -0
  91. package/dist/server/services/quota-fetcher/providers/kimi.d.ts +20 -0
  92. package/dist/server/services/quota-fetcher/providers/kimi.js +89 -0
  93. package/dist/server/services/quota-fetcher/providers/zai.d.ts +17 -0
  94. package/dist/server/services/quota-fetcher/providers/zai.js +58 -0
  95. package/dist/server/services/quota-fetcher/service.d.ts +28 -0
  96. package/dist/server/services/quota-fetcher/service.js +58 -0
  97. package/dist/server/services/quota-fetcher/usage.d.ts +22 -0
  98. package/dist/server/services/quota-fetcher/usage.js +49 -0
  99. package/dist/server/utils/checkout-git.d.ts +6 -0
  100. package/dist/server/utils/directory-suggestions.js +98 -2
  101. package/package.json +5 -5
@@ -0,0 +1,58 @@
1
+ import { z } from "zod";
2
+ import { ApiOptionalStringSchema, fetchProviderApi, unavailableUsage } from "../usage.js";
3
+ const ZaiUsageResponseSchema = z.object({
4
+ data: z
5
+ .array(z.object({
6
+ productName: ApiOptionalStringSchema,
7
+ status: ApiOptionalStringSchema,
8
+ purchaseTime: ApiOptionalStringSchema,
9
+ valid: ApiOptionalStringSchema,
10
+ }))
11
+ .optional(),
12
+ });
13
+ export class ZaiQuotaProvider {
14
+ constructor(options) {
15
+ this.providerId = "zai";
16
+ this.displayName = "Z.ai";
17
+ this.logger = options.logger;
18
+ this.fetchApi = options.fetch ?? fetch;
19
+ }
20
+ async fetchUsage() {
21
+ const token = process.env["ZAI_API_KEY"] || process.env["GLM_API_KEY"];
22
+ if (!token)
23
+ return unavailableUsage(this);
24
+ const res = await fetchProviderApi(this.fetchApi, "https://api.z.ai/api/biz/subscription/list", {
25
+ headers: {
26
+ Authorization: `Bearer ${token}`,
27
+ Accept: "application/json",
28
+ },
29
+ });
30
+ if (!res.ok) {
31
+ this.logger.debug({ status: res.status }, "Z.ai usage fetch failed");
32
+ return unavailableUsage(this);
33
+ }
34
+ const resp = ZaiUsageResponseSchema.parse(await res.json());
35
+ const sub = resp.data?.[0];
36
+ if (!sub)
37
+ return unavailableUsage(this);
38
+ const details = [];
39
+ if (sub.status)
40
+ details.push({ id: "status", label: "Status", value: sub.status });
41
+ if (sub.valid)
42
+ details.push({ id: "valid", label: "Valid", value: sub.valid });
43
+ if (sub.purchaseTime) {
44
+ details.push({ id: "purchase_time", label: "Purchased", value: sub.purchaseTime });
45
+ }
46
+ return {
47
+ providerId: this.providerId,
48
+ displayName: this.displayName,
49
+ status: "available",
50
+ planLabel: sub.productName || null,
51
+ windows: [],
52
+ balances: [],
53
+ details,
54
+ error: null,
55
+ };
56
+ }
57
+ }
58
+ //# sourceMappingURL=zai.js.map
@@ -0,0 +1,28 @@
1
+ import type { Logger } from "pino";
2
+ import type { ProviderUsage } from "../../server/messages.js";
3
+ import type { ProviderApiFetch, ProviderUsageFetcher } from "./provider.js";
4
+ export interface ProviderUsageServiceOptions {
5
+ logger: Logger;
6
+ fetchers?: ProviderUsageFetcher[];
7
+ fetch?: ProviderApiFetch;
8
+ cacheTtlMs?: number;
9
+ now?: () => number;
10
+ }
11
+ export interface ProviderUsageListResult {
12
+ fetchedAt: string;
13
+ providers: ProviderUsage[];
14
+ }
15
+ export declare class ProviderUsageService {
16
+ private readonly logger;
17
+ private readonly fetchers;
18
+ private readonly cacheTtlMs;
19
+ private readonly now;
20
+ private cached;
21
+ private inFlight;
22
+ constructor(options: ProviderUsageServiceOptions);
23
+ listUsage(options?: {
24
+ forceRefresh?: boolean;
25
+ }): Promise<ProviderUsageListResult>;
26
+ private fetchFreshUsage;
27
+ }
28
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1,58 @@
1
+ import { createProviderUsageFetchers } from "./manifest.js";
2
+ import { unavailableUsage } from "./usage.js";
3
+ const DEFAULT_PROVIDER_USAGE_CACHE_TTL_MS = 5 * 60 * 1000;
4
+ export class ProviderUsageService {
5
+ constructor(options) {
6
+ this.cached = null;
7
+ this.inFlight = null;
8
+ this.logger = options.logger.child({ module: "provider-usage-service" });
9
+ this.fetchers =
10
+ options.fetchers ??
11
+ createProviderUsageFetchers({
12
+ logger: this.logger,
13
+ fetch: options.fetch,
14
+ });
15
+ this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_PROVIDER_USAGE_CACHE_TTL_MS;
16
+ this.now = options.now ?? Date.now;
17
+ }
18
+ async listUsage(options) {
19
+ const nowMs = this.now();
20
+ if (!options?.forceRefresh &&
21
+ this.cached &&
22
+ nowMs - this.cached.fetchedAtMs < this.cacheTtlMs) {
23
+ return this.cached.result;
24
+ }
25
+ if (this.inFlight) {
26
+ return this.inFlight;
27
+ }
28
+ const request = this.fetchFreshUsage(nowMs);
29
+ this.inFlight = request;
30
+ try {
31
+ return await request;
32
+ }
33
+ finally {
34
+ if (this.inFlight === request) {
35
+ this.inFlight = null;
36
+ }
37
+ }
38
+ }
39
+ async fetchFreshUsage(nowMs) {
40
+ const settled = await Promise.allSettled(this.fetchers.map((fetcher) => fetcher.fetchUsage()));
41
+ const providers = settled.map((result, index) => {
42
+ const fetcher = this.fetchers[index];
43
+ if (result.status === "fulfilled") {
44
+ return result.value;
45
+ }
46
+ this.logger.debug({ err: result.reason, providerId: fetcher.providerId }, "Provider usage fetch failed");
47
+ return unavailableUsage({
48
+ providerId: fetcher.providerId,
49
+ displayName: fetcher.displayName,
50
+ error: result.reason instanceof Error ? result.reason.message : String(result.reason),
51
+ });
52
+ });
53
+ const result = { fetchedAt: new Date(nowMs).toISOString(), providers };
54
+ this.cached = { fetchedAtMs: nowMs, result };
55
+ return result;
56
+ }
57
+ }
58
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ import type { ProviderUsage, ProviderUsageBalance, ProviderUsageWindow } from "../../server/messages.js";
3
+ import type { ProviderApiFetch } from "./provider.js";
4
+ export declare const ApiNumberSchema: z.ZodCoercedNumber<unknown>;
5
+ export declare const ApiNullableNumberSchema: z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
6
+ export declare const ApiOptionalStringSchema: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedString<unknown>>>;
7
+ export declare function fetchProviderApi(fetchApi: ProviderApiFetch, input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
8
+ export declare function unavailableUsage(provider: {
9
+ providerId: string;
10
+ displayName: string;
11
+ error?: string | null;
12
+ }): ProviderUsage;
13
+ export declare function windowFromUsedPct(input: {
14
+ id: string;
15
+ label: string;
16
+ utilizationPct: number | null | undefined;
17
+ resetsAt?: string | null;
18
+ tone?: ProviderUsageWindow["tone"];
19
+ }): ProviderUsageWindow;
20
+ export declare function balanceToneFromRemaining(remaining: number | null | undefined): ProviderUsageBalance["tone"];
21
+ export declare function toIsoStringOrNull(timestampMs: number): string | null;
22
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ const PROVIDER_HTTP_TIMEOUT_MS = 15000;
3
+ export const ApiNumberSchema = z.coerce.number().finite();
4
+ export const ApiNullableNumberSchema = z.preprocess((value) => (value == null ? null : value), ApiNumberSchema.nullable());
5
+ export const ApiOptionalStringSchema = z.preprocess((value) => (value == null ? undefined : value), z.coerce.string().optional());
6
+ export function fetchProviderApi(fetchApi, input, init = {}) {
7
+ return fetchApi(input, {
8
+ ...init,
9
+ signal: init.signal ?? AbortSignal.timeout(PROVIDER_HTTP_TIMEOUT_MS),
10
+ });
11
+ }
12
+ export function unavailableUsage(provider) {
13
+ return {
14
+ providerId: provider.providerId,
15
+ displayName: provider.displayName,
16
+ status: provider.error ? "error" : "unavailable",
17
+ planLabel: null,
18
+ windows: [],
19
+ balances: [],
20
+ details: [],
21
+ error: provider.error ?? null,
22
+ };
23
+ }
24
+ export function windowFromUsedPct(input) {
25
+ const usedPct = typeof input.utilizationPct === "number" ? input.utilizationPct : null;
26
+ const window = {
27
+ id: input.id,
28
+ label: input.label,
29
+ usedPct,
30
+ remainingPct: usedPct === null ? null : Math.max(0, 100 - usedPct),
31
+ resetsAt: input.resetsAt ?? null,
32
+ };
33
+ if (input.tone) {
34
+ window.tone = input.tone;
35
+ }
36
+ return window;
37
+ }
38
+ export function balanceToneFromRemaining(remaining) {
39
+ if (typeof remaining !== "number")
40
+ return "default";
41
+ if (remaining <= 0)
42
+ return "danger";
43
+ return "ok";
44
+ }
45
+ export function toIsoStringOrNull(timestampMs) {
46
+ const date = new Date(timestampMs);
47
+ return Number.isFinite(date.getTime()) ? date.toISOString() : null;
48
+ }
49
+ //# sourceMappingURL=usage.js.map
@@ -1,6 +1,12 @@
1
1
  import type { Logger } from "pino";
2
2
  import type { ParsedDiffFile } from "../server/utils/diff-highlighter.js";
3
3
  import { type GitHubPullRequestStatusFacts, type GitHubService, type PullRequestMergeable } from "../services/github-service.js";
4
+ /**
5
+ * Why a git mutation is forcing a workspace snapshot refresh. Shared between the
6
+ * Session shell (which owns the refresh primitive) and the checkout subsystem
7
+ * (which triggers most of these reasons after a write).
8
+ */
9
+ export type GitMutationRefreshReason = "commit-changes" | "pull" | "push" | "merge-to-base" | "merge-from-base" | "merge-pr" | "enable-pr-auto-merge" | "disable-pr-auto-merge" | "create-pr" | "switch-branch" | "rename-branch" | "create-branch" | "stash-push" | "stash-pop" | "create-worktree";
4
10
  interface CheckoutReadCacheOptions {
5
11
  force?: boolean;
6
12
  reason?: string;
@@ -24,6 +24,15 @@ const IGNORED_SUGGESTION_DIRECTORY_NAMES = new Set([
24
24
  "coverage",
25
25
  "vendor",
26
26
  "__pycache__",
27
+ ".git",
28
+ ]);
29
+ const TRAVERSABLE_HIDDEN_WORKSPACE_DIRECTORY_NAMES = new Set([
30
+ ".agents",
31
+ ".claude",
32
+ ".codex",
33
+ ".github",
34
+ ".paseo",
35
+ ".vscode",
27
36
  ]);
28
37
  export async function searchHomeDirectories(options) {
29
38
  const query = options.query.trim();
@@ -71,6 +80,17 @@ export async function searchWorkspaceEntries(options) {
71
80
  return [];
72
81
  }
73
82
  const matchMode = options.matchMode ?? "fuzzy";
83
+ const exactEntry = queryParts.isPathQuery && matchMode === "suffix"
84
+ ? await resolveWorkspaceExactEntry({
85
+ workspaceRoot,
86
+ query: options.query,
87
+ includeDirectories,
88
+ includeFiles,
89
+ })
90
+ : null;
91
+ if (exactEntry && limit <= 1) {
92
+ return [exactEntry];
93
+ }
74
94
  if (queryParts.isPathQuery && matchMode !== "suffix") {
75
95
  return searchWorkspaceWithinParentDirectory({
76
96
  workspaceRoot,
@@ -84,7 +104,7 @@ export async function searchWorkspaceEntries(options) {
84
104
  const searchTerm = matchMode === "suffix"
85
105
  ? [queryParts.parentPart, queryParts.searchTerm].filter(Boolean).join("/")
86
106
  : queryParts.searchTerm;
87
- return searchWorkspaceAcrossTree({
107
+ const entries = await searchWorkspaceAcrossTree({
88
108
  workspaceRoot,
89
109
  searchTerm,
90
110
  limit,
@@ -94,6 +114,53 @@ export async function searchWorkspaceEntries(options) {
94
114
  maxDepth: options.maxDepth ?? DEFAULT_MAX_DEPTH,
95
115
  maxEntriesScanned: options.maxEntriesScanned ?? DEFAULT_MAX_DIRECTORIES_SCANNED,
96
116
  });
117
+ return exactEntry ? prependWorkspaceEntry(exactEntry, entries).slice(0, limit) : entries;
118
+ }
119
+ async function resolveWorkspaceExactEntry(input) {
120
+ const normalized = input.query
121
+ .trim()
122
+ .replace(/\\/g, "/")
123
+ .replace(/^\.\/+/, "")
124
+ .replace(/\/{2,}/g, "/");
125
+ if (!normalized) {
126
+ return null;
127
+ }
128
+ const candidatePath = path.isAbsolute(normalized)
129
+ ? path.resolve(normalized)
130
+ : path.resolve(input.workspaceRoot, normalized);
131
+ let resolvedPath;
132
+ try {
133
+ resolvedPath = await realpath(candidatePath);
134
+ }
135
+ catch {
136
+ return null;
137
+ }
138
+ if (!isPathInsideRoot(input.workspaceRoot, resolvedPath)) {
139
+ return null;
140
+ }
141
+ const stats = await stat(resolvedPath).catch(() => null);
142
+ if (!stats) {
143
+ return null;
144
+ }
145
+ if (stats.isFile() && input.includeFiles) {
146
+ return {
147
+ path: normalizeRelativePath(input.workspaceRoot, resolvedPath),
148
+ kind: "file",
149
+ };
150
+ }
151
+ if (stats.isDirectory() && input.includeDirectories) {
152
+ return {
153
+ path: normalizeRelativePath(input.workspaceRoot, resolvedPath),
154
+ kind: "directory",
155
+ };
156
+ }
157
+ return null;
158
+ }
159
+ function prependWorkspaceEntry(entry, entries) {
160
+ return [
161
+ entry,
162
+ ...entries.filter((candidate) => candidate.kind !== entry.kind || candidate.path !== entry.path),
163
+ ];
97
164
  }
98
165
  function normalizeLimit(limit) {
99
166
  const candidate = limit ?? DEFAULT_LIMIT;
@@ -185,6 +252,9 @@ async function searchWorkspaceWithinParentDirectory(input) {
185
252
  if (entry.kind === "file" && !input.includeFiles) {
186
253
  continue;
187
254
  }
255
+ if (isHiddenWorkspaceSuggestion(entry)) {
256
+ continue;
257
+ }
188
258
  const rankedEntry = rankWorkspaceEntry({
189
259
  absolutePath: entry.absolutePath,
190
260
  kind: entry.kind,
@@ -230,6 +300,10 @@ async function searchWorkspaceAcrossTree(input) {
230
300
  if (entry.kind === "directory" && !input.includeDirectories) {
231
301
  continue;
232
302
  }
303
+ // Hidden directories are traversed, but not offered as suggestions.
304
+ if (isHiddenWorkspaceSuggestion(entry)) {
305
+ continue;
306
+ }
233
307
  if (entry.kind === "file" && !input.includeFiles) {
234
308
  continue;
235
309
  }
@@ -618,7 +692,23 @@ async function listWorkspaceChildEntries(input) {
618
692
  return cached.entries;
619
693
  }
620
694
  const dirents = await readdir(input.directory, { withFileTypes: true }).catch(() => []);
621
- const candidates = dirents.filter((dirent) => !isHiddenDirectoryName(dirent.name) && !isIgnoredSuggestionDirectoryName(dirent.name));
695
+ const candidates = dirents.filter((dirent) => {
696
+ if (isIgnoredSuggestionDirectoryName(dirent.name)) {
697
+ return false;
698
+ }
699
+ if (isHiddenDirectoryName(dirent.name) &&
700
+ !dirent.isFile() &&
701
+ !isTraversableHiddenWorkspaceDirectoryName(dirent.name)) {
702
+ return false;
703
+ }
704
+ // Allowlisted hidden directories remain traversable so file links like
705
+ // `.claude/settings.local.json` can resolve, but hidden files (e.g.
706
+ // `.DS_Store`) should never be suggested.
707
+ if (dirent.isFile() && isHiddenDirectoryName(dirent.name)) {
708
+ return false;
709
+ }
710
+ return true;
711
+ });
622
712
  const resolved = await Promise.all(candidates.map(async (dirent) => {
623
713
  const candidatePath = path.join(input.directory, dirent.name);
624
714
  const entry = await resolveWorkspaceCandidate({
@@ -687,9 +777,15 @@ async function resolveWorkspaceCandidate(input) {
687
777
  function isHiddenDirectoryName(name) {
688
778
  return name.startsWith(".");
689
779
  }
780
+ function isHiddenWorkspaceSuggestion(entry) {
781
+ return isHiddenDirectoryName(entry.name);
782
+ }
690
783
  function isIgnoredSuggestionDirectoryName(name) {
691
784
  return IGNORED_SUGGESTION_DIRECTORY_NAMES.has(name);
692
785
  }
786
+ function isTraversableHiddenWorkspaceDirectoryName(name) {
787
+ return TRAVERSABLE_HIDDEN_WORKSPACE_DIRECTORY_NAMES.has(name);
788
+ }
693
789
  function setDirectoryListCache(cacheKey, entry) {
694
790
  directoryListCache.set(cacheKey, entry);
695
791
  pruneDirectoryListCache();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpaseo/server",
3
- "version": "0.1.97",
3
+ "version": "0.1.99",
4
4
  "description": "Paseo backend server",
5
5
  "files": [
6
6
  "dist/server",
@@ -65,10 +65,10 @@
65
65
  "@agentclientprotocol/sdk": "^0.17.1",
66
66
  "@anthropic-ai/claude-agent-sdk": "^0.3.181",
67
67
  "@anthropic-ai/sdk": "^0.104.2",
68
- "@getpaseo/client": "0.1.97",
69
- "@getpaseo/highlight": "0.1.97",
70
- "@getpaseo/protocol": "0.1.97",
71
- "@getpaseo/relay": "0.1.97",
68
+ "@getpaseo/client": "0.1.99",
69
+ "@getpaseo/highlight": "0.1.99",
70
+ "@getpaseo/protocol": "0.1.99",
71
+ "@getpaseo/relay": "0.1.99",
72
72
  "@isaacs/ttlcache": "^2.1.4",
73
73
  "@modelcontextprotocol/sdk": "^1.20.1",
74
74
  "@opencode-ai/sdk": "1.14.46",