@getpaseo/server 0.1.100 → 0.1.102-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.
Files changed (172) hide show
  1. package/dist/scripts/supervisor.js +26 -8
  2. package/dist/server/executable-resolution/windows.js +3 -0
  3. package/dist/server/server/agent/activity-curator.d.ts +17 -0
  4. package/dist/server/server/agent/activity-curator.js +101 -24
  5. package/dist/server/server/agent/agent-manager.d.ts +10 -0
  6. package/dist/server/server/agent/agent-manager.js +69 -27
  7. package/dist/server/server/agent/agent-sdk-types.d.ts +15 -2
  8. package/dist/server/server/agent/mcp-server.d.ts +2 -45
  9. package/dist/server/server/agent/mcp-server.js +45 -1985
  10. package/dist/server/server/agent/prompt-attachments.js +6 -2
  11. package/dist/server/server/agent/provider-snapshot-manager.d.ts +12 -1
  12. package/dist/server/server/agent/provider-snapshot-manager.js +132 -42
  13. package/dist/server/server/agent/providers/acp-agent.d.ts +27 -1
  14. package/dist/server/server/agent/providers/acp-agent.js +178 -27
  15. package/dist/server/server/agent/providers/claude/agent.js +111 -24
  16. package/dist/server/server/agent/providers/claude/query.d.ts +3 -0
  17. package/dist/server/server/agent/providers/claude/query.js +4 -2
  18. package/dist/server/server/agent/providers/codex-app-server-agent.js +6 -57
  19. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +1 -0
  20. package/dist/server/server/agent/providers/diagnostic-utils.js +1 -1
  21. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +3 -0
  22. package/dist/server/server/agent/providers/generic-acp-agent.js +41 -23
  23. package/dist/server/server/agent/providers/mock-load-test-agent.js +12 -2
  24. package/dist/server/server/agent/providers/opencode/paths.d.ts +2 -0
  25. package/dist/server/server/agent/providers/opencode/paths.js +7 -0
  26. package/dist/server/server/agent/providers/opencode/server-manager.d.ts +2 -0
  27. package/dist/server/server/agent/providers/opencode/server-manager.js +34 -5
  28. package/dist/server/server/agent/providers/opencode-agent.d.ts +4 -0
  29. package/dist/server/server/agent/providers/opencode-agent.js +14 -2
  30. package/dist/server/server/agent/providers/pi/agent.d.ts +5 -1
  31. package/dist/server/server/agent/providers/pi/agent.js +12 -3
  32. package/dist/server/server/agent/providers/provider-image-output.d.ts +5 -0
  33. package/dist/server/server/agent/providers/provider-image-output.js +61 -1
  34. package/dist/server/server/agent/tools/paseo-tools.d.ts +48 -0
  35. package/dist/server/server/agent/tools/paseo-tools.js +2119 -0
  36. package/dist/server/server/agent/tools/types.d.ts +36 -0
  37. package/dist/server/server/agent/tools/types.js +2 -0
  38. package/dist/server/server/bootstrap.d.ts +7 -1
  39. package/dist/server/server/bootstrap.js +89 -62
  40. package/dist/server/server/config.d.ts +2 -0
  41. package/dist/server/server/config.js +57 -1
  42. package/dist/server/server/daemon-worker.js +19 -7
  43. package/dist/server/server/lifecycle-reasons.d.ts +4 -0
  44. package/dist/server/server/lifecycle-reasons.js +6 -0
  45. package/dist/server/server/persisted-config.d.ts +12 -0
  46. package/dist/server/server/persisted-config.js +18 -2
  47. package/dist/server/server/process-diagnostics.d.ts +17 -0
  48. package/dist/server/server/process-diagnostics.js +22 -0
  49. package/dist/server/server/relay-transport.js +1 -0
  50. package/dist/server/server/resolve-worktree-creation-intent.js +3 -1
  51. package/dist/server/server/session/agent-updates/agent-updates-service.d.ts +59 -0
  52. package/dist/server/server/session/agent-updates/agent-updates-service.js +220 -0
  53. package/dist/server/server/session/checkout/checkout-session.d.ts +13 -15
  54. package/dist/server/server/session/checkout/checkout-session.js +18 -16
  55. package/dist/server/server/session/checkout/git-metadata-generator.d.ts +53 -0
  56. package/dist/server/server/session/checkout/git-metadata-generator.js +159 -0
  57. package/dist/server/server/session/daemon/daemon-self-update-session-controller.d.ts +32 -0
  58. package/dist/server/server/session/daemon/daemon-self-update-session-controller.js +88 -0
  59. package/dist/server/server/session/daemon/daemon-self-updater.d.ts +32 -0
  60. package/dist/server/server/session/daemon/daemon-self-updater.js +56 -0
  61. package/dist/server/server/session/daemon/daemon-session.d.ts +26 -0
  62. package/dist/server/server/session/daemon/daemon-session.js +50 -0
  63. package/dist/server/server/session/daemon/diagnostics.d.ts +41 -0
  64. package/dist/server/server/session/daemon/diagnostics.js +431 -0
  65. package/dist/server/server/session/daemon/install-origin.d.ts +7 -0
  66. package/dist/server/server/session/daemon/install-origin.js +64 -0
  67. package/dist/server/server/session/daemon/npm-global-cli.d.ts +29 -0
  68. package/dist/server/server/session/daemon/npm-global-cli.js +98 -0
  69. package/dist/server/server/session/git-mutation/git-mutation-service.d.ts +34 -0
  70. package/dist/server/server/session/git-mutation/git-mutation-service.js +71 -0
  71. package/dist/server/server/session/provider/provider-catalog-session.js +8 -4
  72. package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.d.ts +36 -0
  73. package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.js +134 -0
  74. package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.d.ts +34 -0
  75. package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.js +190 -0
  76. package/dist/server/server/session/workspace-scripts/workspace-scripts-service.d.ts +41 -0
  77. package/dist/server/server/session/workspace-scripts/workspace-scripts-service.js +100 -0
  78. package/dist/server/server/session.d.ts +12 -54
  79. package/dist/server/server/session.js +187 -970
  80. package/dist/server/server/speech/providers/openai/config.d.ts +1 -2
  81. package/dist/server/server/speech/providers/openai/config.js +13 -9
  82. package/dist/server/server/speech/providers/openai/runtime.js +2 -16
  83. package/dist/server/server/speech/providers/openai/stt.d.ts +1 -0
  84. package/dist/server/server/speech/providers/openai/stt.js +4 -2
  85. package/dist/server/server/speech/providers/openai/tts.d.ts +1 -0
  86. package/dist/server/server/speech/providers/openai/tts.js +1 -0
  87. package/dist/server/server/web-ui.d.ts +10 -0
  88. package/dist/server/server/web-ui.js +205 -0
  89. package/dist/server/server/websocket/runtime-metrics.d.ts +23 -0
  90. package/dist/server/server/websocket-server.d.ts +4 -2
  91. package/dist/server/server/websocket-server.js +215 -52
  92. package/dist/server/server/worktree-bootstrap.d.ts +1 -1
  93. package/dist/server/server/worktree-branch-name-generator.js +3 -1
  94. package/dist/server/services/quota-fetcher/manifest.js +5 -0
  95. package/dist/server/services/quota-fetcher/providers/minimax.d.ts +29 -0
  96. package/dist/server/services/quota-fetcher/providers/minimax.js +227 -0
  97. package/dist/server/terminal/agent-hooks/agent-hook-installer.js +2 -2
  98. package/dist/server/utils/checkout-git.js +203 -25
  99. package/dist/server/utils/directory-suggestions.js +1 -4
  100. package/dist/server/utils/path.d.ts +2 -0
  101. package/dist/server/utils/path.js +13 -0
  102. package/dist/server/utils/worktree.d.ts +1 -0
  103. package/dist/server/utils/worktree.js +92 -11
  104. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css +1 -0
  105. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.br +0 -0
  106. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.gz +0 -0
  107. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js +1 -0
  108. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js.br +0 -0
  109. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js.gz +0 -0
  110. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js +1 -0
  111. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js.br +0 -0
  112. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js.gz +0 -0
  113. package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js +16157 -0
  114. package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js.br +0 -0
  115. package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js.gz +0 -0
  116. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js +1 -0
  117. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js.br +0 -0
  118. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js.gz +0 -0
  119. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js +3 -0
  120. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js.br +0 -0
  121. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js.gz +0 -0
  122. package/dist/server/web-ui/apple-touch-icon.png +0 -0
  123. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
  124. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
  125. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
  126. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
  127. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
  128. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
  129. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
  130. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
  131. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
  132. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
  133. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
  134. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
  135. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
  136. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
  137. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
  138. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
  139. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
  140. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
  141. package/dist/server/web-ui/assets/assets/images/editor-apps/antigravity.6e91a685c33435e0b466a56db86cf141.png +0 -0
  142. package/dist/server/web-ui/assets/assets/images/editor-apps/cursor.c31d6bce4fe9aadc3fe59962f4c4fcf3.png +0 -0
  143. package/dist/server/web-ui/assets/assets/images/editor-apps/file-explorer.3e15e8f72c825c85ce336bcb0cdef776.png +0 -0
  144. package/dist/server/web-ui/assets/assets/images/editor-apps/finder.7f68fc2c475621a672e1be09309d5567.png +0 -0
  145. package/dist/server/web-ui/assets/assets/images/editor-apps/vscode.832bdb4c685d930f1c864c793703600b.png +0 -0
  146. package/dist/server/web-ui/assets/assets/images/editor-apps/webstorm.aa5dc2cd8c20cc0a155c4c5c5ab3c5f5.png +0 -0
  147. package/dist/server/web-ui/assets/assets/images/editor-apps/zed.f3a670b7f9aa226da4fe53fb86f1abbd.png +0 -0
  148. package/dist/server/web-ui/assets/assets/images/favicon-dark-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
  149. package/dist/server/web-ui/assets/assets/images/favicon-dark-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
  150. package/dist/server/web-ui/assets/assets/images/favicon-dark.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
  151. package/dist/server/web-ui/assets/assets/images/favicon-light-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
  152. package/dist/server/web-ui/assets/assets/images/favicon-light-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
  153. package/dist/server/web-ui/assets/assets/images/favicon-light.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
  154. package/dist/server/web-ui/assets/assets/images/notification-icon.3bf81d33ddbf380606bdd248ba83e158.png +0 -0
  155. package/dist/server/web-ui/favicon.ico +0 -0
  156. package/dist/server/web-ui/index.html +90 -0
  157. package/dist/server/web-ui/index.html.br +0 -0
  158. package/dist/server/web-ui/index.html.gz +0 -0
  159. package/dist/server/web-ui/manifest.json +27 -0
  160. package/dist/server/web-ui/manifest.json.br +0 -0
  161. package/dist/server/web-ui/manifest.json.gz +0 -0
  162. package/dist/server/web-ui/metadata.json +1 -0
  163. package/dist/server/web-ui/metadata.json.br +1 -0
  164. package/dist/server/web-ui/metadata.json.gz +0 -0
  165. package/dist/server/web-ui/pwa-icon-192.png +0 -0
  166. package/dist/server/web-ui/pwa-icon-512.png +0 -0
  167. package/dist/server/web-ui/robots.txt +2 -0
  168. package/dist/src/executable-resolution/windows.js +3 -0
  169. package/dist/src/server/persisted-config.js +18 -2
  170. package/package.json +7 -7
  171. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts +0 -42
  172. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +0 -168
@@ -67,14 +67,18 @@ export function buildAgentBranchNameSeed(firstAgentContext) {
67
67
  const parts = [];
68
68
  const prompt = firstAgentContext.prompt?.trim();
69
69
  if (prompt) {
70
- parts.push(prompt);
70
+ parts.push(["<user-prompt>", prompt, "</user-prompt>"].join("\n"));
71
71
  }
72
+ const renderedAttachments = [];
72
73
  for (const attachment of firstAgentContext.attachments ?? []) {
73
74
  const rendered = renderPromptAttachmentAsText(attachment).trim();
74
75
  if (rendered) {
75
- parts.push(rendered);
76
+ renderedAttachments.push(rendered);
76
77
  }
77
78
  }
79
+ if (renderedAttachments.length > 0) {
80
+ parts.push(["<attachments>", renderedAttachments.join("\n\n"), "</attachments>"].join("\n"));
81
+ }
78
82
  return parts.length > 0 ? parts.join("\n\n") : undefined;
79
83
  }
80
84
  //# sourceMappingURL=prompt-attachments.js.map
@@ -5,6 +5,7 @@ import type { WorkspaceGitService } from "../workspace-git-service.js";
5
5
  import type { ManagedProcessRegistry } from "../managed-processes/managed-processes.js";
6
6
  import type { AgentProviderRuntimeSettingsMap, ProviderOverride } from "./provider-launch-config.js";
7
7
  import type { MutableDaemonConfig } from "../daemon-config-store.js";
8
+ export declare const GLOBAL_PROVIDER_SNAPSHOT_KEY = "paseo:global";
8
9
  type ProviderSnapshotChangeListener = (entries: ProviderSnapshotEntry[], cwd: string) => void;
9
10
  export interface ProviderSnapshotManagerOptions {
10
11
  logger: Logger;
@@ -15,11 +16,16 @@ export interface ProviderSnapshotManagerOptions {
15
16
  isDev?: boolean;
16
17
  extraClients?: Partial<Record<AgentProvider, AgentClient>>;
17
18
  refreshTimeoutMs?: number;
19
+ diagnosticTimeoutMs?: number;
18
20
  }
19
21
  interface ProviderSnapshotRefreshOptions {
20
22
  cwd: string;
21
23
  providers?: AgentProvider[];
22
24
  }
25
+ interface ProviderSnapshotWarmUpOptions {
26
+ cwd?: string | null;
27
+ providers?: AgentProvider[];
28
+ }
23
29
  interface ProviderSnapshotReadOptions {
24
30
  cwd?: string | null;
25
31
  providers?: AgentProvider[];
@@ -64,6 +70,7 @@ export declare class ProviderSnapshotManager {
64
70
  private readonly events;
65
71
  private destroyed;
66
72
  private readonly refreshTimeoutMs;
73
+ private readonly diagnosticTimeoutMs;
67
74
  private readonly logger;
68
75
  private readonly workspaceGitService?;
69
76
  private readonly managedProcesses?;
@@ -78,7 +85,7 @@ export declare class ProviderSnapshotManager {
78
85
  getSnapshot(cwd?: string): ProviderSnapshotEntry[];
79
86
  refreshSnapshotForCwd(options: ProviderSnapshotRefreshOptions): Promise<void>;
80
87
  refreshSettingsSnapshot(options?: Omit<ProviderSnapshotRefreshOptions, "cwd">): Promise<void>;
81
- warmUpSnapshotForCwd(options: ProviderSnapshotRefreshOptions): Promise<void>;
88
+ warmUpSnapshotForCwd(options: ProviderSnapshotWarmUpOptions): Promise<void>;
82
89
  refresh(options: ProviderSnapshotRefreshOptions): Promise<void>;
83
90
  listRegisteredProviderIds(): AgentProvider[];
84
91
  hasProvider(provider: AgentProvider): boolean;
@@ -99,8 +106,11 @@ export declare class ProviderSnapshotManager {
99
106
  destroy(): void;
100
107
  private buildRegistry;
101
108
  private resolveParent;
109
+ private getSnapshotForTarget;
102
110
  private getReadyProvider;
103
111
  private requireProvider;
112
+ private refreshDiagnosticSnapshotEntry;
113
+ private getBaseProviderDiagnostic;
104
114
  private createLoadingEntries;
105
115
  private reconcileSnapshotForRegistry;
106
116
  private warmUp;
@@ -120,5 +130,6 @@ export declare class ProviderSnapshotManager {
120
130
  private resolveRefreshProviders;
121
131
  }
122
132
  export declare function resolveSnapshotCwd(cwd?: string | null): string;
133
+ export declare function isGlobalProviderSnapshotKey(cwd: string): boolean;
123
134
  export {};
124
135
  //# sourceMappingURL=provider-snapshot-manager.d.ts.map
@@ -5,9 +5,11 @@ import { expandTilde } from "../../utils/path.js";
5
5
  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
- import { formatProviderDiagnostic } from "./providers/diagnostic-utils.js";
9
- const DEFAULT_REFRESH_TIMEOUT_MS = 30000;
8
+ import { formatProviderDiagnostic, formatProviderDiagnosticError, } from "./providers/diagnostic-utils.js";
9
+ const DEFAULT_REFRESH_TIMEOUT_MS = 60000;
10
+ const DEFAULT_DIAGNOSTIC_TIMEOUT_MS = 120000;
10
11
  const REFRESH_TIMEOUT_ENV_VAR = "PASEO_PROVIDER_REFRESH_TIMEOUT_MS";
12
+ export const GLOBAL_PROVIDER_SNAPSHOT_KEY = "paseo:global";
11
13
  // Provider refresh probes can be slow on cold starts (e.g. Copilot's first
12
14
  // `copilot --acp` invocation, OpenCode workspace probes with many MCP servers).
13
15
  // Allow operators to bump the ceiling via env var without rebuilding.
@@ -25,6 +27,12 @@ function resolveRefreshTimeoutMs(option) {
25
27
  }
26
28
  return DEFAULT_REFRESH_TIMEOUT_MS;
27
29
  }
30
+ function resolveDiagnosticTimeoutMs(option, refreshTimeoutMs) {
31
+ if (typeof option === "number" && Number.isFinite(option) && option > 0) {
32
+ return option;
33
+ }
34
+ return Math.max(refreshTimeoutMs, DEFAULT_DIAGNOSTIC_TIMEOUT_MS);
35
+ }
28
36
  export class ProviderSnapshotManager {
29
37
  constructor(options) {
30
38
  this.snapshots = new Map();
@@ -40,35 +48,35 @@ export class ProviderSnapshotManager {
40
48
  this.providerOverrides = options.providerOverrides;
41
49
  this.baseProviderOverrides = options.providerOverrides;
42
50
  this.refreshTimeoutMs = resolveRefreshTimeoutMs(options.refreshTimeoutMs);
51
+ this.diagnosticTimeoutMs = resolveDiagnosticTimeoutMs(options.diagnosticTimeoutMs, this.refreshTimeoutMs);
43
52
  this.providerRegistry = this.buildRegistry();
44
53
  this.providerClients = { ...this.extraClients };
45
54
  }
46
55
  getSnapshot(cwd) {
47
- const resolvedCwd = resolveSnapshotCwd(cwd);
48
- const providersToWarm = this.resolveProvidersToWarm(resolvedCwd);
49
- if (providersToWarm.length > 0) {
50
- void this.warmUp(resolvedCwd, providersToWarm);
51
- }
52
- return entriesToArray(this.getOrCreateSnapshot(resolvedCwd));
56
+ const target = resolveProviderSnapshotTarget(cwd);
57
+ return this.getSnapshotForTarget(target);
53
58
  }
54
59
  async refreshSnapshotForCwd(options) {
55
60
  const snapshotCwd = resolveSnapshotCwd(options.cwd);
61
+ const target = createWorkspaceSnapshotTarget(snapshotCwd);
56
62
  const providers = this.resolveRefreshProviders(options.providers);
57
63
  this.resetSnapshotToLoading(snapshotCwd, providers, { preserveExisting: false });
58
64
  this.emitChange(snapshotCwd);
59
- await this.refreshProviders(snapshotCwd, providers ?? this.getProviderIds());
65
+ await this.refreshProviders(target, providers ?? this.getProviderIds());
60
66
  }
61
67
  async refreshSettingsSnapshot(options = {}) {
62
- const homeCwd = resolveSnapshotCwd();
68
+ const target = createGlobalSnapshotTarget();
69
+ const homeCwd = target.snapshotCwd;
63
70
  const providers = this.resolveRefreshProviders(options.providers);
64
71
  const providersToRefresh = providers ?? this.getProviderIds();
65
72
  this.clearCachedProviders(providers);
66
73
  this.resetSnapshotToLoading(homeCwd, providers, { preserveExisting: false });
67
74
  this.emitChange(homeCwd);
68
- await this.refreshProviders(homeCwd, providersToRefresh);
75
+ await this.refreshProviders(target, providersToRefresh);
69
76
  }
70
77
  async warmUpSnapshotForCwd(options) {
71
- const snapshotCwd = resolveSnapshotCwd(options.cwd);
78
+ const target = resolveProviderSnapshotTarget(options.cwd);
79
+ const snapshotCwd = target.snapshotCwd;
72
80
  const providers = this.resolveRefreshProviders(options.providers);
73
81
  if (options.providers && providers?.length === 0) {
74
82
  return;
@@ -77,7 +85,7 @@ export class ProviderSnapshotManager {
77
85
  if (providersToWarm.length === 0) {
78
86
  return;
79
87
  }
80
- await this.warmUp(snapshotCwd, providersToWarm);
88
+ await this.warmUp(target, providersToWarm);
81
89
  }
82
90
  async refresh(options) {
83
91
  await this.refreshSnapshotForCwd(options);
@@ -120,12 +128,12 @@ export class ProviderSnapshotManager {
120
128
  return client;
121
129
  }
122
130
  async listProviders(input = {}) {
123
- const cwd = resolveSnapshotCwd(input.cwd);
131
+ const target = resolveProviderSnapshotTarget(input.cwd);
124
132
  if (input.wait) {
125
- await this.warmUpSnapshotForCwd({ cwd, providers: input.providers });
133
+ await this.warmUpSnapshotForCwd({ cwd: input.cwd, providers: input.providers });
126
134
  }
127
135
  const providerFilter = input.providers ? new Set(input.providers) : null;
128
- const entries = this.getSnapshot(cwd);
136
+ const entries = this.getSnapshotForTarget(target);
129
137
  return providerFilter ? entries.filter((entry) => providerFilter.has(entry.provider)) : entries;
130
138
  }
131
139
  async getProvider(input) {
@@ -180,18 +188,23 @@ export class ProviderSnapshotManager {
180
188
  });
181
189
  }
182
190
  async getProviderDiagnostic(provider) {
183
- const definition = this.requireProvider(provider);
184
- const client = this.ensureClient(provider, definition);
185
- // Force-refresh the snapshot so Models/Status come from the single catalog authority.
186
- await this.refreshSnapshotForCwd({ cwd: homedir(), providers: [provider] });
187
- const entry = await this.getProvider({ cwd: homedir(), provider, wait: true });
191
+ const definition = this.providerRegistry[provider];
192
+ if (!definition) {
193
+ return {
194
+ provider,
195
+ diagnostic: formatProviderDiagnostic(provider, [
196
+ { label: "Error", value: `Provider ${provider} is not configured` },
197
+ ]),
198
+ };
199
+ }
200
+ const baseDiagnosticPromise = this.getBaseProviderDiagnostic(provider, definition);
201
+ const snapshotEntryPromise = this.refreshDiagnosticSnapshotEntry(provider, definition);
202
+ const [baseDiagnostic, entry] = await Promise.all([
203
+ baseDiagnosticPromise,
204
+ snapshotEntryPromise,
205
+ ]);
188
206
  const modelCount = entry.status === "ready" ? String(entry.models?.length ?? 0) : "—";
189
207
  const status = formatProviderStatus(entry);
190
- const baseDiagnostic = client.getDiagnostic
191
- ? (await client.getDiagnostic()).diagnostic
192
- : formatProviderDiagnostic(definition.label ?? provider, [
193
- { label: "Diagnostic", value: "No diagnostic available" },
194
- ]);
195
208
  const diagnostic = `${baseDiagnostic}\n Models: ${modelCount}\n Status: ${status}`;
196
209
  return { provider, diagnostic };
197
210
  }
@@ -263,6 +276,13 @@ export class ProviderSnapshotManager {
263
276
  }),
264
277
  };
265
278
  }
279
+ getSnapshotForTarget(target) {
280
+ const providersToWarm = this.resolveProvidersToWarm(target.snapshotCwd);
281
+ if (providersToWarm.length > 0) {
282
+ void this.warmUp(target, providersToWarm);
283
+ }
284
+ return entriesToArray(this.getOrCreateSnapshot(target.snapshotCwd));
285
+ }
266
286
  async getReadyProvider(input) {
267
287
  const entry = await this.getProvider(input);
268
288
  if (!entry.enabled) {
@@ -283,6 +303,40 @@ export class ProviderSnapshotManager {
283
303
  }
284
304
  return definition;
285
305
  }
306
+ async refreshDiagnosticSnapshotEntry(provider, definition) {
307
+ try {
308
+ const target = createGlobalSnapshotTarget();
309
+ this.resetSnapshotToLoading(target.snapshotCwd, [provider], { preserveExisting: false });
310
+ this.emitChange(target.snapshotCwd);
311
+ await this.refreshProviders(target, [provider]);
312
+ return await this.getProvider({ provider, wait: false });
313
+ }
314
+ catch (error) {
315
+ return {
316
+ provider,
317
+ status: "error",
318
+ enabled: definition.enabled,
319
+ label: definition.label,
320
+ description: definition.description,
321
+ defaultModeId: definition.defaultModeId,
322
+ error: toErrorMessage(error),
323
+ };
324
+ }
325
+ }
326
+ async getBaseProviderDiagnostic(provider, definition) {
327
+ try {
328
+ const client = this.ensureClient(provider, definition);
329
+ if (client.getDiagnostic) {
330
+ return (await withTimeout(client.getDiagnostic(), this.diagnosticTimeoutMs, `Timed out collecting ${definition.label ?? provider} diagnostic after ${this.diagnosticTimeoutMs}ms`)).diagnostic;
331
+ }
332
+ return formatProviderDiagnostic(definition.label ?? provider, [
333
+ { label: "Diagnostic", value: "No diagnostic available" },
334
+ ]);
335
+ }
336
+ catch (error) {
337
+ return formatProviderDiagnosticError(definition.label ?? provider, error);
338
+ }
339
+ }
286
340
  createLoadingEntries() {
287
341
  const entries = new Map();
288
342
  for (const provider of this.getProviderIds()) {
@@ -326,16 +380,22 @@ export class ProviderSnapshotManager {
326
380
  }
327
381
  return entries;
328
382
  }
329
- async warmUp(cwd, providers) {
383
+ async warmUp(target, providers) {
330
384
  const providersToRefresh = providers ?? this.getProviderIds();
331
385
  await this.loadProviders({
332
- cwd,
386
+ snapshotCwd: target.snapshotCwd,
387
+ catalogScope: target.catalogScope,
333
388
  providers: providersToRefresh,
334
389
  force: false,
335
390
  });
336
391
  }
337
- async refreshProviders(cwd, providers) {
338
- await this.loadProviders({ cwd, providers, force: true });
392
+ async refreshProviders(target, providers) {
393
+ await this.loadProviders({
394
+ snapshotCwd: target.snapshotCwd,
395
+ catalogScope: target.catalogScope,
396
+ providers,
397
+ force: true,
398
+ });
339
399
  }
340
400
  resolveProvidersToWarm(cwd, providers) {
341
401
  const providersToInspect = providers ?? this.getProviderIds();
@@ -395,40 +455,41 @@ export class ProviderSnapshotManager {
395
455
  if (!definition) {
396
456
  return Promise.resolve();
397
457
  }
398
- const existingLoad = this.getProviderLoad(options.cwd, options.provider);
458
+ const existingLoad = this.getProviderLoad(options.snapshotCwd, options.provider);
399
459
  if (existingLoad && !options.force) {
400
460
  return existingLoad.promise;
401
461
  }
402
- const existingEntry = this.snapshots.get(options.cwd)?.get(options.provider);
462
+ const existingEntry = this.snapshots.get(options.snapshotCwd)?.get(options.provider);
403
463
  if (existingEntry && existingEntry.status !== "loading" && !options.force) {
404
464
  return Promise.resolve();
405
465
  }
406
466
  const load = {
407
467
  promise: Promise.resolve(),
408
468
  };
409
- this.setProviderLoad(options.cwd, options.provider, load);
469
+ this.setProviderLoad(options.snapshotCwd, options.provider, load);
410
470
  load.promise = Promise.resolve()
411
471
  .then(() => this.refreshProvider({
412
- cwd: options.cwd,
472
+ snapshotCwd: options.snapshotCwd,
473
+ catalogScope: options.catalogScope,
413
474
  provider: options.provider,
414
475
  definition,
415
476
  load,
416
477
  force: options.force,
417
478
  }))
418
479
  .finally(() => {
419
- const providerLoads = this.providerLoads.get(options.cwd);
480
+ const providerLoads = this.providerLoads.get(options.snapshotCwd);
420
481
  if (providerLoads?.get(options.provider) === load) {
421
482
  providerLoads.delete(options.provider);
422
483
  }
423
484
  if (providerLoads?.size === 0) {
424
- this.providerLoads.delete(options.cwd);
485
+ this.providerLoads.delete(options.snapshotCwd);
425
486
  }
426
487
  });
427
488
  return load.promise;
428
489
  }
429
490
  async refreshProvider(options) {
430
- const { cwd, provider, definition, load, force } = options;
431
- const snapshot = this.getOrCreateSnapshot(options.cwd);
491
+ const { snapshotCwd, catalogScope, provider, definition, load, force } = options;
492
+ const snapshot = this.getOrCreateSnapshot(snapshotCwd);
432
493
  const base = {
433
494
  provider,
434
495
  label: definition.label,
@@ -436,11 +497,11 @@ export class ProviderSnapshotManager {
436
497
  defaultModeId: definition.defaultModeId,
437
498
  };
438
499
  const setEntry = (entry) => {
439
- if (!this.isCurrentProviderLoad(cwd, provider, load)) {
500
+ if (!this.isCurrentProviderLoad(snapshotCwd, provider, load)) {
440
501
  return false;
441
502
  }
442
503
  snapshot.set(provider, entry);
443
- this.emitChange(cwd);
504
+ this.emitChange(snapshotCwd);
444
505
  return true;
445
506
  };
446
507
  try {
@@ -454,7 +515,8 @@ export class ProviderSnapshotManager {
454
515
  setEntry({ ...base, status: "unavailable", enabled: true });
455
516
  return;
456
517
  }
457
- const catalog = await withTimeout(definition.fetchCatalog({ cwd, force }, client), this.refreshTimeoutMs, `Timed out refreshing ${definition.label} after ${this.refreshTimeoutMs}ms`);
518
+ const catalogOptions = createFetchCatalogOptions(catalogScope, force);
519
+ const catalog = await withTimeout(definition.fetchCatalog({ ...catalogOptions, timeoutMs: this.refreshTimeoutMs }, client), this.refreshTimeoutMs, `Timed out refreshing ${definition.label} after ${this.refreshTimeoutMs}ms`);
458
520
  setEntry({
459
521
  ...base,
460
522
  status: "ready",
@@ -472,7 +534,7 @@ export class ProviderSnapshotManager {
472
534
  error: toErrorMessage(error),
473
535
  });
474
536
  if (emitted) {
475
- this.logger.warn({ err: error, provider, cwd }, "Failed to refresh provider snapshot");
537
+ this.logger.warn({ err: error, provider, cwd: snapshotCwd }, "Failed to refresh provider snapshot");
476
538
  }
477
539
  }
478
540
  }
@@ -564,6 +626,34 @@ export function resolveSnapshotCwd(cwd) {
564
626
  }
565
627
  return resolved;
566
628
  }
629
+ function resolveProviderSnapshotTarget(cwd) {
630
+ const trimmed = cwd?.trim();
631
+ if (!trimmed) {
632
+ return createGlobalSnapshotTarget();
633
+ }
634
+ return createWorkspaceSnapshotTarget(resolveSnapshotCwd(trimmed));
635
+ }
636
+ function createGlobalSnapshotTarget() {
637
+ return {
638
+ snapshotCwd: GLOBAL_PROVIDER_SNAPSHOT_KEY,
639
+ catalogScope: { scope: "global" },
640
+ };
641
+ }
642
+ function createWorkspaceSnapshotTarget(cwd) {
643
+ const snapshotCwd = resolveSnapshotCwd(cwd);
644
+ return {
645
+ snapshotCwd,
646
+ catalogScope: { scope: "workspace", cwd: snapshotCwd },
647
+ };
648
+ }
649
+ function createFetchCatalogOptions(scope, force) {
650
+ return scope.scope === "global"
651
+ ? { scope: "global", force }
652
+ : { scope: "workspace", cwd: scope.cwd, force };
653
+ }
654
+ export function isGlobalProviderSnapshotKey(cwd) {
655
+ return cwd === GLOBAL_PROVIDER_SNAPSHOT_KEY;
656
+ }
567
657
  function entriesToArray(entries) {
568
658
  return Array.from(entries.values(), cloneEntry);
569
659
  }
@@ -5,6 +5,7 @@ import { ClientSideConnection, type Client as ACPClient, type CreateTerminalRequ
5
5
  import type { Logger } from "pino";
6
6
  import { type AgentCapabilityFlags, type AgentClient, type AgentFeature, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type AgentUsage, type FetchCatalogOptions, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ProviderCatalog } from "../agent-sdk-types.js";
7
7
  import { type ProviderRuntimeSettings } from "../provider-launch-config.js";
8
+ import { type DiagnosticEntry } from "./diagnostic-utils.js";
8
9
  export declare function summarizeACPRequestError(error: unknown): {
9
10
  message: string;
10
11
  code?: string;
@@ -62,6 +63,17 @@ export interface SpawnedACPProcess {
62
63
  child: ChildProcessWithoutNullStreams;
63
64
  connection: ClientSideConnection;
64
65
  initialize: InitializeResponse;
66
+ stderrChunks?: string[];
67
+ }
68
+ type UninitializedACPProcess = Omit<SpawnedACPProcess, "initialize"> & {
69
+ initialize?: InitializeResponse;
70
+ };
71
+ interface ACPProcessTransport {
72
+ child: ChildProcessWithoutNullStreams;
73
+ connection: ClientSideConnection;
74
+ stderrChunks: string[];
75
+ spawnReady: Promise<void>;
76
+ spawnError: Promise<never>;
65
77
  }
66
78
  export interface ACPToolSnapshot {
67
79
  toolCallId: string;
@@ -176,10 +188,17 @@ export declare class ACPAgentClient implements AgentClient {
176
188
  isAvailable(): Promise<boolean>;
177
189
  protected spawnProcess(launchEnv?: Record<string, string>, options?: {
178
190
  initializeTimeoutMs?: number;
191
+ onSpawned?: (probe: UninitializedACPProcess) => void;
179
192
  }): Promise<SpawnedACPProcess>;
193
+ protected spawnTransport(launchEnv?: Record<string, string>): Promise<ACPProcessTransport>;
194
+ protected initializeTransport(transport: ACPProcessTransport, initializeTimeoutMs?: number): Promise<InitializeResponse>;
180
195
  protected buildProbeClient(): ACPClient;
181
- protected closeProbe(probe: SpawnedACPProcess): Promise<void>;
196
+ protected closeProbe(probe: UninitializedACPProcess): Promise<void>;
182
197
  protected runACPRequest<T>(request: () => Promise<T>): Promise<T>;
198
+ protected buildACPProbeDiagnosticRows(options?: {
199
+ cwd?: string;
200
+ phaseTimeoutMs?: number;
201
+ }): Promise<DiagnosticEntry[]>;
183
202
  protected resolveLaunchCommand(): Promise<{
184
203
  command: string;
185
204
  args: string[];
@@ -242,6 +261,13 @@ export declare class ACPAgentSession implements AgentSession, ACPClient {
242
261
  constructor(config: AgentSessionConfig, options: ACPAgentSessionOptions);
243
262
  get id(): string | null;
244
263
  initializeNewSession(): Promise<void>;
264
+ /**
265
+ * IMPORTANT: Some ACP providers (e.g., Devin CLI) require all three params
266
+ * (sessionId, cwd, mcpServers) to be present in session/load or
267
+ * unstable_resumeSession — even when mcpServers is an empty array — and
268
+ * return "Invalid params" if any are omitted. Never drop cwd or mcpServers
269
+ * from these calls regardless of capabilities.
270
+ */
245
271
  initializeResumedSession(): Promise<void>;
246
272
  run(prompt: AgentPromptInput, options?: AgentRunOptions): Promise<AgentRunResult>;
247
273
  startTurn(prompt: AgentPromptInput, options?: AgentRunOptions): Promise<{