@hyperdrive.bot/fleet-server 0.3.112 → 0.3.113

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.
@@ -408,6 +408,14 @@ export declare class ClaudeAgentSession implements AgentSession {
408
408
  */
409
409
  private retractPtyDialogCard;
410
410
  private handlePtyDialogChange;
411
+ /**
412
+ * Answer a CLI-drawn confirm box (tool approval, dangerous-command guard, plan
413
+ * approval). Number-only by contract: option 1 proceeds, Esc declines. Unlike the
414
+ * question path this MUST act on a deny too - the box stays up until something answers
415
+ * it, so returning early on `deny` would leave the agent blocked on a card the user
416
+ * already dismissed.
417
+ */
418
+ private answerPtyConfirmFromPermission;
411
419
  /** Map the app's chosen answer back to the dialog's option index and press the keys. */
412
420
  private answerPtyDialogFromPermission;
413
421
  private handlePermissionRequest;
@@ -3908,8 +3908,16 @@ export class ClaudeAgentSession {
3908
3908
  this.retractPtyDialogCard();
3909
3909
  return;
3910
3910
  }
3911
- if (dialog.name !== "AskUserQuestion")
3912
- return;
3911
+ // Every dialog the query hands up raises a card. This used to read
3912
+ // `if (dialog.name !== "AskUserQuestion") return;`, which was STRICTER than the query
3913
+ // layer that feeds it: ExitPlanMode passed the query's filter, got the stall/ESC
3914
+ // protections, and was then dropped here without ever reaching the app. A CLI
3915
+ // confirmation box (`dialog.confirm`) had no path at all.
3916
+ let kind = "question";
3917
+ if (dialog.confirm)
3918
+ kind = "tool";
3919
+ else if (dialog.name === "ExitPlanMode")
3920
+ kind = "plan";
3913
3921
  // Latch on the tool_use id, not on "is anything pending". A bare boolean latch is
3914
3922
  // one missed clear away from muting every future question for the life of the agent:
3915
3923
  // the only thing that cleared it was the matching tool_result, so a query restart or
@@ -3927,8 +3935,18 @@ export class ClaudeAgentSession {
3927
3935
  id: requestId,
3928
3936
  provider: "claude",
3929
3937
  name: dialog.name,
3930
- kind: "question",
3931
- input: normalizeClaudeAskUserQuestionRequestInput(dialog.name, dialog.input),
3938
+ kind,
3939
+ input: kind === "question"
3940
+ ? normalizeClaudeAskUserQuestionRequestInput(dialog.name, dialog.input)
3941
+ : dialog.input,
3942
+ // A confirm box carries no labels of its own (see PtyInteractiveDialog.confirm), so
3943
+ // the card gets the two behaviours the CLI actually offers rather than invented text.
3944
+ actions: kind === "question"
3945
+ ? undefined
3946
+ : [
3947
+ { id: "allow", label: "Yes", behavior: "allow", variant: "primary" },
3948
+ { id: "deny", label: "No", behavior: "deny", variant: "danger" },
3949
+ ],
3932
3950
  metadata: { toolUseId: dialog.toolUseId },
3933
3951
  };
3934
3952
  const optionsByQuestion = dialog.optionsByQuestion.length > 0 ? dialog.optionsByQuestion : [dialog.options];
@@ -3937,12 +3955,31 @@ export class ClaudeAgentSession {
3937
3955
  // There is no SDK promise to settle here: "resolving" means playing the answer into
3938
3956
  // the terminal. An answer that names no known option is left to the user to type.
3939
3957
  resolve: (result) => {
3940
- void this.answerPtyDialogFromPermission(result, optionsByQuestion);
3958
+ if (kind === "question") {
3959
+ void this.answerPtyDialogFromPermission(result, optionsByQuestion);
3960
+ return;
3961
+ }
3962
+ void this.answerPtyConfirmFromPermission(result);
3941
3963
  },
3942
3964
  reject: () => { },
3943
3965
  });
3944
3966
  this.pushEvent({ type: "permission_requested", provider: "claude", request });
3945
3967
  }
3968
+ /**
3969
+ * Answer a CLI-drawn confirm box (tool approval, dangerous-command guard, plan
3970
+ * approval). Number-only by contract: option 1 proceeds, Esc declines. Unlike the
3971
+ * question path this MUST act on a deny too - the box stays up until something answers
3972
+ * it, so returning early on `deny` would leave the agent blocked on a card the user
3973
+ * already dismissed.
3974
+ */
3975
+ async answerPtyConfirmFromPermission(result) {
3976
+ const query = this.query;
3977
+ if (result.behavior === "allow") {
3978
+ await query?.answerDialogByIndex?.(0);
3979
+ return;
3980
+ }
3981
+ await query?.declineDialog?.();
3982
+ }
3946
3983
  /** Map the app's chosen answer back to the dialog's option index and press the keys. */
3947
3984
  async answerPtyDialogFromPermission(result, optionsByQuestion) {
3948
3985
  if (result.behavior !== "allow")
@@ -5,8 +5,15 @@ import { type UserPromptLine } from "./transcript-sdk-reader.js";
5
5
  /** An interactive TUI dialog the user has to answer for the turn to continue. */
6
6
  export interface PtyInteractiveDialog {
7
7
  toolUseId: string;
8
- /** "AskUserQuestion" | "ExitPlanMode" */
8
+ /** "AskUserQuestion" | "ExitPlanMode", or the gated tool's name when `confirm` is set. */
9
9
  name: string;
10
+ /**
11
+ * True for a CLI-drawn confirmation box (tool approval, dangerous-command guard) rather
12
+ * than a tool the model called to ask something. Its options are the CLI's own and
13
+ * version-dependent, so they are never scraped: option 1 proceeds and Esc declines, which
14
+ * is the same number-only contract the plan-approval dialog already runs on.
15
+ */
16
+ confirm?: boolean;
10
17
  /** The tool_use input verbatim, so the app renders the real questions and options. */
11
18
  input: Record<string, unknown>;
12
19
  /** Option labels of the FIRST question, in on-screen order; empty when unknown. */
@@ -120,6 +127,19 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
120
127
  private rejectedCommandNotice;
121
128
  /** Interactive TUI dialog awaiting the user (AskUserQuestion / plan approval), if any. */
122
129
  private pendingDialog;
130
+ /**
131
+ * The most recent assistant `tool_use` with no `tool_result` yet, of ANY name. A CLI
132
+ * confirmation box says nothing about WHICH tool it is gating, so the screen marker alone
133
+ * cannot build a card; this is the other half of the pair. Deliberately not a filter on
134
+ * tool name: the whole defect being fixed here is a name allowlist.
135
+ */
136
+ private lastToolUse;
137
+ /**
138
+ * tool_use id of the last confirm box raised from the screen. The CLI repaints the box on
139
+ * every keystroke, so without this a redraw arriving between the answer and its
140
+ * tool_result re-raises the same card the user just dismissed.
141
+ */
142
+ private confirmRaisedFor;
123
143
  /**
124
144
  * Raw capture window for echo verification. The rolling tail deliberately drops lines
125
145
  * with fewer than three letters as spinner noise, which also swallows the echo of a
@@ -439,6 +459,24 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
439
459
  * record a setting change that did not happen.
440
460
  */
441
461
  sendControlCommand(command: string): Promise<boolean>;
462
+ /**
463
+ * A CLI confirmation box is on screen. Pair it with the tool_use it is gating and raise
464
+ * the same dialog the transcript path raises, so the app gets a card and the three
465
+ * protections listed on {@link trackInteractiveDialog} switch on: the stall backstop
466
+ * stands down, no ESC is sent behind the user's back, and a reply becomes keystrokes.
467
+ *
468
+ * Without this the box was invisible to every one of those. A recording from 2026-08-22
469
+ * (`f30cef74`) shows the guard drawn at 16:44:02 and `STALLED after 600000ms` at
470
+ * 16:54:02: the agent sat dead for ten minutes waiting on a question nobody was shown.
471
+ */
472
+ private raiseConfirmDialog;
473
+ /**
474
+ * Decline the pending confirm box. Esc rather than selecting the last option: the CLI
475
+ * treats Esc as a decline (the behaviour that made stray interrupts read as "User
476
+ * declined"), and it does not depend on how many options this CLI version offers, which
477
+ * is 2 for the dangerous-command guard and 3 for an ordinary tool approval.
478
+ */
479
+ declineDialog(): Promise<boolean>;
442
480
  private looksIdle;
443
481
  private appendTerminalTail;
444
482
  /** Open `$PASEO_HOME/pty-recordings/<sessionId>.log`. Best-effort: never fail a session. */
@@ -218,6 +218,21 @@ const INTERRUPT_PROMPT_MARKER = "what should claude do instead";
218
218
  * Selecting it takes one Down (to move off option 1) and one Enter.
219
219
  */
220
220
  const RESUME_DIALOG_MARKER = "resume from summary";
221
+ /**
222
+ * The footer under every confirmation box the CLI draws ITSELF: an ordinary tool approval,
223
+ * and the dangerous-command guard that prompted this code. Unlike AskUserQuestion these
224
+ * never reach the transcript as a dialog of their own - the transcript only shows the
225
+ * ordinary `tool_use` (Bash, Write, ...) that the CLI then decided to gate - so the screen
226
+ * is the only place the "a human has to answer this" fact exists.
227
+ *
228
+ * Matched WHITESPACE-STRIPPED. The TUI paints its padding with cursor-forward escapes
229
+ * rather than literal spaces and {@link stripTerminalControl} removes them, so the same box
230
+ * reaches the tail as `Do you want to proceed?` on one redraw and `Doyouwanttoproceed?` on
231
+ * the next. Both spellings are in the recordings this was built from
232
+ * (`$PASEO_HOME/pty-recordings`, 2026-08-22 and 2026-09-08); a spaced literal would have
233
+ * matched one session and missed the other.
234
+ */
235
+ const CONFIRM_DIALOG_MARKERS = ["tabtoamend", "doyouwanttoproceed"];
221
236
  /** How long a sighting stays actionable; mirrors INTERRUPT_PROMPT_TTL_MS reasoning. */
222
237
  const RESUME_DIALOG_TTL_MS = 5 * 60000;
223
238
  /** How long a sighting stays actionable. Beyond this, assume the modal is long gone. */
@@ -308,6 +323,19 @@ export class PtyQuery {
308
323
  this.rejectedCommandNotice = null;
309
324
  /** Interactive TUI dialog awaiting the user (AskUserQuestion / plan approval), if any. */
310
325
  this.pendingDialog = null;
326
+ /**
327
+ * The most recent assistant `tool_use` with no `tool_result` yet, of ANY name. A CLI
328
+ * confirmation box says nothing about WHICH tool it is gating, so the screen marker alone
329
+ * cannot build a card; this is the other half of the pair. Deliberately not a filter on
330
+ * tool name: the whole defect being fixed here is a name allowlist.
331
+ */
332
+ this.lastToolUse = null;
333
+ /**
334
+ * tool_use id of the last confirm box raised from the screen. The CLI repaints the box on
335
+ * every keystroke, so without this a redraw arriving between the answer and its
336
+ * tool_result re-raises the same card the user just dismissed.
337
+ */
338
+ this.confirmRaisedFor = null;
311
339
  /**
312
340
  * Raw capture window for echo verification. The rolling tail deliberately drops lines
313
341
  * with fewer than three letters as spinner noise, which also swallows the echo of a
@@ -1420,25 +1448,33 @@ export class PtyQuery {
1420
1448
  if (!block || typeof block !== "object")
1421
1449
  continue;
1422
1450
  const b = block;
1423
- if (message.type === "assistant" &&
1424
- b.type === "tool_use" &&
1425
- b.id &&
1426
- (b.name === "AskUserQuestion" || b.name === "ExitPlanMode")) {
1427
- this.pendingDialog = {
1428
- toolUseId: b.id,
1429
- name: b.name,
1430
- input: isRecord(b.input) ? b.input : {},
1431
- options: extractDialogOptions(b.name, b.input),
1432
- optionsByQuestion: extractDialogOptionsByQuestion(b.name, b.input),
1433
- };
1434
- this.recordLine(`--- interactive dialog pending: ${b.name} ---`);
1435
- this.notifyDialogChange();
1451
+ if (message.type === "assistant" && b.type === "tool_use" && b.id && b.name) {
1452
+ // Remember EVERY tool_use, not just the two dialog-shaped ones. When the CLI
1453
+ // decides to gate one behind a confirmation box, the box names no tool, so this is
1454
+ // the only record of what is being approved.
1455
+ const input = isRecord(b.input) ? b.input : {};
1456
+ this.lastToolUse = { id: b.id, name: b.name, input };
1457
+ if (b.name === "AskUserQuestion" || b.name === "ExitPlanMode") {
1458
+ this.pendingDialog = {
1459
+ toolUseId: b.id,
1460
+ name: b.name,
1461
+ input,
1462
+ options: extractDialogOptions(b.name, b.input),
1463
+ optionsByQuestion: extractDialogOptionsByQuestion(b.name, b.input),
1464
+ };
1465
+ this.recordLine(`--- interactive dialog pending: ${b.name} ---`);
1466
+ this.notifyDialogChange();
1467
+ }
1436
1468
  }
1437
- const pending = this.pendingDialog;
1438
- if (pending && b.type === "tool_result" && b.tool_use_id === pending.toolUseId) {
1439
- this.recordLine(`--- interactive dialog answered: ${pending.name} ---`);
1440
- this.pendingDialog = null;
1441
- this.notifyDialogChange();
1469
+ if (b.type === "tool_result" && b.tool_use_id) {
1470
+ if (this.lastToolUse?.id === b.tool_use_id)
1471
+ this.lastToolUse = null;
1472
+ const pending = this.pendingDialog;
1473
+ if (pending && b.tool_use_id === pending.toolUseId) {
1474
+ this.recordLine(`--- interactive dialog answered: ${pending.name} ---`);
1475
+ this.pendingDialog = null;
1476
+ this.notifyDialogChange();
1477
+ }
1442
1478
  }
1443
1479
  }
1444
1480
  }
@@ -1596,6 +1632,50 @@ export class PtyQuery {
1596
1632
  return false;
1597
1633
  });
1598
1634
  }
1635
+ /**
1636
+ * A CLI confirmation box is on screen. Pair it with the tool_use it is gating and raise
1637
+ * the same dialog the transcript path raises, so the app gets a card and the three
1638
+ * protections listed on {@link trackInteractiveDialog} switch on: the stall backstop
1639
+ * stands down, no ESC is sent behind the user's back, and a reply becomes keystrokes.
1640
+ *
1641
+ * Without this the box was invisible to every one of those. A recording from 2026-08-22
1642
+ * (`f30cef74`) shows the guard drawn at 16:44:02 and `STALLED after 600000ms` at
1643
+ * 16:54:02: the agent sat dead for ten minutes waiting on a question nobody was shown.
1644
+ */
1645
+ raiseConfirmDialog() {
1646
+ const tool = this.lastToolUse;
1647
+ if (!tool || this.pendingDialog || this.confirmRaisedFor === tool.id)
1648
+ return;
1649
+ this.confirmRaisedFor = tool.id;
1650
+ this.pendingDialog = {
1651
+ toolUseId: tool.id,
1652
+ name: tool.name,
1653
+ confirm: true,
1654
+ input: tool.input,
1655
+ // Left empty on purpose: see PtyInteractiveDialog.confirm. Number-only, like plan.
1656
+ options: [],
1657
+ optionsByQuestion: [],
1658
+ };
1659
+ this.recordLine(`--- interactive dialog pending: ${tool.name} (CLI confirm) ---`);
1660
+ this.notifyDialogChange();
1661
+ }
1662
+ /**
1663
+ * Decline the pending confirm box. Esc rather than selecting the last option: the CLI
1664
+ * treats Esc as a decline (the behaviour that made stray interrupts read as "User
1665
+ * declined"), and it does not depend on how many options this CLI version offers, which
1666
+ * is 2 for the dangerous-command guard and 3 for an ordinary tool approval.
1667
+ */
1668
+ async declineDialog() {
1669
+ if (!this.pendingDialog)
1670
+ return false;
1671
+ this.recordLine(`--- declining ${this.pendingDialog.name} with Esc ---`);
1672
+ await this.transport.writeRaw?.("\u001b");
1673
+ const deadline = monotonicNowMs() + DIALOG_ANSWER_CONFIRM_MS;
1674
+ while (this.pendingDialog && !this.done && monotonicNowMs() < deadline) {
1675
+ await delay(250);
1676
+ }
1677
+ return !this.pendingDialog;
1678
+ }
1599
1679
  looksIdle() {
1600
1680
  const tail = this.terminalTail.slice(-400).toLowerCase();
1601
1681
  if (!tail)
@@ -1638,6 +1718,10 @@ export class PtyQuery {
1638
1718
  if (line.toLowerCase().includes(RESUME_DIALOG_MARKER)) {
1639
1719
  this.resumeDialogAt = monotonicNowMs();
1640
1720
  }
1721
+ const squashed = line.toLowerCase().replace(/\s+/g, "");
1722
+ if (CONFIRM_DIALOG_MARKERS.some((marker) => squashed.includes(marker))) {
1723
+ this.raiseConfirmDialog();
1724
+ }
1641
1725
  this.recordLine(line);
1642
1726
  }
1643
1727
  if (this.terminalTail.length > TERMINAL_TAIL_MAX_CHARS) {
@@ -849,7 +849,7 @@ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{v
849
849
  __d(function(g,r,i,a,m,e,d){"use strict";var t=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.shouldAppendSitemap=u,e.shouldAppendNotFound=s,e.getRootStackRouteNames=function(){const t=[n.INTERNAL_SLOT_NAME];s()&&t.push(n.NOT_FOUND_ROUTE_NAME);u()&&t.push(n.SITEMAP_ROUTE_NAME);return t};const o=t(r(d[0])),n=r(d[1]);function u(){const t=o.default.expoConfig?.extra?.router;return!1!==t?.sitemap}function s(){const t=o.default.expoConfig?.extra?.router;return!1!==t?.notFound}},717,[718,721]);
850
850
  __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}),Object.defineProperty(_e,"default",{enumerable:!0,get:function(){return N}}),Object.defineProperty(_e,"AppOwnership",{enumerable:!0,get:function(){return l.AppOwnership}}),Object.defineProperty(_e,"ExecutionEnvironment",{enumerable:!0,get:function(){return l.ExecutionEnvironment}}),Object.defineProperty(_e,"UserInterfaceIdiom",{enumerable:!0,get:function(){return l.UserInterfaceIdiom}});var n=e(r(d[0])),t=r(d[1]);r(d[2]);var u=e(r(d[3])),l=r(d[4]),o=e(r(d[5]));o.default||console.warn("No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?");const s=(0,t.requireOptionalNativeModule)('ExpoUpdates');let f=null;if(s){let e;s.manifest?e=s.manifest:s.manifestString&&(e=JSON.parse(s.manifestString)),e&&Object.keys(e).length>0&&(f=e)}let c=null;if(u.default.EXDevLauncher){let e;u.default.EXDevLauncher.manifestString&&(e=JSON.parse(u.default.EXDevLauncher.manifestString)),e&&Object.keys(e).length>0&&(c=e)}let p=null;if(o.default&&o.default.manifest){const e=o.default.manifest;p='string'==typeof e?JSON.parse(e):e}let b=f??c??p;const E=o.default||{},{appOwnership:O}=E,x=(0,n.default)(E,["name","appOwnership"]),v=Object.assign({},x,{appOwnership:O??null});function _(e){return!h(e)}function h(e){return'metadata'in e}function S(e=!1){if(!b){const e=null===b?'null':'undefined';if(x.executionEnvironment,l.ExecutionEnvironment.Bare,x.executionEnvironment===l.ExecutionEnvironment.StoreClient||x.executionEnvironment===l.ExecutionEnvironment.Standalone)throw new t.CodedError('ERR_CONSTANTS_MANIFEST_UNAVAILABLE',`Constants.manifest is ${e}, must be an object.`)}return b}Object.defineProperties(v,{__unsafeNoWarnManifest:{get(){const e=S(!0);return e&&_(e)?e:null},enumerable:!1},__unsafeNoWarnManifest2:{get(){const e=S(!0);return e&&h(e)?e:null},enumerable:!1},manifest:{get(){const e=S();return e&&_(e)?e:null},enumerable:!0},manifest2:{get(){const e=S();return e&&h(e)?e:null},enumerable:!0},expoConfig:{get(){const e=S(!0);return e?s&&s.isEmbeddedLaunch?p:h(e)?e.extra?.expoClient??null:_(e)?e:null:null},enumerable:!0},expoGoConfig:{get(){const e=S(!0);return e?h(e)?e.extra?.expoGo??null:_(e)?e:null:null},enumerable:!0},easConfig:{get(){const e=S(!0);return e?h(e)?e.extra?.eas??null:_(e)?e:null:null},enumerable:!0},__rawManifest_TEST:{get:()=>b,set(e){b=e},enumerable:!1}});var N=v},718,[35,4,25,637,719,720]);
851
851
  __d(function(g,r,i,a,m,e,d){"use strict";var t,n,o;Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"AppOwnership",{enumerable:!0,get:function(){return t}}),Object.defineProperty(e,"ExecutionEnvironment",{enumerable:!0,get:function(){return n}}),Object.defineProperty(e,"UserInterfaceIdiom",{enumerable:!0,get:function(){return o}}),(function(t){t.Expo="expo"})(t||(t={})),(function(t){t.Bare="bare",t.Standalone="standalone",t.StoreClient="storeClient"})(n||(n={})),(function(t){t.Handset="handset",t.Tablet="tablet",t.Desktop="desktop",t.TV="tv",t.Unsupported="unsupported"})(o||(o={}))},719,[]);
852
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return s}});var t=r(d[0]);const n=(Date.now()+'-'+Math.floor(1e9*Math.random())).toString();function o(){if('undefined'!=typeof navigator&&'string'==typeof navigator.userAgent){const t=navigator.userAgent.toLowerCase();if(t.includes('edge'))return'Edge';if(t.includes('edg'))return'Chromium Edge';if(t.includes('opr')&&'opr'in window&&window.opr)return'Opera';if(t.includes('chrome')&&'chrome'in window&&window.chrome)return'Chrome';if(t.includes('trident'))return'IE';if(t.includes('firefox'))return'Firefox';if(t.includes('safari'))return'Safari'}}var s={get appOwnership(){return null},get executionEnvironment(){return t.ExecutionEnvironment.Bare},get sessionId(){return n},get isHeadless(){return'undefined'==typeof navigator||/\bHeadlessChrome\//.test(navigator.userAgent)},get expoVersion(){return this.manifest.sdkVersion||null},get linkingUri(){return'undefined'!=typeof location?location.origin:''},get expoRuntimeVersion(){return this.expoVersion},get deviceName(){return o()},get systemFonts(){return[]},get statusBarHeight(){return 0},get deviceYearClass(){return null},get manifest(){return"{\"name\":\"Paseo\",\"slug\":\"paseo-hyperdrive\",\"version\":\"0.3.112\",\"orientation\":\"portrait\",\"icon\":\"./assets/images/icon.png\",\"scheme\":\"paseo\",\"userInterfaceStyle\":\"automatic\",\"newArchEnabled\":true,\"web\":{\"output\":\"single\",\"favicon\":\"./assets/images/favicon.png\",\"shortName\":\"Paseo\",\"orientation\":\"portrait\",\"name\":\"Paseo\"},\"autolinking\":{\"searchPaths\":[\"../../node_modules\",\"./node_modules\"]},\"experiments\":{\"typedRoutes\":true,\"reactCompiler\":true,\"autolinkingModuleResolution\":true},\"extra\":{\"router\":{},\"eas\":{\"build\":{\"experimental\":{\"ios\":{\"appExtensions\":[{\"bundleIdentifier\":\"bot.hyperdrive.paseo.AgentActivity\",\"targetName\":\"AgentActivity\"}]}}}}},\"sdkVersion\":\"54.0.0\",\"platforms\":[\"ios\",\"android\",\"web\"]}"},get manifest2(){return null},get experienceUrl(){return'undefined'!=typeof location?location.origin:''},get debugMode(){return!1},getWebViewUserAgentAsync:async()=>'undefined'!=typeof navigator?navigator.userAgent:null}},720,[719]);
852
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return s}});var t=r(d[0]);const n=(Date.now()+'-'+Math.floor(1e9*Math.random())).toString();function o(){if('undefined'!=typeof navigator&&'string'==typeof navigator.userAgent){const t=navigator.userAgent.toLowerCase();if(t.includes('edge'))return'Edge';if(t.includes('edg'))return'Chromium Edge';if(t.includes('opr')&&'opr'in window&&window.opr)return'Opera';if(t.includes('chrome')&&'chrome'in window&&window.chrome)return'Chrome';if(t.includes('trident'))return'IE';if(t.includes('firefox'))return'Firefox';if(t.includes('safari'))return'Safari'}}var s={get appOwnership(){return null},get executionEnvironment(){return t.ExecutionEnvironment.Bare},get sessionId(){return n},get isHeadless(){return'undefined'==typeof navigator||/\bHeadlessChrome\//.test(navigator.userAgent)},get expoVersion(){return this.manifest.sdkVersion||null},get linkingUri(){return'undefined'!=typeof location?location.origin:''},get expoRuntimeVersion(){return this.expoVersion},get deviceName(){return o()},get systemFonts(){return[]},get statusBarHeight(){return 0},get deviceYearClass(){return null},get manifest(){return"{\"name\":\"Paseo\",\"slug\":\"paseo-hyperdrive\",\"version\":\"0.3.113\",\"orientation\":\"portrait\",\"icon\":\"./assets/images/icon.png\",\"scheme\":\"paseo\",\"userInterfaceStyle\":\"automatic\",\"newArchEnabled\":true,\"web\":{\"output\":\"single\",\"favicon\":\"./assets/images/favicon.png\",\"shortName\":\"Paseo\",\"orientation\":\"portrait\",\"name\":\"Paseo\"},\"autolinking\":{\"searchPaths\":[\"../../node_modules\",\"./node_modules\"]},\"experiments\":{\"typedRoutes\":true,\"reactCompiler\":true,\"autolinkingModuleResolution\":true},\"extra\":{\"router\":{},\"eas\":{\"build\":{\"experimental\":{\"ios\":{\"appExtensions\":[{\"bundleIdentifier\":\"bot.hyperdrive.paseo.AgentActivity\",\"targetName\":\"AgentActivity\"}]}}}}},\"sdkVersion\":\"54.0.0\",\"platforms\":[\"ios\",\"android\",\"web\"]}"},get manifest2(){return null},get experienceUrl(){return'undefined'!=typeof location?location.origin:''},get debugMode(){return!1},getWebViewUserAgentAsync:async()=>'undefined'!=typeof navigator?navigator.userAgent:null}},720,[719]);
853
853
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.SITEMAP_ROUTE_NAME=e.NOT_FOUND_ROUTE_NAME=e.INTERNAL_SLOT_NAME=void 0,e.INTERNAL_SLOT_NAME='__root',e.NOT_FOUND_ROUTE_NAME='+not-found',e.SITEMAP_ROUTE_NAME='_sitemap'},721,[]);
854
854
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.resolveHref=void 0,e.resolveHrefStringWithSegments=function(t,{segments:n=[],params:s={}}={},{relativeToDirectory:o}={}){if(t.startsWith('.')){let c=n?.map(t=>{if(!t.startsWith('['))return t;if(t.startsWith('[...')){t=t.slice(4,-1);const n=s[t];return Array.isArray(n)?n.join('/'):n?.split(',')?.join('/')??''}return t=t.slice(1,-1),s[t]}).filter(Boolean).join('/')??'/';o&&(c=`${c}/`);const f=new URL(t,`http://hostname/${c}`);t=`${f.pathname}${f.search}`}return t};function t(t,s){for(const[o,c=""]of Object.entries(s)){const f=`[${o}]`,l=`[...${o}]`;if(t.includes(f))t=t.replace(f,n(c));else{if(!t.includes(l))continue;t=t.replace(l,n(c))}delete s[o]}return{pathname:t,params:s}}function n(t){return Array.isArray(t)?t.map(t=>n(t)).join('/'):encodeURIComponent(t.toString())}function s(t){return Object.entries(t).filter(([,t])=>null!=t).map(([t,n])=>`${t}=${encodeURIComponent(n.toString())}`).join('&')}e.resolveHref=n=>{if('string'==typeof n)return(0,e.resolveHref)({pathname:n});const o=n.pathname??'';if(!n?.params)return o;const{pathname:c,params:f}=t(o,Object.assign({},n.params)),l=s(f);return c+(l?`?${l}`:'')}},722,[]);
855
855
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.isRoutePreloadedInStack=function(t,o){if(!t||'stack'!==t.type)return!1;return t.preloadedRoutes.some(t=>t.key===o.key)}},723,[]);
@@ -15057,7 +15057,7 @@ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{v
15057
15057
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"decodeOfferFragmentPayload",{enumerable:!0,get:function(){return n.decodeOfferFragmentPayload}}),Object.defineProperty(e,"buildDaemonWebSocketUrl",{enumerable:!0,get:function(){return t.buildDaemonWebSocketUrl}}),Object.defineProperty(e,"deriveLabelFromEndpoint",{enumerable:!0,get:function(){return t.deriveLabelFromEndpoint}}),Object.defineProperty(e,"extractHostPortFromWebSocketUrl",{enumerable:!0,get:function(){return t.extractHostPortFromWebSocketUrl}}),Object.defineProperty(e,"normalizeHostPort",{enumerable:!0,get:function(){return t.normalizeHostPort}}),Object.defineProperty(e,"parseConnectionUri",{enumerable:!0,get:function(){return t.parseConnectionUri}}),Object.defineProperty(e,"parseHostPort",{enumerable:!0,get:function(){return t.parseHostPort}}),Object.defineProperty(e,"serializeConnectionUri",{enumerable:!0,get:function(){return t.serializeConnectionUri}}),Object.defineProperty(e,"serializeConnectionUriForStorage",{enumerable:!0,get:function(){return t.serializeConnectionUriForStorage}}),Object.defineProperty(e,"shouldUseTlsForDefaultHostedRelay",{enumerable:!0,get:function(){return t.shouldUseTlsForDefaultHostedRelay}}),e.buildRelayWebSocketUrl=function(n){return(0,t.buildRelayWebSocketUrl)(Object.assign({},n,{role:"client"}))};var t=r(d[0]),n=r(d[1])},3412,[3392,3413]);
15058
15058
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"ConnectionOfferV2Schema",{enumerable:!0,get:function(){return t}}),Object.defineProperty(e,"ConnectionOfferSchema",{enumerable:!0,get:function(){return o}}),e.decodeOfferFragmentPayload=l,e.parseConnectionOfferFromUrl=function(n){const t=f(n);if(!t)return null;const c=l(t);return o.parse(c)};var n=r(d[0]);const t=n.z.object({v:n.z.literal(2),serverId:n.z.string().min(1),daemonPublicKeyB64:n.z.string().min(1),relay:n.z.object({endpoint:n.z.string().min(1),useTls:n.z.boolean().optional()})}),o=t;function c(n){const t=n.replace(/-/g,"+").replace(/_/g,"/"),o=t.padEnd(t.length+(4-t.length%4)%4,"="),c=globalThis.atob(o),l=Uint8Array.from(c,n=>n.charCodeAt(0));return new TextDecoder("utf-8",{fatal:!0}).decode(l)}function l(n){const t=c(n);return JSON.parse(t)}const u="#offer=";function f(n){const t=n.trim();if(!t)return null;const o=t.indexOf(u);if(-1===o)return null;const c=t.slice(o+u.length).trim();return c.length>0?c:null}},3413,[3285]);
15059
15059
  __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}},3414,[718,3415]);
15060
- __d(function(e,t,r,a,i,o,n){i.exports={name:"@hyperdrive.bot/fleet-app",version:"0.3.112",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","build:terminal-webview":"node ./scripts/build-terminal-webview-html.mjs","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 --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 --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='Desktop Chrome'","test:e2e:real":"cross-env E2E_FORK_PASEO_HOME_FROM=../../.dev/paseo-home playwright test --project=real-provider","test:e2e:ui":"playwright test --ui","test:coverage":"vitest run --project unit --coverage",build:"npm run build:web","build:web":"npm --prefix ../.. run build:app-deps && expo export --platform web --source-maps","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"},dependencies:{"@bacons/apple-targets":"4.0.6","@datadog/browser-rum":"^6.23.0","@datadog/browser-rum-react":"^6.23.0","@datadog/mobile-react-native":"^2.7.0","@datadog/mobile-react-native-session-replay":"^2.14.8","@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@expo/image-utils":"0.8.8","@expo/plist":"0.4.9","@expo/prebuild-config":"54.0.8","@floating-ui/react-native":"^0.10.7","@gorhom/bottom-sheet":"^5.2.14","@gorhom/portal":"^1.0.14","@hyperdrive.bot/fleet-client":"*","@hyperdrive.bot/fleet-expo-two-way-audio":"*","@hyperdrive.bot/fleet-extension-sdk":"*","@hyperdrive.bot/fleet-highlight":"*","@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","@sentry/electron":"^6.11.0","@sentry/react-native":"^6.20.0","@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-background-fetch":"~14.0.9","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-speech":"~14.0.8","expo-speech-recognition":"^56.0.1","expo-splash-screen":"~31.0.10","expo-system-ui":"~6.0.7","expo-task-manager":"~14.0.9","expo-video":"~3.0.16","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","mnemonic-id":"^3.2.7",qrcode:"^1.5.4",react:"19.1.0","react-dom":"19.1.0","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.7","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","use-sync-external-store":"^1.6.0",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/chai":"^5.2.2","@types/markdown-it":"^14.1.2","@types/qrcode":"^1.5.6","@types/react":"~19.2.0","@types/ws":"^8.18.1","@vitest/browser":"^4.1.7","@vitest/browser-playwright":"^4.1.7","@vitest/coverage-v8":"^4.1.7","@xterm/headless":"^6.1.0-beta.213",dotenv:"^17.2.3",eslint:"^9.25.0","eslint-config-expo":"~10.0.0",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"}}},3415,[]);
15060
+ __d(function(e,t,r,a,i,o,n){i.exports={name:"@hyperdrive.bot/fleet-app",version:"0.3.113",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","build:terminal-webview":"node ./scripts/build-terminal-webview-html.mjs","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 --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 --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='Desktop Chrome'","test:e2e:real":"cross-env E2E_FORK_PASEO_HOME_FROM=../../.dev/paseo-home playwright test --project=real-provider","test:e2e:ui":"playwright test --ui","test:coverage":"vitest run --project unit --coverage",build:"npm run build:web","build:web":"npm --prefix ../.. run build:app-deps && expo export --platform web --source-maps","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"},dependencies:{"@bacons/apple-targets":"4.0.6","@datadog/browser-rum":"^6.23.0","@datadog/browser-rum-react":"^6.23.0","@datadog/mobile-react-native":"^2.7.0","@datadog/mobile-react-native-session-replay":"^2.14.8","@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@expo/image-utils":"0.8.8","@expo/plist":"0.4.9","@expo/prebuild-config":"54.0.8","@floating-ui/react-native":"^0.10.7","@gorhom/bottom-sheet":"^5.2.14","@gorhom/portal":"^1.0.14","@hyperdrive.bot/fleet-client":"*","@hyperdrive.bot/fleet-expo-two-way-audio":"*","@hyperdrive.bot/fleet-extension-sdk":"*","@hyperdrive.bot/fleet-highlight":"*","@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","@sentry/electron":"^6.11.0","@sentry/react-native":"^6.20.0","@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-background-fetch":"~14.0.9","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-speech":"~14.0.8","expo-speech-recognition":"^56.0.1","expo-splash-screen":"~31.0.10","expo-system-ui":"~6.0.7","expo-task-manager":"~14.0.9","expo-video":"~3.0.16","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","mnemonic-id":"^3.2.7",qrcode:"^1.5.4",react:"19.1.0","react-dom":"19.1.0","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.7","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","use-sync-external-store":"^1.6.0",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/chai":"^5.2.2","@types/markdown-it":"^14.1.2","@types/qrcode":"^1.5.6","@types/react":"~19.2.0","@types/ws":"^8.18.1","@vitest/browser":"^4.1.7","@vitest/browser-playwright":"^4.1.7","@vitest/coverage-v8":"^4.1.7","@xterm/headless":"^6.1.0-beta.213",dotenv:"^17.2.3",eslint:"^9.25.0","eslint-config-expo":"~10.0.0",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"}}},3415,[]);
15061
15061
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.shouldUseDesktopDaemon=function(){return(0,n.isElectronRuntime)()},e.getDesktopDaemonStatus=async function(){return c(await(0,t.invokeDesktopCommand)("desktop_daemon_status"))},e.startDesktopDaemon=async function(){return c(await(0,t.invokeDesktopCommand)("start_desktop_daemon"))},e.stopDesktopDaemon=async function(n="manual_ipc"){return c(await(0,t.invokeDesktopCommand)("stop_desktop_daemon",{reason:n}))},e.restartDesktopDaemon=async function(){return c(await(0,t.invokeDesktopCommand)("restart_desktop_daemon"))},e.getDesktopDaemonLogs=async function(){return p(await(0,t.invokeDesktopCommand)("desktop_daemon_logs"))},e.getDesktopDaemonPairing=async function(){return k(await(0,t.invokeDesktopCommand)("desktop_daemon_pairing"))},e.getCliDaemonStatus=async function(){const n=await(0,t.invokeDesktopCommand)("cli_daemon_status");if("string"!=typeof n)throw new Error("Unexpected CLI daemon status response.");return n},e.listenToLocalTransportEvents=async function(t){const u=(0,n.getDesktopHost)()?.events?.on;if("function"!=typeof u)throw new Error("Desktop events API is unavailable.");const c=await u("local-daemon-transport-event",n=>{o(n)&&t({sessionId:s(n.sessionId)??"",kind:s(n.kind)??"error",text:s(n.text),binaryBase64:s(n.binaryBase64),code:l(n.code),reason:s(n.reason),error:s(n.error)})});return"function"==typeof c?c:()=>{}},e.openLocalTransportSession=async function(n){const o=await(0,t.invokeDesktopCommand)("open_local_daemon_transport",n);if("string"!=typeof o||0===o.trim().length)throw new Error("Unexpected local transport session response.");return o},e.sendLocalTransportMessage=async function(n){await(0,t.invokeDesktopCommand)("send_local_daemon_transport_message",Object.assign({sessionId:n.sessionId},n.text?{text:n.text}:{},n.binaryBase64?{binaryBase64:n.binaryBase64}:{}))},e.closeLocalTransportSession=async function(n){await(0,t.invokeDesktopCommand)("close_local_daemon_transport",{sessionId:n})},e.getCliInstallStatus=async function(){return f(await(0,t.invokeDesktopCommand)("get_cli_install_status"))},e.installCli=async function(){return f(await(0,t.invokeDesktopCommand)("install_cli"))},e.getSkillsStatus=async function(){return y(await(0,t.invokeDesktopCommand)("get_skills_status"))},e.installSkills=async function(){return y(await(0,t.invokeDesktopCommand)("install_skills"))},e.updateSkills=async function(){return y(await(0,t.invokeDesktopCommand)("update_skills"))},e.uninstallSkills=async function(){return y(await(0,t.invokeDesktopCommand)("uninstall_skills"))};var n=r(d[0]),t=r(d[1]);function o(n){return"object"==typeof n&&null!==n}function s(n){return"string"==typeof n&&n.trim().length>0?n:null}function l(n){return"number"==typeof n&&Number.isFinite(n)?n:null}function u(n){const t=s(n)?.toLowerCase();switch(t){case"starting":return"starting";case"running":return"running";case"errored":case"error":return"errored";default:return"stopped"}}function c(n){if(!o(n))throw new Error("Unexpected desktop daemon status response.");return{serverId:s(n.serverId)??"",status:u(n.status),listen:s(n.listen),hostname:s(n.hostname),pid:l(n.pid),home:s(n.home)??"",version:s(n.version),desktopManaged:!0===n.desktopManaged,error:s(n.error)}}function p(n){if(!o(n))throw new Error("Unexpected desktop daemon logs response.");return{logPath:s(n.logPath)??"",contents:"string"==typeof n.contents?n.contents:""}}function k(n){if(!o(n))throw new Error("Unexpected desktop daemon pairing response.");return{relayEnabled:!0===n.relayEnabled,url:s(n.url),qr:s(n.qr)}}function f(n){if(!o(n))throw new Error("Unexpected install status response.");return{installed:!0===n.installed}}function w(n){switch(n){case"not-installed":case"up-to-date":case"drift":return n;default:throw new Error(`Unexpected skills status state: ${String(n)}`)}}function _(n){if(!o(n))throw new Error("Unexpected skill op response.");const t=s(n.name);if(!t)throw new Error("Skill op missing name.");switch(n.kind){case"add":return{kind:"add",name:t};case"update":return{kind:"update",name:t};case"delete":return{kind:"delete",name:t};default:throw new Error(`Unexpected skill op kind: ${String(n.kind)}`)}}function y(n){if(!o(n))throw new Error("Unexpected skills status response.");const t=Array.isArray(n.ops)?n.ops.map(_):[];return{state:w(n.state),ops:t}}},3416,[3417,3419]);
15062
15062
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.getDesktopHost=n,e.isElectronRuntime=o,e.isElectronRuntimeMac=function(){if(!o())return!1;if("undefined"==typeof navigator)return!1;const t=n()?.platform?.toLowerCase();if("darwin"===t||"mac"===t||"macos"===t)return!0;const u=navigator.userAgent;return u.includes("Mac OS")||u.includes("Macintosh")},r(d[0]);var t=r(d[1]);function n(){return(0,t.getElectronHost)()}function o(){return null!==n()}},3417,[25,3418]);
15063
15063
  __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.getElectronHost=function(){if("undefined"==typeof window)return null;const t=window.paseoDesktop;if(!t||"object"!=typeof t)return null;return t}},3418,[]);
@@ -16693,5 +16693,5 @@ __d(function(g,r,_i,a,_m,_e,d){"use strict";var e,t=r(d[0]),n=this&&this.__creat
16693
16693
  __r(694);
16694
16694
  __r(341);
16695
16695
  __r(0);
16696
- //# sourceMappingURL=/_expo/static/js/web/index-f0af96232964666b628f584f6787e6ed.js.map
16697
- //# debugId=91b6cd2b-9d37-4c1f-8843-d8b513ded0d0
16696
+ //# sourceMappingURL=/_expo/static/js/web/index-b33889b85e0a8825e23526bfc802ee7e.js.map
16697
+ //# debugId=ce995c89-4d8b-4dc5-989b-323e2bba4b33
@@ -191,6 +191,6 @@
191
191
  <body>
192
192
  <noscript>You need to enable JavaScript to run this app.</noscript>
193
193
  <div id="root"></div>
194
- <script src="/_expo/static/js/web/index-f0af96232964666b628f584f6787e6ed.js" defer></script>
194
+ <script src="/_expo/static/js/web/index-b33889b85e0a8825e23526bfc802ee7e.js" defer></script>
195
195
  </body>
196
196
  </html>
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperdrive.bot/fleet-server",
3
- "version": "0.3.112",
3
+ "version": "0.3.113",
4
4
  "description": "Paseo backend server",
5
5
  "license": "Apache-2.0",
6
6
  "files": [
@@ -66,11 +66,11 @@
66
66
  "@agentclientprotocol/sdk": "^0.17.1",
67
67
  "@anthropic-ai/claude-agent-sdk": "^0.3.195",
68
68
  "@anthropic-ai/sdk": "^0.104.2",
69
- "@hyperdrive.bot/fleet-client": "0.3.112",
70
- "@hyperdrive.bot/fleet-extension-sdk": "0.3.112",
71
- "@hyperdrive.bot/fleet-highlight": "0.3.112",
72
- "@hyperdrive.bot/fleet-protocol": "0.3.112",
73
- "@hyperdrive.bot/fleet-relay": "0.3.112",
69
+ "@hyperdrive.bot/fleet-client": "0.3.113",
70
+ "@hyperdrive.bot/fleet-extension-sdk": "0.3.113",
71
+ "@hyperdrive.bot/fleet-highlight": "0.3.113",
72
+ "@hyperdrive.bot/fleet-protocol": "0.3.113",
73
+ "@hyperdrive.bot/fleet-relay": "0.3.113",
74
74
  "@isaacs/ttlcache": "^2.1.4",
75
75
  "@modelcontextprotocol/sdk": "^1.20.1",
76
76
  "@opencode-ai/sdk": "1.2.6",