@getpaseo/server 0.10.1 → 0.10.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.
@@ -164,6 +164,14 @@ function deriveOpencodeTaskDetail(input, output, error, metadata) {
164
164
  actions: [],
165
165
  };
166
166
  }
167
+ function toOpencodeEditInput(value) {
168
+ return {
169
+ filePath: value.filePath,
170
+ oldString: nonEmptyString(value.oldString),
171
+ newString: nonEmptyString(value.newString),
172
+ unifiedDiff: undefined,
173
+ };
174
+ }
167
175
  const OpencodeEditInputSchema = z.union([
168
176
  z
169
177
  .object({
@@ -172,12 +180,12 @@ const OpencodeEditInputSchema = z.union([
172
180
  newString: z.string().optional(),
173
181
  })
174
182
  .passthrough()
175
- .transform((value) => ({
176
- filePath: value.filePath,
177
- oldString: nonEmptyString(value.oldString),
178
- newString: nonEmptyString(value.newString),
179
- unifiedDiff: undefined,
180
- })),
183
+ .transform(toOpencodeEditInput),
184
+ // OpenCode v2's edit tool names the file `path`.
185
+ z
186
+ .object({ path: z.string(), oldString: z.string(), newString: z.string() })
187
+ .passthrough()
188
+ .transform((value) => toOpencodeEditInput({ ...value, filePath: value.path })),
181
189
  ToolEditInputSchema,
182
190
  ]);
183
191
  const OpencodeEditOutputSchema = z.union([z.string().transform(() => null), ToolEditOutputSchema]);
@@ -199,6 +207,8 @@ const OpencodeKnownToolDetailSchema = z.union([
199
207
  toolDetailBranchByToolName("edit", OpencodeEditInputSchema, OpencodeEditOutputSchema, toEditToolDetail),
200
208
  toolDetailBranchByToolName("apply_patch", OpencodeEditInputSchema, OpencodeEditOutputSchema, toEditToolDetail),
201
209
  toolDetailBranchByToolName("apply_patch", OpencodeApplyPatchTextInputSchema, z.unknown(), (input) => toEditToolDetail(input, null)),
210
+ // OpenCode v2 reports apply_patch as `patch`.
211
+ toolDetailBranchByToolName("patch", OpencodeApplyPatchTextInputSchema, z.unknown(), (input) => toEditToolDetail(input, null)),
202
212
  toolDetailBranchByToolName("apply_diff", OpencodeEditInputSchema, OpencodeEditOutputSchema, toEditToolDetail),
203
213
  toolDetailBranchByToolName("search", ToolSearchInputSchema, z.unknown(), (input) => toSearchToolDetail({ input, toolName: "search" })),
204
214
  toolDetailBranchByToolName("grep", ToolSearchInputSchema, OpencodeGrepOutputSchema, (input, output) => toSearchToolDetail({ input, output, toolName: "grep" })),
@@ -1,7 +1,7 @@
1
1
  import type { OpenCodeClient } from "@opencode/client";
2
2
  export interface V2Api {
3
3
  server: OpenCodeClient["server"];
4
- session: Pick<OpenCodeClient["session"], "create" | "get" | "list" | "active" | "remove" | "switchAgent" | "switchModel" | "environment" | "instructions" | "prompt" | "command" | "compact" | "wait" | "interrupt" | "revert" | "log"> & {
4
+ session: Pick<OpenCodeClient["session"], "create" | "get" | "list" | "active" | "remove" | "switchAgent" | "switchModel" | "environment" | "instructions" | "prompt" | "command" | "compact" | "interrupt" | "revert" | "log"> & {
5
5
  form: Pick<OpenCodeClient["session"]["form"], "list" | "reply" | "cancel">;
6
6
  };
7
7
  plugin: Pick<OpenCodeClient["plugin"], "list">;
@@ -94,10 +94,11 @@ export class SessionPermissions {
94
94
  title: form.title,
95
95
  input: {
96
96
  questions: form.fields.map((field) => ({
97
- header: field.key,
98
- question: field.title ?? field.key,
97
+ header: field.title ?? field.key,
98
+ question: field.description ?? field.title ?? field.key,
99
99
  options: "options" in field ? field.options : undefined,
100
100
  multiple: field.type === "multiselect",
101
+ allowOther: "custom" in field && field.custom === true,
101
102
  })),
102
103
  },
103
104
  };
@@ -20,6 +20,7 @@ export declare class OpenCodeV2Session implements AgentSession {
20
20
  private readonly permissions;
21
21
  private readonly turns;
22
22
  private readonly children;
23
+ private readonly usage;
23
24
  private stream;
24
25
  private streamAbort;
25
26
  private exited;
@@ -63,7 +64,7 @@ export declare class OpenCodeV2Session implements AgentSession {
63
64
  describePersistence(): AgentPersistenceHandle;
64
65
  run(prompt: AgentPromptInput, options?: AgentRunOptions): Promise<import("../../../agent-sdk-types.js").AgentRunResult>;
65
66
  startTurn(prompt: AgentPromptInput, options?: AgentRunOptions): Promise<{
66
- turnId: `${string}-${string}-${string}-${string}-${string}`;
67
+ turnId: string;
67
68
  }>;
68
69
  steerActiveTurn(prompt: AgentPromptInput, options: SteerActiveTurnOptions): Promise<SteerResult>;
69
70
  interrupt(): Promise<void>;
@@ -13,6 +13,7 @@ import { features } from "./configuration.js";
13
13
  import { commands } from "./commands.js";
14
14
  import { messages } from "./history.js";
15
15
  import { SessionPermissions } from "./permissions.js";
16
+ import { SessionUsage } from "./usage.js";
16
17
  export class OpenCodeV2Session {
17
18
  constructor(connection, info, config, logger, persist, requiresPaseoPlugin, unbind, bindChild, acquire, moved) {
18
19
  this.connection = connection;
@@ -57,11 +58,19 @@ export class OpenCodeV2Session {
57
58
  await this.reconcile();
58
59
  return { info: this.info, history: this.history };
59
60
  },
61
+ reportReconciliationError: (error) => this.logger.warn({ error: toDiagnosticErrorMessage(error) }, "OpenCode turn reconciliation failed; retrying"),
60
62
  clearPermissions: async () => {
61
63
  for (const request of this.permissions.list())
62
64
  await this.permissions.respondToPermission(request.id, { behavior: "deny" });
63
65
  },
64
66
  });
67
+ this.usage = new SessionUsage({
68
+ client: () => this.client,
69
+ cwd: config.cwd,
70
+ info: () => this.info,
71
+ emit: (event) => this.emit(event),
72
+ reportError: (error) => this.logger.warn({ error: toDiagnosticErrorMessage(error) }, "OpenCode context usage update failed"),
73
+ });
65
74
  }
66
75
  get id() {
67
76
  return this.info.id;
@@ -377,9 +386,7 @@ export class OpenCodeV2Session {
377
386
  await this.client.session.environment({ sessionID: this.id, variables: this.launchEnv });
378
387
  await this.reconcile();
379
388
  await this.children.reconcile(this.id);
380
- const active = await this.client.session.active();
381
- if (active[this.id])
382
- this.turns.observeActiveTurn();
389
+ await this.turns.reconcile();
383
390
  }
384
391
  scheduleReconcile() {
385
392
  if (this.refreshTimer || this.closed)
@@ -422,12 +429,9 @@ export class OpenCodeV2Session {
422
429
  return;
423
430
  }
424
431
  this.permissions.observe(event);
425
- if (event.type === "session.execution.failed")
426
- this.turns.executionError = event.data.error.message;
432
+ this.usage.observe(event);
433
+ this.turns.observe(event);
427
434
  this.scheduleReconcile();
428
- if (event.type !== "session.execution.started" || this.turns.id)
429
- return;
430
- this.turns.observeActiveTurn();
431
435
  }
432
436
  async consume(ready, fail) {
433
437
  const signal = AbortSignal.any([this.abort.signal, this.streamAbort.signal]);
@@ -466,6 +470,7 @@ export class OpenCodeV2Session {
466
470
  return;
467
471
  this.closed = true;
468
472
  this.abort.abort();
473
+ this.turns.close();
469
474
  this.streamAbort.abort();
470
475
  if (this.refreshTimer)
471
476
  clearTimeout(this.refreshTimer);
@@ -1,4 +1,4 @@
1
- import type { SessionInfo, SessionMessageInfo } from "@opencode/client";
1
+ import type { OpenCodeEvent, SessionInfo, SessionMessageInfo } from "@opencode/client";
2
2
  import type { AgentPromptInput, AgentRunOptions, AgentStreamEvent, SteerActiveTurnOptions, SteerResult } from "../../../agent-sdk-types.js";
3
3
  import type { V2Api } from "./api.js";
4
4
  interface TurnSnapshot {
@@ -13,28 +13,43 @@ interface TurnOptions {
13
13
  emit(event: AgentStreamEvent): void;
14
14
  reconcile(): Promise<TurnSnapshot>;
15
15
  clearPermissions(): Promise<void>;
16
+ reportReconciliationError(error: unknown): void;
16
17
  }
17
18
  export declare class SessionTurns {
18
19
  private readonly options;
19
20
  private turn;
20
21
  private stopping;
21
22
  private stopFailed;
22
- executionError: string | null;
23
+ private revision;
24
+ private execution;
25
+ private sequence;
26
+ private refresh;
27
+ private dirty;
28
+ private retryTimer;
23
29
  constructor(options: TurnOptions);
24
30
  get id(): string | undefined;
25
31
  get hasStructuredOutput(): boolean;
26
32
  fail(error: Error): void;
33
+ private release;
34
+ close(): void;
35
+ private createTurn;
27
36
  startTurn(prompt: AgentPromptInput, options?: AgentRunOptions): Promise<{
28
- turnId: `${string}-${string}-${string}-${string}-${string}`;
37
+ turnId: string;
29
38
  }>;
30
39
  private submit;
40
+ observe(event: OpenCodeEvent): void;
41
+ private requestReconciliation;
42
+ private scheduleRecovery;
43
+ reconcile(): Promise<void>;
44
+ private drainReconciliation;
45
+ private reconcileTurn;
31
46
  private dispatch;
32
47
  private finish;
33
- private readExecutionError;
48
+ private readExecution;
34
49
  private promptInput;
35
50
  steerActiveTurn(prompt: AgentPromptInput, options: SteerActiveTurnOptions): Promise<SteerResult>;
36
51
  interrupt(): Promise<void>;
37
- observeActiveTurn(): void;
52
+ private observeActiveTurn;
38
53
  }
39
54
  export {};
40
55
  //# sourceMappingURL=turns.d.ts.map
@@ -4,13 +4,24 @@ import { toDiagnosticErrorMessage } from "../../diagnostic-utils.js";
4
4
  import { renderPromptAttachmentAsText } from "../../../prompt-attachments.js";
5
5
  import { usageFromV2 } from "./mapping.js";
6
6
  import { commands } from "./commands.js";
7
+ function isExecutionEvent(event) {
8
+ return (event.type === "session.execution.started" ||
9
+ event.type === "session.execution.succeeded" ||
10
+ event.type === "session.execution.failed" ||
11
+ event.type === "session.execution.interrupted");
12
+ }
7
13
  export class SessionTurns {
8
14
  constructor(options) {
9
15
  this.options = options;
10
16
  this.turn = null;
11
17
  this.stopping = null;
12
18
  this.stopFailed = false;
13
- this.executionError = null;
19
+ this.revision = 0;
20
+ this.execution = null;
21
+ this.sequence = 0;
22
+ this.refresh = null;
23
+ this.dirty = false;
24
+ this.retryTimer = null;
14
25
  }
15
26
  get id() {
16
27
  return this.turn?.id;
@@ -20,14 +31,47 @@ export class SessionTurns {
20
31
  }
21
32
  fail(error) {
22
33
  const turn = this.turn;
34
+ if (!turn)
35
+ return;
36
+ this.release(turn);
37
+ this.options.emit({
38
+ type: "turn_failed",
39
+ provider: "opencode",
40
+ turnId: turn.id,
41
+ error: toDiagnosticErrorMessage(error),
42
+ });
43
+ }
44
+ release(turn) {
23
45
  this.turn = null;
24
- if (turn)
25
- this.options.emit({
26
- type: "turn_failed",
27
- provider: "opencode",
28
- turnId: turn.id,
29
- error: error.message,
30
- });
46
+ this.revision += 1;
47
+ if (this.retryTimer)
48
+ clearTimeout(this.retryTimer);
49
+ this.retryTimer = null;
50
+ turn.settle();
51
+ }
52
+ close() {
53
+ if (this.turn)
54
+ this.release(this.turn);
55
+ }
56
+ createTurn(submitted, accepted, output) {
57
+ let settle;
58
+ const completion = new Promise((resolve) => {
59
+ settle = resolve;
60
+ });
61
+ const turn = {
62
+ id: randomUUID(),
63
+ submitted,
64
+ completion,
65
+ settle,
66
+ accepted,
67
+ output,
68
+ };
69
+ this.turn = turn;
70
+ this.execution = null;
71
+ this.revision += 1;
72
+ this.options.emit({ type: "turn_started", provider: "opencode", turnId: turn.id });
73
+ this.scheduleRecovery();
74
+ return turn;
31
75
  }
32
76
  async startTurn(prompt, options) {
33
77
  await this.stopping;
@@ -35,42 +79,117 @@ export class SessionTurns {
35
79
  throw new Error("OpenCode session is closed");
36
80
  if (this.turn)
37
81
  throw new Error("OpenCode session already has an active turn");
38
- this.executionError = null;
39
- const id = randomUUID();
40
82
  const input = this.promptInput(prompt);
41
83
  let accept;
42
84
  const submitted = new Promise((resolve) => {
43
85
  accept = resolve;
44
86
  });
45
87
  const output = options?.outputSchema === undefined ? undefined : structuredOutput(options.outputSchema);
46
- const completion = this.submit(id, input, accept, options, output);
47
- this.turn = { id, submitted, completion, output };
48
- return { turnId: id };
49
- }
50
- async submit(id, input, accept, options, output) {
51
- // Defer until startTurn publishes ownership, including for immediately resolved test transports.
52
- await Promise.resolve();
53
- this.options.emit({ type: "turn_started", provider: "opencode", turnId: id });
88
+ const turn = this.createTurn(submitted, false, output);
89
+ void this.submit(turn, input, accept, options);
90
+ return { turnId: turn.id };
91
+ }
92
+ async submit(turn, input, accept, options) {
54
93
  try {
55
- await this.dispatch(input, options, output);
56
- accept();
57
- await this.finish(id);
94
+ await this.dispatch(input, options, turn.output);
95
+ if (this.turn !== turn)
96
+ return;
97
+ turn.accepted = true;
98
+ this.revision += 1;
99
+ // Covers a fast execution whose terminal event preceded the admission response.
100
+ this.requestReconciliation();
58
101
  }
59
102
  catch (error) {
60
- if (this.turn?.id === id) {
61
- this.turn = null;
62
- this.options.emit({
63
- type: "turn_failed",
64
- provider: "opencode",
65
- turnId: id,
66
- error: toDiagnosticErrorMessage(error),
67
- });
68
- }
103
+ if (this.turn === turn)
104
+ this.fail(new Error(toDiagnosticErrorMessage(error)));
69
105
  }
70
106
  finally {
71
107
  accept();
72
108
  }
73
109
  }
110
+ observe(event) {
111
+ if (!isExecutionEvent(event) || event.durable.seq <= this.sequence)
112
+ return;
113
+ this.revision += 1;
114
+ if (event.type === "session.execution.started")
115
+ this.observeActiveTurn();
116
+ this.execution = event;
117
+ this.sequence = event.durable.seq;
118
+ this.requestReconciliation();
119
+ }
120
+ requestReconciliation() {
121
+ void this.reconcile().catch((error) => this.options.reportReconciliationError(error));
122
+ }
123
+ // Recovery reads state; a quiet stream (including SSE comment heartbeats) is not a reason to reconnect.
124
+ scheduleRecovery() {
125
+ if (this.retryTimer || !this.turn || this.options.signal.aborted)
126
+ return;
127
+ this.retryTimer = setTimeout(() => {
128
+ this.retryTimer = null;
129
+ this.requestReconciliation();
130
+ }, 5000);
131
+ this.retryTimer.unref();
132
+ }
133
+ reconcile() {
134
+ this.dirty = true;
135
+ if (this.refresh)
136
+ return this.refresh;
137
+ this.refresh = Promise.resolve()
138
+ .then(() => this.drainReconciliation())
139
+ .finally(() => {
140
+ this.refresh = null;
141
+ this.scheduleRecovery();
142
+ });
143
+ return this.refresh;
144
+ }
145
+ async drainReconciliation() {
146
+ while (this.dirty && !this.options.signal.aborted) {
147
+ this.dirty = false;
148
+ await this.reconcileTurn();
149
+ }
150
+ }
151
+ async reconcileTurn() {
152
+ const revision = this.revision;
153
+ const turn = this.turn;
154
+ const active = await this.options.client().session.active({ signal: this.options.signal });
155
+ if (revision !== this.revision) {
156
+ this.dirty = true;
157
+ return;
158
+ }
159
+ if (active[this.options.id]) {
160
+ this.observeActiveTurn();
161
+ return;
162
+ }
163
+ if (!turn?.accepted)
164
+ return;
165
+ // Idle outcome survives shutdown, and /event has no replay. Recover the latest
166
+ // durable execution even when its start or terminal was lost across reconnect.
167
+ const execution = await this.readExecution();
168
+ if (revision !== this.revision) {
169
+ this.dirty = true;
170
+ return;
171
+ }
172
+ if (!execution)
173
+ return;
174
+ this.execution = execution;
175
+ this.sequence = execution.durable.seq;
176
+ if (execution.type === "session.execution.started" ||
177
+ (execution.type === "session.execution.interrupted" && execution.data.reason === "shutdown"))
178
+ return;
179
+ // Read the final history only after observing idle. Never turn an observation transport error into an execution failure.
180
+ const snapshot = await this.options.reconcile();
181
+ if (revision !== this.revision) {
182
+ this.dirty = true;
183
+ return;
184
+ }
185
+ try {
186
+ this.finish(turn, snapshot, execution);
187
+ }
188
+ catch (error) {
189
+ if (this.turn === turn)
190
+ this.fail(new Error(toDiagnosticErrorMessage(error)));
191
+ }
192
+ }
74
193
  async dispatch(input, options, output) {
75
194
  const command = input.text.match(/^\/([^\s]+)(?:\s+([\s\S]*))?$/);
76
195
  if (command?.[1] === "compact" || command?.[1] === "summarize") {
@@ -104,50 +223,41 @@ export class SessionTurns {
104
223
  },
105
224
  });
106
225
  }
107
- async finish(id) {
108
- await this.options
109
- .client()
110
- .session.wait({ sessionID: this.options.id }, { signal: this.options.signal });
111
- const { info, history } = await this.options.reconcile();
112
- if (this.turn?.id !== id)
113
- return;
114
- if (info.outcome !== "failed" && info.outcome !== "interrupted")
115
- this.turn.output?.assert(history);
116
- const failure = info.outcome === "failed" ? (this.executionError ?? (await this.readExecutionError())) : null;
117
- if (this.turn?.id !== id)
118
- return;
119
- this.turn = null;
120
- if (info.outcome === "interrupted")
226
+ finish(turn, { info, history }, execution) {
227
+ if (execution.type === "session.execution.succeeded")
228
+ turn.output?.assert(history);
229
+ this.release(turn);
230
+ if (execution.type === "session.execution.interrupted")
121
231
  this.options.emit({
122
232
  type: "turn_canceled",
123
233
  provider: "opencode",
124
- turnId: id,
234
+ turnId: turn.id,
125
235
  reason: "OpenCode interrupted execution",
126
236
  });
127
- else if (info.outcome === "failed")
237
+ else if (execution.type === "session.execution.failed")
128
238
  this.options.emit({
129
239
  type: "turn_failed",
130
240
  provider: "opencode",
131
- turnId: id,
132
- error: failure ?? "OpenCode execution failed",
241
+ turnId: turn.id,
242
+ error: execution.data.error.message,
133
243
  });
134
244
  else
135
245
  this.options.emit({
136
246
  type: "turn_completed",
137
247
  provider: "opencode",
138
- turnId: id,
248
+ turnId: turn.id,
139
249
  usage: usageFromV2(info),
140
250
  });
141
251
  }
142
- async readExecutionError() {
143
- let message = "OpenCode execution failed";
252
+ async readExecution() {
253
+ let execution = this.execution;
144
254
  for await (const event of this.options
145
255
  .client()
146
- .session.log({ sessionID: this.options.id, follow: false }, { signal: this.options.signal })) {
147
- if (event.type === "session.execution.failed")
148
- message = event.data.error.message;
256
+ .session.log({ sessionID: this.options.id, follow: false, after: this.sequence }, { signal: this.options.signal })) {
257
+ if (isExecutionEvent(event) && event.durable.seq > (execution?.durable.seq ?? this.sequence))
258
+ execution = event;
149
259
  }
150
- return message;
260
+ return execution;
151
261
  }
152
262
  promptInput(prompt) {
153
263
  if (typeof prompt === "string")
@@ -187,6 +297,7 @@ export class SessionTurns {
187
297
  // A stop sent before the queued prompt is accepted would interrupt an idle session.
188
298
  await turn?.submitted;
189
299
  await this.options.client().session.interrupt({ sessionID: this.options.id });
300
+ await this.reconcile();
190
301
  await turn?.completion;
191
302
  })();
192
303
  this.stopping = stop;
@@ -203,24 +314,9 @@ export class SessionTurns {
203
314
  await this.stopping;
204
315
  }
205
316
  observeActiveTurn() {
206
- if (this.turn)
317
+ if (this.turn || this.options.signal.aborted)
207
318
  return;
208
- const id = randomUUID();
209
- const completion = Promise.resolve()
210
- .then(() => this.finish(id))
211
- .catch((error) => {
212
- if (this.turn?.id !== id)
213
- return;
214
- this.turn = null;
215
- this.options.emit({
216
- type: "turn_failed",
217
- provider: "opencode",
218
- turnId: id,
219
- error: toDiagnosticErrorMessage(error),
220
- });
221
- });
222
- this.turn = { id, submitted: Promise.resolve(), completion };
223
- this.options.emit({ type: "turn_started", provider: "opencode", turnId: id });
319
+ this.createTurn(Promise.resolve(), true);
224
320
  }
225
321
  }
226
322
  //# sourceMappingURL=turns.js.map
@@ -0,0 +1,21 @@
1
+ import type { OpenCodeEvent, SessionInfo } from "@opencode/client";
2
+ import type { AgentStreamEvent } from "../../../agent-sdk-types.js";
3
+ import type { V2Api } from "./api.js";
4
+ interface UsageOptions {
5
+ client(): V2Api;
6
+ cwd: string;
7
+ info(): SessionInfo;
8
+ emit(event: AgentStreamEvent): void;
9
+ reportError(error: unknown): void;
10
+ }
11
+ export declare class SessionUsage {
12
+ private readonly options;
13
+ private readonly limits;
14
+ private reports;
15
+ constructor(options: UsageOptions);
16
+ observe(event: OpenCodeEvent): void;
17
+ private report;
18
+ private contextLimit;
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1,48 @@
1
+ import { usageFromV2 } from "./mapping.js";
2
+ // A step is one model call, so its tokens are the context that call used.
3
+ function contextWindowUsedTokens(tokens) {
4
+ return tokens.input + tokens.output + tokens.reasoning + tokens.cache.read + tokens.cache.write;
5
+ }
6
+ export class SessionUsage {
7
+ constructor(options) {
8
+ this.options = options;
9
+ this.limits = new Map();
10
+ this.reports = Promise.resolve();
11
+ }
12
+ observe(event) {
13
+ if (event.type !== "session.step.ended")
14
+ return;
15
+ const { tokens } = event.data;
16
+ // Reports stay in step order while a model's context limit is still being looked up.
17
+ this.reports = this.reports
18
+ .then(() => this.report(tokens))
19
+ .catch((error) => this.options.reportError(error));
20
+ }
21
+ async report(tokens) {
22
+ const model = this.options.info().model;
23
+ const contextWindowMaxTokens = model ? await this.contextLimit(model) : undefined;
24
+ this.options.emit({
25
+ type: "usage_updated",
26
+ provider: "opencode",
27
+ usage: {
28
+ ...usageFromV2(this.options.info()),
29
+ contextWindowUsedTokens: contextWindowUsedTokens(tokens),
30
+ ...(contextWindowMaxTokens === undefined ? {} : { contextWindowMaxTokens }),
31
+ },
32
+ });
33
+ }
34
+ contextLimit(model) {
35
+ const key = `${model.providerID}/${model.id}`;
36
+ const cached = this.limits.get(key);
37
+ if (cached)
38
+ return cached;
39
+ const limit = this.options
40
+ .client()
41
+ .model.list({ location: { directory: this.options.cwd } })
42
+ .then((catalog) => catalog.data.find((entry) => entry.providerID === model.providerID && entry.id === model.id)?.limit.context);
43
+ this.limits.set(key, limit);
44
+ limit.catch(() => this.limits.delete(key));
45
+ return limit;
46
+ }
47
+ }
48
+ //# sourceMappingURL=usage.js.map
@@ -15106,7 +15106,7 @@ __d(function(g,r,i,_a,m,e,d){'use strict';const t=r(d[0]);m.exports=(s,c,n)=>t(s
15106
15106
  __d(function(g,r,i,_a,m,e,d){'use strict';const t=r(d[0]);m.exports=(s,c,n)=>t(s,c,n)<=0},3461,[3456]);
15107
15107
  __d(function(g,r,i,a,m,e,d){'use strict';const t=r(d[0]);m.exports=(n,c,s)=>{try{c=new t(c,s)}catch(t){return!1}return c.test(n)}},3462,[3451]);
15108
15108
  __d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),_e.resolveAppVersion=function(){const e=u(t.default?.version);if(e)return e;const o=u(n.default.expoConfig?.version);if(o)return o;const f=u(n.default.manifest?.version);if(f)return f;return null};var n=e(r(d[0])),t=e(r(d[1]));function u(e){if("string"!=typeof e)return null;const n=e.trim();return 0===n.length?null:n}},3463,[701,3464]);
15109
- __d(function(e,t,r,o,i,a,n){i.exports={name:"@getpaseo/app",version:"0.10.1",private:!0,main:"index.ts",scripts:{start:"npm run start:expo","start:expo":"cross-env APP_VARIANT=development expo start","reset-project":"node ./scripts/reset-project.js","eas-build-post-install":"npm --prefix ../.. run build:app-deps && npm run build:terminal-webview",android:"npm run android:development","android:development":"npm --prefix ../.. run build:client && cross-env APP_VARIANT=development expo prebuild --platform android --clean --non-interactive && cross-env APP_VARIANT=development expo run:android --variant=debug","android:production":"npm --prefix ../.. run build:client && cross-env APP_VARIANT=production expo prebuild --platform android --clean --non-interactive && cross-env APP_VARIANT=production expo run:android --variant=release","android:release":"npm run android:production","android:clear":"node -e \"require('node:fs').rmSync('android', { recursive: true, force: true })\"",ios:"npm --prefix ../.. run build:client && expo run:ios","ios:release":"npm --prefix ../.. run build:client && expo run:ios --configuration Release",web:"npm --prefix ../.. run build:client && concurrently --kill-others --names protocol,client,expo --prefix-colors yellow,blue,magenta \"npm --prefix ../.. run watch:protocol\" \"npm --prefix ../.. run watch:client\" \"npm run web:expo\"","web:expo":"expo start --web",lint:"expo lint",typecheck:"tsgo --noEmit",test:"vitest run","test:browser":"vitest run --project browser","test:e2e":"playwright test --project=browser","test:e2e:diff-performance":"cross-env PASEO_DIFF_PERF_E2E=1 playwright test --project=browser e2e/browser/diff-performance.spec.ts","test:e2e:stream-smoothness":"cross-env PASEO_AGENT_STREAM_PERF_E2E=1 playwright test --project=browser e2e/browser/agent-stream-smoothness.spec.ts","test:e2e:real":"cross-env E2E_FORK_PASEO_HOME_FROM=../../.dev/paseo-home playwright test --project=real-provider","test:e2e:relay-deployment":"npm --prefix ../.. run build:server && npm --prefix ../.. run build:daemon-web-ui && cross-env E2E_FORK_PASEO_HOME_FROM=../../.dev/paseo-home playwright test --project=relay-deployment e2e/browser/relay-deployment-reconnect.real.spec.ts","test:e2e:ui":"playwright test --ui",build:"npm run build:web","build:web":"npm --prefix ../.. run build:app-deps && expo export --platform web","profile:composer-typing":"node ./scripts/profile-composer-typing.mjs","profile:explorer-toggle":"node ./scripts/profile-explorer-toggle.mjs","profile:side-pane":"playwright test --config playwright.profile.config.ts side-pane-performance.spec.ts","profile:workspace-switching":"node ./scripts/profile-workspace-switching.mjs","profile:workspace-tabs":"node ./scripts/profile-workspace-tabs.mjs","deploy:web":"npm run build:web && wrangler pages deploy dist --project-name paseo-app --branch main","build:terminal-webview":"node ./scripts/build-terminal-webview-html.mjs","build:mermaid-runtime":"node ./src/components/markdown/fence/mermaid/build-runtime.mjs"},dependencies:{"@codemirror/commands":"6.10.4","@codemirror/language":"6.12.4","@codemirror/search":"6.7.1","@codemirror/state":"6.7.1","@codemirror/view":"6.43.6","@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@floating-ui/react-native":"^0.10.7","@getpaseo/client":"*","@getpaseo/expo-two-way-audio":"*","@getpaseo/highlight":"*","@getpaseo/plugin":"*","@getpaseo/protocol":"*","@gorhom/bottom-sheet":"^5.2.14","@gorhom/portal":"^1.0.14","@marijn/find-cluster-break":"^1.0.2","@mattermost/react-native-paste-input":"2.0.1","@react-native-async-storage/async-storage":"2.2.0","@react-native-masked-view/masked-view":"^0.3.2","@react-native/normalize-colors":"^0.81.5","@react-navigation/native":"^7.1.8","@replit/codemirror-vim":"6.3.0","@shopify/react-native-skia":"2.2.12","@tanstack/react-query":"^5.90.11","@tanstack/react-virtual":"^3.13.21","@xterm/addon-clipboard":"^0.3.0-beta.213","@xterm/addon-fit":"^0.12.0-beta.213","@xterm/addon-image":"^0.10.0-beta.213","@xterm/addon-ligatures":"^0.11.0-beta.213","@xterm/addon-search":"^0.17.0-beta.213","@xterm/addon-unicode11":"^0.10.0-beta.213","@xterm/addon-web-links":"^0.13.0-beta.213","@xterm/addon-webgl":"^0.20.0-beta.212","@xterm/xterm":"^6.1.0-beta.213",buffer:"^6.0.3",expo:"^54.0.18","expo-asset":"~12.0.12","expo-audio":"~1.0.13","expo-build-properties":"^1.0.9","expo-camera":"~17.0.10","expo-clipboard":"~8.0.7","expo-constants":"~18.0.9","expo-crypto":"^15.0.8","expo-dev-client":"^6.0.15","expo-document-picker":"~14.0.8","expo-file-system":"~19.0.17","expo-haptics":"~15.0.7","expo-image":"~3.0.10","expo-image-manipulator":"~14.0.8","expo-image-picker":"^17.0.8","expo-keep-awake":"^15.0.7","expo-linking":"~8.0.8","expo-localization":"~17.0.9","expo-notifications":"^0.32.16","expo-router":"~6.0.13","expo-sharing":"^14.0.8","expo-splash-screen":"~31.0.10","expo-sqlite":"~16.0.10","expo-system-ui":"~6.0.7","fast-deep-equal":"^3.1.3",htmlparser2:"^12.0.0",i18next:"^26.3.0","lucide-react-native":"^0.546.0","markdown-it":"^10.0.0",mermaid:"^11.16.0","mnemonic-id":"^3.2.7",qrcode:"^1.5.4",react:"19.1.0","react-dom":"19.1.0","react-freeze":"1.0.4","react-i18next":"^17.0.8","react-native":"0.81.5","react-native-draggable-flatlist":"^4.0.3","react-native-edge-to-edge":"^1.7.0","react-native-gesture-handler":"~2.28.0","react-native-keyboard-controller":"1.21.12","react-native-markdown-display":"^7.0.2","react-native-nitro-modules":"0.35.5","react-native-reanimated":"~4.3.1","react-native-safe-area-context":"~5.6.0","react-native-screens":"~4.16.0","react-native-svg":"^15.14.0","react-native-uitextview":"^2.2.0","react-native-unistyles":"^3.2.4","react-native-web":"~0.21.0","react-native-webview":"^13.16.0","react-native-worklets":"~0.8.3","tiny-invariant":"^1.3.3",turndown:"^7.2.4","turndown-plugin-gfm":"^1.0.2","use-sync-external-store":"^1.6.0",yaml:"^2.8.4",zod:"^4.4.3",zustand:"^5.0.9"},devDependencies:{"@playwright/test":"^1.56.1","@testing-library/dom":"^10.4.1","@testing-library/react":"^16.3.2","@types/markdown-it":"^14.1.2","@types/node":"~22.19.0","@types/qrcode":"^1.5.6","@types/react":"~19.2.0","@types/turndown":"^5.0.6","@types/ws":"^8.18.1","@vitest/browser":"^4.1.7","@vitest/browser-playwright":"^4.1.7","@xterm/headless":"^6.1.0-beta.213",dotenv:"^17.2.3","eas-cli":"^16.24.1",esbuild:"0.28.1",eslint:"^9.25.0","eslint-config-expo":"~10.0.0","expo-gradle-jvmargs":"^1.1.2","fake-indexeddb":"^6.2.5",jsdom:"^20.0.3","material-icon-theme":"^5.32.0",playwright:"^1.56.1","serve-sim":"^0.1.40",typescript:"~5.9.2",vitest:"^4.1.6",wrangler:"^4.105.0",ws:"^8.20.0"},reanimated:{staticFeatureFlags:{FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS:!1}}}},3464,[]);
15109
+ __d(function(e,t,r,o,i,a,n){i.exports={name:"@getpaseo/app",version:"0.10.2",private:!0,main:"index.ts",scripts:{start:"npm run start:expo","start:expo":"cross-env APP_VARIANT=development expo start","reset-project":"node ./scripts/reset-project.js","eas-build-post-install":"npm --prefix ../.. run build:app-deps && npm run build:terminal-webview",android:"npm run android:development","android:development":"npm --prefix ../.. run build:client && cross-env APP_VARIANT=development expo prebuild --platform android --clean --non-interactive && cross-env APP_VARIANT=development expo run:android --variant=debug","android:production":"npm --prefix ../.. run build:client && cross-env APP_VARIANT=production expo prebuild --platform android --clean --non-interactive && cross-env APP_VARIANT=production expo run:android --variant=release","android:release":"npm run android:production","android:clear":"node -e \"require('node:fs').rmSync('android', { recursive: true, force: true })\"",ios:"npm --prefix ../.. run build:client && expo run:ios","ios:release":"npm --prefix ../.. run build:client && expo run:ios --configuration Release",web:"npm --prefix ../.. run build:client && concurrently --kill-others --names protocol,client,expo --prefix-colors yellow,blue,magenta \"npm --prefix ../.. run watch:protocol\" \"npm --prefix ../.. run watch:client\" \"npm run web:expo\"","web:expo":"expo start --web",lint:"expo lint",typecheck:"tsgo --noEmit",test:"vitest run","test:browser":"vitest run --project browser","test:e2e":"playwright test --project=browser","test:e2e:diff-performance":"cross-env PASEO_DIFF_PERF_E2E=1 playwright test --project=browser e2e/browser/diff-performance.spec.ts","test:e2e:stream-smoothness":"cross-env PASEO_AGENT_STREAM_PERF_E2E=1 playwright test --project=browser e2e/browser/agent-stream-smoothness.spec.ts","test:e2e:real":"cross-env E2E_FORK_PASEO_HOME_FROM=../../.dev/paseo-home playwright test --project=real-provider","test:e2e:relay-deployment":"npm --prefix ../.. run build:server && npm --prefix ../.. run build:daemon-web-ui && cross-env E2E_FORK_PASEO_HOME_FROM=../../.dev/paseo-home playwright test --project=relay-deployment e2e/browser/relay-deployment-reconnect.real.spec.ts","test:e2e:ui":"playwright test --ui",build:"npm run build:web","build:web":"npm --prefix ../.. run build:app-deps && expo export --platform web","profile:composer-typing":"node ./scripts/profile-composer-typing.mjs","profile:explorer-toggle":"node ./scripts/profile-explorer-toggle.mjs","profile:side-pane":"playwright test --config playwright.profile.config.ts side-pane-performance.spec.ts","profile:workspace-switching":"node ./scripts/profile-workspace-switching.mjs","profile:workspace-tabs":"node ./scripts/profile-workspace-tabs.mjs","deploy:web":"npm run build:web && wrangler pages deploy dist --project-name paseo-app --branch main","build:terminal-webview":"node ./scripts/build-terminal-webview-html.mjs","build:mermaid-runtime":"node ./src/components/markdown/fence/mermaid/build-runtime.mjs"},dependencies:{"@codemirror/commands":"6.10.4","@codemirror/language":"6.12.4","@codemirror/search":"6.7.1","@codemirror/state":"6.7.1","@codemirror/view":"6.43.6","@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@floating-ui/react-native":"^0.10.7","@getpaseo/client":"*","@getpaseo/expo-two-way-audio":"*","@getpaseo/highlight":"*","@getpaseo/plugin":"*","@getpaseo/protocol":"*","@gorhom/bottom-sheet":"^5.2.14","@gorhom/portal":"^1.0.14","@marijn/find-cluster-break":"^1.0.2","@mattermost/react-native-paste-input":"2.0.1","@react-native-async-storage/async-storage":"2.2.0","@react-native-masked-view/masked-view":"^0.3.2","@react-native/normalize-colors":"^0.81.5","@react-navigation/native":"^7.1.8","@replit/codemirror-vim":"6.3.0","@shopify/react-native-skia":"2.2.12","@tanstack/react-query":"^5.90.11","@tanstack/react-virtual":"^3.13.21","@xterm/addon-clipboard":"^0.3.0-beta.213","@xterm/addon-fit":"^0.12.0-beta.213","@xterm/addon-image":"^0.10.0-beta.213","@xterm/addon-ligatures":"^0.11.0-beta.213","@xterm/addon-search":"^0.17.0-beta.213","@xterm/addon-unicode11":"^0.10.0-beta.213","@xterm/addon-web-links":"^0.13.0-beta.213","@xterm/addon-webgl":"^0.20.0-beta.212","@xterm/xterm":"^6.1.0-beta.213",buffer:"^6.0.3",expo:"^54.0.18","expo-asset":"~12.0.12","expo-audio":"~1.0.13","expo-build-properties":"^1.0.9","expo-camera":"~17.0.10","expo-clipboard":"~8.0.7","expo-constants":"~18.0.9","expo-crypto":"^15.0.8","expo-dev-client":"^6.0.15","expo-document-picker":"~14.0.8","expo-file-system":"~19.0.17","expo-haptics":"~15.0.7","expo-image":"~3.0.10","expo-image-manipulator":"~14.0.8","expo-image-picker":"^17.0.8","expo-keep-awake":"^15.0.7","expo-linking":"~8.0.8","expo-localization":"~17.0.9","expo-notifications":"^0.32.16","expo-router":"~6.0.13","expo-sharing":"^14.0.8","expo-splash-screen":"~31.0.10","expo-sqlite":"~16.0.10","expo-system-ui":"~6.0.7","fast-deep-equal":"^3.1.3",htmlparser2:"^12.0.0",i18next:"^26.3.0","lucide-react-native":"^0.546.0","markdown-it":"^10.0.0",mermaid:"^11.16.0","mnemonic-id":"^3.2.7",qrcode:"^1.5.4",react:"19.1.0","react-dom":"19.1.0","react-freeze":"1.0.4","react-i18next":"^17.0.8","react-native":"0.81.5","react-native-draggable-flatlist":"^4.0.3","react-native-edge-to-edge":"^1.7.0","react-native-gesture-handler":"~2.28.0","react-native-keyboard-controller":"1.21.12","react-native-markdown-display":"^7.0.2","react-native-nitro-modules":"0.35.5","react-native-reanimated":"~4.3.1","react-native-safe-area-context":"~5.6.0","react-native-screens":"~4.16.0","react-native-svg":"^15.14.0","react-native-uitextview":"^2.2.0","react-native-unistyles":"^3.2.4","react-native-web":"~0.21.0","react-native-webview":"^13.16.0","react-native-worklets":"~0.8.3","tiny-invariant":"^1.3.3",turndown:"^7.2.4","turndown-plugin-gfm":"^1.0.2","use-sync-external-store":"^1.6.0",yaml:"^2.8.4",zod:"^4.4.3",zustand:"^5.0.9"},devDependencies:{"@playwright/test":"^1.56.1","@testing-library/dom":"^10.4.1","@testing-library/react":"^16.3.2","@types/markdown-it":"^14.1.2","@types/node":"~22.19.0","@types/qrcode":"^1.5.6","@types/react":"~19.2.0","@types/turndown":"^5.0.6","@types/ws":"^8.18.1","@vitest/browser":"^4.1.7","@vitest/browser-playwright":"^4.1.7","@xterm/headless":"^6.1.0-beta.213",dotenv:"^17.2.3","eas-cli":"^16.24.1",esbuild:"0.28.1",eslint:"^9.25.0","eslint-config-expo":"~10.0.0","expo-gradle-jvmargs":"^1.1.2","fake-indexeddb":"^6.2.5",jsdom:"^20.0.3","material-icon-theme":"^5.32.0",playwright:"^1.56.1","serve-sim":"^0.1.40",typescript:"~5.9.2",vitest:"^4.1.6",wrangler:"^4.105.0",ws:"^8.20.0"},reanimated:{staticFeatureFlags:{FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS:!1}}}},3464,[]);
15110
15110
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createPluginClientRuntime=function(P,I){const v=(0,c.createPluginSurfaceRuntime)(I,P);if(!v)throw new Error("Plugin host is offline");const f=(0,l.createPluginClientStateSource)(P.serverId),w=(0,o.createPluginCapabilities)(P,v,(0,s.createPluginNavigation)({serverId:P.serverId,workspaceId:null}));return Object.assign({},w,{hosts:(0,n.createPluginHosts)((0,t.getHostRuntimeStore)(),P.lifetime.signal),addComposerPill:t=>u.pluginButtonStore.addComposerPill(P,t),addHeaderButton:t=>u.pluginButtonStore.addHeaderButton(P,t),openPanel(t,n){p({installation:P,runtime:v,state:f,panelId:t,options:n})}})};var t=r(d[0]),n=r(d[1]),o=r(d[2]),l=r(d[3]),s=r(d[4]),u=r(d[5]),c=r(d[6]);function p(t){const{installation:n,runtime:l,state:u,panelId:c,options:p}=t,P=p.workspaceId.trim(),I=p.agentId?.trim(),v=(0,s.createPluginNavigation)({serverId:n.serverId,workspaceId:P}),f=I?(0,o.createPluginAgentActionContext)({plugin:n,runtime:l,navigation:v,state:u,workspaceId:P,agentId:I}):(0,o.createPluginWorkspaceActionContext)({plugin:n,runtime:l,navigation:v,state:u,workspaceId:P});if(!f)throw new Error("Plugin panel context is unavailable");f.openPanel(c,{location:p.location})}},3465,[3466,3636,3639,3648,3653,3665,3670]);
15111
15111
  __d(function(g,r,i,a,m,_e,d){"use strict";const e=["password"];function t(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),_e.isHostRuntimeConnected=X,_e.isHostRuntimeDirectoryLoading=Y,Object.defineProperty(_e,"HostRuntimeController",{enumerable:!0,get:function(){return de}}),_e.readInitialDaemonConnectionHint=fe,_e.hasConfiguredLocalDaemonOverride=function(){return null!==Ce()},Object.defineProperty(_e,"HostRuntimeStore",{enumerable:!0,get:function(){return Ie}}),_e.getHostRuntimeStore=Re,_e.getHostRuntimeConnectionStatusSince=function(e){return Re().getConnectionStatusSince(e)},_e.useHostRuntimeSnapshot=function(e){const t=(0,s.c)(5);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]!==e?(l=t=>c.subscribe(e,t),h=()=>c.getSnapshot(e),u=()=>c.getSnapshot(e),t[1]=e,t[2]=l,t[3]=h,t[4]=u):(l=t[2],h=t[3],u=t[4]);return(0,o.useSyncExternalStore)(l,h,u)},_e.useHostRuntimeClient=function(e){const t=(0,s.c)(5);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]!==e?(l=t=>c.subscribe(e,t),h=()=>c.getSnapshot(e)?.client??null,u=()=>c.getSnapshot(e)?.client??null,t[1]=e,t[2]=l,t[3]=h,t[4]=u):(l=t[2],h=t[3],u=t[4]);return(0,o.useSyncExternalStore)(l,h,u)},_e.useHostRuntimeIsConnected=function(e){const t=(0,s.c)(5);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]!==e?(l=t=>c.subscribe(e,t),h=()=>X(c.getSnapshot(e)),u=()=>X(c.getSnapshot(e)),t[1]=e,t[2]=l,t[3]=h,t[4]=u):(l=t[2],h=t[3],u=t[4]);return(0,o.useSyncExternalStore)(l,h,u)},_e.useHostRuntimeConnectionStatus=function(e){const t=(0,s.c)(5);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]!==e?(l=t=>c.subscribe(e,t),h=()=>c.getSnapshot(e)?.connectionStatus??"connecting",u=()=>c.getSnapshot(e)?.connectionStatus??"connecting",t[1]=e,t[2]=l,t[3]=h,t[4]=u):(l=t[2],h=t[3],u=t[4]);return(0,o.useSyncExternalStore)(l,h,u)},_e.useHostRuntimeConnectionStatuses=function(e){const t=(0,s.c)(7);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]===Symbol.for("react.memo_cache_sentinel")?(l=e=>c.subscribeAll(e),h=()=>c.getVersion(),u=()=>c.getVersion(),t[1]=l,t[2]=h,t[3]=u):(l=t[1],h=t[2],u=t[3]);(0,o.useSyncExternalStore)(l,h,u);let p;if(t[4]!==e){let n;t[6]===Symbol.for("react.memo_cache_sentinel")?(n=e=>[e,c.getSnapshot(e)?.connectionStatus??"connecting"],t[6]=n):n=t[6];const s=e.map(n);p=new Map(s),t[4]=e,t[5]=p}else p=t[5];return p},_e.useHostRuntimeLastError=function(e){const t=(0,s.c)(5);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]!==e?(l=t=>c.subscribe(e,t),h=()=>c.getSnapshot(e)?.lastError??null,u=()=>c.getSnapshot(e)?.lastError??null,t[1]=e,t[2]=l,t[3]=h,t[4]=u):(l=t[2],h=t[3],u=t[4]);return(0,o.useSyncExternalStore)(l,h,u)},_e.useHostRuntimeAgentDirectoryStatus=function(e){const t=(0,s.c)(5);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]!==e?(l=t=>c.subscribe(e,t),h=()=>c.getSnapshot(e)?.agentDirectoryStatus??"idle",u=()=>c.getSnapshot(e)?.agentDirectoryStatus??"idle",t[1]=e,t[2]=l,t[3]=h,t[4]=u):(l=t[2],h=t[3],u=t[4]);return(0,o.useSyncExternalStore)(l,h,u)},_e.useHostRuntimeIsDirectoryLoading=function(e){const t=(0,s.c)(5);let n;t[0]===Symbol.for("react.memo_cache_sentinel")?(n=Re(),t[0]=n):n=t[0];const c=n;let l,h,u;t[1]!==e?(l=t=>c.subscribe(e,t),h=()=>Y(c.getSnapshot(e)),u=()=>Y(c.getSnapshot(e)),t[1]=e,t[2]=l,t[3]=h,t[4]=u):(l=t[2],h=t[3],u=t[4]);return(0,o.useSyncExternalStore)(l,h,u)},_e.useHosts=function(){const e=(0,s.c)(4);let t;e[0]===Symbol.for("react.memo_cache_sentinel")?(t=Re(),e[0]=t):t=e[0];const n=t;let c,l,h;e[1]===Symbol.for("react.memo_cache_sentinel")?(c=e=>n.subscribeHostList(e),l=()=>n.getHosts(),h=()=>n.getHosts(),e[1]=c,e[2]=l,e[3]=h):(c=e[1],l=e[2],h=e[3]);return(0,o.useSyncExternalStore)(c,l,h)},_e.useHostRegistryStatus=function(){const e=(0,s.c)(4);let t;e[0]===Symbol.for("react.memo_cache_sentinel")?(t=Re(),e[0]=t):t=e[0];const n=t;let c,l,h;e[1]===Symbol.for("react.memo_cache_sentinel")?(c=e=>n.subscribeHostList(e),l=()=>n.getHostRegistryStatus(),h=()=>n.getHostRegistryStatus(),e[1]=c,e[2]=l,e[3]=h):(c=e[1],l=e[2],h=e[3]);return(0,o.useSyncExternalStore)(c,l,h)},_e.useHostRegistryLoaded=function(){const e=(0,s.c)(4);let t;e[0]===Symbol.for("react.memo_cache_sentinel")?(t=Re(),e[0]=t):t=e[0];const n=t;let c,l,h;e[1]===Symbol.for("react.memo_cache_sentinel")?(c=e=>n.subscribeHostList(e),l=()=>n.isHostRegistryLoaded(),h=()=>n.isHostRegistryLoaded(),e[1]=c,e[2]=l,e[3]=h):(c=e[1],l=e[2],h=e[3]);return(0,o.useSyncExternalStore)(c,l,h)},_e.useHostMutations=function(){const e=(0,s.c)(2);let t;e[0]===Symbol.for("react.memo_cache_sentinel")?(t=Re(),e[0]=t):t=e[0];const n=t;let o;e[1]===Symbol.for("react.memo_cache_sentinel")?(o={upsertDirectConnection:e=>n.upsertDirectConnection(e),probeAndUpsertDirectConnection:e=>n.probeAndUpsertDirectConnection(e),probeAndUpsertRemoteSshConnection:e=>n.probeAndUpsertRemoteSshConnection(e),upsertRelayConnection:e=>n.upsertRelayConnection(e),upsertConnectionFromOffer:(e,t)=>n.upsertConnectionFromOffer(e,t),upsertConnectionFromOfferUrl:(e,t,s)=>n.upsertConnectionFromOfferUrl(e,t,s),probeAndUpsertConnectionFromOfferUrl:(e,t)=>n.probeAndUpsertConnectionFromOfferUrl(e,t),renameHost:(e,t)=>n.renameHost(e,t),setHostColor:(e,t)=>n.setHostColor(e,t),setHostBadgeDisplay:(e,t)=>n.setHostBadgeDisplay(e,t),removeHost:e=>n.removeHost(e),removeConnection:(e,t)=>n.removeConnection(e,t)},e[1]=o):o=e[1];return o};var n=t(r(d[0])),s=r(d[1]),o=r(d[2]),c=t(r(d[3])),l=t(r(d[4])),h=r(d[5]),u=r(d[6]),p=r(d[7]),y=r(d[8]),S=r(d[9]),f=r(d[10]),C=r(d[11]),v=r(d[12]),b=r(d[13]),w=r(d[14]),I=r(d[15]),A=r(d[16]),H=r(d[17]),R=r(d[18]),D=r(d[19]),E=r(d[20]),O=r(d[21]),P=r(d[22]),L=r(d[23]),T=r(d[24]),_=r(d[25]),M=r(d[26]),B=r(d[27]),F=r(d[28]),k=r(d[29]),j=r(d[30]),q=r(d[31]),U=r(d[32]),x=r(d[33]),V=r(d[34]),W=r(d[35]),$=r(d[36]),N=r(d[37]),G=r(d[38]),z=r(d[39]),K=r(d[40]),Q=r(d[41]);function J(e,t,n){e[t]=n}function X(e){return"online"===e?.connectionStatus}function Y(e){return!e||("initial_loading"===e.agentDirectoryStatus||"revalidating"===e.agentDirectoryStatus||!e.hasEverLoadedAgentDirectory&&("connecting"===e.connectionStatus||"online"===e.connectionStatus))}function Z(e){return e instanceof Error?e.message:String(e)}function ee(e){let t=0;for(let n=0;n<e.length;n+=1)t=31*t+e.charCodeAt(n)|0;return`h_${Math.abs(t).toString(16)}`}function te(e){return"directSocket"===e.type?{type:"directSocket",endpoint:e.path,display:"socket"}:"directPipe"===e.type?{type:"directPipe",endpoint:e.path,display:"pipe"}:"remoteSsh"===e.type?{type:"remoteSsh",endpoint:e.host,display:e.host}:"directTcp"===e.type?{type:"directTcp",endpoint:e.endpoint,display:e.endpoint}:{type:"relay",endpoint:e.relayEndpoint,display:"relay"}}function ne(e){return"connecting"===e.tag||"online"===e.tag||"offline"===e.tag||"error"===e.tag?{id:e.activeConnectionId,connection:e.activeConnection}:{id:null,connection:null}}function se(e,t,n){const s=n.state.status;return"connected"===s?{tag:"online",activeConnectionId:e,activeConnection:t,lastOnlineAt:(new Date).toISOString()}:"connecting"===s||"idle"===s?{tag:"connecting",activeConnectionId:e,activeConnection:t}:"disposed"===s?{tag:"offline",activeConnectionId:e,activeConnection:t}:null}function oe(e,t,n){const s=se(e,t,n);if(s)return s;const o=("disconnected"===n.state.status?n.state.reason??null:null)??n.lastError??null;return o&&"client_closed"!==o?{tag:"error",activeConnectionId:e,activeConnection:t,message:o}:{tag:"offline",activeConnectionId:e,activeConnection:t}}function ie(e){const{state:t,event:n}=e;if("select_connection"===n.type)return{tag:"connecting",activeConnectionId:n.connectionId,activeConnection:n.connection};if("connect_failed"===n.type){const e=ne(t);return{tag:"error",activeConnectionId:e.id,activeConnection:e.connection,message:n.message}}if("no_connections"===n.type||"stopped"===n.type)return{tag:"offline",activeConnectionId:null,activeConnection:null};const s=ne(t);return s.id&&s.connection?oe(s.id,s.connection,n):"booting"===t.tag?t:{tag:"offline",activeConnectionId:null,activeConnection:null}}function re(e,t){return"booting"===e.tag?{activeConnectionId:null,activeConnection:null,connectionStatus:"connecting",lastError:null,lastOnlineAt:null,connectionEpoch:t}:"connecting"===e.tag?{activeConnectionId:e.activeConnectionId,activeConnection:e.activeConnection,connectionStatus:"connecting",lastError:null,lastOnlineAt:null,connectionEpoch:t}:"online"===e.tag?{activeConnectionId:e.activeConnectionId,activeConnection:e.activeConnection,connectionStatus:"online",lastError:null,lastOnlineAt:e.lastOnlineAt,connectionEpoch:t}:"offline"===e.tag?{activeConnectionId:e.activeConnectionId,activeConnection:e.activeConnection,connectionStatus:"offline",lastError:null,lastOnlineAt:null,connectionEpoch:t}:{activeConnectionId:e.activeConnectionId,activeConnection:e.activeConnection,connectionStatus:"error",lastError:e.message,lastOnlineAt:null,connectionEpoch:t}}function ce(e){return e.connections.map(e=>({connectionId:e.id,connection:e}))}function ae(e,t){return t?e.connections.find(e=>e.id===t)??null:null}function le(e,t,n,s){if(t)return 1e4;if(n)return 12e4;const o=s-e;return o<1e4?2e3:o<3e4?5e3:o<6e4?1e4:3e4}function he(){const e="function"==typeof(0,D.getDesktopHost)()?.browser?.executeAutomationCommand?{[O.CLIENT_CAPS.browserHost]:{supportedCommands:[...P.BROWSER_AUTOMATION_COMMAND_NAMES],hostKind:"desktop app"}}:void 0,t=Object.assign({},e);return{createClient:({host:e,connection:n,clientId:s,runtimeGeneration:o})=>{const c=(0,R.createDesktopDaemonTransportFactory)(),l={webSocketFactory:(0,Q.createAppWebSocketFactory)()},u=Object.assign({suppressSendErrors:!0,clientId:s,clientType:"mobile",appVersion:(0,S.resolveAppVersion)()??void 0,runtimeGeneration:o,capabilities:t,trace:z.nativePerformanceTrace,providerSnapshots:"wire"},e.password?{password:e.password}:{},{localCredential:()=>(0,E.readDesktopManagedLocalCredential)(n)});if("directSocket"===n.type||"directPipe"===n.type)return new h.DaemonClient(Object.assign({},u,c?{transportFactory:c}:{},{url:(0,R.buildDesktopDaemonTransportUrl)({transportType:"directSocket"===n.type?"socket":"pipe",transportPath:n.path})}));if("remoteSsh"===n.type){if(!c)throw new Error("Remote SSH is only available in the desktop app.");return new h.DaemonClient(Object.assign({},u,{transportFactory:c,url:(0,R.buildDesktopDaemonTransportUrl)(Object.assign({transportType:"ssh",host:n.host},void 0!==n.sshPort?{sshPort:n.sshPort}:{},void 0!==n.daemonPort?{daemonPort:n.daemonPort}:{}))}))}return"directTcp"===n.type?new h.DaemonClient(Object.assign({},u,l,{url:(0,y.buildDaemonWebSocketUrl)(n.endpoint,{useTls:n.useTls??!1})})):new h.DaemonClient(Object.assign({},u,l,{url:(0,y.buildRelayWebSocketUrl)({endpoint:n.relayEndpoint,useTls:n.useTls??(0,y.shouldUseTlsForDefaultHostedRelay)(n.relayEndpoint),serverId:e.serverId}),e2ee:{enabled:!0,daemonPublicKeyB64:n.daemonPublicKeyB64}}))},connectToDaemon:({host:e,connection:n,timeoutMs:s})=>(0,b.connectToDaemon)(n,Object.assign({},e.serverId?{serverId:e.serverId}:{},e.password?{password:e.password}:{},{localCredential:()=>(0,E.readDesktopManagedLocalCredential)(n)},void 0!==s?{timeoutMs:s}:{},{capabilities:t,trace:z.nativePerformanceTrace})),getClientId:()=>(0,w.getOrCreateClientId)(),mountClientHandlers:({client:t,host:n})=>{const s=(0,B.mountServerDataPushRouter)({client:t,queryClient:M.queryClient,serverId:n.serverId});if(!e)return s;const o=(0,F.mountBrowserAutomationDaemonClientHandler)(t,{serverId:n.serverId});return()=>{o(),s()}}}}class de{connectionEpoch=0;listeners=new Set;activeClient=null;unsubscribeClientStatus=null;unsubscribeClientHandlers=null;probeIntervalHandle=null;started=!1;connectionFirstSeenAt=new Map;connectionLastProbedAt=new Map;switchCandidateConnectionId=null;switchCandidateHitCount=0;clientIdPromise=null;clientIdHash=null;switchRequestVersion=0;probeRequestVersion=0;probeCycleInFlight=null;authRejectedConnectionIds=new Set;constructor(e){this.host=e.host,this.deps=e.deps??he(),this.onReconcileServerId=e.onReconcileServerId??null,this.connectionMachineState={tag:"booting"},this.snapshot=Object.assign({serverId:this.host.serverId},re(this.connectionMachineState,this.connectionEpoch),{client:null,agentDirectoryStatus:"idle",agentDirectoryError:null,hasEverLoadedAgentDirectory:!1,probeByConnectionId:new Map,clientGeneration:0})}getSnapshot(){return this.snapshot}getClient(){return this.snapshot.client}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}async start(e){this.started||(this.started=!0,this.trackConnectionFirstSeen(),e?.initialConnection&&await this.switchToConnection({connectionId:e.initialConnection.connectionId,existingClient:e.initialConnection.existingClient}),await this.runProbeCycleNow(),!1!==e?.autoProbe&&(this.probeIntervalHandle=setInterval(()=>{this.runProbeCycleNow()},2e3)))}async stop(){if(this.switchRequestVersion+=1,this.probeRequestVersion+=1,this.started=!1,this.probeIntervalHandle&&(clearInterval(this.probeIntervalHandle),this.probeIntervalHandle=null),this.unsubscribeClientStatus&&(this.unsubscribeClientStatus(),this.unsubscribeClientStatus=null),this.unsubscribeClientHandlers&&(this.unsubscribeClientHandlers(),this.unsubscribeClientHandlers=null),this.activeClient){const e=this.activeClient;this.activeClient=null,await e.close().catch(()=>{})}this.applyConnectionEvent({type:"stopped"}),this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch),{client:null}))}async updateHost(e){const t=this.host.password!==e.password;t&&(this.probeRequestVersion+=1,this.authRejectedConnectionIds.clear(),this.updateSnapshot({authFailureReason:null}));const n=this.snapshot.activeConnectionId,s=ae(this.host,n);this.host=e,this.trackConnectionFirstSeen();const o=ae(this.host,n);n&&s&&o&&(!(0,l.default)(s,o)||t)&&(this.connectionLastProbedAt.delete(n),await this.switchToConnection({connectionId:n})),t&&this.connectionLastProbedAt.clear(),t&&await this.probeCycleInFlight,await this.runProbeCycleNow()}ensureConnected(e){this.activeClient?.ensureConnected(e)}markAgentDirectorySyncLoading(){const e=this.snapshot.hasEverLoadedAgentDirectory?"revalidating":"initial_loading";this.updateSnapshot({agentDirectoryStatus:e,agentDirectoryError:null})}markAgentDirectorySyncReady(){this.updateSnapshot({agentDirectoryStatus:"ready",agentDirectoryError:null,hasEverLoadedAgentDirectory:!0})}markAgentDirectorySyncError(e){const t=this.snapshot.hasEverLoadedAgentDirectory;this.updateSnapshot({agentDirectoryStatus:t?"error_after_ready":"error_before_first_success",agentDirectoryError:e,hasEverLoadedAgentDirectory:t})}markAgentDirectorySyncIdle(){this.updateSnapshot({agentDirectoryStatus:this.snapshot.hasEverLoadedAgentDirectory?"ready":"idle",agentDirectoryError:null})}markStartupError(e){this.applyConnectionEvent({type:"connect_failed",message:e}),this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch)))}async activateConnection(e){await this.switchToConnection(e)}async runProbeCycleNow(){if(this.probeCycleInFlight)return this.probeCycleInFlight;const e=this.runProbeCycle().finally(()=>{this.probeCycleInFlight===e&&(this.probeCycleInFlight=null)});return this.probeCycleInFlight=e,e}async runProbeCycle(){const e=++this.probeRequestVersion;if(0===this.host.connections.length){if(!this.isCurrentProbeRequest(e))return;return this.applyConnectionEvent({type:"no_connections"}),void this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch),{probeByConnectionId:new Map}))}const t=performance.now(),n="online"===this.snapshot.connectionStatus,s=this.snapshot.activeConnectionId,o=n&&null!==s,c=this.host.connections.filter(e=>{if(this.authRejectedConnectionIds.has(e.id))return!1;const c=this.connectionLastProbedAt.get(e.id);if(null==c)return!0;const l=le(this.connectionFirstSeenAt.get(e.id)??t,n&&e.id===s,o,t);return t-c>=l});if(0===c.length)return;const l=new Map(this.snapshot.probeByConnectionId);for(const e of c){this.connectionLastProbedAt.set(e.id,performance.now());const t=l.get(e.id);n&&e.id===s&&"available"===t?.status||l.set(e.id,{status:"pending",latencyMs:null})}this.updateSnapshot({probeByConnectionId:new Map(l)});let u=c.length,p=null,y=null;const S=()=>{this.isCurrentProbeRequest(e)&&this.updateSnapshot({probeByConnectionId:new Map(l)})},f=async(t,n)=>{for(;!this.snapshot.activeConnectionId;){if(!y)return y=this.switchToConnection({connectionId:t,expectedProbeVersion:e,existingClient:n}).finally(()=>{y=null}),await y,this.snapshot.activeConnectionId===t;await y}return!1},C=async()=>{if(u>0||!this.isCurrentProbeRequest(e))return;const t=this.snapshot.activeConnectionId,n=t?l.get(t):null;if(!t||!ae(this.host,t)){const t=(0,H.selectBestConnection)({candidates:ce(this.host),probeByConnectionId:l});if(t)await this.switchToConnection({connectionId:t,expectedProbeVersion:e});else if(p){const e=new h.DaemonAuthenticationError(p).message;this.applyConnectionEvent({type:"connect_failed",message:e}),this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch),{authFailureReason:p}))}return}if(this.isConnectionUnavailable(t,n)){const n=(0,H.selectBestConnection)({candidates:ce(this.host),probeByConnectionId:l});return n&&n!==t&&await this.switchToConnection({connectionId:n,expectedProbeVersion:e}),this.switchCandidateConnectionId=null,void(this.switchCandidateHitCount=0)}if(!n||"available"!==n.status)return;const s=Array.from(l.entries()).filter(e=>"available"===e[1].status).map(([e,t])=>({connectionId:e,latencyMs:t.latencyMs})).sort((e,t)=>e.latencyMs-t.latencyMs)[0]??null;if(!s||s.connectionId===t)return this.switchCandidateConnectionId=null,void(this.switchCandidateHitCount=0);if(n.latencyMs-s.latencyMs<40)return this.switchCandidateConnectionId=null,void(this.switchCandidateHitCount=0);this.switchCandidateConnectionId===s.connectionId?this.switchCandidateHitCount+=1:(this.switchCandidateConnectionId=s.connectionId,this.switchCandidateHitCount=1),this.switchCandidateHitCount>=3&&(this.switchCandidateConnectionId=null,this.switchCandidateHitCount=0,await this.switchToConnection({connectionId:s.connectionId,expectedProbeVersion:e}))};await new Promise(t=>{for(const n of c)(async()=>{let s=null,o=!1;try{const t=this.snapshot.activeConnectionId===n.id?this.snapshot.client:null;if(t)s=t;else{const{client:e,serverId:t}=await this.deps.connectToDaemon({host:this.host,connection:n});if(t!==this.host.serverId){if(!me(this.host.serverId)||!this.onReconcileServerId)throw await e.close().catch(()=>{}),new Error(`Connection resolved to ${t}, expected ${this.host.serverId}.`);this.onReconcileServerId(this.host.serverId,t)}s=e,o=!0}if(!this.isCurrentProbeRequest(e))return;const c=await f(n.id,s);if(o=o&&!c,t){const s=t.getLastLivenessRttMs();if(!this.isCurrentProbeRequest(e))return;return void(null!==s&&(l.set(n.id,{status:"available",latencyMs:s}),S()))}const h=await s.measureLatency({timeoutMs:5e3});if(!this.isCurrentProbeRequest(e))return;l.set(n.id,{status:"available",latencyMs:h}),S()}catch(t){if(this.isCurrentProbeRequest(e)){const e=(0,b.getConnectionAuthFailureReason)(t);e&&(this.authRejectedConnectionIds.add(n.id),p=e),l.set(n.id,{status:"unavailable",latencyMs:null}),S()}}finally{s&&o&&await s.close().catch(()=>{}),u-=1,C().finally(()=>{0===u&&t()})}})()})}isConnectionUnavailable(e,t){return"unavailable"===t?.status||this.authRejectedConnectionIds.has(e)}updateSnapshot(e){const t=Object.assign({},e);let n=this.host.serverId!==this.snapshot.serverId;for(const s of Object.keys(e)){const o=e[s];(0,l.default)(this.snapshot[s],o)?J(t,s,this.snapshot[s]):n=!0}if(n){this.snapshot=Object.assign({},this.snapshot,t,{serverId:this.host.serverId});for(const e of this.listeners)e()}}applyConnectionEvent(e){const t=this.connectionMachineState,n=ie({state:t,event:e});"online"!==t.tag&&"online"===n.tag&&(this.connectionEpoch+=1),this.connectionMachineState=n,this.logConnectionTransition({from:t.tag,to:n.tag,event:e})}logConnectionTransition(e){}trackConnectionFirstSeen(){const e=performance.now(),t=new Set(this.host.connections.map(e=>e.id));for(const e of this.connectionFirstSeenAt.keys())t.has(e)||(this.connectionFirstSeenAt.delete(e),this.connectionLastProbedAt.delete(e));for(const t of this.host.connections)this.connectionFirstSeenAt.has(t.id)||this.connectionFirstSeenAt.set(t.id,e)}isCurrentSwitchRequest(e){return e===this.switchRequestVersion}isCurrentProbeRequest(e){return e===this.probeRequestVersion}canProceedForProbe(e){return void 0===e||this.isCurrentProbeRequest(e)}async abortSwitchWithClient(e){e&&await e.close().catch(()=>{})}isSwitchStillValid(e,t){return this.isCurrentSwitchRequest(e)&&this.canProceedForProbe(t)}async resolveClientIdForSwitch(e){try{return await this.resolveClientId()}catch(t){if(await this.abortSwitchWithClient(e.existingClient),!this.isCurrentSwitchRequest(e.requestVersion))return null;const n=Z(t);return this.applyConnectionEvent({type:"connect_failed",message:`Failed to resolve client id: ${n}`}),this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch))),null}}async disposePreviousActiveClient(){if(this.unsubscribeClientStatus&&(this.unsubscribeClientStatus(),this.unsubscribeClientStatus=null),this.unsubscribeClientHandlers&&(this.unsubscribeClientHandlers(),this.unsubscribeClientHandlers=null),this.activeClient){const e=this.activeClient;this.activeClient=null,await e.close().catch(()=>{})}}buildAgentDirectoryStatusPatch(){if(this.snapshot.hasEverLoadedAgentDirectory)return{};const e=this.connectionMachineState.tag;return"connecting"===e||"online"===e?{agentDirectoryStatus:"initial_loading",agentDirectoryError:null}:"error"===e?{agentDirectoryStatus:"error_before_first_success",agentDirectoryError:this.connectionMachineState.message}:{agentDirectoryStatus:"idle",agentDirectoryError:null}}async switchToConnection(e){const{connectionId:t,expectedProbeVersion:n,existingClient:s}=e;if(!this.canProceedForProbe(n))return void await this.abortSwitchWithClient(s);const o=ae(this.host,t);if(!o)return void await this.abortSwitchWithClient(s);const c=++this.switchRequestVersion,l=await this.resolveClientIdForSwitch({existingClient:s,requestVersion:c});if(null===l)return;if(!this.isSwitchStillValid(c,n))return void await this.abortSwitchWithClient(s);if(await this.disposePreviousActiveClient(),!this.isSwitchStillValid(c,n))return void await this.abortSwitchWithClient(s);const u=this.snapshot.clientGeneration+1,p=s??this.deps.createClient({host:this.host,connection:o,clientId:l,runtimeGeneration:u});if(p.setReconnectEnabled(!0),!this.isSwitchStillValid(c,n))return void await p.close().catch(()=>{});this.activeClient=p,this.applyConnectionEvent({type:"select_connection",connectionId:o.id,connection:te(o)}),this.snapshot=Object.assign({},this.snapshot,{clientGeneration:u}),this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch),{client:null}));const y=async e=>{if(!this.isCurrentSwitchRequest(c)||this.activeClient!==p)return;const t=(0,b.getConnectionAuthFailureReason)(e);if(t&&this.authRejectedConnectionIds.add(o.id),this.unsubscribeClientStatus?.(),this.unsubscribeClientStatus=null,this.unsubscribeClientHandlers?.(),this.unsubscribeClientHandlers=null,p.setReconnectEnabled(!1),this.applyConnectionEvent({type:"connect_failed",message:Z(e)}),this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch),{client:null,authFailureReason:t})),t){const e=new Map(this.snapshot.probeByConnectionId);e.set(o.id,{status:"unavailable",latencyMs:null}),this.updateSnapshot({probeByConnectionId:e});for(const e of this.host.connections)this.authRejectedConnectionIds.has(e.id)||this.connectionLastProbedAt.delete(e.id)}try{await p.close()}catch{}t&&this.host.connections.some(e=>!this.authRejectedConnectionIds.has(e.id))&&this.runProbeCycleNow()};try{if(s||await p.connect(),!this.isCurrentSwitchRequest(c)||this.activeClient!==p)return;this.unsubscribeClientHandlers=this.deps.mountClientHandlers?.({client:p,host:this.host,connection:o})??null,this.unsubscribeClientStatus=p.subscribeConnectionStatus(e=>{this.isCurrentSwitchRequest(c)&&this.activeClient===p&&(p.authFailureReason?y(new h.DaemonAuthenticationError(p.authFailureReason)):(this.applyConnectionEvent({type:"client_state",state:e,lastError:p.lastError}),this.updateSnapshot(Object.assign({},re(this.connectionMachineState,this.connectionEpoch),this.buildAgentDirectoryStatusPatch(),{client:p,authFailureReason:null}))))})}catch(e){await y(e)}}adoptReconciledServerId(e){this.host=Object.assign({},this.host,{serverId:e}),this.snapshot=Object.assign({},this.snapshot,{serverId:e});for(const e of this.listeners)e()}resolveClientId(){return this.clientIdPromise||(this.clientIdPromise=this.deps.getClientId().then(e=>(this.clientIdHash=ee(e),e))),this.clientIdPromise}}const ue="@paseo:daemon-registry",pe="localhost:6767",ye=2500,ge="__PASEO_INITIAL_DAEMON_CONNECTION__",Se=I.z.object({listen:I.z.string().trim().min(1),useTls:I.z.boolean().optional().default(!1)});function fe(e){if(!(e?.isWebRuntime??v.isWeb)||"undefined"==typeof globalThis)return null;const t=Se.safeParse(Reflect.get(globalThis,ge));return t.success?t.data:null}function Ce(){return null}function ve(e){if(e.trim().startsWith("relay://")||e.includes("#connect="))return(0,y.parseRelayConnectionUri)(e);const t="#offer=",n=e.indexOf(t);if(-1===n)throw new Error("Missing #offer= fragment");const s=e.slice(n+7).trim();if(!s)throw new Error("Offer payload is empty");const o=(0,y.decodeOfferFragmentPayload)(s);return{offer:f.ConnectionOfferSchema.parse(o)}}function me(e){return e.startsWith("local:")}function be(e){return new Promise(t=>setTimeout(t,e))}function we(e,t,n){const s=e.get(t);void 0!==s&&(e.delete(t),e.set(n,s))}class Ie{controllers=new Map;serverListeners=new Map;globalListeners=new Set;hostListListeners=new Set;version=0;hostListVersion=0;hostRegistryLoaded=!1;hosts=[];hostAppearanceMutationTail=Promise.resolve();hostRegistryStatus="loading";lastConnectionStatusByServer=new Map;connectionStatusStartedAtByServer=new Map;queuedAgentDrainInFlight=new Set;directorySyncByServer=new Map;nextCancellationRequestId=0;timelineReplicaByServer=new Map;configuredOverrideBootstrapInFlight=null;bootPromise=null;constructor(e){this.deps=e?.deps??he(),this.storage=e?.storage??c.default,this.replicaCache=new W.ReplicaCache(e?.replicaRowStore??(0,$.createReplicaRowStore)()),this.revokePushNotifications=e?.revokePushNotifications??K.revokePushNotifications}getHosts(){return this.hosts}getHostRegistryStatus(){return this.hostRegistryStatus}subscribeHostList(e){return this.hostListListeners.add(e),()=>{this.hostListListeners.delete(e)}}getHostListVersion(){return this.hostListVersion}isHostRegistryLoaded(){return this.hostRegistryLoaded}boot(){return this.bootPromise||(this.bootPromise=this.runBoot()),this.bootPromise}async runBoot(){await this.loadFromStorage(),this.markHostRegistryLoaded();let e=null;try{e=await(0,A.readValidatedString)(this.storage,"@paseo:e2e",I.z.string().min(1))}catch{return}if(e)return;if((0,C.shouldUseDesktopDaemon)())return;const t=this.deps.readInitialConnectionHint?this.deps.readInitialConnectionHint():fe();if(t){if(await this.bootstrapInitialConnectionHint(t))return}await this.bootstrapDefaultLocalhost()}async loadFromStorage(){let e=!1,t=[];try{const n=await(0,A.readValidatedJson)(this.storage,ue,u.StoredHostRegistrySchema);if(n){const s=[];for(const t of n){const n=(0,u.normalizeStoredHostProfile)(t);if(!n){await this.storage.removeItem(ue),s.length=0;break}t.connections.some(e=>"directTcp"===e.type&&e.password)&&(e=!0),s.push(n)}t=s.filter(e=>!me(e.serverId)),t.length!==s.length&&(e=!0)}this.hosts=t,this.replicaCache.setHosts(t.map(e=>e.serverId)),G.projectIconCache.setHosts(t.map(e=>e.serverId)),await G.projectIconCache.restore(),this.syncHosts(t);for(const e of t)this.directorySyncByServer.get(e.serverId)?.restoreCachedDirectory().catch(()=>{})}catch(e){console.error("[HostRuntime] Failed to load host registry from storage",e)}finally{this.hostRegistryStatus="ready",this.emitHostList(),e&&this.persistHosts().catch(e=>console.error("[HostRuntime] Failed to persist host registry",e))}}markHostRegistryLoaded(){this.hostRegistryLoaded||(this.hostRegistryLoaded=!0,this.emitHostList())}async bootstrapDefaultLocalhost(){const e=(0,u.connectionFromListen)(pe);if(e&&!(0,u.registryHasConnection)(this.hosts,e))try{await this.probeAndUpsertConnection({connection:e,timeoutMs:ye})}catch(e){console.warn("[HostRuntime] bootstrap probe failed",{endpoint:pe,error:e})}}bootstrapConfiguredOverride(e){const t=(0,u.connectionFromListen)(e);if(!t)return;if((0,u.registryHasConnection)(this.hosts,t))return;if(this.configuredOverrideBootstrapInFlight)return;const n=this.runConfiguredOverrideBootstrap(e,t).finally(()=>{this.configuredOverrideBootstrapInFlight===n&&(this.configuredOverrideBootstrapInFlight=null)});this.configuredOverrideBootstrapInFlight=n}async runConfiguredOverrideBootstrap(e,t){let n=0;for(;!(0,u.registryHasConnection)(this.hosts,t);){n+=1;try{return void await this.probeAndUpsertConnection({connection:t,timeoutMs:ye})}catch(t){1!==n&&n%10!=0||console.warn("[HostRuntime] configured bootstrap probe failed",{endpoint:e,attempt:n,error:t}),await be(1e3)}}}async bootstrapInitialConnectionHint(e){const t=(0,u.connectionFromListen)(e.listen);if(!t)return!1;const n="directTcp"===t.type?Object.assign({},t,{useTls:e.useTls??t.useTls??!1}):t;if((0,u.registryHasConnection)(this.hosts,n))return!0;try{return await this.probeAndUpsertConnection({connection:n,timeoutMs:ye}),!0}catch(t){return console.warn("[HostRuntime] initial connection hint probe failed",{listen:e.listen,useTls:e.useTls,error:t}),!1}}reconcileServerId(e,t){if(e===t)return;const n=this.controllers.get(e);if(!n)return;if(this.controllers.has(t))return;we(this.controllers,e,t),we(this.lastConnectionStatusByServer,e,t),we(this.connectionStatusStartedAtByServer,e,t),this.replicaCache.reconcileServerId(e,t),G.projectIconCache.reconcileServerId(e,t),this.directorySyncByServer.get(e)?.dispose(),this.directorySyncByServer.delete(e),this.timelineReplicaByServer.delete(e);const s=new V.DirectorySync(t,{onAgentStoppedRunning:e=>this.drainQueuedAgentMessage(t,e),markAgentLoading:()=>n.markAgentDirectorySyncLoading(),markAgentReady:()=>n.markAgentDirectorySyncReady(),markAgentError:e=>n.markAgentDirectorySyncError(e)},this.replicaCache);this.directorySyncByServer.set(t,s),this.timelineReplicaByServer.set(t,(0,N.createTimelineReplica)({serverId:t,storage:this.replicaCache,prepareAgent:e=>s.prepareAgentRoute(e)})),n.adoptReconciledServerId(t);const o=n.getSnapshot();this.clearHostReplica(e),this.syncSessionReplica(t,o),s.connectionChanged({client:o.client,status:"online"===o.connectionStatus?"online":"offline",source:{clientGeneration:o.clientGeneration,connectionEpoch:o.connectionEpoch}});const c=this.serverListeners.get(e);if(c){this.serverListeners.delete(e);const n=this.serverListeners.get(t)??new Set;for(const e of c)n.add(e);this.serverListeners.set(t,n)}this.hosts=this.hosts.map(n=>n.serverId===e?Object.assign({},n,{serverId:t,updatedAt:(new Date).toISOString()}):n),this.emitHostList(),this.emit(t),this.persistHosts().catch(e=>console.error("[HostRuntime] Failed to persist host registry",e))}async upsertDirectConnection(e){const t=(0,y.normalizeHostPort)(e.endpoint),n=e.password?.trim();return this.upsertHostConnection({serverId:e.serverId,label:e.label,password:n,connection:{id:`direct:${t}`,type:"directTcp",endpoint:t,useTls:e.useTls??!1},existingClient:e.existingClient})}async probeAndUpsertConnection(e){if("relay"===e.connection.type)throw new Error("Cannot probe a relay connection without a server id.");const t=Object.assign({serverId:""},e.password?{password:e.password}:{},{label:e.label??e.connection.id,appearance:(0,p.defaultHostAppearance)(),lifecycle:{},connections:[e.connection],preferredConnectionId:e.connection.id,createdAt:new Date(0).toISOString(),updatedAt:new Date(0).toISOString()}),{client:n,serverId:s,hostname:o}=await this.deps.connectToDaemon(Object.assign({host:t,connection:e.connection},void 0!==e.timeoutMs?{timeoutMs:e.timeoutMs}:{}));return{profile:await this.upsertHostConnection({serverId:s,label:e.label??o??void 0,password:e.password,connection:e.connection,existingClient:n}),serverId:s,hostname:o}}async probeAndUpsertDirectConnection(e){const t=(0,y.normalizeHostPort)(e.endpoint),n=e.password?.trim();return this.probeAndUpsertConnection({label:e.label,password:n,connection:{id:`direct:${t}`,type:"directTcp",endpoint:t,useTls:e.useTls??!1}})}async probeAndUpsertRemoteSshConnection(e){return this.probeAndUpsertConnection({label:e.label,connection:(0,u.createRemoteSshHostConnection)(e)})}async upsertRelayConnection(e){const t=(0,y.normalizeHostPort)(e.relayEndpoint),n=e.useTls??!1,s=e.daemonPublicKeyB64.trim();if(!s)throw new Error("daemonPublicKeyB64 is required");const o=void 0!==e.useTls,c=await this.upsertHostConnection({serverId:e.serverId,label:e.label,connection:Object.assign({id:n?`relay:wss:${t}`:`relay:${t}`,type:"relay",relayEndpoint:t},o?{useTls:n}:{},{daemonPublicKeyB64:s})});return e.password?(await this.setHostPassword(c.serverId,e.password),this.hosts.find(e=>e.serverId===c.serverId)??c):c}async upsertConnectionFromOffer(e,t,n){const s=e.relay.useTls??(0,y.shouldUseTlsForDefaultHostedRelay)(e.relay.endpoint);return this.upsertRelayConnection({serverId:e.serverId,relayEndpoint:e.relay.endpoint,useTls:s,daemonPublicKeyB64:e.daemonPublicKeyB64,label:t,password:n})}async upsertConnectionFromOfferUrl(e,t,n){const s=ve(e);return this.upsertConnectionFromOffer(s.offer,t,n??s.password)}async probeAndUpsertConnectionFromOfferUrl(e,t){const n=ve(e),s=n.offer,o=t??n.password,c=s.relay.useTls??(0,y.shouldUseTlsForDefaultHostedRelay)(s.relay.endpoint),l=(0,y.normalizeHostPort)(s.relay.endpoint),h={id:c?`relay:wss:${l}`:`relay:${l}`,type:"relay",relayEndpoint:l,useTls:c,daemonPublicKeyB64:s.daemonPublicKeyB64},u=Object.assign({serverId:s.serverId},o?{password:o}:{},{label:s.serverId,appearance:(0,p.defaultHostAppearance)(),lifecycle:{},connections:[h],preferredConnectionId:h.id,createdAt:new Date(0).toISOString(),updatedAt:new Date(0).toISOString()}),{client:S,hostname:f}=await this.deps.connectToDaemon({host:u,connection:h});await S.close().catch(()=>{});return{profile:await this.upsertConnectionFromOffer(s,f??void 0,o),serverId:s.serverId,hostname:f}}async importConnectionLink(e,t){if("openProject"===t){return{status:"connected",serverId:(await this.upsertConnectionFromOfferUrl(e)).serverId}}try{const{serverId:t}=await this.probeAndUpsertConnectionFromOfferUrl(e);return{status:"connected",serverId:t}}catch(e){if(!(0,b.getConnectionAuthFailureReason)(e))throw e;return{status:"password_required"}}}async upsertConnectionFromListen(e){const t=e.listenAddress.trim(),n=e.serverId.trim(),s=(0,u.connectionFromListen)(t);if(!s)throw new Error(`Unsupported listen address: ${e.listenAddress}`);if(!n)throw new Error("Desktop daemon did not return a server id.");return this.upsertHostConnection({serverId:n,label:e.hostname??void 0,connection:s})}async updateHost(e,t){const n=(new Date).toISOString(),s=this.hosts.map(s=>s.serverId===e?Object.assign({},t(s),{updatedAt:n}):s);this.setHostsAndSync(s),await this.persistHosts()}async renameHost(e,t){await this.updateHost(e,e=>Object.assign({},e,{label:t}))}async setHostPassword(t,s){await this.updateHost(t,t=>{const o=(0,n.default)(t,e);return s?Object.assign({},o,{password:s}):o})}async setHostColor(e,t){await this.updateHostAppearance(e,e=>Object.assign({},e,{appearance:Object.assign({},e.appearance,{color:t})}))}async setHostBadgeDisplay(e,t){await this.updateHostAppearance(e,e=>Object.assign({},e,{appearance:Object.assign({},e.appearance,{badgeDisplay:t})}))}updateHostAppearance(e,t){const n=this.hostAppearanceMutationTail.then(()=>this.applyHostAppearance(e,t));return this.hostAppearanceMutationTail=n.catch(()=>{}),n}async applyHostAppearance(e,t){const n=(new Date).toISOString(),s=this.hosts.map(s=>s.serverId===e?Object.assign({},t(s),{updatedAt:n}):s);await this.persistHosts(s),this.setHostsAndSync(s)}async removeHost(e){await this.revokePushNotifications({client:this.getClient(e),serverId:e});const t=this.hosts.filter(t=>t.serverId!==e);this.setHostsAndSync(t),await this.persistHosts()}async removeConnection(e,t){const n=this.hosts.find(t=>t.serverId===e);if(1===n?.connections.length&&n.connections[0]?.id===t)return void await this.removeHost(e);const s=(new Date).toISOString(),o=this.hosts.map(n=>{if(n.serverId!==e)return n;const o=n.connections.filter(e=>e.id!==t);if(0===o.length)return null;const c=n.preferredConnectionId===t?o[0]?.id??null:n.preferredConnectionId;return Object.assign({},n,{connections:o,preferredConnectionId:c,updatedAt:s})}).filter(e=>null!==e);this.setHostsAndSync(o),await this.persistHosts()}async upsertHostConnection(e){const t=(new Date).toISOString(),n=(0,u.upsertHostConnectionInProfiles)({profiles:this.hosts,serverId:e.serverId,label:e.label,connection:e.connection,password:e.password,now:t});this.setHostsAndSync(n,{initialConnectionByServerId:e.existingClient?new Map([[e.serverId,{connectionId:e.connection.id,existingClient:e.existingClient}]]):void 0}),this.persistHosts().catch(e=>console.error("[HostRuntime] Failed to persist host registry",e));const s=n.find(t=>t.serverId===e.serverId);if(!s)throw new Error(`Host ${e.serverId} was not inserted`);return s}setHostsAndSync(e,t){this.hosts=e,this.syncHosts(e,t),this.emitHostList()}async persistHosts(e=this.hosts){await this.storage.setItem(ue,JSON.stringify(e))}emitHostList(){this.hostListVersion+=1;for(const e of this.hostListListeners)e()}syncHosts(e,t){this.replicaCache.setHosts(e.map(e=>e.serverId)),G.projectIconCache.setHosts(e.map(e=>e.serverId));const n=new Set(e.map(e=>e.serverId));for(const[e,t]of this.controllers)n.has(e)||(this.controllers.delete(e),this.lastConnectionStatusByServer.delete(e),this.connectionStatusStartedAtByServer.delete(e),this.directorySyncByServer.get(e)?.dispose(),this.directorySyncByServer.delete(e),this.timelineReplicaByServer.delete(e),this.clearHostReplica(e),t.stop(),this.emit(e));for(const n of e){const e=t?.initialConnectionByServerId?.get(n.serverId),s=this.controllers.get(n.serverId);if(s){s.updateHost(n),e&&s.activateConnection(e).catch(()=>{e.existingClient.close().catch(()=>{})});continue}const o=new de({host:n,deps:this.deps,onReconcileServerId:(e,t)=>this.reconcileServerId(e,t)});this.controllers.set(n.serverId,o),L.useSessionStore.getState().initializeSession(n.serverId,null);const c=new V.DirectorySync(n.serverId,{onAgentStoppedRunning:e=>this.drainQueuedAgentMessage(n.serverId,e),markAgentLoading:()=>o.markAgentDirectorySyncLoading(),markAgentReady:()=>o.markAgentDirectorySyncReady(),markAgentError:e=>o.markAgentDirectorySyncError(e)},this.replicaCache);this.directorySyncByServer.set(n.serverId,c),this.timelineReplicaByServer.set(n.serverId,(0,N.createTimelineReplica)({serverId:n.serverId,storage:this.replicaCache,prepareAgent:e=>c.prepareAgentRoute(e)}));const l=o.getSnapshot();this.lastConnectionStatusByServer.set(n.serverId,l.connectionStatus),this.connectionStatusStartedAtByServer.set(n.serverId,Date.now()),o.subscribe(()=>{const e=o.getSnapshot();this.syncSessionReplica(e.serverId,e),this.syncDirectoryConnection(e.serverId),this.emit(e.serverId)}),o.start(e?{initialConnection:e}:{}).catch(e=>{const t=e instanceof Error?e.message:String(e);o.markStartupError(t)}),this.emit(n.serverId)}}syncSessionReplica(e,t){if(!t.client)return;const n=L.useSessionStore.getState();n.initializeSession(e,t.client,t.clientGeneration),n.updateSessionClient(e,t.client,t.clientGeneration)}clearHostReplica(e){L.useSessionStore.getState().clearSession(e),T.useWorkspaceSetupStore.getState().clearServer(e)}syncDirectoryConnection(e){const t=this.controllers.get(e);if(!t)return this.lastConnectionStatusByServer.delete(e),void this.connectionStatusStartedAtByServer.delete(e);const n=t.getSnapshot(),s=this.directorySyncByServer.get(e);s?.connectionChanged({client:n.client,status:"online"===n.connectionStatus?"online":"offline",source:{clientGeneration:n.clientGeneration,connectionEpoch:n.connectionEpoch}});const o=this.lastConnectionStatusByServer.get(e),c=o!==n.connectionStatus,l="online"!==n.connectionStatus&&"idle"!==n.connectionStatus;!c||void 0!==o&&"online"!==o&&"idle"!==o&&l||this.connectionStatusStartedAtByServer.set(e,Date.now()),this.lastConnectionStatusByServer.set(e,n.connectionStatus);"online"===n.connectionStatus&&"online"!==o&&(L.useSessionStore.getState().bumpHistorySyncGeneration(e),(0,_.invalidateCheckoutGitQueriesForServer)(M.queryClient,e),(0,B.invalidateServerDataQueriesAfterReconnect)({queryClient:M.queryClient,serverId:e}),M.queryClient.invalidateQueries({queryKey:k.schedulesQueryBaseKey}))}drainQueuedAgentMessage(e,t){const n=`${e}:${t}`;if(this.queuedAgentDrainInFlight.has(n))return;const s=L.useSessionStore.getState().sessions[e],o=s?.queuedMessages.get(t),c=s?.client;if(!c||!o?.length||!0===s.initializingAgents.get(t))return;this.queuedAgentDrainInFlight.add(n);const l=o[0];(0,j.sendQueuedComposerMessageNow)({agentId:t,messageId:l.id,queue:{read:t=>L.useSessionStore.getState().sessions[e]?.queuedMessages.get(t)??[],write:t=>L.useSessionStore.getState().setQueuedMessages(e,t)},submitMessage:async({text:n,attachments:s})=>{const o=!0===L.useSessionStore.getState().sessions[e]?.serverInfo?.features?.forgeSearch;await(0,j.dispatchComposerAgentMessage)({client:c,agentId:t,text:n,attachments:s,attachmentSubmitFormat:(0,U.resolveComposerAttachmentSubmitFormat)({supportsForgeAttachments:o}),encodeImages:x.encodeImages,submission:(0,q.createMessageSubmissionWriter)(e)})}}).then(n=>("failed"===n.status&&console.error("[HostRuntime] failed to drain queued agent message",{serverId:e,agentId:t,error:n.errorMessage}),n)).finally(()=>{this.queuedAgentDrainInFlight.delete(n)})}applyAgentTurnLiveness(e,t,n){this.directorySyncByServer.get(e)?.applyAgentTurnLiveness(t,n)}beginAgentCancellation(e,t){const n=++this.nextCancellationRequestId;return this.applyAgentTurnLiveness(e,t,{type:"cancellation_started",requestId:n}),n}settleAgentCancellation(e,t,n){this.applyAgentTurnLiveness(e,t,{type:"cancellation_settled",requestId:n})}acceptAgentSnapshot(e,t){return this.requireDirectory(e).acceptAgent(t)}archiveAgentSnapshot(e,t,n){this.requireDirectory(e).archiveAgent(t,n)}restoreAgentSnapshot(e,t,n){const s=this.requireDirectory(e);n?s.acceptAgent(n):s.removeAgent(t)}acceptWorkspaceSnapshots(e,t){this.requireDirectory(e).acceptWorkspaces(t)}acceptProjectSnapshot(e,t){this.requireDirectory(e).acceptProject(t)}removeWorkspaceSnapshot(e,t){this.requireDirectory(e).removeWorkspace(t)}requireDirectory(e){const t=this.directorySyncByServer.get(e);if(!t)throw new Error(`Unknown host runtime for serverId ${e}`);return t}getSnapshot(e){return this.controllers.get(e)?.getSnapshot()??null}getConnectionStatusSince(e){return this.connectionStatusStartedAtByServer.get(e)??null}getVersion(){return this.version}getClient(e){return this.controllers.get(e)?.getClient()??null}subscribe(e,t){const n=this.serverListeners.get(e)??new Set;return n.add(t),this.serverListeners.set(e,n),()=>{const n=this.serverListeners.get(e);n&&(n.delete(t),0===n.size&&this.serverListeners.delete(e))}}subscribeAll(e){return this.globalListeners.add(e),()=>{this.globalListeners.delete(e)}}getEarliestOnlineHostServerId(){let e=null,t=null;for(const n of this.hosts){const s=this.getSnapshot(n.serverId);X(s)&&s?.lastOnlineAt&&((!t||s.lastOnlineAt<t)&&(t=s.lastOnlineAt,e=n.serverId))}return e}ensureConnectedAll(e){for(const t of this.controllers.values())t.ensureConnected(e)}setAppVisible(e){e?this.ensureConnectedAll({verify:!0}):this.replicaCache.flush()}runProbeCycleNow(e){return e?this.controllers.get(e)?.runProbeCycleNow()??Promise.resolve():Promise.all(Array.from(this.controllers.values(),e=>e.runProbeCycleNow())).then(()=>{})}async refreshAgentDirectory(e){const t=this.directorySyncByServer.get(e.serverId);if(!t)throw new Error(`Unknown host runtime for serverId ${e.serverId}`);return t.refreshAgents(e)}async refreshWorkspaceDirectory(e){const t=this.directorySyncByServer.get(e.serverId);if(!t)throw new Error(`Unknown host runtime for serverId ${e.serverId}`);await t.refreshWorkspaces({subscribe:e.subscribe})}async refreshDirectories(e){const t=this.directorySyncByServer.get(e);if(!t)throw new Error(`Unknown host runtime for serverId ${e}`);await t.refreshDemand()}acquireDirectoryDemand(e){const t=this.directorySyncByServer.get(e);if(!t)return()=>{};const n={};return t.setDemand(n,!0),()=>t.setDemand(n,!1)}async prepareAgentRoute(e,t){const n=this.directorySyncByServer.get(e);if(!n)throw new Error(`Unknown host runtime for serverId ${e}`);await n.prepareAgentRoute(t)}async prepareWorkspaceRoute(e,t){const n=this.directorySyncByServer.get(e);if(!n)throw new Error(`Unknown host runtime for serverId ${e}`);await n.prepareWorkspaceRoute(t)}async prepareAgentTimeline(e,t){const n=this.timelineReplicaByServer.get(e);if(!n)throw new Error(`Unknown host runtime for serverId ${e}`);await n.prepare(t)}async fetchAgentTimeline(e,t,n){const s=this.directorySyncByServer.get(e);if(!s)throw new Error(`Unknown host runtime for serverId ${e}`);const o=L.useSessionStore.getState().sessions[e]?.viewedTimelineSync,c=await s.fetchTimeline(t,n);return o&&L.useSessionStore.getState().sessions[e]?.viewedTimelineSync===o&&(o.flushStreamAgent(t),o.applyTimelineResponse(c)),c}createViewedTimelineOwner(e,t){const n=this.directorySyncByServer.get(e);if(!n)throw new Error(`Unknown host runtime for serverId ${e}`);const s=this.timelineReplicaByServer.get(e);if(!s)throw new Error(`Unknown host runtime for serverId ${e}`);return(0,N.createViewedTimelineOwner)({serverId:e,replica:s,replaceDemandedAgentIds:e=>n.setAgentRouteDemand(e),drainQueuedAgentMessage:t=>this.drainQueuedAgentMessage(e,t),ports:t})}emit(e){this.version+=1;const t=this.serverListeners.get(e);if(t){for(const e of t)e();for(const e of this.globalListeners)e()}else for(const e of this.globalListeners)e()}}let Ae=null;const He="__paseoHostRuntimeStore";function Re(){if(Ae)return Ae;const e=Reflect.get(globalThis,He);return e instanceof Ie?(Ae=e,e):(Ae=new Ie,Reflect.set(globalThis,He,Ae),Ae)}},3466,[35,453,36,884,3467,3468,3518,3521,3523,3463,3524,3525,880,3527,3528,2898,2979,3531,3529,881,3532,3479,3491,3420,3533,3540,848,3542,3553,3571,3573,3584,3575,3585,3591,3621,3625,3626,3630,3632,3634,3635]);
15112
15112
  __d(function(g,r,_i,_a,m,e,d){'use strict';m.exports=function t(n,f){if(n===f)return!0;if(n&&f&&'object'==typeof n&&'object'==typeof f){if(n.constructor!==f.constructor)return!1;var i,o,u;if(Array.isArray(n)){if((i=n.length)!=f.length)return!1;for(o=i;0!==o--;)if(!t(n[o],f[o]))return!1;return!0}if(n instanceof Map&&f instanceof Map){if(n.size!==f.size)return!1;for(o of n.entries())if(!f.has(o[0]))return!1;for(o of n.entries())if(!t(o[1],f.get(o[0])))return!1;return!0}if(n instanceof Set&&f instanceof Set){if(n.size!==f.size)return!1;for(o of n.entries())if(!f.has(o[0]))return!1;return!0}if(ArrayBuffer.isView(n)&&ArrayBuffer.isView(f)){if((i=n.length)!=f.length)return!1;for(o=i;0!==o--;)if(n[o]!==f[o])return!1;return!0}if(n.constructor===RegExp)return n.source===f.source&&n.flags===f.flags;if(n.valueOf!==Object.prototype.valueOf)return n.valueOf()===f.valueOf();if(n.toString!==Object.prototype.toString)return n.toString()===f.toString();if((i=(u=Object.keys(n)).length)!==Object.keys(f).length)return!1;for(o=i;0!==o--;)if(!Object.prototype.hasOwnProperty.call(f,u[o]))return!1;for(o=i;0!==o--;){var s=u[o];if(!t(n[s],f[s]))return!1}return!0}return n!=n&&f!=f}},3467,[]);
@@ -85,6 +85,6 @@
85
85
  <body>
86
86
  <noscript>You need to enable JavaScript to run this app.</noscript>
87
87
  <div id="root"></div>
88
- <script src="/_expo/static/js/web/index-cefb3a051a5e61705f20366980a641f6.js" defer></script>
88
+ <script src="/_expo/static/js/web/index-48b52108bb348a6334547c3c03400d50.js" defer></script>
89
89
  </body>
90
90
  </html>
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpaseo/server",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Paseo backend server",
5
5
  "files": [
6
6
  "dist/server",
@@ -107,11 +107,11 @@
107
107
  "@agentclientprotocol/sdk": "^0.17.1",
108
108
  "@anthropic-ai/claude-agent-sdk": "0.3.246",
109
109
  "@anthropic-ai/sdk": "^0.104.2",
110
- "@getpaseo/client": "0.10.1",
111
- "@getpaseo/highlight": "0.10.1",
112
- "@getpaseo/plugin": "0.10.1",
113
- "@getpaseo/protocol": "0.10.1",
114
- "@getpaseo/relay": "0.10.1",
110
+ "@getpaseo/client": "0.10.2",
111
+ "@getpaseo/highlight": "0.10.2",
112
+ "@getpaseo/plugin": "0.10.2",
113
+ "@getpaseo/protocol": "0.10.2",
114
+ "@getpaseo/relay": "0.10.2",
115
115
  "@isaacs/ttlcache": "^2.1.4",
116
116
  "@modelcontextprotocol/sdk": "1.29.0",
117
117
  "@opencode-ai/sdk": "1.14.46",