@hyperdrive.bot/paseo-server 0.3.8 → 0.3.10
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/agent.js +38 -0
- package/dist/server/server/agent/providers/claude/transport/pty-query.d.ts +31 -0
- package/dist/server/server/agent/providers/claude/transport/pty-query.js +97 -0
- package/dist/server/server/agent/providers/claude/transport/redact.d.ts +6 -0
- package/dist/server/server/agent/providers/claude/transport/redact.js +29 -1
- package/dist/server/server/agent/providers/claude/transport/transcript-sdk-reader.js +42 -3
- package/dist/server/web-ui/_expo/static/js/web/{index-68340cc45e88f3ef22a85ab2201b94ed.js → index-461cf3ab1d54d6debea0e037829768e9.js} +4 -4
- package/dist/server/web-ui/_expo/static/js/web/index-461cf3ab1d54d6debea0e037829768e9.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-461cf3ab1d54d6debea0e037829768e9.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-68340cc45e88f3ef22a85ab2201b94ed.js.map.br → index-461cf3ab1d54d6debea0e037829768e9.js.map.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-68340cc45e88f3ef22a85ab2201b94ed.js.map.gz → index-461cf3ab1d54d6debea0e037829768e9.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-68340cc45e88f3ef22a85ab2201b94ed.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-68340cc45e88f3ef22a85ab2201b94ed.js.gz +0 -0
|
@@ -3303,6 +3303,24 @@ export class ClaudeAgentSession {
|
|
|
3303
3303
|
if (message.subtype === "task_progress") {
|
|
3304
3304
|
return;
|
|
3305
3305
|
}
|
|
3306
|
+
// `api_error` is claude's transcript shape, not a member of the SDK's typed system
|
|
3307
|
+
// subtype union (which has `api_retry` instead), so read it off a widened record.
|
|
3308
|
+
if (toObjectRecord(message)?.subtype === "api_error") {
|
|
3309
|
+
// Provider failure (rate limit, auth, network). On the PTY transport this is the
|
|
3310
|
+
// ONLY way the failure can reach the user: the terminal that prints it is
|
|
3311
|
+
// unsubscribed after the readiness gate, and a turn that never recovers otherwise
|
|
3312
|
+
// renders as an endless spinner. Non-fatal on purpose, claude retries and the turn
|
|
3313
|
+
// still completes normally if a retry lands.
|
|
3314
|
+
const text = readApiErrorText(message);
|
|
3315
|
+
if (text) {
|
|
3316
|
+
events.push({
|
|
3317
|
+
type: "timeline",
|
|
3318
|
+
provider: "claude",
|
|
3319
|
+
item: { type: "error", message: text },
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3322
|
+
return;
|
|
3323
|
+
}
|
|
3306
3324
|
}
|
|
3307
3325
|
appendTaskNotificationEvents(message, events) {
|
|
3308
3326
|
// Expire a tracked background shell when its terminal notification lands.
|
|
@@ -4243,6 +4261,26 @@ function hasToolLikeBlock(block) {
|
|
|
4243
4261
|
const type = typeof block.type === "string" ? block.type.toLowerCase() : "";
|
|
4244
4262
|
return type.includes("tool");
|
|
4245
4263
|
}
|
|
4264
|
+
/**
|
|
4265
|
+
* Human-readable text from a `system` / `api_error` message. The PTY transport builds
|
|
4266
|
+
* these in transcript-sdk-reader from claude's own `error.formatted` (already redacted
|
|
4267
|
+
* there); the shape is tolerated loosely because it is not part of the SDK's typed union.
|
|
4268
|
+
*/
|
|
4269
|
+
function readApiErrorText(source) {
|
|
4270
|
+
const record = toObjectRecord(source);
|
|
4271
|
+
if (!record) {
|
|
4272
|
+
return null;
|
|
4273
|
+
}
|
|
4274
|
+
const error = toObjectRecord(record.error);
|
|
4275
|
+
const candidates = [error?.formatted, error?.message, record.message];
|
|
4276
|
+
for (const candidate of candidates) {
|
|
4277
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
4278
|
+
return candidate.trim();
|
|
4279
|
+
}
|
|
4280
|
+
}
|
|
4281
|
+
const status = error?.status;
|
|
4282
|
+
return typeof status === "number" ? `API error ${status}` : null;
|
|
4283
|
+
}
|
|
4246
4284
|
function readCompactionMetadata(source) {
|
|
4247
4285
|
const sourceRecord = toObjectRecord(source);
|
|
4248
4286
|
if (!sourceRecord) {
|
|
@@ -10,6 +10,11 @@ export interface PtyQueryOptions {
|
|
|
10
10
|
/** Optional synthesized system:init message. Omitted in MVP (not needed to render turns). */
|
|
11
11
|
initMessage?: SDKSystemMessage;
|
|
12
12
|
logger: Logger;
|
|
13
|
+
/**
|
|
14
|
+
* Transcript-silence budget for an in-flight turn, in ms. Defaults to
|
|
15
|
+
* {@link TURN_STALL_TIMEOUT_MS}. Pass `0` to disable the liveness backstop.
|
|
16
|
+
*/
|
|
17
|
+
stallTimeoutMs?: number;
|
|
13
18
|
}
|
|
14
19
|
export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
15
20
|
private readonly transport;
|
|
@@ -28,6 +33,9 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
28
33
|
private lastUsage;
|
|
29
34
|
private turnStartedAt;
|
|
30
35
|
private numTurns;
|
|
36
|
+
private readonly stallTimeoutMs;
|
|
37
|
+
private stallTimer;
|
|
38
|
+
private turnInFlight;
|
|
31
39
|
constructor(opts: PtyQueryOptions);
|
|
32
40
|
private emit;
|
|
33
41
|
next(): Promise<IteratorResult<SDKMessage, void>>;
|
|
@@ -47,7 +55,30 @@ export declare class PtyQuery implements AsyncGenerator<SDKMessage, void> {
|
|
|
47
55
|
private onTranscriptMessage;
|
|
48
56
|
private scheduleTurnEndCheck;
|
|
49
57
|
private maybeCompleteTurn;
|
|
58
|
+
/**
|
|
59
|
+
* (Re)arm the liveness backstop. Called when a turn starts and on every transcript
|
|
60
|
+
* message, so the deadline only expires after an unbroken window of silence.
|
|
61
|
+
*/
|
|
62
|
+
private armStallTimer;
|
|
63
|
+
private clearStallTimer;
|
|
64
|
+
/**
|
|
65
|
+
* No transcript activity for the whole budget while a turn was outstanding. Surface it as
|
|
66
|
+
* a failed turn instead of leaving the caller on an endless spinner. We do NOT kill the
|
|
67
|
+
* PTY: claude may still be retrying, and if it recovers its messages keep flowing through
|
|
68
|
+
* the reader as a fresh turn.
|
|
69
|
+
*/
|
|
70
|
+
private onTurnStalled;
|
|
50
71
|
private buildResult;
|
|
72
|
+
/**
|
|
73
|
+
* A non-success `result` for a stalled turn. agent.ts's `appendResultEvents()` turns any
|
|
74
|
+
* `subtype !== "success"` into a `turn_failed` carrying `errors.join("\n")`, which is what
|
|
75
|
+
* puts a real message in front of the user.
|
|
76
|
+
*
|
|
77
|
+
* Wording matters: `isAbortError()` suppresses results whose errors match /\baborted\b/i,
|
|
78
|
+
* and `buildTurnFailedEvent()` scrapes /\bcode\s+(\d+)\b/i for an exit code. Avoid both so
|
|
79
|
+
* this neither gets swallowed nor reports a phantom exit code.
|
|
80
|
+
*/
|
|
81
|
+
private buildStalledResult;
|
|
51
82
|
interrupt(): Promise<void>;
|
|
52
83
|
setPermissionMode(): Promise<void>;
|
|
53
84
|
setModel(): Promise<void>;
|
|
@@ -27,6 +27,27 @@ const READY_FIRST_DATA_SETTLE_MS = 1500;
|
|
|
27
27
|
const READY_MAX_WAIT_MS = 12000;
|
|
28
28
|
const TURN_END_IDLE_MS = 700;
|
|
29
29
|
const TERMINAL_STOP_REASONS = new Set(["end_turn", "stop_sequence", "max_tokens"]);
|
|
30
|
+
/**
|
|
31
|
+
* Liveness backstop: how long an in-flight turn may append NOTHING to the transcript
|
|
32
|
+
* before PtyQuery gives up and synthesizes a failed `result`.
|
|
33
|
+
*
|
|
34
|
+
* Without this the PTY path has no liveness detection at all, and a claude-side stall is
|
|
35
|
+
* indistinguishable from a long turn: the agent sits at `status: running` forever with no
|
|
36
|
+
* output, no error and no timeout. Observed 2026-07-31: an agent accepted a prompt, hit a
|
|
37
|
+
* provider auth failure, and stayed "running" for 2h33m emitting nothing, because
|
|
38
|
+
* - the PTY's own output is unsubscribed once the readiness gate settles, so whatever the
|
|
39
|
+
* TUI prints (`API Error 401 · Retrying in 32s`, …) is never seen, and
|
|
40
|
+
* - `scheduleTurnEndCheck()` is only ever armed from `onTranscriptMessage()`, so silence
|
|
41
|
+
* never arms anything, and `maybeCompleteTurn()` returns early unless it already saw a
|
|
42
|
+
* terminal `stop_reason`.
|
|
43
|
+
* `TURN_END_IDLE_MS` is a 700ms turn-BOUNDARY debounce, not a stall detector.
|
|
44
|
+
*
|
|
45
|
+
* Deliberately generous: a legitimate turn can be quiet for a long time (one slow tool call
|
|
46
|
+
* writes nothing until its `tool_result` lands), and a false positive marks a healthy turn
|
|
47
|
+
* failed. Ten minutes is far past any normal tool call while still bounded. Tune per-call
|
|
48
|
+
* with `stallTimeoutMs`; `0` disables the backstop entirely.
|
|
49
|
+
*/
|
|
50
|
+
const TURN_STALL_TIMEOUT_MS = 10 * 60000;
|
|
30
51
|
export class PtyQuery {
|
|
31
52
|
constructor(opts) {
|
|
32
53
|
// output queue → async iterator
|
|
@@ -40,11 +61,14 @@ export class PtyQuery {
|
|
|
40
61
|
this.lastUsage = null;
|
|
41
62
|
this.turnStartedAt = 0;
|
|
42
63
|
this.numTurns = 0;
|
|
64
|
+
this.stallTimer = null;
|
|
65
|
+
this.turnInFlight = false;
|
|
43
66
|
this.transport = opts.transport;
|
|
44
67
|
this.input = opts.input;
|
|
45
68
|
this.sessionId = opts.sessionId;
|
|
46
69
|
this.transcriptPath = opts.transcriptPath;
|
|
47
70
|
this.logger = opts.logger;
|
|
71
|
+
this.stallTimeoutMs = opts.stallTimeoutMs ?? TURN_STALL_TIMEOUT_MS;
|
|
48
72
|
this.reader = new TranscriptSdkReader({
|
|
49
73
|
transcriptPath: opts.transcriptPath,
|
|
50
74
|
onMessage: (m) => this.onTranscriptMessage(m),
|
|
@@ -103,6 +127,8 @@ export class PtyQuery {
|
|
|
103
127
|
if (this.turnEndTimer)
|
|
104
128
|
clearTimeout(this.turnEndTimer);
|
|
105
129
|
this.turnEndTimer = null;
|
|
130
|
+
this.turnInFlight = false;
|
|
131
|
+
this.clearStallTimer();
|
|
106
132
|
this.offReadyData?.();
|
|
107
133
|
try {
|
|
108
134
|
this.reader.stop();
|
|
@@ -130,6 +156,11 @@ export class PtyQuery {
|
|
|
130
156
|
await this.transport.write(text);
|
|
131
157
|
await delay(200);
|
|
132
158
|
await this.submitTurn();
|
|
159
|
+
// The turn is now claude's to answer; start the liveness clock. submitTurn() has
|
|
160
|
+
// already confirmed claude accepted it (the transcript grew), so from here on
|
|
161
|
+
// silence means a stall, not a slow start.
|
|
162
|
+
this.turnInFlight = true;
|
|
163
|
+
this.armStallTimer();
|
|
133
164
|
}
|
|
134
165
|
}
|
|
135
166
|
catch (err) {
|
|
@@ -168,6 +199,8 @@ export class PtyQuery {
|
|
|
168
199
|
if (beta.usage)
|
|
169
200
|
this.lastUsage = beta.usage;
|
|
170
201
|
}
|
|
202
|
+
// Any transcript activity proves the turn is alive; push the stall deadline out.
|
|
203
|
+
this.armStallTimer();
|
|
171
204
|
this.scheduleTurnEndCheck();
|
|
172
205
|
}
|
|
173
206
|
scheduleTurnEndCheck() {
|
|
@@ -182,10 +215,50 @@ export class PtyQuery {
|
|
|
182
215
|
if (!stop || !TERMINAL_STOP_REASONS.has(stop))
|
|
183
216
|
return; // e.g. "tool_use" → more coming
|
|
184
217
|
this.numTurns += 1;
|
|
218
|
+
// The turn ended on its own; stand the liveness backstop down before emitting.
|
|
219
|
+
this.turnInFlight = false;
|
|
220
|
+
this.clearStallTimer();
|
|
185
221
|
this.emit(this.buildResult(stop));
|
|
186
222
|
// reset so a stale terminal reason can't re-fire before the next assistant turn
|
|
187
223
|
this.lastStopReason = null;
|
|
188
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* (Re)arm the liveness backstop. Called when a turn starts and on every transcript
|
|
227
|
+
* message, so the deadline only expires after an unbroken window of silence.
|
|
228
|
+
*/
|
|
229
|
+
armStallTimer() {
|
|
230
|
+
if (this.stallTimeoutMs <= 0 || !this.turnInFlight)
|
|
231
|
+
return;
|
|
232
|
+
this.clearStallTimer();
|
|
233
|
+
this.stallTimer = setTimeout(() => this.onTurnStalled(), this.stallTimeoutMs);
|
|
234
|
+
// Never hold the event loop open just to wait for a stall.
|
|
235
|
+
this.stallTimer.unref?.();
|
|
236
|
+
}
|
|
237
|
+
clearStallTimer() {
|
|
238
|
+
if (this.stallTimer)
|
|
239
|
+
clearTimeout(this.stallTimer);
|
|
240
|
+
this.stallTimer = null;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* No transcript activity for the whole budget while a turn was outstanding. Surface it as
|
|
244
|
+
* a failed turn instead of leaving the caller on an endless spinner. We do NOT kill the
|
|
245
|
+
* PTY: claude may still be retrying, and if it recovers its messages keep flowing through
|
|
246
|
+
* the reader as a fresh turn.
|
|
247
|
+
*/
|
|
248
|
+
onTurnStalled() {
|
|
249
|
+
this.stallTimer = null;
|
|
250
|
+
if (this.done || !this.turnInFlight)
|
|
251
|
+
return;
|
|
252
|
+
this.turnInFlight = false;
|
|
253
|
+
const silentForMs = this.stallTimeoutMs;
|
|
254
|
+
this.logger.error({
|
|
255
|
+
sessionId: this.sessionId,
|
|
256
|
+
transcriptPath: this.transcriptPath,
|
|
257
|
+
silentForMs,
|
|
258
|
+
}, "PtyQuery: turn stalled, no transcript activity within the liveness budget");
|
|
259
|
+
this.numTurns += 1;
|
|
260
|
+
this.emit(this.buildStalledResult(silentForMs));
|
|
261
|
+
}
|
|
189
262
|
buildResult(stopReason) {
|
|
190
263
|
const usage = (this.lastUsage ?? {
|
|
191
264
|
input_tokens: 0,
|
|
@@ -211,6 +284,30 @@ export class PtyQuery {
|
|
|
211
284
|
};
|
|
212
285
|
return result;
|
|
213
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* A non-success `result` for a stalled turn. agent.ts's `appendResultEvents()` turns any
|
|
289
|
+
* `subtype !== "success"` into a `turn_failed` carrying `errors.join("\n")`, which is what
|
|
290
|
+
* puts a real message in front of the user.
|
|
291
|
+
*
|
|
292
|
+
* Wording matters: `isAbortError()` suppresses results whose errors match /\baborted\b/i,
|
|
293
|
+
* and `buildTurnFailedEvent()` scrapes /\bcode\s+(\d+)\b/i for an exit code. Avoid both so
|
|
294
|
+
* this neither gets swallowed nor reports a phantom exit code.
|
|
295
|
+
*/
|
|
296
|
+
buildStalledResult(silentForMs) {
|
|
297
|
+
const minutes = Math.round(silentForMs / 60000);
|
|
298
|
+
const base = this.buildResult("stall_timeout");
|
|
299
|
+
return {
|
|
300
|
+
...base,
|
|
301
|
+
subtype: "error_during_execution",
|
|
302
|
+
is_error: true,
|
|
303
|
+
errors: [
|
|
304
|
+
`No response from the claude PTY session for ${minutes} min. ` +
|
|
305
|
+
`The turn was accepted but produced no output, so it was marked failed. ` +
|
|
306
|
+
`The underlying session is still running and may recover; check the provider ` +
|
|
307
|
+
`endpoint and credentials, then retry.`,
|
|
308
|
+
],
|
|
309
|
+
};
|
|
310
|
+
}
|
|
214
311
|
// ---- control surface ------------------------------------------------------
|
|
215
312
|
async interrupt() {
|
|
216
313
|
// ESC interrupts the active turn in the claude TUI.
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strip credentials from text about to be persisted or shown to a user. Used for PTY
|
|
3
|
+
* output (see {@link redactChunk}) and for provider error text lifted out of the session
|
|
4
|
+
* transcript, which is the one path on which a key can reach the timeline.
|
|
5
|
+
*/
|
|
6
|
+
export declare function redactSecrets(text: string): string;
|
|
1
7
|
export declare function redactChunk(chunk: string): string;
|
|
2
8
|
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
const JWT_PATTERN = /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g;
|
|
2
|
+
/**
|
|
3
|
+
* Bearer-style credentials that turn up in provider error text and terminal output.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately prefix-anchored rather than "any long random-looking string": provider
|
|
6
|
+
* errors carry plenty of high-entropy non-secrets (request ids, uuids, session ids) and
|
|
7
|
+
* scrubbing those would make a surfaced error useless for diagnosis. Each entry is a
|
|
8
|
+
* credential shape that actually reaches this path:
|
|
9
|
+
* - `sk-ant-…` Anthropic API keys
|
|
10
|
+
* - `cp_…` claude-proxy client keys (paseo `agents.providers.*.env`)
|
|
11
|
+
* - `hd_sk_…` hyperdrive CI tokens
|
|
12
|
+
*/
|
|
13
|
+
const SECRET_PATTERNS = [
|
|
14
|
+
[/sk-ant-[A-Za-z0-9_-]{16,}/g, "[REDACTED-KEY]"],
|
|
15
|
+
[/\bcp_[A-Za-z0-9_-]{16,}/g, "[REDACTED-KEY]"],
|
|
16
|
+
[/\bhd_sk_[A-Za-z0-9_-]{16,}/g, "[REDACTED-KEY]"],
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Strip credentials from text about to be persisted or shown to a user. Used for PTY
|
|
20
|
+
* output (see {@link redactChunk}) and for provider error text lifted out of the session
|
|
21
|
+
* transcript, which is the one path on which a key can reach the timeline.
|
|
22
|
+
*/
|
|
23
|
+
export function redactSecrets(text) {
|
|
24
|
+
let out = text.replace(JWT_PATTERN, "[REDACTED-JWT]");
|
|
25
|
+
for (const [pattern, replacement] of SECRET_PATTERNS) {
|
|
26
|
+
out = out.replace(pattern, replacement);
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
2
30
|
export function redactChunk(chunk) {
|
|
3
|
-
return chunk
|
|
31
|
+
return redactSecrets(chunk);
|
|
4
32
|
}
|
|
5
33
|
//# sourceMappingURL=redact.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
+
import { redactSecrets } from "./redact.js";
|
|
2
3
|
/**
|
|
3
4
|
* Tails a Claude Code session-transcript JSONL (`~/.claude/projects/<slug>/<sid>.jsonl`)
|
|
4
5
|
* and reconstructs the `SDKMessage` stream the query pump consumes — so the PTY transport
|
|
@@ -12,7 +13,12 @@ import * as fs from "node:fs";
|
|
|
12
13
|
* emitSubmittedUserMessage, so re-yielding would double-render)
|
|
13
14
|
* - `isSidechain` lines (subagent messages live in `<sid>/subagents/*.jsonl`, tracked
|
|
14
15
|
* separately by ClaudeSidechainTracker)
|
|
15
|
-
* - `system` lines (PtyQuery synthesizes the init message
|
|
16
|
+
* - `system` lines, EXCEPT `subtype: "api_error"` (PtyQuery synthesizes the init message
|
|
17
|
+
* from buildOptions instead). The api_error exception matters: claude writes provider
|
|
18
|
+
* failures here (`429 Rate limit ... Retry in 16s`, auth failures, network drops) and
|
|
19
|
+
* dropping them was the reason a rate-limited agent showed a spinner and nothing else.
|
|
20
|
+
* The PTY path cannot recover these anywhere else, because the terminal that prints
|
|
21
|
+
* them is unsubscribed once the readiness gate settles.
|
|
16
22
|
* - `result` (transcript has none — PtyQuery synthesizes it on the Stop hook)
|
|
17
23
|
* - bookkeeping: attachment / queue-operation / last-prompt / file-history-snapshot
|
|
18
24
|
*
|
|
@@ -21,6 +27,22 @@ import * as fs from "node:fs";
|
|
|
21
27
|
* object is already the exact BetaMessage/MessageParam the SDK produced — passed through.
|
|
22
28
|
*/
|
|
23
29
|
const POLL_INTERVAL_MS = 200;
|
|
30
|
+
/**
|
|
31
|
+
* Human-readable text for an `api_error` line. Prefers claude's own `formatted` string
|
|
32
|
+
* (`"429 Rate limit: ... Retry in 16s."`), which is already the terse one-liner the TUI
|
|
33
|
+
* shows; falls back to the raw message, then to the bare status.
|
|
34
|
+
*/
|
|
35
|
+
function describeApiError(line) {
|
|
36
|
+
const err = line.error;
|
|
37
|
+
if (!err)
|
|
38
|
+
return null;
|
|
39
|
+
const text = (err.formatted ?? err.message ?? "").trim();
|
|
40
|
+
if (text)
|
|
41
|
+
return text;
|
|
42
|
+
if (typeof err.status === "number")
|
|
43
|
+
return `API error ${err.status}`;
|
|
44
|
+
return "API error";
|
|
45
|
+
}
|
|
24
46
|
export class TranscriptSdkReader {
|
|
25
47
|
constructor(opts) {
|
|
26
48
|
this.timer = null;
|
|
@@ -142,9 +164,26 @@ export class TranscriptSdkReader {
|
|
|
142
164
|
};
|
|
143
165
|
return message;
|
|
144
166
|
}
|
|
167
|
+
case "system": {
|
|
168
|
+
// Only api_error. Every other system subtype really is bookkeeping (init is
|
|
169
|
+
// synthesized by PtyQuery, status/compact_boundary/task_* are SDK-path concerns).
|
|
170
|
+
if (line.subtype !== "api_error")
|
|
171
|
+
return null;
|
|
172
|
+
const text = describeApiError(line);
|
|
173
|
+
if (!text)
|
|
174
|
+
return null;
|
|
175
|
+
const message = {
|
|
176
|
+
type: "system",
|
|
177
|
+
subtype: "api_error",
|
|
178
|
+
level: line.level ?? "error",
|
|
179
|
+
error: { message: redactSecrets(text) },
|
|
180
|
+
uuid,
|
|
181
|
+
session_id,
|
|
182
|
+
};
|
|
183
|
+
return message;
|
|
184
|
+
}
|
|
145
185
|
default:
|
|
146
|
-
//
|
|
147
|
-
// paseo/CC bookkeeping the pump never reads.
|
|
186
|
+
// result → synthesized on Stop; the rest is paseo/CC bookkeeping the pump never reads.
|
|
148
187
|
return null;
|
|
149
188
|
}
|
|
150
189
|
}
|
|
@@ -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.10\",\"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.10",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,[]);
|
|
@@ -16537,5 +16537,5 @@ __d(function(g,r,_i,a,_m,_e,d){"use strict";var e,t=r(d[0]),n=this&&this.__creat
|
|
|
16537
16537
|
__r(975);
|
|
16538
16538
|
__r(341);
|
|
16539
16539
|
__r(0);
|
|
16540
|
-
//# sourceMappingURL=/_expo/static/js/web/index-
|
|
16541
|
-
//# debugId=
|
|
16540
|
+
//# sourceMappingURL=/_expo/static/js/web/index-461cf3ab1d54d6debea0e037829768e9.js.map
|
|
16541
|
+
//# debugId=0f2139ee-ae03-4ea5-b1f0-060337e29480
|
|
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-461cf3ab1d54d6debea0e037829768e9.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.10",
|
|
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.10",
|
|
69
|
+
"@hyperdrive.bot/paseo-extension-sdk": "0.3.10",
|
|
70
|
+
"@hyperdrive.bot/paseo-highlight": "0.3.10",
|
|
71
|
+
"@hyperdrive.bot/paseo-protocol": "0.3.10",
|
|
72
|
+
"@hyperdrive.bot/paseo-relay": "0.3.10",
|
|
73
73
|
"@isaacs/ttlcache": "^2.1.4",
|
|
74
74
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
75
75
|
"@opencode-ai/sdk": "1.2.6",
|
|
Binary file
|