@hyperdrive.bot/paseo-server 0.3.15 → 0.3.16
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 +14 -0
- package/dist/server/server/agent/providers/claude/transport/pty-query.js +104 -2
- package/dist/server/web-ui/_expo/static/js/web/{index-638e4dd51cc8b1802850f1fd8ad63b97.js → index-bb2e4887026c2e6d1254dee6e102847d.js} +4 -4
- package/dist/server/web-ui/_expo/static/js/web/index-bb2e4887026c2e6d1254dee6e102847d.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-638e4dd51cc8b1802850f1fd8ad63b97.js.gz → index-bb2e4887026c2e6d1254dee6e102847d.js.gz} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-638e4dd51cc8b1802850f1fd8ad63b97.js.map.br → index-bb2e4887026c2e6d1254dee6e102847d.js.map.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-638e4dd51cc8b1802850f1fd8ad63b97.js.map.gz → index-bb2e4887026c2e6d1254dee6e102847d.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-638e4dd51cc8b1802850f1fd8ad63b97.js.br +0 -0
|
@@ -60,6 +60,8 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
60
60
|
private lastBusyAt;
|
|
61
61
|
/** Last sighting of the large-session resume dialog. 0 = never seen. */
|
|
62
62
|
private resumeDialogAt;
|
|
63
|
+
/** Set when the CLI rejected the just-submitted command; carries the CLI's own reply. */
|
|
64
|
+
private rejectedCommandNotice;
|
|
63
65
|
private interruptPromptAt;
|
|
64
66
|
constructor(opts: PtyQueryOptions);
|
|
65
67
|
private emit;
|
|
@@ -77,6 +79,8 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
77
79
|
* resend. Shaped as a normal result so it renders in the timeline rather than being
|
|
78
80
|
* buried in the daemon log.
|
|
79
81
|
*/
|
|
82
|
+
/** The CLI refused the command; relay its own reply so the sender can correct and resend. */
|
|
83
|
+
private buildCommandRejectedResult;
|
|
80
84
|
private buildSubmitFailedResult;
|
|
81
85
|
/**
|
|
82
86
|
* Press Enter to submit the composed prompt, and CONFIRM the turn actually started by
|
|
@@ -110,6 +114,16 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
110
114
|
* Down+Enter is at best a wasted keystroke and at worst an answer to a different menu.
|
|
111
115
|
*/
|
|
112
116
|
private answerResumeDialog;
|
|
117
|
+
/**
|
|
118
|
+
* Type the prompt and confirm the terminal actually received it, retrying against a
|
|
119
|
+
* deaf terminal with backoff.
|
|
120
|
+
*
|
|
121
|
+
* Returns true once an echo (or a transcript user line) confirms the keystrokes landed;
|
|
122
|
+
* false only after the terminal stayed deaf for the whole {@link READY_BUSY_MAX_WAIT_MS}
|
|
123
|
+
* ceiling. Retyping cannot double-deliver: a deaf terminal demonstrably discards input
|
|
124
|
+
* (zero echo), and every iteration first checks whether a user line landed anyway.
|
|
125
|
+
*/
|
|
126
|
+
private typeWithEchoVerify;
|
|
113
127
|
private submitTurn;
|
|
114
128
|
/**
|
|
115
129
|
* True once a real `user` line has been appended past `offset`. Reads only the bytes
|
|
@@ -73,6 +73,24 @@ const TURN_END_IDLE_MS = 700;
|
|
|
73
73
|
* run it twice.
|
|
74
74
|
*/
|
|
75
75
|
const SLASH_COMMAND_ECHO_WAIT_MS = 3000;
|
|
76
|
+
/**
|
|
77
|
+
* Echo-verified delivery.
|
|
78
|
+
*
|
|
79
|
+
* A claude TUI that is still parsing a large resumed transcript PAINTS its idle footer
|
|
80
|
+
* before its input loop is live, and in that state it DISCARDS keystrokes: typing produces
|
|
81
|
+
* no echo at all. Observed 2026-08-03 on a 215MB session: attach at 13:03:00, idle footer
|
|
82
|
+
* by 13:03:04, prompt typed plus five Enters, zero echo in the recording, no user line,
|
|
83
|
+
* message lost -- while every successful delivery in the same recordings shows the typed
|
|
84
|
+
* text echoed back. Echo is therefore the one signal that distinguishes "idle" from
|
|
85
|
+
* "idle-looking but deaf", and its absence also proves the keystrokes were discarded,
|
|
86
|
+
* which is exactly what makes retyping safe rather than a duplication risk.
|
|
87
|
+
*/
|
|
88
|
+
const ECHO_VERIFY_WINDOW_MS = 1500;
|
|
89
|
+
/** Minimum PTY bytes that count as an echo; a real input-box repaint is far larger. */
|
|
90
|
+
const ECHO_MIN_BYTES = 8;
|
|
91
|
+
/** Backoff between retype attempts against a deaf terminal. */
|
|
92
|
+
const DEAF_RETRY_INITIAL_MS = 5000;
|
|
93
|
+
const DEAF_RETRY_MAX_MS = 60000;
|
|
76
94
|
const TERMINAL_STOP_REASONS = new Set(["end_turn", "stop_sequence", "max_tokens"]);
|
|
77
95
|
/**
|
|
78
96
|
* Liveness backstop: how long an in-flight turn may append NOTHING to the transcript
|
|
@@ -218,6 +236,8 @@ export class PtyQuery {
|
|
|
218
236
|
this.lastBusyAt = 0;
|
|
219
237
|
/** Last sighting of the large-session resume dialog. 0 = never seen. */
|
|
220
238
|
this.resumeDialogAt = 0;
|
|
239
|
+
/** Set when the CLI rejected the just-submitted command; carries the CLI's own reply. */
|
|
240
|
+
this.rejectedCommandNotice = null;
|
|
221
241
|
this.interruptPromptAt = 0;
|
|
222
242
|
this.transport = opts.transport;
|
|
223
243
|
this.input = opts.input;
|
|
@@ -417,11 +437,32 @@ export class PtyQuery {
|
|
|
417
437
|
// consumed by it, so recovering at submit time is already too late.
|
|
418
438
|
await this.answerResumeDialog();
|
|
419
439
|
await this.clearInterruptPrompt();
|
|
420
|
-
|
|
421
|
-
|
|
440
|
+
// Deliberately NOT normalized (e.g. lowercasing an auto-capitalized command
|
|
441
|
+
// token): paseo must never silently rewrite what the user typed. A wrong command is
|
|
442
|
+
// handled by relaying the CLI's own rejection -- including its "did you mean"
|
|
443
|
+
// suggestion -- back to the sender, which corrects every rejection cause honestly
|
|
444
|
+
// instead of hiding one narrow cause invisibly.
|
|
445
|
+
const typed = await this.typeWithEchoVerify(text);
|
|
446
|
+
if (this.done)
|
|
447
|
+
break;
|
|
448
|
+
if (!typed) {
|
|
449
|
+
// The terminal stayed deaf for the whole ceiling: keystrokes discarded, nothing
|
|
450
|
+
// delivered, and only the sender can decide what to do next.
|
|
451
|
+
this.recordLine("--- terminal deaf for the whole budget; message not delivered ---");
|
|
452
|
+
this.emit(this.buildSubmitFailedResult());
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
422
455
|
const started = await this.submitTurn(text);
|
|
423
456
|
if (!started && this.done)
|
|
424
457
|
break;
|
|
458
|
+
if (!started && this.rejectedCommandNotice) {
|
|
459
|
+
// Not lost, refused: hand the CLI's own answer (which includes its "did you
|
|
460
|
+
// mean" suggestion) to the sender instead of a phantom running turn.
|
|
461
|
+
const notice = this.rejectedCommandNotice;
|
|
462
|
+
this.rejectedCommandNotice = null;
|
|
463
|
+
this.emit(this.buildCommandRejectedResult(notice));
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
425
466
|
if (!started && !this.looksIdle()) {
|
|
426
467
|
// NOT a lost message. The TUI accepts keystrokes into a queue while a turn is
|
|
427
468
|
// running and only writes the user line when that turn ends, which can be far
|
|
@@ -460,6 +501,16 @@ export class PtyQuery {
|
|
|
460
501
|
* resend. Shaped as a normal result so it renders in the timeline rather than being
|
|
461
502
|
* buried in the daemon log.
|
|
462
503
|
*/
|
|
504
|
+
/** The CLI refused the command; relay its own reply so the sender can correct and resend. */
|
|
505
|
+
buildCommandRejectedResult(notice) {
|
|
506
|
+
const base = this.buildResult("submit_failed");
|
|
507
|
+
return {
|
|
508
|
+
...base,
|
|
509
|
+
subtype: "error_during_execution",
|
|
510
|
+
is_error: true,
|
|
511
|
+
errors: [`The agent's CLI rejected the command: ${notice} Nothing was run.`],
|
|
512
|
+
};
|
|
513
|
+
}
|
|
463
514
|
buildSubmitFailedResult() {
|
|
464
515
|
const base = this.buildResult("submit_failed");
|
|
465
516
|
const excerpt = this.terminalTail.slice(-TERMINAL_TAIL_EXCERPT_CHARS).trim();
|
|
@@ -541,6 +592,42 @@ export class PtyQuery {
|
|
|
541
592
|
await delay(500);
|
|
542
593
|
this.resumeDialogAt = 0;
|
|
543
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* Type the prompt and confirm the terminal actually received it, retrying against a
|
|
597
|
+
* deaf terminal with backoff.
|
|
598
|
+
*
|
|
599
|
+
* Returns true once an echo (or a transcript user line) confirms the keystrokes landed;
|
|
600
|
+
* false only after the terminal stayed deaf for the whole {@link READY_BUSY_MAX_WAIT_MS}
|
|
601
|
+
* ceiling. Retyping cannot double-deliver: a deaf terminal demonstrably discards input
|
|
602
|
+
* (zero echo), and every iteration first checks whether a user line landed anyway.
|
|
603
|
+
*/
|
|
604
|
+
async typeWithEchoVerify(text) {
|
|
605
|
+
const transcriptBefore = this.transcriptSize();
|
|
606
|
+
const deadline = monotonicNowMs() + READY_BUSY_MAX_WAIT_MS;
|
|
607
|
+
let backoff = DEAF_RETRY_INITIAL_MS;
|
|
608
|
+
let attempt = 0;
|
|
609
|
+
while (!this.done && monotonicNowMs() < deadline) {
|
|
610
|
+
attempt += 1;
|
|
611
|
+
const bytesBefore = this.ptyBytesTotal;
|
|
612
|
+
await this.transport.write(text);
|
|
613
|
+
const echoed = await pollUntil(() => this.ptyBytesTotal - bytesBefore >= ECHO_MIN_BYTES, ECHO_VERIFY_WINDOW_MS, 100);
|
|
614
|
+
if (echoed) {
|
|
615
|
+
if (attempt > 1) {
|
|
616
|
+
this.recordLine(`--- terminal came back after ${attempt - 1} deaf attempt(s); prompt delivered ---`);
|
|
617
|
+
}
|
|
618
|
+
await delay(200);
|
|
619
|
+
return true;
|
|
620
|
+
}
|
|
621
|
+
// Deaf. The keystrokes were discarded (no echo), so waiting and retyping is safe.
|
|
622
|
+
if (this.sawUserLineSince(transcriptBefore))
|
|
623
|
+
return true;
|
|
624
|
+
this.logger.warn({ sessionId: this.sessionId, attempt, nextRetryMs: backoff }, "PtyQuery: terminal painted but is not accepting input yet; holding the prompt");
|
|
625
|
+
this.recordLine(`--- terminal deaf (attempt ${attempt}); retrying in ${Math.round(backoff / 1000)}s ---`);
|
|
626
|
+
await delay(backoff);
|
|
627
|
+
backoff = Math.min(backoff * 2, DEAF_RETRY_MAX_MS);
|
|
628
|
+
}
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
544
631
|
async submitTurn(text) {
|
|
545
632
|
const before = this.transcriptSize();
|
|
546
633
|
// A slash command gets EXACTLY ONE Enter. Never retry it.
|
|
@@ -567,6 +654,21 @@ export class PtyQuery {
|
|
|
567
654
|
const bytesBefore = this.ptyBytesTotal;
|
|
568
655
|
await this.transport.writeRaw?.("\r");
|
|
569
656
|
const reacted = await pollUntil(() => this.sawUserLineSince(before) || this.ptyBytesTotal > bytesBefore, SLASH_COMMAND_ECHO_WAIT_MS, 150);
|
|
657
|
+
// The terminal responding is not the same as the command running. An unknown command
|
|
658
|
+
// is answered with `Unknown command: /X. Did you mean /y?` and NOTHING starts -- but
|
|
659
|
+
// that reply previously counted as acceptance, so the app showed a running turn that
|
|
660
|
+
// did not exist and the sender saw dead silence. Observed live: a phone-keyboard
|
|
661
|
+
// auto-capitalized "/WhatsApp-read" rejected twice while the UI said "working".
|
|
662
|
+
// Checked regardless of the byte-poll outcome: the rejection can repaint before the
|
|
663
|
+
// poll's baseline is captured, in which case `reacted` is false but the refusal is
|
|
664
|
+
// already sitting in the tail.
|
|
665
|
+
await delay(400);
|
|
666
|
+
const m = this.terminalTail.slice(-500).match(/Unknown command:[^\n]{0,160}/i);
|
|
667
|
+
if (m) {
|
|
668
|
+
this.rejectedCommandNotice = m[0].trim();
|
|
669
|
+
this.recordLine(`--- CLI rejected the command: ${this.rejectedCommandNotice} ---`);
|
|
670
|
+
return false;
|
|
671
|
+
}
|
|
570
672
|
if (!reacted) {
|
|
571
673
|
this.logger.warn({ sessionId: this.sessionId, command: text.trim().split(/\s/, 1)[0] }, "PtyQuery: slash command produced no terminal response; not retrying to avoid double execution");
|
|
572
674
|
}
|
|
@@ -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.16\",\"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]);
|
|
@@ -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.16",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,[]);
|
|
@@ -16538,5 +16538,5 @@ __d(function(g,r,_i,a,_m,_e,d){"use strict";var e,t=r(d[0]),n=this&&this.__creat
|
|
|
16538
16538
|
__r(975);
|
|
16539
16539
|
__r(341);
|
|
16540
16540
|
__r(0);
|
|
16541
|
-
//# sourceMappingURL=/_expo/static/js/web/index-
|
|
16542
|
-
//# debugId=
|
|
16541
|
+
//# sourceMappingURL=/_expo/static/js/web/index-bb2e4887026c2e6d1254dee6e102847d.js.map
|
|
16542
|
+
//# debugId=be672a5b-d536-40fb-aef8-47922046962c
|
|
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-bb2e4887026c2e6d1254dee6e102847d.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.16",
|
|
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.16",
|
|
69
|
+
"@hyperdrive.bot/paseo-extension-sdk": "0.3.16",
|
|
70
|
+
"@hyperdrive.bot/paseo-highlight": "0.3.16",
|
|
71
|
+
"@hyperdrive.bot/paseo-protocol": "0.3.16",
|
|
72
|
+
"@hyperdrive.bot/paseo-relay": "0.3.16",
|
|
73
73
|
"@isaacs/ttlcache": "^2.1.4",
|
|
74
74
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
75
75
|
"@opencode-ai/sdk": "1.2.6",
|