@hyperdrive.bot/paseo-server 0.3.19 → 0.3.23
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.
- package/dist/server/server/agent/providers/claude/transport/pty-query.d.ts +32 -0
- package/dist/server/server/agent/providers/claude/transport/pty-query.js +239 -2
- package/dist/server/server/workspace/all-sessions-route.js +97 -17
- package/dist/server/web-ui/_expo/static/js/web/{index-16f1edcbe9fa1e0c322b20c78461f39d.js → index-47b07b144bbc651587bf14a2bf8bc9e4.js} +5 -5
- package/dist/server/web-ui/_expo/static/js/web/index-47b07b144bbc651587bf14a2bf8bc9e4.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-47b07b144bbc651587bf14a2bf8bc9e4.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-16f1edcbe9fa1e0c322b20c78461f39d.js.map.br → index-47b07b144bbc651587bf14a2bf8bc9e4.js.map.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-16f1edcbe9fa1e0c322b20c78461f39d.js.map.gz → index-47b07b144bbc651587bf14a2bf8bc9e4.js.map.gz} +0 -0
- package/dist/server/web-ui/index.html +1 -1
- package/dist/server/web-ui/index.html.br +0 -0
- package/dist/server/web-ui/index.html.gz +0 -0
- package/package.json +6 -6
- package/dist/server/web-ui/_expo/static/js/web/index-16f1edcbe9fa1e0c322b20c78461f39d.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-16f1edcbe9fa1e0c322b20c78461f39d.js.gz +0 -0
|
@@ -62,6 +62,8 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
62
62
|
private resumeDialogAt;
|
|
63
63
|
/** Set when the CLI rejected the just-submitted command; carries the CLI's own reply. */
|
|
64
64
|
private rejectedCommandNotice;
|
|
65
|
+
/** Interactive TUI dialog awaiting the user (AskUserQuestion / plan approval), if any. */
|
|
66
|
+
private pendingDialog;
|
|
65
67
|
/**
|
|
66
68
|
* Raw capture window for echo verification. The rolling tail deliberately drops lines
|
|
67
69
|
* with fewer than three letters as spinner noise, which also swallows the echo of a
|
|
@@ -89,6 +91,28 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
89
91
|
*/
|
|
90
92
|
/** The CLI refused the command; relay its own reply so the sender can correct and resend. */
|
|
91
93
|
private buildCommandRejectedResult;
|
|
94
|
+
/**
|
|
95
|
+
* Write each inline base64 image block to a temp file so the terminal agent can Read it
|
|
96
|
+
* by path. A staging failure is logged and skipped rather than thrown: the text part of
|
|
97
|
+
* the message (if any) must still be delivered.
|
|
98
|
+
*/
|
|
99
|
+
private stageInlineImages;
|
|
100
|
+
/**
|
|
101
|
+
* The message had no text and no stageable image, so there is literally nothing to type.
|
|
102
|
+
* Emitted instead of dropping the message, because the manager has already marked the
|
|
103
|
+
* agent running by the time the input loop sees it: silence here is a forever-spinner.
|
|
104
|
+
*/
|
|
105
|
+
private buildNothingDeliverableResult;
|
|
106
|
+
/**
|
|
107
|
+
* Try to answer the pending TUI dialog with the user's reply. A reply that names an
|
|
108
|
+
* option (its 1-based number or its label) becomes Down-arrow presses + Enter, the same
|
|
109
|
+
* proven mechanism as the resume-dialog answerer. Anything else gets the question echoed
|
|
110
|
+
* back with the options, and nothing is typed - an unanswerable message must never turn
|
|
111
|
+
* into a silent decline.
|
|
112
|
+
*/
|
|
113
|
+
private answerPendingDialog;
|
|
114
|
+
/** The agent is waiting on a dialog; tell the sender what it asks and how to answer. */
|
|
115
|
+
private buildDialogPendingResult;
|
|
92
116
|
private buildSubmitFailedResult;
|
|
93
117
|
/**
|
|
94
118
|
* Press Enter to submit the composed prompt, and CONFIRM the turn actually started by
|
|
@@ -141,6 +165,14 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
141
165
|
private sawUserLineSince;
|
|
142
166
|
private transcriptSize;
|
|
143
167
|
private onTranscriptMessage;
|
|
168
|
+
/**
|
|
169
|
+
* Track interactive TUI dialogs (AskUserQuestion / plan-mode approval) from the
|
|
170
|
+
* transcript. While one is pending the terminal is WAITING, not stalled: the stall
|
|
171
|
+
* backstop must stand down, no ESC may be sent (it declines the dialog - the source of
|
|
172
|
+
* every phantom "User declined" this week), and an incoming reply is translated to
|
|
173
|
+
* dialog keystrokes instead of typed text.
|
|
174
|
+
*/
|
|
175
|
+
private trackInteractiveDialog;
|
|
144
176
|
private scheduleTurnEndCheck;
|
|
145
177
|
private maybeCompleteTurn;
|
|
146
178
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
3
4
|
import * as path from "node:path";
|
|
4
5
|
import { TranscriptSdkReader } from "./transcript-sdk-reader.js";
|
|
5
6
|
/**
|
|
@@ -245,6 +246,8 @@ export class PtyQuery {
|
|
|
245
246
|
this.resumeDialogAt = 0;
|
|
246
247
|
/** Set when the CLI rejected the just-submitted command; carries the CLI's own reply. */
|
|
247
248
|
this.rejectedCommandNotice = null;
|
|
249
|
+
/** Interactive TUI dialog awaiting the user (AskUserQuestion / plan approval), if any. */
|
|
250
|
+
this.pendingDialog = null;
|
|
248
251
|
/**
|
|
249
252
|
* Raw capture window for echo verification. The rolling tail deliberately drops lines
|
|
250
253
|
* with fewer than three letters as spinner noise, which also swallows the echo of a
|
|
@@ -414,6 +417,7 @@ export class PtyQuery {
|
|
|
414
417
|
if (this.done)
|
|
415
418
|
return;
|
|
416
419
|
this.done = true;
|
|
420
|
+
this.pendingDialog = null;
|
|
417
421
|
this.cancelReadiness?.();
|
|
418
422
|
if (this.turnEndTimer)
|
|
419
423
|
clearTimeout(this.turnEndTimer);
|
|
@@ -444,9 +448,30 @@ export class PtyQuery {
|
|
|
444
448
|
for await (const userMessage of this.input) {
|
|
445
449
|
if (this.done)
|
|
446
450
|
break;
|
|
447
|
-
|
|
448
|
-
|
|
451
|
+
// Inline images cannot be typed into a terminal, but the CLI agent can Read a
|
|
452
|
+
// file: stage each image to disk and reference it by path, the same serialization
|
|
453
|
+
// job toSdkUserMessage does for the SDK path.
|
|
454
|
+
const imageRefs = this.stageInlineImages(userMessage)
|
|
455
|
+
.map((p) => `[Attached image: ${p}]`)
|
|
456
|
+
.join(" ");
|
|
457
|
+
const text = [extractUserText(userMessage), imageRefs].filter(Boolean).join(" ").trim();
|
|
458
|
+
if (!text) {
|
|
459
|
+
// An empty prompt used to be dropped silently right here, AFTER the manager had
|
|
460
|
+
// already flipped the agent to "running": the sender stared at a spinner forever
|
|
461
|
+
// (observed live 2026-08-04, an image-only message from a 0.3.10 app whose
|
|
462
|
+
// composer also stripped the attachment). Nothing-deliverable is an answerable
|
|
463
|
+
// outcome, so answer it.
|
|
464
|
+
this.recordLine("--- message had no deliverable content; notifying sender ---");
|
|
465
|
+
this.emit(this.buildNothingDeliverableResult());
|
|
449
466
|
continue;
|
|
467
|
+
}
|
|
468
|
+
if (this.pendingDialog) {
|
|
469
|
+
// The TUI is showing a question/plan dialog: typed text would be eaten by it and
|
|
470
|
+
// pre-typing ESC would decline it. Either answer it (a reply that names an
|
|
471
|
+
// option) or tell the sender what is being asked - never type across it.
|
|
472
|
+
await this.answerPendingDialog(text);
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
450
475
|
this.turnStartedAt = monotonicNowMs();
|
|
451
476
|
// Clear modals BEFORE typing, not after: text typed into either dialog is
|
|
452
477
|
// consumed by it, so recovering at submit time is already too late.
|
|
@@ -526,6 +551,116 @@ export class PtyQuery {
|
|
|
526
551
|
errors: [`The agent's CLI rejected the command: ${notice} Nothing was run.`],
|
|
527
552
|
};
|
|
528
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* Write each inline base64 image block to a temp file so the terminal agent can Read it
|
|
556
|
+
* by path. A staging failure is logged and skipped rather than thrown: the text part of
|
|
557
|
+
* the message (if any) must still be delivered.
|
|
558
|
+
*/
|
|
559
|
+
stageInlineImages(message) {
|
|
560
|
+
const content = message.message?.content;
|
|
561
|
+
if (!Array.isArray(content))
|
|
562
|
+
return [];
|
|
563
|
+
const staged = [];
|
|
564
|
+
for (const block of content) {
|
|
565
|
+
if (!block || typeof block !== "object")
|
|
566
|
+
continue;
|
|
567
|
+
const image = block;
|
|
568
|
+
if (image.type !== "image")
|
|
569
|
+
continue;
|
|
570
|
+
const source = image.source;
|
|
571
|
+
if (!source || source.type !== "base64" || !source.data)
|
|
572
|
+
continue;
|
|
573
|
+
try {
|
|
574
|
+
const dir = path.join(os.tmpdir(), "paseo-pty-images", this.sessionId);
|
|
575
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
576
|
+
const ext = IMAGE_MEDIA_TYPE_EXT[source.media_type ?? ""] ?? "png";
|
|
577
|
+
const file = path.join(dir, `image-${randomUUID().slice(0, 8)}.${ext}`);
|
|
578
|
+
fs.writeFileSync(file, Buffer.from(source.data, "base64"));
|
|
579
|
+
staged.push(file);
|
|
580
|
+
}
|
|
581
|
+
catch (err) {
|
|
582
|
+
this.logger.warn({ err }, "PtyQuery: failed to stage an inline image for delivery");
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return staged;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* The message had no text and no stageable image, so there is literally nothing to type.
|
|
589
|
+
* Emitted instead of dropping the message, because the manager has already marked the
|
|
590
|
+
* agent running by the time the input loop sees it: silence here is a forever-spinner.
|
|
591
|
+
*/
|
|
592
|
+
buildNothingDeliverableResult() {
|
|
593
|
+
const base = this.buildResult("submit_failed");
|
|
594
|
+
return {
|
|
595
|
+
...base,
|
|
596
|
+
subtype: "error_during_execution",
|
|
597
|
+
is_error: true,
|
|
598
|
+
errors: [
|
|
599
|
+
`Your message had nothing the terminal transport could deliver: no text, and no ` +
|
|
600
|
+
`image it could stage to disk. Nothing was sent, so please resend it with text. ` +
|
|
601
|
+
`The session itself is still running.`,
|
|
602
|
+
],
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Try to answer the pending TUI dialog with the user's reply. A reply that names an
|
|
607
|
+
* option (its 1-based number or its label) becomes Down-arrow presses + Enter, the same
|
|
608
|
+
* proven mechanism as the resume-dialog answerer. Anything else gets the question echoed
|
|
609
|
+
* back with the options, and nothing is typed - an unanswerable message must never turn
|
|
610
|
+
* into a silent decline.
|
|
611
|
+
*/
|
|
612
|
+
async answerPendingDialog(text) {
|
|
613
|
+
const dialog = this.pendingDialog;
|
|
614
|
+
if (!dialog)
|
|
615
|
+
return;
|
|
616
|
+
const index = matchDialogOption(text, dialog.options);
|
|
617
|
+
if (index === null) {
|
|
618
|
+
this.recordLine(`--- reply does not name a ${dialog.name} option; echoing question ---`);
|
|
619
|
+
this.emit(this.buildDialogPendingResult(dialog));
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
this.recordLine(`--- answering ${dialog.name} with option ${index + 1} ---`);
|
|
623
|
+
for (let i = 0; i < index && !this.done; i++) {
|
|
624
|
+
await this.transport.writeRaw?.("\u001b[B");
|
|
625
|
+
await delay(DIALOG_KEY_DELAY_MS);
|
|
626
|
+
}
|
|
627
|
+
await this.transport.writeRaw?.("\r");
|
|
628
|
+
// Confirmation is the tool_result landing in the transcript (trackInteractiveDialog
|
|
629
|
+
// clears pendingDialog). Optimistic flags would record intent as fact.
|
|
630
|
+
const deadline = monotonicNowMs() + DIALOG_ANSWER_CONFIRM_MS;
|
|
631
|
+
while (this.pendingDialog && !this.done && monotonicNowMs() < deadline) {
|
|
632
|
+
await delay(250);
|
|
633
|
+
}
|
|
634
|
+
if (this.pendingDialog) {
|
|
635
|
+
this.recordLine(`--- ${dialog.name} answer did not register ---`);
|
|
636
|
+
this.emit(this.buildDialogPendingResult(dialog, true));
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
// Answer accepted: the turn is live again, restart the liveness clock.
|
|
640
|
+
this.turnStartedAt = monotonicNowMs();
|
|
641
|
+
this.turnInFlight = true;
|
|
642
|
+
this.armStallTimer();
|
|
643
|
+
this.startHeartbeat();
|
|
644
|
+
}
|
|
645
|
+
/** The agent is waiting on a dialog; tell the sender what it asks and how to answer. */
|
|
646
|
+
buildDialogPendingResult(dialog, answerFailed = false) {
|
|
647
|
+
const base = this.buildResult("submit_failed");
|
|
648
|
+
const optionLines = dialog.options.length > 0
|
|
649
|
+
? ` Options: ${dialog.options.map((o, i) => `${i + 1}) ${o}`).join(" ")}.`
|
|
650
|
+
: "";
|
|
651
|
+
const preamble = answerFailed
|
|
652
|
+
? `The answer keystrokes did not register in the terminal, so the dialog is still up.`
|
|
653
|
+
: `Your message was NOT delivered because the agent is showing a ${dialog.name === "ExitPlanMode" ? "plan-approval" : "question"} dialog and is waiting for an answer.`;
|
|
654
|
+
return {
|
|
655
|
+
...base,
|
|
656
|
+
subtype: "error_during_execution",
|
|
657
|
+
is_error: true,
|
|
658
|
+
errors: [
|
|
659
|
+
`${preamble}${optionLines} Reply with just the option number (or its exact text) ` +
|
|
660
|
+
`to answer it.`,
|
|
661
|
+
],
|
|
662
|
+
};
|
|
663
|
+
}
|
|
529
664
|
buildSubmitFailedResult() {
|
|
530
665
|
const base = this.buildResult("submit_failed");
|
|
531
666
|
const excerpt = this.terminalTail.slice(-TERMINAL_TAIL_EXCERPT_CHARS).trim();
|
|
@@ -565,6 +700,12 @@ export class PtyQuery {
|
|
|
565
700
|
async clearInterruptPrompt() {
|
|
566
701
|
if (!this.interruptPromptAt)
|
|
567
702
|
return;
|
|
703
|
+
if (this.pendingDialog) {
|
|
704
|
+
// ESC here would DECLINE the pending question/plan dialog - that is where every
|
|
705
|
+
// phantom "User declined to answer" came from. The dialog branch of the input loop
|
|
706
|
+
// owns this state; never clear modals across it.
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
568
709
|
if (monotonicNowMs() - this.interruptPromptAt > INTERRUPT_PROMPT_TTL_MS) {
|
|
569
710
|
this.interruptPromptAt = 0;
|
|
570
711
|
return;
|
|
@@ -775,6 +916,7 @@ export class PtyQuery {
|
|
|
775
916
|
// ---- transcript → SDKMessage stream + turn-end ----------------------------
|
|
776
917
|
onTranscriptMessage(message) {
|
|
777
918
|
this.emit(message);
|
|
919
|
+
this.trackInteractiveDialog(message);
|
|
778
920
|
if (message.type === "assistant") {
|
|
779
921
|
const beta = message.message;
|
|
780
922
|
this.lastStopReason = beta.stop_reason ?? null;
|
|
@@ -788,6 +930,39 @@ export class PtyQuery {
|
|
|
788
930
|
this.armStallTimer();
|
|
789
931
|
this.scheduleTurnEndCheck();
|
|
790
932
|
}
|
|
933
|
+
/**
|
|
934
|
+
* Track interactive TUI dialogs (AskUserQuestion / plan-mode approval) from the
|
|
935
|
+
* transcript. While one is pending the terminal is WAITING, not stalled: the stall
|
|
936
|
+
* backstop must stand down, no ESC may be sent (it declines the dialog - the source of
|
|
937
|
+
* every phantom "User declined" this week), and an incoming reply is translated to
|
|
938
|
+
* dialog keystrokes instead of typed text.
|
|
939
|
+
*/
|
|
940
|
+
trackInteractiveDialog(message) {
|
|
941
|
+
const content = message.message?.content;
|
|
942
|
+
if (!Array.isArray(content))
|
|
943
|
+
return;
|
|
944
|
+
for (const block of content) {
|
|
945
|
+
if (!block || typeof block !== "object")
|
|
946
|
+
continue;
|
|
947
|
+
const b = block;
|
|
948
|
+
if (message.type === "assistant" &&
|
|
949
|
+
b.type === "tool_use" &&
|
|
950
|
+
b.id &&
|
|
951
|
+
(b.name === "AskUserQuestion" || b.name === "ExitPlanMode")) {
|
|
952
|
+
this.pendingDialog = {
|
|
953
|
+
toolUseId: b.id,
|
|
954
|
+
name: b.name,
|
|
955
|
+
options: extractDialogOptions(b.name, b.input),
|
|
956
|
+
};
|
|
957
|
+
this.recordLine(`--- interactive dialog pending: ${b.name} ---`);
|
|
958
|
+
}
|
|
959
|
+
const pending = this.pendingDialog;
|
|
960
|
+
if (pending && b.type === "tool_result" && b.tool_use_id === pending.toolUseId) {
|
|
961
|
+
this.recordLine(`--- interactive dialog answered: ${pending.name} ---`);
|
|
962
|
+
this.pendingDialog = null;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
791
966
|
scheduleTurnEndCheck() {
|
|
792
967
|
if (this.turnEndTimer)
|
|
793
968
|
clearTimeout(this.turnEndTimer);
|
|
@@ -835,6 +1010,14 @@ export class PtyQuery {
|
|
|
835
1010
|
this.stallTimer = null;
|
|
836
1011
|
if (this.done || !this.turnInFlight)
|
|
837
1012
|
return;
|
|
1013
|
+
if (this.pendingDialog) {
|
|
1014
|
+
// Waiting on a human is not a stall. Observed live 2026-08-04: an ExitPlanMode
|
|
1015
|
+
// approval sat pending for 2.5 hours and the backstop declared the turn failed,
|
|
1016
|
+
// which read as a wedge and got a healthy process killed.
|
|
1017
|
+
this.recordLine(`--- stall budget elapsed but ${this.pendingDialog.name} is pending ---`);
|
|
1018
|
+
this.armStallTimer();
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
838
1021
|
this.turnInFlight = false;
|
|
839
1022
|
this.stopHeartbeat();
|
|
840
1023
|
const silentForMs = this.stallTimeoutMs;
|
|
@@ -1074,6 +1257,60 @@ export class PtyQuery {
|
|
|
1074
1257
|
}
|
|
1075
1258
|
}
|
|
1076
1259
|
/** Extract the plain-text prompt from a user SDK message for typing into the PTY. */
|
|
1260
|
+
/** Delay between Down-arrow presses when answering a dialog; the TUI animates selection. */
|
|
1261
|
+
const DIALOG_KEY_DELAY_MS = 150;
|
|
1262
|
+
/** How long to wait for the dialog's tool_result to land after answering keystrokes. */
|
|
1263
|
+
const DIALOG_ANSWER_CONFIRM_MS = 8000;
|
|
1264
|
+
/**
|
|
1265
|
+
* Options the TUI dialog offers, in on-screen order. AskUserQuestion carries them in its
|
|
1266
|
+
* input; the plan-approval dialog's options are the CLI's own and version-dependent, so
|
|
1267
|
+
* they stay empty and replies are matched by number only.
|
|
1268
|
+
*/
|
|
1269
|
+
function extractDialogOptions(name, input) {
|
|
1270
|
+
if (name !== "AskUserQuestion")
|
|
1271
|
+
return [];
|
|
1272
|
+
const questions = input?.questions;
|
|
1273
|
+
if (!Array.isArray(questions) || questions.length === 0)
|
|
1274
|
+
return [];
|
|
1275
|
+
const options = questions[0]?.options;
|
|
1276
|
+
if (!Array.isArray(options))
|
|
1277
|
+
return [];
|
|
1278
|
+
const labels = [];
|
|
1279
|
+
for (const option of options) {
|
|
1280
|
+
if (typeof option === "string")
|
|
1281
|
+
labels.push(option);
|
|
1282
|
+
else if (option && typeof option === "object") {
|
|
1283
|
+
const label = option.label;
|
|
1284
|
+
if (typeof label === "string")
|
|
1285
|
+
labels.push(label);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
return labels;
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Resolve the user's reply to a 0-based dialog option index, or null when it names none.
|
|
1292
|
+
* "2" picks the second option; an exact case-insensitive label match works too. Free text
|
|
1293
|
+
* stays null on purpose: guessing would answer a question the user did not answer.
|
|
1294
|
+
*/
|
|
1295
|
+
function matchDialogOption(text, options) {
|
|
1296
|
+
const reply = text.trim();
|
|
1297
|
+
if (/^[1-9]$/.test(reply)) {
|
|
1298
|
+
const index = Number(reply) - 1;
|
|
1299
|
+
if (options.length === 0 || index < options.length)
|
|
1300
|
+
return index;
|
|
1301
|
+
return null;
|
|
1302
|
+
}
|
|
1303
|
+
const lowered = reply.toLowerCase();
|
|
1304
|
+
const byLabel = options.findIndex((o) => o.trim().toLowerCase() === lowered);
|
|
1305
|
+
return byLabel >= 0 ? byLabel : null;
|
|
1306
|
+
}
|
|
1307
|
+
/** Extensions for the media types the app can send; anything unknown stages as .png. */
|
|
1308
|
+
const IMAGE_MEDIA_TYPE_EXT = {
|
|
1309
|
+
"image/jpeg": "jpg",
|
|
1310
|
+
"image/png": "png",
|
|
1311
|
+
"image/gif": "gif",
|
|
1312
|
+
"image/webp": "webp",
|
|
1313
|
+
};
|
|
1077
1314
|
function extractUserText(message) {
|
|
1078
1315
|
const content = message.message?.content;
|
|
1079
1316
|
if (typeof content === "string")
|
|
@@ -1,7 +1,48 @@
|
|
|
1
1
|
import * as fsp from "node:fs/promises";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import { createCwdResolver } from "../search/resolve-cwd.js";
|
|
4
5
|
const HEADER_READ_BYTES = 64 * 1024;
|
|
6
|
+
/** Take any field this record supplies that the header does not have yet. */
|
|
7
|
+
function absorbRecord(header, obj) {
|
|
8
|
+
if (header.title === null && typeof obj["custom-title"] === "string") {
|
|
9
|
+
header.title = obj["custom-title"];
|
|
10
|
+
}
|
|
11
|
+
if (header.cwd === null && typeof obj.cwd === "string" && obj.cwd.length > 0) {
|
|
12
|
+
header.cwd = obj.cwd;
|
|
13
|
+
}
|
|
14
|
+
if (header.agentName === null && typeof obj.agentName === "string") {
|
|
15
|
+
header.agentName = obj.agentName;
|
|
16
|
+
}
|
|
17
|
+
if (header.lastActivity === null && typeof obj.lastActivity === "string") {
|
|
18
|
+
header.lastActivity = obj.lastActivity;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Nothing further down the file can add anything — stop scanning. */
|
|
22
|
+
function isHeaderComplete(header) {
|
|
23
|
+
return (header.title !== null &&
|
|
24
|
+
header.cwd !== null &&
|
|
25
|
+
header.agentName !== null &&
|
|
26
|
+
header.lastActivity !== null);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Recover the fields the palette needs from the head of a transcript.
|
|
30
|
+
*
|
|
31
|
+
* The FIRST record still decides whether this file is a transcript at all — if
|
|
32
|
+
* it does not parse, the file is treated as corrupt and skipped, exactly as
|
|
33
|
+
* before. What changed is that a parseable first record no longer ends the
|
|
34
|
+
* search: later records in the read window are scanned for any field the first
|
|
35
|
+
* one left unset, `cwd` above all.
|
|
36
|
+
*
|
|
37
|
+
* Why it matters: the opening record is often session meta that carries no
|
|
38
|
+
* `cwd`, and the caller then fell through to `recoverCwdFromDirName`, which
|
|
39
|
+
* FABRICATES a path. The slug is lossy — `-home-claudiao-super-repo` decodes
|
|
40
|
+
* to `/home/claudiao/super/repo`, a directory that exists nowhere — so every
|
|
41
|
+
* palette row offered to resume into a directory that was not there, and
|
|
42
|
+
* resuming into a missing directory hydrates an empty chat. The authoritative
|
|
43
|
+
* value was sitting a few records further down the same buffer we had already
|
|
44
|
+
* read.
|
|
45
|
+
*/
|
|
5
46
|
async function readHeader(filePath) {
|
|
6
47
|
const fh = await fsp.open(filePath, "r");
|
|
7
48
|
try {
|
|
@@ -9,19 +50,37 @@ async function readHeader(filePath) {
|
|
|
9
50
|
const { bytesRead } = await fh.read(buf, 0, HEADER_READ_BYTES, 0);
|
|
10
51
|
if (bytesRead === 0)
|
|
11
52
|
return null;
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
53
|
+
const text = buf.subarray(0, bytesRead).toString("utf-8");
|
|
54
|
+
// A trailing fragment with no newline is a COMPLETE record only when the
|
|
55
|
+
// read reached EOF; mid-window it is truncated and must not be parsed.
|
|
56
|
+
const readHitEof = bytesRead < HEADER_READ_BYTES;
|
|
57
|
+
const header = { title: null, cwd: null, agentName: null, lastActivity: null };
|
|
58
|
+
let isFirstRecord = true;
|
|
59
|
+
let cursor = 0;
|
|
60
|
+
while (cursor < text.length) {
|
|
61
|
+
const nl = text.indexOf("\n", cursor);
|
|
62
|
+
if (nl === -1 && !readHitEof)
|
|
63
|
+
break;
|
|
64
|
+
const line = (nl === -1 ? text.slice(cursor) : text.slice(cursor, nl)).trim();
|
|
65
|
+
cursor = nl === -1 ? text.length : nl + 1;
|
|
66
|
+
if (line.length === 0)
|
|
67
|
+
continue;
|
|
68
|
+
let obj;
|
|
69
|
+
try {
|
|
70
|
+
obj = JSON.parse(line);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// The opening record must parse; anything later is best-effort.
|
|
74
|
+
if (isFirstRecord)
|
|
75
|
+
return null;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
isFirstRecord = false;
|
|
79
|
+
absorbRecord(header, obj);
|
|
80
|
+
if (isHeaderComplete(header))
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
return isFirstRecord ? null : header;
|
|
25
84
|
}
|
|
26
85
|
finally {
|
|
27
86
|
await fh.close();
|
|
@@ -51,13 +110,19 @@ async function loadSession(transcriptDir, dirSlug, fileName, logger) {
|
|
|
51
110
|
return null;
|
|
52
111
|
try {
|
|
53
112
|
const header = await readHeader(filePath);
|
|
54
|
-
|
|
113
|
+
// No parseable opening record — not a transcript we can offer to resume.
|
|
114
|
+
// This used to happen via a thrown JSON.parse caught below; `readHeader`
|
|
115
|
+
// now reports it by returning null, so the skip has to be explicit or a
|
|
116
|
+
// corrupt file would be listed with a fabricated cwd and an mtime date.
|
|
117
|
+
if (header === null)
|
|
118
|
+
return null;
|
|
119
|
+
const lastActivity = header.lastActivity ?? new Date(stat.mtimeMs).toISOString();
|
|
55
120
|
return {
|
|
56
121
|
sid,
|
|
57
|
-
title: header
|
|
122
|
+
title: header.title,
|
|
58
123
|
lastActivity,
|
|
59
|
-
cwd: header
|
|
60
|
-
agentName: header
|
|
124
|
+
cwd: header.cwd ?? recoverCwdFromDirName(dirSlug),
|
|
125
|
+
agentName: header.agentName,
|
|
61
126
|
};
|
|
62
127
|
}
|
|
63
128
|
catch (err) {
|
|
@@ -108,7 +173,22 @@ export async function collectAllSessions(projectsRoot, logger) {
|
|
|
108
173
|
throw err;
|
|
109
174
|
}
|
|
110
175
|
const perDir = await Promise.all(topLevel.map((dirSlug) => loadDir(projectsRoot, dirSlug, logger)));
|
|
176
|
+
// History moves between machines; paths do not. Roughly half of this corpus
|
|
177
|
+
// carries a `/Users/<mac-user>/…` cwd that means nothing on a Linux box, and
|
|
178
|
+
// resuming into a directory that is not there hydrates an empty chat. Reuse
|
|
179
|
+
// the same resolver the search path uses so a palette row and a search hit
|
|
180
|
+
// for the SAME session agree on where to resume. It only ever remaps onto a
|
|
181
|
+
// directory that EXISTS and leaves anything unresolvable untouched, so the
|
|
182
|
+
// UI keeps showing the truth rather than a plausible lie. The resolver
|
|
183
|
+
// caches per call — thousands of sessions share a handful of cwds, so this
|
|
184
|
+
// collapses into one stat per distinct directory.
|
|
185
|
+
const resolveCwd = createCwdResolver();
|
|
111
186
|
const sessions = perDir.flat();
|
|
187
|
+
await Promise.all(sessions.map(async (entry) => {
|
|
188
|
+
// Assigned in place: `loadSession` just built these and nothing else
|
|
189
|
+
// holds a reference yet, so there is no copy worth allocating.
|
|
190
|
+
entry.cwd = (await resolveCwd(entry.cwd)).cwd;
|
|
191
|
+
}));
|
|
112
192
|
sessions.sort((a, b) => {
|
|
113
193
|
if (a.lastActivity < b.lastActivity)
|
|
114
194
|
return 1;
|
|
@@ -1103,7 +1103,7 @@ __d(function(g,r,_i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?
|
|
|
1103
1103
|
__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},1006,[35,4,25,1007,1008,1009]);
|
|
1104
1104
|
__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 u}});var e,t=r(d[0]),u={UIManager:((e=t)&&e.__esModule?e:{default:e}).default}},1007,[159]);
|
|
1105
1105
|
__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={}))},1008,[]);
|
|
1106
|
-
__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.
|
|
1106
|
+
__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.23\",\"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}},1009,[1008]);
|
|
1107
1107
|
__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 u}});var e,t=r(d[0]),n=r(d[1]),o=(e=n)&&e.__esModule?e:{default:e};async function u(){if(!o.default.unregisterForNotificationsAsync)throw new t.UnavailabilityError('ExpoNotifications','unregisterForNotificationsAsync');return o.default.unregisterForNotificationsAsync()}},1010,[4,1011]);
|
|
1108
1108
|
__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 n}}),r(d[0]);let t=!1;var n={addListener:()=>(t||(console.warn("[expo-notifications] Listening to push token changes is not yet fully supported on web. Adding a listener will have no effect."),t=!0),{remove:()=>{}}),removeListener:()=>{},removeAllListeners:()=>{},emit:()=>{},listenerCount:()=>0}},1011,[4]);
|
|
1109
1109
|
__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 u}});var t=(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach(function(o){var n=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,n.get?n:{enumerable:!0,get:function(){return e[o]}})}),t.default=e,t})(r(_d[0])),o=e(r(_d[1])),n=r(_d[2]),c=r(_d[3]),s=e(r(_d[4])),d=e(r(_d[5]));const p='https://exp.host/--/api/v2/';async function u(e={}){const s=e.devicePushToken||await(0,d.default)(),u=e.deviceId||await h(),R=e.projectId||o.default.easConfig?.projectId||o.default.expoConfig?.extra?.eas?.projectId;if(!R)throw new n.CodedError('ERR_NOTIFICATIONS_NO_EXPERIENCE_ID',"No \"projectId\" found. If \"projectId\" can't be inferred from the manifest (for instance, in bare workflow), you have to pass it in yourself.");const w=e.applicationId||t.applicationId;if(!w)throw new n.CodedError('ERR_NOTIFICATIONS_NO_APPLICATION_ID',"No \"applicationId\" found. If it can't be inferred from native configuration by expo-application, you have to pass it in yourself.");const O=e.type||y(s),_=e.development||await I(),v=e.baseUrl??p,N=e.url??`${v}push/getExpoPushToken`,x={type:O,deviceId:u.toLowerCase(),development:_,appId:w,deviceToken:E(s),projectId:R},T=await fetch(N,{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify(x)}).catch(e=>{throw new n.CodedError('ERR_NOTIFICATIONS_NETWORK_ERROR',`Error encountered while fetching Expo token: ${e}.`)});if(!T.ok){const e=T.statusText||T.status;let t;try{t=await T.text()}catch{}throw new n.CodedError('ERR_NOTIFICATIONS_SERVER_ERROR',`Error encountered while fetching Expo token, expected an OK response, received: ${e} (body: "${t}").`)}const b=l(await f(T));try{e.url||e.baseUrl?console.debug("[expo-notifications] Since the URL endpoint to register in has been customized in the options, expo-notifications won't try to auto-update the device push token on the server."):await(0,c.setAutoServerRegistrationEnabledAsync)(!0)}catch(e){console.warn('[expo-notifications] Could not enable automatically registering new device tokens with the Expo notification service',e)}return{type:'expo',data:b}}async function f(e){try{return await e.json()}catch{try{throw new n.CodedError('ERR_NOTIFICATIONS_SERVER_ERROR',`Expected a JSON response from server when fetching Expo token, received body: ${JSON.stringify(await e.text())}.`)}catch{throw new n.CodedError('ERR_NOTIFICATIONS_SERVER_ERROR',`Expected a JSON response from server when fetching Expo token, received response: ${JSON.stringify(e)}.`)}}}function l(e){if(!e||'object'!=typeof e||!e.data||'object'!=typeof e.data||!e.data.expoPushToken||'string'!=typeof e.data.expoPushToken)throw new n.CodedError('ERR_NOTIFICATIONS_SERVER_ERROR',`Malformed response from server, expected "{ data: { expoPushToken: string } }", received: ${JSON.stringify(e,null,2)}.`);return e.data.expoPushToken}async function h(){try{if(!s.default.getInstallationIdAsync)throw new n.UnavailabilityError('ExpoServerRegistrationModule','getInstallationIdAsync');return await s.default.getInstallationIdAsync()}catch(e){throw new n.CodedError('ERR_NOTIF_DEVICE_ID',`Could not have fetched installation ID of the application: ${e}.`)}}function E(e){return'string'==typeof e.data?e.data:JSON.stringify(e.data)}async function I(){return!1}function y(e){switch(e.type){case'ios':return'apns';case'android':return'fcm';default:return e.type}}},1012,[1013,1006,4,1016,1020,1005]);
|
|
@@ -14906,7 +14906,7 @@ __d(function(g,r,i,a,m,_e,_d){"use strict";const e=["color","size","strokeWidth"
|
|
|
14906
14906
|
* This source code is licensed under the ISC license.
|
|
14907
14907
|
* See the LICENSE file in the root directory of this source tree.
|
|
14908
14908
|
*/function t(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"default",{enumerable:!0,get:function(){return d}});var n=t(r(_d[0])),o=r(_d[1]),c=(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach(function(n){var o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,o.get?o:{enumerable:!0,get:function(){return e[n]}})}),t.default=e,t})(r(_d[2])),u=r(_d[3]),s=t(u);const d=(0,o.forwardRef)((t,d)=>{let{color:l="currentColor",size:f=24,strokeWidth:b=2,absoluteStrokeWidth:h,children:O,iconNode:j}=t,p=(0,n.default)(t,e);const _=Object.assign({stroke:l,strokeWidth:h?24*Number(b)/Number(f):b},p);return(0,o.createElement)(c.Svg,Object.assign({ref:d},s.default,{width:f,height:f},_),[...j.map(([e,t])=>{const n=e.charAt(0).toUpperCase()+e.slice(1);return(0,o.createElement)(c[n],Object.assign({},u.childDefaultAttributes,_,t))}),...(Array.isArray(O)?O:[O])||[]])})},3263,[35,36,1604,1625]);
|
|
14909
|
-
__d(function(g,_r,i,_a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.useCommandCenter=function(){const c=(0,t.c)(107),{t:w}=(0,o.useTranslation)(),y=(0,r.usePathname)(),{overrides:C}=(0,v.useKeyboardShortcutOverrides)(),k=(0,s.useKeyboardShortcutsStore)(V),X=(0,s.useKeyboardShortcutsStore)(J),Y=(0,n.useRef)(null),Z=(0,n.useRef)(!1),ee=(0,n.useRef)(k),te=(0,n.useRef)(0);let ne;c[0]===Symbol.for("react.memo_cache_sentinel")?(ne=[],c[0]=ne):ne=c[0];const re=(0,n.useRef)(ne),oe=(0,n.useRef)(G),se=(0,n.useRef)(z),[ie,ce]=(0,n.useState)(""),[ue,ae]=(0,n.useState)(0),le=(0,n.useSyncExternalStore)(_.subscribeCommandContributions,_.getCommandContributions,_.getCommandContributions),de=(0,K.useActiveServerId)(),fe=k?de:null,{agents:me}=(0,l.useAggregatedAgents)();let ge;c[1]!==fe||c[2]!==k?(ge={serverId:fe,enabled:k},c[1]=fe,c[2]=k,c[3]=ge):ge=c[3];const{sessions:he}=(0,u.useAllSessionsList)(ge);let pe;c[4]!==fe||c[5]!==k||c[6]!==ie?(pe={serverId:fe,query:ie,enabled:k},c[4]=fe,c[5]=k,c[6]=ie,c[7]=pe):pe=c[7];const{results:we,capable:ye,isLoading:ve}=(0,a.useRecallSearch)(pe);let Ce;e:{if(!k||0===me.length){Ce=D;break e}let t;if(c[8]!==me||c[9]!==ie){let n;c[11]!==ie?(n=t=>x(t,ie),c[11]=ie,c[12]=n):n=c[12],t=me.filter(n),t.sort(q),c[8]=me,c[9]=ie,c[10]=t}else t=c[10];Ce=t}const ke=Ce,Ae=ye&&ie.trim().length>=2&&(we.length>0||ve);let Se;e:{if(!k||0===he.length||Ae){Se=F;break e}let t,n;if(c[13]!==me){t=new Set;for(const n of me)t.add(n.id);c[13]=me,c[14]=t}else t=c[14];if(c[15]!==he||c[16]!==t||c[17]!==ie){let r;c[19]!==t||c[20]!==ie?(r=n=>!t.has(n.sid)&&W(n,ie),c[19]=t,c[20]=ie,c[21]=r):r=c[21],n=he.filter(r),n.sort($),c[15]=he,c[16]=t,c[17]=ie,c[18]=n}else n=c[18];Se=n}const be=Se;let Ee;e:{if(!k||!Ae||0===we.length){Ee=O;break e}let t,n;if(c[22]!==me){t=new Set;for(const n of me)t.add(n.id);c[22]=me,c[23]=t}else t=c[23];if(c[24]!==t||c[25]!==we){let r;c[27]!==t?(r=n=>!t.has(n.sid),c[27]=t,c[28]=r):r=c[28],n=we.filter(r),c[24]=t,c[25]=we,c[26]=n}else n=c[26];Ee=n}const Ie=Ee;let Ke;c[29]===Symbol.for("react.memo_cache_sentinel")?(Ke=(0,p.buildSettingsRoute)(),c[29]=Ke):Ke=c[29];const Re=Ke;let Le;c[30]===Symbol.for("react.memo_cache_sentinel")?(Le=(0,p.buildOpenProjectRoute)(),c[30]=Le):Le=c[30];const Te=Le;let Pe;e:{if(!k){Pe=M;break e}let t;if(c[31]!==le||c[32]!==C||c[33]!==ie||c[34]!==w){let n,r;c[36]!==ie||c[37]!==w?(n=t=>!("home"===t.routeKind&&!Te)&&N(ie,t,w(t.titleKey)),c[36]=ie,c[37]=w,c[38]=n):n=c[38],c[39]!==C||c[40]!==w?(r=t=>{let n;return"settings"===t.routeKind?n=Re:"home"===t.routeKind&&(n=Te),{kind:"action",id:t.id,title:w(t.titleKey),icon:t.icon,route:n,shortcutKeys:U(t.actionId,C)}},c[39]=C,c[40]=w,c[41]=r):r=c[41];const o=B.filter(n).map(r),s=ie.trim().toLowerCase();t=[...o,...le.filter(t=>0===s.length||t.title.toLowerCase().includes(s)||t.keywords.some(t=>t.includes(s))).map(Q)],c[31]=le,c[32]=C,c[33]=ie,c[34]=w,c[35]=t}else t=c[35];Pe=t}const _e=Pe;let De;e:{if(!k){De=j;break e}let t;if(c[42]!==_e||c[43]!==ke||c[44]!==Ie||c[45]!==be){t=[];for(const n of _e)t.push({kind:"action",action:n});for(const n of ke)t.push({kind:"agent",agent:n});for(const n of be)t.push({kind:"session",session:n});for(const n of Ie)t.push({kind:"recallMatch",match:n});c[42]=_e,c[43]=ke,c[44]=Ie,c[45]=be,c[46]=t}else t=c[46];De=t}const Fe=De;let Oe;c[47]!==X?(Oe=()=>{X(!1)},c[47]=X,c[48]=Oe):Oe=c[48];const Me=Oe;let je;c[49]!==X?(je=t=>{Z.current=!0,(0,h.clearCommandCenterFocusRestoreElement)(),X(!1),(0,A.navigateToAgent)({serverId:t.serverId,agentId:t.id})},c[49]=X,c[50]=je):je=c[50];const xe=je,We=(0,f.useOpenProjectPicker)();let qe;c[51]!==We||c[52]!==X?(qe=t=>{(0,h.clearCommandCenterFocusRestoreElement)(),X(!1),t.run?t.run():"new-agent"!==t.id?t.route&&(Z.current=!0,r.router.push(t.route)):We()},c[51]=We,c[52]=X,c[53]=qe):qe=c[53];const Be=qe,Ne=(0,R.useHostRuntimeClient)(fe??""),Ue=(0,T.useToast)();let He;c[54]!==fe||c[55]!==y||c[56]!==X||c[57]!==Ue?(He=(t,n)=>{Z.current=!0,(0,h.clearCommandCenterFocusRestoreElement)(),X(!1);const r=fe;if(!r)return void Ue.error("Couldn't open session: no active server.");const o=n?.trim();if(o){const n=E.useSessionStore.getState().sessions[r]?.workspaces,s=(0,b.resolveWorkspaceIdByExecutionDirectory)({workspaces:n?.values(),workspaceDirectory:o});if(s)return void(0,S.navigateToPreparedWorkspaceTab)({serverId:r,workspaceId:s,target:{kind:"agent",agentId:t},currentPathname:y,pin:!0})}(0,A.navigateToAgent)({serverId:r,agentId:t,currentPathname:y})},c[54]=fe,c[55]=y,c[56]=X,c[57]=Ue,c[58]=He):He=c[58];const Qe=He;let $e;c[59]!==fe||c[60]!==y||c[61]!==Ne||c[62]!==X||c[63]!==Ue?($e=t=>{Z.current=!0,(0,h.clearCommandCenterFocusRestoreElement)(),X(!1);const n=fe;Ne&&n?Ne.createAgent({config:{provider:"claude",cwd:t.cwd},resumeSessionId:t.sid}).then(t=>(0,A.navigateToAgent)({serverId:n,agentId:t.id,currentPathname:y})).catch(t=>{const n=t instanceof Error?t.message:String(t);Ue.error(`Couldn't open session: ${n}`)}):Ue.error("Couldn't open session: daemon not connected.")},c[59]=fe,c[60]=y,c[61]=Ne,c[62]=X,c[63]=Ue,c[64]=$e):$e=c[64];const ze=$e;let Ge;c[65]!==ze||c[66]!==Qe?(Ge=t=>{"open-agent"!==(0,P.recallSelectionKind)(t.source)?ze({sid:t.sid,title:null,lastActivity:t.timestamp,cwd:t.cwd,agentName:null}):Qe(t.sid,t.cwd)},c[65]=ze,c[66]=Qe,c[67]=Ge):Ge=c[67];const Je=Ge;let Ve;c[68]!==Be||c[69]!==xe||c[70]!==Je||c[71]!==ze?(Ve=t=>{"action"!==t.kind?"session"!==t.kind?"recallMatch"!==t.kind?xe(t.agent):Je(t.match):ze(t.session):Be(t.action)},c[68]=Be,c[69]=xe,c[70]=Je,c[71]=ze,c[72]=Ve):Ve=c[72];const Xe=Ve;let Ye,Ze,et,tt,nt,rt,ot,st,it,ct,ut,at,lt;c[73]!==ue?(Ye=()=>{te.current=ue},Ze=[ue],c[73]=ue,c[74]=Ye,c[75]=Ze):(Ye=c[74],Ze=c[75]);(0,n.useEffect)(Ye,Ze),c[76]!==Fe?(et=()=>{re.current=Fe},tt=[Fe],c[76]=Fe,c[77]=et,c[78]=tt):(et=c[77],tt=c[78]);(0,n.useEffect)(et,tt),c[79]!==Me?(nt=()=>{oe.current=Me},rt=[Me],c[79]=Me,c[80]=nt,c[81]=rt):(nt=c[80],rt=c[81]);(0,n.useEffect)(nt,rt),c[82]!==Xe?(ot=()=>{se.current=Xe},st=[Xe],c[82]=Xe,c[83]=ot,c[84]=st):(ot=c[83],st=c[84]);(0,n.useEffect)(ot,st),c[85]!==k?(it=()=>{const t=ee.current;if(ee.current=k,!k){if(ce(""),ae(0),t&&!Z.current&&L.isWeb){const t=(0,h.takeCommandCenterFocusRestoreElement)(),n=()=>Boolean(t)&&"undefined"!=typeof document&&document.activeElement===t;return(0,I.focusWithRetries)({focus:()=>t?.focus(),isFocused:n,onTimeout:H})}return}Z.current=!1;const n=setTimeout(()=>{Y.current?.focus()},0);return()=>clearTimeout(n)},ct=[k],c[85]=k,c[86]=it,c[87]=ct):(it=c[86],ct=c[87]);(0,n.useEffect)(it,ct),c[88]!==ue||c[89]!==Fe.length||c[90]!==k?(ut=()=>{k&&ue>=Fe.length&&ae(Fe.length>0?Fe.length-1:0)},at=[ue,Fe.length,k],c[88]=ue,c[89]=Fe.length,c[90]=k,c[91]=ut,c[92]=at):(ut=c[91],at=c[92]);(0,n.useEffect)(ut,at),c[93]!==k?(lt=t=>{if(!k)return!1;const n=re.current;if("Escape"===t)return oe.current(),!0;if("Enter"===t){if(0===n.length)return!1;const t=Math.max(0,Math.min(te.current,n.length-1));return se.current(n[t]),!0}return("ArrowDown"===t||"ArrowUp"===t)&&(0!==n.length&&(ae(r=>{const o=r+("ArrowDown"===t?1:-1);return o<0?n.length-1:o>=n.length?0:o}),!0))},c[93]=k,c[94]=lt):lt=c[94];const dt=lt;let ft,mt,gt;c[95]!==dt||c[96]!==k?(ft=()=>{if(!k||!L.isWeb)return;const t=t=>{"ArrowDown"!==t.key&&"ArrowUp"!==t.key&&"Enter"!==t.key&&"Escape"!==t.key||dt(t.key)&&t.preventDefault()};return window.addEventListener("keydown",t,!0),()=>window.removeEventListener("keydown",t,!0)},mt=[k,dt],c[95]=dt,c[96]=k,c[97]=ft,c[98]=mt):(ft=c[97],mt=c[98]);(0,n.useEffect)(ft,mt),c[99]!==ue||c[100]!==Me||c[101]!==dt||c[102]!==Xe||c[103]!==Fe||c[104]!==k||c[105]!==ie?(gt={open:k,inputRef:Y,query:ie,setQuery:ce,activeIndex:ue,setActiveIndex:ae,items:Fe,handleClose:Me,handleSelectItem:Xe,handleKeyEvent:dt},c[99]=ue,c[100]=Me,c[101]=dt,c[102]=Xe,c[103]=Fe,c[104]=k,c[105]=ie,c[106]=gt):gt=c[106];return gt};var t=_r(d[0]),n=_r(d[1]),r=_r(d[2]),o=_r(d[3]),s=_r(d[4]),c=_r(d[5]),u=_r(d[6]),a=_r(d[7]),l=_r(d[8]),f=_r(d[9]),h=_r(d[10]),p=_r(d[11]),w=_r(d[12]),y=_r(d[13]),v=_r(d[14]),C=_r(d[15]),k=_r(d[16]),A=_r(d[17]),S=_r(d[18]),b=_r(d[19]),E=_r(d[20]),I=_r(d[21]),K=_r(d[22]),R=_r(d[23]),L=_r(d[24]),T=_r(d[25]),P=_r(d[26]),_=_r(d[27]);const D=[],F=[],O=[],M=[],j=[];function x(t,n){if(!n)return!0;const r=n.toLowerCase(),o=(t.title??"New agent").toLowerCase(),s=t.cwd.toLowerCase();return o.includes(r)||s.includes(r)}function W(t,n){if(!n)return!0;const r=n.toLowerCase(),o=(t.title??"").toLowerCase(),s=(t.cwd??"").toLowerCase(),c=t.sid.toLowerCase();return o.includes(r)||s.includes(r)||c.includes(r)}function q(t,n){const r=(t.pendingPermissionCount??0)>0?1:0,o=(n.pendingPermissionCount??0)>0?1:0;if(r!==o)return o-r;const s=t.requiresAttention?1:0,c=n.requiresAttention?1:0;if(s!==c)return c-s;const u="running"===t.status?1:0,a="running"===n.status?1:0;return u!==a?a-u:n.lastActivityAt.getTime()-t.lastActivityAt.getTime()}const B=[{id:"new-agent",titleKey:"shell.commandCenter.openProject",icon:"plus",actionId:"new-agent",keywords:["open","project","folder","workspace","repo"],routeKind:"none"},{id:"home",titleKey:"shell.commandCenter.home",icon:"home",keywords:["home","start","import","session","pair","device","providers"],routeKind:"home"},{id:"settings",titleKey:"sidebar.actions.settings",icon:"settings",keywords:["settings","preferences","config","configuration"],routeKind:"settings"}];function N(t,n,r){const o=t.trim().toLowerCase();return!o||(!!r.toLowerCase().includes(o)||n.keywords.some(t=>t.includes(o)))}function U(t,n){if(!t)return;const r={isMac:"mac"===(0,C.getShortcutOs)(),isDesktop:(0,k.getIsElectronRuntime)()},o=(0,y.getBindingIdForAction)(t,r);if(!o)return;const s=n[o];if(s)return(0,w.chordStringToShortcutKeys)(s);const c=(0,y.getDefaultKeysForAction)(t,r);return c?[c]:void 0}function H(){c.keyboardActionDispatcher.dispatch({id:"message-input.focus",scope:"message-input"})}function Q(t){return{kind:"action",id:t.id,title:t.title,run:t.run}}function $(t,n){return t.lastActivity<n.lastActivity?1:t.lastActivity>n.lastActivity?-1:0}function z(){}function G(){}function J(t){return t.setCommandCenterOpen}function V(t){return t.commandCenterOpen}},3264,[349,36,1143,1573,3265,3269,3270,3446,3447,3452,3479,3477,3480,3481,3482,3483,3457,3484,3486,3495,3414,3496,3497,3271,3407,3499,3503,3504]);
|
|
14909
|
+
__d(function(g,_r,i,_a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.useCommandCenter=function(){const c=(0,t.c)(107),{t:w}=(0,o.useTranslation)(),y=(0,r.usePathname)(),{overrides:C}=(0,v.useKeyboardShortcutOverrides)(),k=(0,s.useKeyboardShortcutsStore)(V),X=(0,s.useKeyboardShortcutsStore)(J),Y=(0,n.useRef)(null),Z=(0,n.useRef)(!1),ee=(0,n.useRef)(k),te=(0,n.useRef)(0);let ne;c[0]===Symbol.for("react.memo_cache_sentinel")?(ne=[],c[0]=ne):ne=c[0];const re=(0,n.useRef)(ne),oe=(0,n.useRef)(G),se=(0,n.useRef)(z),[ie,ce]=(0,n.useState)(""),[ue,ae]=(0,n.useState)(0),le=(0,n.useSyncExternalStore)(_.subscribeCommandContributions,_.getCommandContributions,_.getCommandContributions),de=(0,K.useActiveServerId)(),fe=k?de:null,{agents:me}=(0,l.useAggregatedAgents)();let ge;c[1]!==fe||c[2]!==k?(ge={serverId:fe,enabled:k},c[1]=fe,c[2]=k,c[3]=ge):ge=c[3];const{sessions:he}=(0,u.useAllSessionsList)(ge);let pe;c[4]!==fe||c[5]!==k||c[6]!==ie?(pe={serverId:fe,query:ie,enabled:k},c[4]=fe,c[5]=k,c[6]=ie,c[7]=pe):pe=c[7];const{results:we,capable:ye,isLoading:ve}=(0,a.useRecallSearch)(pe);let Ce;e:{if(!k||0===me.length){Ce=D;break e}let t;if(c[8]!==me||c[9]!==ie){let n;c[11]!==ie?(n=t=>x(t,ie),c[11]=ie,c[12]=n):n=c[12],t=me.filter(n),t.sort(q),c[8]=me,c[9]=ie,c[10]=t}else t=c[10];Ce=t}const ke=Ce,Ae=ye&&ie.trim().length>=2&&(we.length>0||ve);let Se;e:{if(!k||0===he.length||Ae){Se=F;break e}let t,n;if(c[13]!==me){t=new Set;for(const n of me)t.add(n.id);c[13]=me,c[14]=t}else t=c[14];if(c[15]!==he||c[16]!==t||c[17]!==ie){let r;c[19]!==t||c[20]!==ie?(r=n=>!t.has(n.sid)&&W(n,ie),c[19]=t,c[20]=ie,c[21]=r):r=c[21],n=he.filter(r),n.sort($),c[15]=he,c[16]=t,c[17]=ie,c[18]=n}else n=c[18];Se=n}const be=Se;let Ee;e:{if(!k||!Ae||0===we.length){Ee=O;break e}let t,n;if(c[22]!==me){t=new Set;for(const n of me)t.add(n.id);c[22]=me,c[23]=t}else t=c[23];if(c[24]!==t||c[25]!==we){let r;c[27]!==t?(r=n=>!t.has(n.sid),c[27]=t,c[28]=r):r=c[28],n=we.filter(r),c[24]=t,c[25]=we,c[26]=n}else n=c[26];Ee=n}const Ie=Ee;let Ke;c[29]===Symbol.for("react.memo_cache_sentinel")?(Ke=(0,p.buildSettingsRoute)(),c[29]=Ke):Ke=c[29];const Re=Ke;let Le;c[30]===Symbol.for("react.memo_cache_sentinel")?(Le=(0,p.buildOpenProjectRoute)(),c[30]=Le):Le=c[30];const Te=Le;let Pe;e:{if(!k){Pe=M;break e}let t;if(c[31]!==le||c[32]!==C||c[33]!==ie||c[34]!==w){let n,r;c[36]!==ie||c[37]!==w?(n=t=>!("home"===t.routeKind&&!Te)&&N(ie,t,w(t.titleKey)),c[36]=ie,c[37]=w,c[38]=n):n=c[38],c[39]!==C||c[40]!==w?(r=t=>{let n;return"settings"===t.routeKind?n=Re:"home"===t.routeKind&&(n=Te),{kind:"action",id:t.id,title:w(t.titleKey),icon:t.icon,route:n,shortcutKeys:U(t.actionId,C)}},c[39]=C,c[40]=w,c[41]=r):r=c[41];const o=B.filter(n).map(r),s=ie.trim().toLowerCase();t=[...o,...le.filter(t=>0===s.length||t.title.toLowerCase().includes(s)||t.keywords.some(t=>t.includes(s))).map(Q)],c[31]=le,c[32]=C,c[33]=ie,c[34]=w,c[35]=t}else t=c[35];Pe=t}const _e=Pe;let De;e:{if(!k){De=j;break e}let t;if(c[42]!==_e||c[43]!==ke||c[44]!==Ie||c[45]!==be){t=[];for(const n of _e)t.push({kind:"action",action:n});for(const n of ke)t.push({kind:"agent",agent:n});for(const n of Ie)t.push({kind:"recallMatch",match:n});for(const n of be)t.push({kind:"session",session:n});c[42]=_e,c[43]=ke,c[44]=Ie,c[45]=be,c[46]=t}else t=c[46];De=t}const Fe=De;let Oe;c[47]!==X?(Oe=()=>{X(!1)},c[47]=X,c[48]=Oe):Oe=c[48];const Me=Oe;let je;c[49]!==X?(je=t=>{Z.current=!0,(0,h.clearCommandCenterFocusRestoreElement)(),X(!1),(0,A.navigateToAgent)({serverId:t.serverId,agentId:t.id})},c[49]=X,c[50]=je):je=c[50];const xe=je,We=(0,f.useOpenProjectPicker)();let qe;c[51]!==We||c[52]!==X?(qe=t=>{(0,h.clearCommandCenterFocusRestoreElement)(),X(!1),t.run?t.run():"new-agent"!==t.id?t.route&&(Z.current=!0,r.router.push(t.route)):We()},c[51]=We,c[52]=X,c[53]=qe):qe=c[53];const Be=qe,Ne=(0,R.useHostRuntimeClient)(fe??""),Ue=(0,T.useToast)();let He;c[54]!==fe||c[55]!==y||c[56]!==X||c[57]!==Ue?(He=(t,n)=>{Z.current=!0,(0,h.clearCommandCenterFocusRestoreElement)(),X(!1);const r=fe;if(!r)return void Ue.error("Couldn't open session: no active server.");const o=n?.trim();if(o){const n=E.useSessionStore.getState().sessions[r]?.workspaces,s=(0,b.resolveWorkspaceIdByExecutionDirectory)({workspaces:n?.values(),workspaceDirectory:o});if(s)return void(0,S.navigateToPreparedWorkspaceTab)({serverId:r,workspaceId:s,target:{kind:"agent",agentId:t},currentPathname:y,pin:!0})}(0,A.navigateToAgent)({serverId:r,agentId:t,currentPathname:y})},c[54]=fe,c[55]=y,c[56]=X,c[57]=Ue,c[58]=He):He=c[58];const Qe=He;let $e;c[59]!==fe||c[60]!==y||c[61]!==Ne||c[62]!==X||c[63]!==Ue?($e=t=>{Z.current=!0,(0,h.clearCommandCenterFocusRestoreElement)(),X(!1);const n=fe;Ne&&n?Ne.createAgent({config:{provider:"claude",cwd:t.cwd},resumeSessionId:t.sid}).then(t=>(0,A.navigateToAgent)({serverId:n,agentId:t.id,currentPathname:y})).catch(t=>{const n=t instanceof Error?t.message:String(t);Ue.error(`Couldn't open session: ${n}`)}):Ue.error("Couldn't open session: daemon not connected.")},c[59]=fe,c[60]=y,c[61]=Ne,c[62]=X,c[63]=Ue,c[64]=$e):$e=c[64];const ze=$e;let Ge;c[65]!==ze||c[66]!==Qe?(Ge=t=>{"open-agent"!==(0,P.recallSelectionKind)(t.source)?ze({sid:t.sid,title:null,lastActivity:t.timestamp,cwd:t.cwd,agentName:null}):Qe(t.sid,t.cwd)},c[65]=ze,c[66]=Qe,c[67]=Ge):Ge=c[67];const Je=Ge;let Ve;c[68]!==Be||c[69]!==xe||c[70]!==Je||c[71]!==ze?(Ve=t=>{"action"!==t.kind?"session"!==t.kind?"recallMatch"!==t.kind?xe(t.agent):Je(t.match):ze(t.session):Be(t.action)},c[68]=Be,c[69]=xe,c[70]=Je,c[71]=ze,c[72]=Ve):Ve=c[72];const Xe=Ve;let Ye,Ze,et,tt,nt,rt,ot,st,it,ct,ut,at,lt;c[73]!==ue?(Ye=()=>{te.current=ue},Ze=[ue],c[73]=ue,c[74]=Ye,c[75]=Ze):(Ye=c[74],Ze=c[75]);(0,n.useEffect)(Ye,Ze),c[76]!==Fe?(et=()=>{re.current=Fe},tt=[Fe],c[76]=Fe,c[77]=et,c[78]=tt):(et=c[77],tt=c[78]);(0,n.useEffect)(et,tt),c[79]!==Me?(nt=()=>{oe.current=Me},rt=[Me],c[79]=Me,c[80]=nt,c[81]=rt):(nt=c[80],rt=c[81]);(0,n.useEffect)(nt,rt),c[82]!==Xe?(ot=()=>{se.current=Xe},st=[Xe],c[82]=Xe,c[83]=ot,c[84]=st):(ot=c[83],st=c[84]);(0,n.useEffect)(ot,st),c[85]!==k?(it=()=>{const t=ee.current;if(ee.current=k,!k){if(ce(""),ae(0),t&&!Z.current&&L.isWeb){const t=(0,h.takeCommandCenterFocusRestoreElement)(),n=()=>Boolean(t)&&"undefined"!=typeof document&&document.activeElement===t;return(0,I.focusWithRetries)({focus:()=>t?.focus(),isFocused:n,onTimeout:H})}return}Z.current=!1;const n=setTimeout(()=>{Y.current?.focus()},0);return()=>clearTimeout(n)},ct=[k],c[85]=k,c[86]=it,c[87]=ct):(it=c[86],ct=c[87]);(0,n.useEffect)(it,ct),c[88]!==ue||c[89]!==Fe.length||c[90]!==k?(ut=()=>{k&&ue>=Fe.length&&ae(Fe.length>0?Fe.length-1:0)},at=[ue,Fe.length,k],c[88]=ue,c[89]=Fe.length,c[90]=k,c[91]=ut,c[92]=at):(ut=c[91],at=c[92]);(0,n.useEffect)(ut,at),c[93]!==k?(lt=t=>{if(!k)return!1;const n=re.current;if("Escape"===t)return oe.current(),!0;if("Enter"===t){if(0===n.length)return!1;const t=Math.max(0,Math.min(te.current,n.length-1));return se.current(n[t]),!0}return("ArrowDown"===t||"ArrowUp"===t)&&(0!==n.length&&(ae(r=>{const o=r+("ArrowDown"===t?1:-1);return o<0?n.length-1:o>=n.length?0:o}),!0))},c[93]=k,c[94]=lt):lt=c[94];const dt=lt;let ft,mt,gt;c[95]!==dt||c[96]!==k?(ft=()=>{if(!k||!L.isWeb)return;const t=t=>{"ArrowDown"!==t.key&&"ArrowUp"!==t.key&&"Enter"!==t.key&&"Escape"!==t.key||dt(t.key)&&t.preventDefault()};return window.addEventListener("keydown",t,!0),()=>window.removeEventListener("keydown",t,!0)},mt=[k,dt],c[95]=dt,c[96]=k,c[97]=ft,c[98]=mt):(ft=c[97],mt=c[98]);(0,n.useEffect)(ft,mt),c[99]!==ue||c[100]!==Me||c[101]!==dt||c[102]!==Xe||c[103]!==Fe||c[104]!==k||c[105]!==ie?(gt={open:k,inputRef:Y,query:ie,setQuery:ce,activeIndex:ue,setActiveIndex:ae,items:Fe,handleClose:Me,handleSelectItem:Xe,handleKeyEvent:dt},c[99]=ue,c[100]=Me,c[101]=dt,c[102]=Xe,c[103]=Fe,c[104]=k,c[105]=ie,c[106]=gt):gt=c[106];return gt};var t=_r(d[0]),n=_r(d[1]),r=_r(d[2]),o=_r(d[3]),s=_r(d[4]),c=_r(d[5]),u=_r(d[6]),a=_r(d[7]),l=_r(d[8]),f=_r(d[9]),h=_r(d[10]),p=_r(d[11]),w=_r(d[12]),y=_r(d[13]),v=_r(d[14]),C=_r(d[15]),k=_r(d[16]),A=_r(d[17]),S=_r(d[18]),b=_r(d[19]),E=_r(d[20]),I=_r(d[21]),K=_r(d[22]),R=_r(d[23]),L=_r(d[24]),T=_r(d[25]),P=_r(d[26]),_=_r(d[27]);const D=[],F=[],O=[],M=[],j=[];function x(t,n){if(!n)return!0;const r=n.toLowerCase(),o=(t.title??"New agent").toLowerCase(),s=t.cwd.toLowerCase();return o.includes(r)||s.includes(r)}function W(t,n){if(!n)return!0;const r=n.toLowerCase(),o=(t.title??"").toLowerCase(),s=(t.cwd??"").toLowerCase(),c=t.sid.toLowerCase();return o.includes(r)||s.includes(r)||c.includes(r)}function q(t,n){const r=(t.pendingPermissionCount??0)>0?1:0,o=(n.pendingPermissionCount??0)>0?1:0;if(r!==o)return o-r;const s=t.requiresAttention?1:0,c=n.requiresAttention?1:0;if(s!==c)return c-s;const u="running"===t.status?1:0,a="running"===n.status?1:0;return u!==a?a-u:n.lastActivityAt.getTime()-t.lastActivityAt.getTime()}const B=[{id:"new-agent",titleKey:"shell.commandCenter.openProject",icon:"plus",actionId:"new-agent",keywords:["open","project","folder","workspace","repo"],routeKind:"none"},{id:"home",titleKey:"shell.commandCenter.home",icon:"home",keywords:["home","start","import","session","pair","device","providers"],routeKind:"home"},{id:"settings",titleKey:"sidebar.actions.settings",icon:"settings",keywords:["settings","preferences","config","configuration"],routeKind:"settings"}];function N(t,n,r){const o=t.trim().toLowerCase();return!o||(!!r.toLowerCase().includes(o)||n.keywords.some(t=>t.includes(o)))}function U(t,n){if(!t)return;const r={isMac:"mac"===(0,C.getShortcutOs)(),isDesktop:(0,k.getIsElectronRuntime)()},o=(0,y.getBindingIdForAction)(t,r);if(!o)return;const s=n[o];if(s)return(0,w.chordStringToShortcutKeys)(s);const c=(0,y.getDefaultKeysForAction)(t,r);return c?[c]:void 0}function H(){c.keyboardActionDispatcher.dispatch({id:"message-input.focus",scope:"message-input"})}function Q(t){return{kind:"action",id:t.id,title:t.title,run:t.run}}function $(t,n){return t.lastActivity<n.lastActivity?1:t.lastActivity>n.lastActivity?-1:0}function z(){}function G(){}function J(t){return t.setCommandCenterOpen}function V(t){return t.commandCenterOpen}},3264,[349,36,1143,1573,3265,3269,3270,3446,3447,3452,3479,3477,3480,3481,3482,3483,3457,3484,3486,3495,3414,3496,3497,3271,3407,3499,3503,3504]);
|
|
14910
14910
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"useKeyboardShortcutsStore",{enumerable:!0,get:function(){return s}});var t=r(d[0]);let o=null;function n(t,n){const{altDown:s,cmdOrCtrlDown:c}=n(),u=s||c;o&&(clearTimeout(o),o=null),u?o=setTimeout(()=>{t({showShortcutBadges:!0})},150):t({showShortcutBadges:!1})}const s=(0,t.create)((t,o)=>({commandCenterOpen:!1,shortcutsDialogOpen:!1,capturingShortcut:!1,altDown:!1,cmdOrCtrlDown:!1,showShortcutBadges:!1,sidebarShortcutWorkspaceTargets:[],setCommandCenterOpen:o=>t({commandCenterOpen:o}),setShortcutsDialogOpen:o=>t({shortcutsDialogOpen:o}),setCapturingShortcut:o=>t({capturingShortcut:o}),setAltDown:s=>{t({altDown:s}),n(t,o)},setCmdOrCtrlDown:s=>{t({cmdOrCtrlDown:s}),n(t,o)},setSidebarShortcutWorkspaceTargets:o=>t({sidebarShortcutWorkspaceTargets:o}),resetModifiers:()=>{t({altDown:!1,cmdOrCtrlDown:!1}),n(t,o)}}))},3265,[3266]);
|
|
14911
14911
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0});var t=r(d[0]);Object.keys(t).forEach(function(n){'default'===n||Object.prototype.hasOwnProperty.call(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[n]}})});var n=r(d[1]);Object.keys(n).forEach(function(t){'default'===t||Object.prototype.hasOwnProperty.call(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:function(){return n[t]}})})},3266,[3267,3268]);
|
|
14912
14912
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"createStore",{enumerable:!0,get:function(){return n}});const t=t=>{let n;const c=new Set,o=(t,o)=>{const s="function"==typeof t?t(n):t;if(!Object.is(s,n)){const t=n;n=(null!=o?o:"object"!=typeof s||null===s)?s:Object.assign({},n,s),c.forEach(c=>c(n,t))}},s=()=>n,u={setState:o,getState:s,getInitialState:()=>l,subscribe:t=>(c.add(t),()=>c.delete(t))},l=n=t(o,s,u);return u},n=n=>n?t(n):t},3267,[]);
|
|
@@ -15044,7 +15044,7 @@ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{v
|
|
|
15044
15044
|
__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])},3399,[3379,3400]);
|
|
15045
15045
|
__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}},3400,[3282]);
|
|
15046
15046
|
__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}},3401,[1006,3402]);
|
|
15047
|
-
__d(function(e,t,r,a,o,i,n){o.exports={name:"@hyperdrive.bot/paseo-app",version:"0.3.
|
|
15047
|
+
__d(function(e,t,r,a,o,i,n){o.exports={name:"@hyperdrive.bot/paseo-app",version:"0.3.23",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/paseo-client":"*","@hyperdrive.bot/paseo-expo-two-way-audio":"*","@hyperdrive.bot/paseo-extension-sdk":"*","@hyperdrive.bot/paseo-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","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"}}},3402,[]);
|
|
15048
15048
|
__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}}},3403,[3404,3406]);
|
|
15049
15049
|
__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()}},3404,[25,3405]);
|
|
15050
15050
|
__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}},3405,[]);
|
|
@@ -16539,5 +16539,5 @@ __d(function(g,r,_i,a,_m,_e,d){"use strict";var e,t=r(d[0]),n=this&&this.__creat
|
|
|
16539
16539
|
__r(975);
|
|
16540
16540
|
__r(341);
|
|
16541
16541
|
__r(0);
|
|
16542
|
-
//# sourceMappingURL=/_expo/static/js/web/index-
|
|
16543
|
-
//# debugId=
|
|
16542
|
+
//# sourceMappingURL=/_expo/static/js/web/index-47b07b144bbc651587bf14a2bf8bc9e4.js.map
|
|
16543
|
+
//# debugId=7cd4c1b0-8077-4285-991c-19c1481d11c5
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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-
|
|
88
|
+
<script src="/_expo/static/js/web/index-47b07b144bbc651587bf14a2bf8bc9e4.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": "@hyperdrive.bot/paseo-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.23",
|
|
4
4
|
"description": "Paseo backend server",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/server",
|
|
@@ -65,11 +65,11 @@
|
|
|
65
65
|
"@agentclientprotocol/sdk": "^0.17.1",
|
|
66
66
|
"@anthropic-ai/claude-agent-sdk": "^0.3.195",
|
|
67
67
|
"@anthropic-ai/sdk": "^0.104.2",
|
|
68
|
-
"@hyperdrive.bot/paseo-client": "0.3.
|
|
69
|
-
"@hyperdrive.bot/paseo-extension-sdk": "0.3.
|
|
70
|
-
"@hyperdrive.bot/paseo-highlight": "0.3.
|
|
71
|
-
"@hyperdrive.bot/paseo-protocol": "0.3.
|
|
72
|
-
"@hyperdrive.bot/paseo-relay": "0.3.
|
|
68
|
+
"@hyperdrive.bot/paseo-client": "0.3.23",
|
|
69
|
+
"@hyperdrive.bot/paseo-extension-sdk": "0.3.23",
|
|
70
|
+
"@hyperdrive.bot/paseo-highlight": "0.3.23",
|
|
71
|
+
"@hyperdrive.bot/paseo-protocol": "0.3.23",
|
|
72
|
+
"@hyperdrive.bot/paseo-relay": "0.3.23",
|
|
73
73
|
"@isaacs/ttlcache": "^2.1.4",
|
|
74
74
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
75
75
|
"@opencode-ai/sdk": "1.2.6",
|
|
Binary file
|