@hyperdrive.bot/fleet-server 0.3.140 → 0.3.141
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.d.ts +12 -0
- package/dist/server/server/agent/providers/claude/agent.js +119 -28
- package/dist/server/web-ui/_expo/static/js/web/{index-25c59c2eb63391a475704950f8759b0f.js → index-cc716b9bd29f4801a9439c028fb5b5e2.js} +4 -4
- package/dist/server/web-ui/_expo/static/js/web/index-cc716b9bd29f4801a9439c028fb5b5e2.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-cc716b9bd29f4801a9439c028fb5b5e2.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-25c59c2eb63391a475704950f8759b0f.js.map.br → index-cc716b9bd29f4801a9439c028fb5b5e2.js.map.br} +0 -0
- package/dist/server/web-ui/_expo/static/js/web/{index-25c59c2eb63391a475704950f8759b0f.js.map.gz → index-cc716b9bd29f4801a9439c028fb5b5e2.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-25c59c2eb63391a475704950f8759b0f.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-25c59c2eb63391a475704950f8759b0f.js.gz +0 -0
|
@@ -44,6 +44,7 @@ interface ClaudeAgentSessionOptions {
|
|
|
44
44
|
resolveBinary: () => Promise<string>;
|
|
45
45
|
resumeSessionId?: string;
|
|
46
46
|
}
|
|
47
|
+
export declare function resolvePtyIdleSuspendMs(env?: NodeJS.ProcessEnv): number;
|
|
47
48
|
export declare function extractUserMessageText(content: unknown): string | null;
|
|
48
49
|
export declare function toClaudeSdkMcpConfig(config: McpServerConfig): ClaudeSdkMcpServerConfig;
|
|
49
50
|
export declare function readEventIdentifiers(message: SDKMessage): EventIdentifiers;
|
|
@@ -172,6 +173,9 @@ export declare class ClaudeAgentSession implements AgentSession {
|
|
|
172
173
|
private readonly turnIdReconciler;
|
|
173
174
|
private readonly rewindTurnAnchors;
|
|
174
175
|
private pendingFreshSessionId;
|
|
176
|
+
private idleSuspendTimer;
|
|
177
|
+
/** Last command list, so a suspended session can answer the palette without respawning. */
|
|
178
|
+
private cachedCommands;
|
|
175
179
|
/**
|
|
176
180
|
* Parsed per-run tool allowlist. Empty array = no allowlist configured, which
|
|
177
181
|
* is the historical behaviour (everything the permission mode permits runs).
|
|
@@ -303,6 +307,11 @@ export declare class ClaudeAgentSession implements AgentSession {
|
|
|
303
307
|
private rememberTranscriptProgress;
|
|
304
308
|
private resolveClaudeMessageId;
|
|
305
309
|
private resolveConversationRewindTarget;
|
|
310
|
+
/**
|
|
311
|
+
* End the current query and its process tree while keeping the session and its pinned
|
|
312
|
+
* claudeSessionId, so the next ensureQuery() resumes the same conversation.
|
|
313
|
+
*/
|
|
314
|
+
private teardownQuery;
|
|
306
315
|
private ensureQuery;
|
|
307
316
|
private awaitWithTimeout;
|
|
308
317
|
private resolveThinkingConfig;
|
|
@@ -341,6 +350,9 @@ export declare class ClaudeAgentSession implements AgentSession {
|
|
|
341
350
|
private toSdkUserMessage;
|
|
342
351
|
private enforceCumulativeImageBudget;
|
|
343
352
|
private transitionTurnState;
|
|
353
|
+
/** Arm the idle-suspend timer while a PTY session sits idle with a live query; clear it otherwise. */
|
|
354
|
+
private updateIdleSuspendTimer;
|
|
355
|
+
private suspendIdleQuery;
|
|
344
356
|
private syncTurnState;
|
|
345
357
|
private isAbortError;
|
|
346
358
|
private buildTurnFailedEvent;
|
|
@@ -269,6 +269,32 @@ function isClaudeThinkingOption(value) {
|
|
|
269
269
|
const MAX_RECENT_STDERR_CHARS = 4000;
|
|
270
270
|
const STDERR_FLUSH_WAIT_MS = 150;
|
|
271
271
|
const STDERR_FLUSH_POLL_INTERVAL_MS = 10;
|
|
272
|
+
/**
|
|
273
|
+
* Idle window after which a PTY agent's claude process is suspended.
|
|
274
|
+
*
|
|
275
|
+
* Under the PTY transport claude runs inside tmux precisely so it outlives the daemon, which
|
|
276
|
+
* also means nothing ever ends it: an agent that went quiet keeps a ~300 MB claude process
|
|
277
|
+
* (plus its MCP children) alive indefinitely. Measured on claudiao 2026-09-14: 187 live claude
|
|
278
|
+
* processes against 2 running agents, 89 of them (26.3 GB) belonging to agents with no user
|
|
279
|
+
* message in over 3 days. The agent itself stays open: suspending only ends the process, and
|
|
280
|
+
* the next turn resumes the same conversation with --resume through ensureQuery.
|
|
281
|
+
*
|
|
282
|
+
* Override with PASEO_PTY_IDLE_SUSPEND_MS; 0 disables suspension.
|
|
283
|
+
*/
|
|
284
|
+
const DEFAULT_PTY_IDLE_SUSPEND_MS = 36 * 60 * 60 * 1000;
|
|
285
|
+
/** setTimeout clamps anything above a signed 32-bit int to 1ms, so never schedule past it. */
|
|
286
|
+
const MAX_TIMER_DELAY_MS = 2147483647;
|
|
287
|
+
export function resolvePtyIdleSuspendMs(env = process.env) {
|
|
288
|
+
const raw = env.PASEO_PTY_IDLE_SUSPEND_MS;
|
|
289
|
+
if (raw === undefined || raw.trim() === "") {
|
|
290
|
+
return DEFAULT_PTY_IDLE_SUSPEND_MS;
|
|
291
|
+
}
|
|
292
|
+
const parsed = Number(raw);
|
|
293
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
294
|
+
return DEFAULT_PTY_IDLE_SUSPEND_MS;
|
|
295
|
+
}
|
|
296
|
+
return Math.min(parsed, MAX_TIMER_DELAY_MS);
|
|
297
|
+
}
|
|
272
298
|
function summarizeClaudeOptionsForLog(options) {
|
|
273
299
|
const systemPromptRaw = options.systemPrompt;
|
|
274
300
|
const systemPromptSummary = (() => {
|
|
@@ -1651,6 +1677,9 @@ export class ClaudeAgentSession {
|
|
|
1651
1677
|
this.turnIdReconciler = new TurnIdReconciler();
|
|
1652
1678
|
this.rewindTurnAnchors = [];
|
|
1653
1679
|
this.pendingFreshSessionId = null;
|
|
1680
|
+
this.idleSuspendTimer = null;
|
|
1681
|
+
/** Last command list, so a suspended session can answer the palette without respawning. */
|
|
1682
|
+
this.cachedCommands = null;
|
|
1654
1683
|
/** PTY-transport guard files for the current session; removed on teardown. */
|
|
1655
1684
|
this.toolAllowGuard = null;
|
|
1656
1685
|
this.cumulativeImageBase64Bytes = 0;
|
|
@@ -2225,6 +2254,10 @@ export class ClaudeAgentSession {
|
|
|
2225
2254
|
removeGuardArtifacts(this.toolAllowGuard);
|
|
2226
2255
|
this.toolAllowGuard = null;
|
|
2227
2256
|
this.rejectAllPendingPermissions(new Error("Claude session closed"));
|
|
2257
|
+
if (this.idleSuspendTimer) {
|
|
2258
|
+
clearTimeout(this.idleSuspendTimer);
|
|
2259
|
+
this.idleSuspendTimer = null;
|
|
2260
|
+
}
|
|
2228
2261
|
this.cancelCurrentTurn?.();
|
|
2229
2262
|
this.subscribers.clear();
|
|
2230
2263
|
this.activeForegroundTurnId = null;
|
|
@@ -2275,6 +2308,11 @@ export class ClaudeAgentSession {
|
|
|
2275
2308
|
}, "provider.claude.session_close.complete");
|
|
2276
2309
|
}
|
|
2277
2310
|
async listCommands() {
|
|
2311
|
+
// A suspended session has no live query. Opening the command palette must not respawn
|
|
2312
|
+
// claude just to list commands, so answer from the last list when there is one.
|
|
2313
|
+
if (!this.query && this.cachedCommands) {
|
|
2314
|
+
return this.cachedCommands;
|
|
2315
|
+
}
|
|
2278
2316
|
const q = await this.ensureQuery();
|
|
2279
2317
|
const commands = await q.supportedCommands();
|
|
2280
2318
|
const commandMap = new Map();
|
|
@@ -2291,7 +2329,9 @@ export class ClaudeAgentSession {
|
|
|
2291
2329
|
if (!commandMap.has(REWIND_COMMAND_NAME)) {
|
|
2292
2330
|
commandMap.set(REWIND_COMMAND_NAME, REWIND_COMMAND);
|
|
2293
2331
|
}
|
|
2294
|
-
|
|
2332
|
+
const sorted = Array.from(commandMap.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
2333
|
+
this.cachedCommands = sorted;
|
|
2334
|
+
return sorted;
|
|
2295
2335
|
}
|
|
2296
2336
|
async revertConversation(input) {
|
|
2297
2337
|
const target = this.resolveConversationRewindTarget(input.messageId);
|
|
@@ -2656,6 +2696,42 @@ export class ClaudeAgentSession {
|
|
|
2656
2696
|
}
|
|
2657
2697
|
return { kind: "fork", messageId: previousTurn.assistantMessageId };
|
|
2658
2698
|
}
|
|
2699
|
+
/**
|
|
2700
|
+
* End the current query and its process tree while keeping the session and its pinned
|
|
2701
|
+
* claudeSessionId, so the next ensureQuery() resumes the same conversation.
|
|
2702
|
+
*/
|
|
2703
|
+
async teardownQuery() {
|
|
2704
|
+
const oldQuery = this.query;
|
|
2705
|
+
const oldInput = this.input;
|
|
2706
|
+
if (!oldQuery) {
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2709
|
+
// Null out query/input BEFORE awaiting the old iterator's return so the
|
|
2710
|
+
// old pump sees this.query !== activeQuery and skips failActiveTurns.
|
|
2711
|
+
this.query = null;
|
|
2712
|
+
this.input = null;
|
|
2713
|
+
this.queryPumpPromise = null;
|
|
2714
|
+
oldInput?.end();
|
|
2715
|
+
oldQuery.close?.();
|
|
2716
|
+
try {
|
|
2717
|
+
await oldQuery.return?.();
|
|
2718
|
+
}
|
|
2719
|
+
catch {
|
|
2720
|
+
/* ignore */
|
|
2721
|
+
}
|
|
2722
|
+
// Tree-kill the old process tree now that the SDK has cleaned up.
|
|
2723
|
+
// If we skip this, MCP children of the previous claude process can
|
|
2724
|
+
// survive as orphans when the session spawns a replacement query.
|
|
2725
|
+
if (this.childProcess) {
|
|
2726
|
+
await terminateWithTreeKill(this.childProcess, {
|
|
2727
|
+
gracefulTimeoutMs: 2000,
|
|
2728
|
+
forceTimeoutMs: 2000,
|
|
2729
|
+
}).catch(() => {
|
|
2730
|
+
/* process may already be dead */
|
|
2731
|
+
});
|
|
2732
|
+
this.childProcess = null;
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2659
2735
|
async ensureQuery() {
|
|
2660
2736
|
// Story 4.1 — Cache the resolved transport on first use. Even though the
|
|
2661
2737
|
// current path always instantiates SdkTransport, recording the choice means
|
|
@@ -2665,34 +2741,8 @@ export class ClaudeAgentSession {
|
|
|
2665
2741
|
return this.query;
|
|
2666
2742
|
}
|
|
2667
2743
|
if (this.queryRestartNeeded && this.query) {
|
|
2668
|
-
const oldQuery = this.query;
|
|
2669
|
-
const oldInput = this.input;
|
|
2670
|
-
// Null out query/input BEFORE awaiting the old iterator's return so the
|
|
2671
|
-
// old pump sees this.query !== activeQuery and skips failActiveTurns.
|
|
2672
|
-
this.query = null;
|
|
2673
|
-
this.input = null;
|
|
2674
|
-
this.queryPumpPromise = null;
|
|
2675
2744
|
this.queryRestartNeeded = false;
|
|
2676
|
-
|
|
2677
|
-
oldQuery.close?.();
|
|
2678
|
-
try {
|
|
2679
|
-
await oldQuery.return?.();
|
|
2680
|
-
}
|
|
2681
|
-
catch {
|
|
2682
|
-
/* ignore */
|
|
2683
|
-
}
|
|
2684
|
-
// Tree-kill the old process tree now that the SDK has cleaned up.
|
|
2685
|
-
// If we skip this, MCP children of the previous claude process can
|
|
2686
|
-
// survive as orphans when the session spawns a replacement query.
|
|
2687
|
-
if (this.childProcess) {
|
|
2688
|
-
await terminateWithTreeKill(this.childProcess, {
|
|
2689
|
-
gracefulTimeoutMs: 2000,
|
|
2690
|
-
forceTimeoutMs: 2000,
|
|
2691
|
-
}).catch(() => {
|
|
2692
|
-
/* process may already be dead */
|
|
2693
|
-
});
|
|
2694
|
-
this.childProcess = null;
|
|
2695
|
-
}
|
|
2745
|
+
await this.teardownQuery();
|
|
2696
2746
|
}
|
|
2697
2747
|
// Preserve claudeSessionId across query recreation so buildOptions() passes
|
|
2698
2748
|
// resume: sessionId and the new query continues the existing conversation.
|
|
@@ -2737,6 +2787,9 @@ export class ClaudeAgentSession {
|
|
|
2737
2787
|
this.query = ptySession.query;
|
|
2738
2788
|
// Pin the resolved session id so a later query restart resumes this conversation.
|
|
2739
2789
|
this.claudeSessionId = ptySessionId;
|
|
2790
|
+
// A query can be born without a turn (listCommands, setMode), leaving turnState at
|
|
2791
|
+
// "idle" with no transition to arm the timer, so arm it here too.
|
|
2792
|
+
this.updateIdleSuspendTimer();
|
|
2740
2793
|
}
|
|
2741
2794
|
else {
|
|
2742
2795
|
const sdkTransport = new SdkTransport({
|
|
@@ -3043,6 +3096,44 @@ export class ClaudeAgentSession {
|
|
|
3043
3096
|
}
|
|
3044
3097
|
this.logger.debug({ from: this.turnState, to: next, reason }, "Claude turn state transition");
|
|
3045
3098
|
this.turnState = next;
|
|
3099
|
+
this.updateIdleSuspendTimer();
|
|
3100
|
+
}
|
|
3101
|
+
/** Arm the idle-suspend timer while a PTY session sits idle with a live query; clear it otherwise. */
|
|
3102
|
+
updateIdleSuspendTimer() {
|
|
3103
|
+
if (this.idleSuspendTimer) {
|
|
3104
|
+
clearTimeout(this.idleSuspendTimer);
|
|
3105
|
+
this.idleSuspendTimer = null;
|
|
3106
|
+
}
|
|
3107
|
+
if (this.closed ||
|
|
3108
|
+
!this.query ||
|
|
3109
|
+
this.turnState !== "idle" ||
|
|
3110
|
+
this.runtimeSettings?.transport !== "pty") {
|
|
3111
|
+
return;
|
|
3112
|
+
}
|
|
3113
|
+
const delayMs = resolvePtyIdleSuspendMs();
|
|
3114
|
+
if (delayMs <= 0) {
|
|
3115
|
+
return;
|
|
3116
|
+
}
|
|
3117
|
+
const timer = setTimeout(() => {
|
|
3118
|
+
void this.suspendIdleQuery(delayMs);
|
|
3119
|
+
}, delayMs);
|
|
3120
|
+
timer.unref?.();
|
|
3121
|
+
this.idleSuspendTimer = timer;
|
|
3122
|
+
}
|
|
3123
|
+
async suspendIdleQuery(idleMs) {
|
|
3124
|
+
this.idleSuspendTimer = null;
|
|
3125
|
+
// Re-check at fire time: a turn, an autonomous run or a pending permission may have
|
|
3126
|
+
// started without the timer being cleared in between.
|
|
3127
|
+
if (this.closed ||
|
|
3128
|
+
!this.query ||
|
|
3129
|
+
this.turnState !== "idle" ||
|
|
3130
|
+
this.activeForegroundTurnId ||
|
|
3131
|
+
this.autonomousTurn ||
|
|
3132
|
+
this.pendingPermissions.size > 0) {
|
|
3133
|
+
return;
|
|
3134
|
+
}
|
|
3135
|
+
this.logger.info({ sessionId: this.claudeSessionId, idleMs }, "Suspending idle Claude PTY session; the next turn resumes it");
|
|
3136
|
+
await this.teardownQuery();
|
|
3046
3137
|
}
|
|
3047
3138
|
syncTurnState(reason) {
|
|
3048
3139
|
if (this.activeForegroundTurnId) {
|
|
@@ -849,7 +849,7 @@ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{v
|
|
|
849
849
|
__d(function(g,r,i,a,m,e,d){"use strict";var t=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0}),e.shouldAppendSitemap=u,e.shouldAppendNotFound=s,e.getRootStackRouteNames=function(){const t=[n.INTERNAL_SLOT_NAME];s()&&t.push(n.NOT_FOUND_ROUTE_NAME);u()&&t.push(n.SITEMAP_ROUTE_NAME);return t};const o=t(r(d[0])),n=r(d[1]);function u(){const t=o.default.expoConfig?.extra?.router;return!1!==t?.sitemap}function s(){const t=o.default.expoConfig?.extra?.router;return!1!==t?.notFound}},717,[718,721]);
|
|
850
850
|
__d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"default",{enumerable:!0,get:function(){return N}}),Object.defineProperty(_e,"AppOwnership",{enumerable:!0,get:function(){return l.AppOwnership}}),Object.defineProperty(_e,"ExecutionEnvironment",{enumerable:!0,get:function(){return l.ExecutionEnvironment}}),Object.defineProperty(_e,"UserInterfaceIdiom",{enumerable:!0,get:function(){return l.UserInterfaceIdiom}});var n=e(r(d[0])),t=r(d[1]);r(d[2]);var u=e(r(d[3])),l=r(d[4]),o=e(r(d[5]));o.default||console.warn("No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?");const s=(0,t.requireOptionalNativeModule)('ExpoUpdates');let f=null;if(s){let e;s.manifest?e=s.manifest:s.manifestString&&(e=JSON.parse(s.manifestString)),e&&Object.keys(e).length>0&&(f=e)}let c=null;if(u.default.EXDevLauncher){let e;u.default.EXDevLauncher.manifestString&&(e=JSON.parse(u.default.EXDevLauncher.manifestString)),e&&Object.keys(e).length>0&&(c=e)}let p=null;if(o.default&&o.default.manifest){const e=o.default.manifest;p='string'==typeof e?JSON.parse(e):e}let b=f??c??p;const E=o.default||{},{appOwnership:O}=E,x=(0,n.default)(E,["name","appOwnership"]),v=Object.assign({},x,{appOwnership:O??null});function _(e){return!h(e)}function h(e){return'metadata'in e}function S(e=!1){if(!b){const e=null===b?'null':'undefined';if(x.executionEnvironment,l.ExecutionEnvironment.Bare,x.executionEnvironment===l.ExecutionEnvironment.StoreClient||x.executionEnvironment===l.ExecutionEnvironment.Standalone)throw new t.CodedError('ERR_CONSTANTS_MANIFEST_UNAVAILABLE',`Constants.manifest is ${e}, must be an object.`)}return b}Object.defineProperties(v,{__unsafeNoWarnManifest:{get(){const e=S(!0);return e&&_(e)?e:null},enumerable:!1},__unsafeNoWarnManifest2:{get(){const e=S(!0);return e&&h(e)?e:null},enumerable:!1},manifest:{get(){const e=S();return e&&_(e)?e:null},enumerable:!0},manifest2:{get(){const e=S();return e&&h(e)?e:null},enumerable:!0},expoConfig:{get(){const e=S(!0);return e?s&&s.isEmbeddedLaunch?p:h(e)?e.extra?.expoClient??null:_(e)?e:null:null},enumerable:!0},expoGoConfig:{get(){const e=S(!0);return e?h(e)?e.extra?.expoGo??null:_(e)?e:null:null},enumerable:!0},easConfig:{get(){const e=S(!0);return e?h(e)?e.extra?.eas??null:_(e)?e:null:null},enumerable:!0},__rawManifest_TEST:{get:()=>b,set(e){b=e},enumerable:!1}});var N=v},718,[35,4,25,637,719,720]);
|
|
851
851
|
__d(function(g,r,i,a,m,e,d){"use strict";var t,n,o;Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"AppOwnership",{enumerable:!0,get:function(){return t}}),Object.defineProperty(e,"ExecutionEnvironment",{enumerable:!0,get:function(){return n}}),Object.defineProperty(e,"UserInterfaceIdiom",{enumerable:!0,get:function(){return o}}),(function(t){t.Expo="expo"})(t||(t={})),(function(t){t.Bare="bare",t.Standalone="standalone",t.StoreClient="storeClient"})(n||(n={})),(function(t){t.Handset="handset",t.Tablet="tablet",t.Desktop="desktop",t.TV="tv",t.Unsupported="unsupported"})(o||(o={}))},719,[]);
|
|
852
|
-
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return s}});var t=r(d[0]);const n=(Date.now()+'-'+Math.floor(1e9*Math.random())).toString();function o(){if('undefined'!=typeof navigator&&'string'==typeof navigator.userAgent){const t=navigator.userAgent.toLowerCase();if(t.includes('edge'))return'Edge';if(t.includes('edg'))return'Chromium Edge';if(t.includes('opr')&&'opr'in window&&window.opr)return'Opera';if(t.includes('chrome')&&'chrome'in window&&window.chrome)return'Chrome';if(t.includes('trident'))return'IE';if(t.includes('firefox'))return'Firefox';if(t.includes('safari'))return'Safari'}}var s={get appOwnership(){return null},get executionEnvironment(){return t.ExecutionEnvironment.Bare},get sessionId(){return n},get isHeadless(){return'undefined'==typeof navigator||/\bHeadlessChrome\//.test(navigator.userAgent)},get expoVersion(){return this.manifest.sdkVersion||null},get linkingUri(){return'undefined'!=typeof location?location.origin:''},get expoRuntimeVersion(){return this.expoVersion},get deviceName(){return o()},get systemFonts(){return[]},get statusBarHeight(){return 0},get deviceYearClass(){return null},get manifest(){return"{\"name\":\"Paseo\",\"slug\":\"paseo-hyperdrive\",\"version\":\"0.3.
|
|
852
|
+
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return s}});var t=r(d[0]);const n=(Date.now()+'-'+Math.floor(1e9*Math.random())).toString();function o(){if('undefined'!=typeof navigator&&'string'==typeof navigator.userAgent){const t=navigator.userAgent.toLowerCase();if(t.includes('edge'))return'Edge';if(t.includes('edg'))return'Chromium Edge';if(t.includes('opr')&&'opr'in window&&window.opr)return'Opera';if(t.includes('chrome')&&'chrome'in window&&window.chrome)return'Chrome';if(t.includes('trident'))return'IE';if(t.includes('firefox'))return'Firefox';if(t.includes('safari'))return'Safari'}}var s={get appOwnership(){return null},get executionEnvironment(){return t.ExecutionEnvironment.Bare},get sessionId(){return n},get isHeadless(){return'undefined'==typeof navigator||/\bHeadlessChrome\//.test(navigator.userAgent)},get expoVersion(){return this.manifest.sdkVersion||null},get linkingUri(){return'undefined'!=typeof location?location.origin:''},get expoRuntimeVersion(){return this.expoVersion},get deviceName(){return o()},get systemFonts(){return[]},get statusBarHeight(){return 0},get deviceYearClass(){return null},get manifest(){return"{\"name\":\"Paseo\",\"slug\":\"paseo-hyperdrive\",\"version\":\"0.3.141\",\"orientation\":\"portrait\",\"icon\":\"./assets/images/icon.png\",\"scheme\":\"paseo\",\"userInterfaceStyle\":\"automatic\",\"newArchEnabled\":true,\"web\":{\"output\":\"single\",\"favicon\":\"./assets/images/favicon.png\",\"shortName\":\"Paseo\",\"orientation\":\"portrait\",\"name\":\"Paseo\"},\"autolinking\":{\"searchPaths\":[\"../../node_modules\",\"./node_modules\"]},\"experiments\":{\"typedRoutes\":true,\"reactCompiler\":true,\"autolinkingModuleResolution\":true},\"extra\":{\"router\":{},\"eas\":{\"build\":{\"experimental\":{\"ios\":{\"appExtensions\":[{\"bundleIdentifier\":\"bot.hyperdrive.paseo.AgentActivity\",\"targetName\":\"AgentActivity\"}]}}}}},\"sdkVersion\":\"54.0.0\",\"platforms\":[\"ios\",\"android\",\"web\"]}"},get manifest2(){return null},get experienceUrl(){return'undefined'!=typeof location?location.origin:''},get debugMode(){return!1},getWebViewUserAgentAsync:async()=>'undefined'!=typeof navigator?navigator.userAgent:null}},720,[719]);
|
|
853
853
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.SITEMAP_ROUTE_NAME=e.NOT_FOUND_ROUTE_NAME=e.INTERNAL_SLOT_NAME=void 0,e.INTERNAL_SLOT_NAME='__root',e.NOT_FOUND_ROUTE_NAME='+not-found',e.SITEMAP_ROUTE_NAME='_sitemap'},721,[]);
|
|
854
854
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.resolveHref=void 0,e.resolveHrefStringWithSegments=function(t,{segments:n=[],params:s={}}={},{relativeToDirectory:o}={}){if(t.startsWith('.')){let c=n?.map(t=>{if(!t.startsWith('['))return t;if(t.startsWith('[...')){t=t.slice(4,-1);const n=s[t];return Array.isArray(n)?n.join('/'):n?.split(',')?.join('/')??''}return t=t.slice(1,-1),s[t]}).filter(Boolean).join('/')??'/';o&&(c=`${c}/`);const f=new URL(t,`http://hostname/${c}`);t=`${f.pathname}${f.search}`}return t};function t(t,s){for(const[o,c=""]of Object.entries(s)){const f=`[${o}]`,l=`[...${o}]`;if(t.includes(f))t=t.replace(f,n(c));else{if(!t.includes(l))continue;t=t.replace(l,n(c))}delete s[o]}return{pathname:t,params:s}}function n(t){return Array.isArray(t)?t.map(t=>n(t)).join('/'):encodeURIComponent(t.toString())}function s(t){return Object.entries(t).filter(([,t])=>null!=t).map(([t,n])=>`${t}=${encodeURIComponent(n.toString())}`).join('&')}e.resolveHref=n=>{if('string'==typeof n)return(0,e.resolveHref)({pathname:n});const o=n.pathname??'';if(!n?.params)return o;const{pathname:c,params:f}=t(o,Object.assign({},n.params)),l=s(f);return c+(l?`?${l}`:'')}},722,[]);
|
|
855
855
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.isRoutePreloadedInStack=function(t,o){if(!t||'stack'!==t.type)return!1;return t.preloadedRoutes.some(t=>t.key===o.key)}},723,[]);
|
|
@@ -15057,7 +15057,7 @@ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{v
|
|
|
15057
15057
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"decodeOfferFragmentPayload",{enumerable:!0,get:function(){return n.decodeOfferFragmentPayload}}),Object.defineProperty(e,"buildDaemonWebSocketUrl",{enumerable:!0,get:function(){return t.buildDaemonWebSocketUrl}}),Object.defineProperty(e,"deriveLabelFromEndpoint",{enumerable:!0,get:function(){return t.deriveLabelFromEndpoint}}),Object.defineProperty(e,"extractHostPortFromWebSocketUrl",{enumerable:!0,get:function(){return t.extractHostPortFromWebSocketUrl}}),Object.defineProperty(e,"normalizeHostPort",{enumerable:!0,get:function(){return t.normalizeHostPort}}),Object.defineProperty(e,"parseConnectionUri",{enumerable:!0,get:function(){return t.parseConnectionUri}}),Object.defineProperty(e,"parseHostPort",{enumerable:!0,get:function(){return t.parseHostPort}}),Object.defineProperty(e,"serializeConnectionUri",{enumerable:!0,get:function(){return t.serializeConnectionUri}}),Object.defineProperty(e,"serializeConnectionUriForStorage",{enumerable:!0,get:function(){return t.serializeConnectionUriForStorage}}),Object.defineProperty(e,"shouldUseTlsForDefaultHostedRelay",{enumerable:!0,get:function(){return t.shouldUseTlsForDefaultHostedRelay}}),e.buildRelayWebSocketUrl=function(n){return(0,t.buildRelayWebSocketUrl)(Object.assign({},n,{role:"client"}))};var t=r(d[0]),n=r(d[1])},3412,[3392,3413]);
|
|
15058
15058
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"ConnectionOfferV2Schema",{enumerable:!0,get:function(){return t}}),Object.defineProperty(e,"ConnectionOfferSchema",{enumerable:!0,get:function(){return o}}),e.decodeOfferFragmentPayload=l,e.parseConnectionOfferFromUrl=function(n){const t=f(n);if(!t)return null;const c=l(t);return o.parse(c)};var n=r(d[0]);const t=n.z.object({v:n.z.literal(2),serverId:n.z.string().min(1),daemonPublicKeyB64:n.z.string().min(1),relay:n.z.object({endpoint:n.z.string().min(1),useTls:n.z.boolean().optional()})}),o=t;function c(n){const t=n.replace(/-/g,"+").replace(/_/g,"/"),o=t.padEnd(t.length+(4-t.length%4)%4,"="),c=globalThis.atob(o),l=Uint8Array.from(c,n=>n.charCodeAt(0));return new TextDecoder("utf-8",{fatal:!0}).decode(l)}function l(n){const t=c(n);return JSON.parse(t)}const u="#offer=";function f(n){const t=n.trim();if(!t)return null;const o=t.indexOf(u);if(-1===o)return null;const c=t.slice(o+u.length).trim();return c.length>0?c:null}},3413,[3285]);
|
|
15059
15059
|
__d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),_e.resolveAppVersion=function(){const e=u(t.default?.version);if(e)return e;const o=u(n.default.expoConfig?.version);if(o)return o;const f=u(n.default.manifest?.version);if(f)return f;return null};var n=e(r(d[0])),t=e(r(d[1]));function u(e){if("string"!=typeof e)return null;const n=e.trim();return 0===n.length?null:n}},3414,[718,3415]);
|
|
15060
|
-
__d(function(e,t,r,a,o,i,n){o.exports={name:"@hyperdrive.bot/fleet-app",version:"0.3.
|
|
15060
|
+
__d(function(e,t,r,a,o,i,n){o.exports={name:"@hyperdrive.bot/fleet-app",version:"0.3.141",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:reels":"cross-env NODE_ENV=development playwright test --config playwright.reels.config.ts","test:e2e:real":"cross-env E2E_FORK_PASEO_HOME_FROM=../../.dev/paseo-home playwright test --project=real-provider","test:e2e:ui":"playwright test --ui","test:coverage":"vitest run --project unit --coverage",build:"npm run build:web","build:web":"npm --prefix ../.. run build:app-deps && expo export --platform web --source-maps","profile:workspace-tabs":"node ./scripts/profile-workspace-tabs.mjs","deploy:web":"npm run build:web && wrangler pages deploy dist --project-name paseo-app --branch main"},dependencies:{"@bacons/apple-targets":"4.0.6","@datadog/browser-rum":"^6.23.0","@datadog/browser-rum-react":"^6.23.0","@datadog/mobile-react-native":"^2.7.0","@datadog/mobile-react-native-session-replay":"^2.14.8","@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2","@expo/image-utils":"0.8.8","@expo/plist":"0.4.9","@expo/prebuild-config":"54.0.8","@floating-ui/react-native":"^0.10.7","@gorhom/bottom-sheet":"^5.2.14","@gorhom/portal":"^1.0.14","@hyperdrive.bot/fleet-client":"*","@hyperdrive.bot/fleet-expo-two-way-audio":"*","@hyperdrive.bot/fleet-extension-sdk":"*","@hyperdrive.bot/fleet-highlight":"*","@react-native-async-storage/async-storage":"2.2.0","@react-native-masked-view/masked-view":"^0.3.2","@react-native/normalize-colors":"^0.81.5","@react-navigation/native":"^7.1.8","@sentry/electron":"^6.11.0","@sentry/react-native":"^6.20.0","@tanstack/react-query":"^5.90.11","@tanstack/react-virtual":"^3.13.21","@xterm/addon-clipboard":"^0.3.0-beta.213","@xterm/addon-fit":"^0.12.0-beta.213","@xterm/addon-image":"^0.10.0-beta.213","@xterm/addon-ligatures":"0.11.0-beta.213","@xterm/addon-search":"^0.17.0-beta.213","@xterm/addon-unicode11":"^0.10.0-beta.213","@xterm/addon-web-links":"^0.13.0-beta.213","@xterm/addon-webgl":"^0.20.0-beta.212","@xterm/xterm":"^6.1.0-beta.213",buffer:"^6.0.3",expo:"^54.0.18","expo-asset":"~12.0.12","expo-audio":"~1.0.13","expo-background-fetch":"~14.0.9","expo-build-properties":"^1.0.9","expo-camera":"~17.0.10","expo-clipboard":"~8.0.7","expo-constants":"~18.0.9","expo-crypto":"^15.0.8","expo-dev-client":"^6.0.15","expo-document-picker":"~14.0.8","expo-file-system":"~19.0.17","expo-haptics":"~15.0.7","expo-image":"~3.0.10","expo-image-manipulator":"~14.0.8","expo-image-picker":"^17.0.8","expo-keep-awake":"^15.0.7","expo-linking":"~8.0.8","expo-localization":"~17.0.9","expo-notifications":"^0.32.16","expo-router":"~6.0.13","expo-sharing":"^14.0.8","expo-speech":"~14.0.8","expo-speech-recognition":"^56.0.1","expo-splash-screen":"~31.0.10","expo-system-ui":"~6.0.7","expo-task-manager":"~14.0.9","expo-video":"~3.0.16","fast-deep-equal":"^3.1.3",htmlparser2:"^12.0.0",i18next:"^26.3.0","lucide-react-native":"^0.546.0","markdown-it":"^10.0.0","mnemonic-id":"^3.2.7","posthog-js":"^1.431.2",qrcode:"^1.5.4",react:"19.1.0","react-dom":"19.1.0","react-i18next":"^17.0.8","react-native":"0.81.5","react-native-draggable-flatlist":"^4.0.3","react-native-edge-to-edge":"^1.7.0","react-native-gesture-handler":"~2.28.0","react-native-keyboard-controller":"^1.21.7","react-native-markdown-display":"^7.0.2","react-native-nitro-modules":"0.35.5","react-native-reanimated":"~4.3.1","react-native-safe-area-context":"~5.6.0","react-native-screens":"~4.16.0","react-native-svg":"^15.14.0","react-native-uitextview":"^2.2.0","react-native-unistyles":"^3.2.4","react-native-web":"~0.21.0","react-native-webview":"^13.16.0","react-native-worklets":"~0.8.3","tiny-invariant":"^1.3.3","use-sync-external-store":"^1.6.0",zod:"^4.4.3",zustand:"^5.0.9"},devDependencies:{"@playwright/test":"^1.56.1","@testing-library/dom":"^10.4.1","@testing-library/react":"^16.3.2","@types/chai":"^5.2.2","@types/markdown-it":"^14.1.2","@types/qrcode":"^1.5.6","@types/react":"~19.2.0","@types/ws":"^8.18.1","@vitest/browser":"^4.1.7","@vitest/browser-playwright":"^4.1.7","@vitest/coverage-v8":"^4.1.7","@xterm/headless":"^6.1.0-beta.213",dotenv:"^17.2.3",eslint:"^9.25.0","eslint-config-expo":"~10.0.0",jsdom:"^20.0.3","material-icon-theme":"^5.32.0",playwright:"^1.56.1","serve-sim":"^0.1.40",typescript:"~5.9.2",vitest:"^4.1.6",wrangler:"^4.105.0",ws:"^8.20.0"}}},3415,[]);
|
|
15061
15061
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.shouldUseDesktopDaemon=function(){return(0,n.isElectronRuntime)()},e.getDesktopDaemonStatus=async function(){return c(await(0,t.invokeDesktopCommand)("desktop_daemon_status"))},e.startDesktopDaemon=async function(){return c(await(0,t.invokeDesktopCommand)("start_desktop_daemon"))},e.stopDesktopDaemon=async function(n="manual_ipc"){return c(await(0,t.invokeDesktopCommand)("stop_desktop_daemon",{reason:n}))},e.restartDesktopDaemon=async function(){return c(await(0,t.invokeDesktopCommand)("restart_desktop_daemon"))},e.getDesktopDaemonLogs=async function(){return p(await(0,t.invokeDesktopCommand)("desktop_daemon_logs"))},e.getDesktopDaemonPairing=async function(){return k(await(0,t.invokeDesktopCommand)("desktop_daemon_pairing"))},e.getCliDaemonStatus=async function(){const n=await(0,t.invokeDesktopCommand)("cli_daemon_status");if("string"!=typeof n)throw new Error("Unexpected CLI daemon status response.");return n},e.listenToLocalTransportEvents=async function(t){const u=(0,n.getDesktopHost)()?.events?.on;if("function"!=typeof u)throw new Error("Desktop events API is unavailable.");const c=await u("local-daemon-transport-event",n=>{o(n)&&t({sessionId:s(n.sessionId)??"",kind:s(n.kind)??"error",text:s(n.text),binaryBase64:s(n.binaryBase64),code:l(n.code),reason:s(n.reason),error:s(n.error)})});return"function"==typeof c?c:()=>{}},e.openLocalTransportSession=async function(n){const o=await(0,t.invokeDesktopCommand)("open_local_daemon_transport",n);if("string"!=typeof o||0===o.trim().length)throw new Error("Unexpected local transport session response.");return o},e.sendLocalTransportMessage=async function(n){await(0,t.invokeDesktopCommand)("send_local_daemon_transport_message",Object.assign({sessionId:n.sessionId},n.text?{text:n.text}:{},n.binaryBase64?{binaryBase64:n.binaryBase64}:{}))},e.closeLocalTransportSession=async function(n){await(0,t.invokeDesktopCommand)("close_local_daemon_transport",{sessionId:n})},e.getCliInstallStatus=async function(){return f(await(0,t.invokeDesktopCommand)("get_cli_install_status"))},e.installCli=async function(){return f(await(0,t.invokeDesktopCommand)("install_cli"))},e.getSkillsStatus=async function(){return y(await(0,t.invokeDesktopCommand)("get_skills_status"))},e.installSkills=async function(){return y(await(0,t.invokeDesktopCommand)("install_skills"))},e.updateSkills=async function(){return y(await(0,t.invokeDesktopCommand)("update_skills"))},e.uninstallSkills=async function(){return y(await(0,t.invokeDesktopCommand)("uninstall_skills"))};var n=r(d[0]),t=r(d[1]);function o(n){return"object"==typeof n&&null!==n}function s(n){return"string"==typeof n&&n.trim().length>0?n:null}function l(n){return"number"==typeof n&&Number.isFinite(n)?n:null}function u(n){const t=s(n)?.toLowerCase();switch(t){case"starting":return"starting";case"running":return"running";case"errored":case"error":return"errored";default:return"stopped"}}function c(n){if(!o(n))throw new Error("Unexpected desktop daemon status response.");return{serverId:s(n.serverId)??"",status:u(n.status),listen:s(n.listen),hostname:s(n.hostname),pid:l(n.pid),home:s(n.home)??"",version:s(n.version),desktopManaged:!0===n.desktopManaged,error:s(n.error)}}function p(n){if(!o(n))throw new Error("Unexpected desktop daemon logs response.");return{logPath:s(n.logPath)??"",contents:"string"==typeof n.contents?n.contents:""}}function k(n){if(!o(n))throw new Error("Unexpected desktop daemon pairing response.");return{relayEnabled:!0===n.relayEnabled,url:s(n.url),qr:s(n.qr)}}function f(n){if(!o(n))throw new Error("Unexpected install status response.");return{installed:!0===n.installed}}function w(n){switch(n){case"not-installed":case"up-to-date":case"drift":return n;default:throw new Error(`Unexpected skills status state: ${String(n)}`)}}function _(n){if(!o(n))throw new Error("Unexpected skill op response.");const t=s(n.name);if(!t)throw new Error("Skill op missing name.");switch(n.kind){case"add":return{kind:"add",name:t};case"update":return{kind:"update",name:t};case"delete":return{kind:"delete",name:t};default:throw new Error(`Unexpected skill op kind: ${String(n.kind)}`)}}function y(n){if(!o(n))throw new Error("Unexpected skills status response.");const t=Array.isArray(n.ops)?n.ops.map(_):[];return{state:w(n.state),ops:t}}},3416,[3417,3419]);
|
|
15062
15062
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.getDesktopHost=n,e.isElectronRuntime=o,e.isElectronRuntimeMac=function(){if(!o())return!1;if("undefined"==typeof navigator)return!1;const t=n()?.platform?.toLowerCase();if("darwin"===t||"mac"===t||"macos"===t)return!0;const u=navigator.userAgent;return u.includes("Mac OS")||u.includes("Macintosh")},r(d[0]);var t=r(d[1]);function n(){return(0,t.getElectronHost)()}function o(){return null!==n()}},3417,[25,3418]);
|
|
15063
15063
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.getElectronHost=function(){if("undefined"==typeof window)return null;const t=window.paseoDesktop;if(!t||"object"!=typeof t)return null;return t}},3418,[]);
|
|
@@ -16706,5 +16706,5 @@ __d(function(g,r,_i,a,_m,_e,d){"use strict";var e,t=r(d[0]),n=this&&this.__creat
|
|
|
16706
16706
|
__r(694);
|
|
16707
16707
|
__r(341);
|
|
16708
16708
|
__r(0);
|
|
16709
|
-
//# sourceMappingURL=/_expo/static/js/web/index-
|
|
16710
|
-
//# debugId=
|
|
16709
|
+
//# sourceMappingURL=/_expo/static/js/web/index-cc716b9bd29f4801a9439c028fb5b5e2.js.map
|
|
16710
|
+
//# debugId=72bd1c0f-9ef3-4a6d-968a-60d771b63fcd
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -191,6 +191,6 @@
|
|
|
191
191
|
<body>
|
|
192
192
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
193
193
|
<div id="root"></div>
|
|
194
|
-
<script src="/_expo/static/js/web/index-
|
|
194
|
+
<script src="/_expo/static/js/web/index-cc716b9bd29f4801a9439c028fb5b5e2.js" defer></script>
|
|
195
195
|
</body>
|
|
196
196
|
</html>
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperdrive.bot/fleet-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.141",
|
|
4
4
|
"description": "Paseo backend server",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"files": [
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"@agentclientprotocol/sdk": "^0.17.1",
|
|
67
67
|
"@anthropic-ai/claude-agent-sdk": "^0.3.195",
|
|
68
68
|
"@anthropic-ai/sdk": "^0.104.2",
|
|
69
|
-
"@hyperdrive.bot/fleet-client": "0.3.
|
|
70
|
-
"@hyperdrive.bot/fleet-extension-sdk": "0.3.
|
|
71
|
-
"@hyperdrive.bot/fleet-highlight": "0.3.
|
|
72
|
-
"@hyperdrive.bot/fleet-protocol": "0.3.
|
|
73
|
-
"@hyperdrive.bot/fleet-relay": "0.3.
|
|
69
|
+
"@hyperdrive.bot/fleet-client": "0.3.141",
|
|
70
|
+
"@hyperdrive.bot/fleet-extension-sdk": "0.3.141",
|
|
71
|
+
"@hyperdrive.bot/fleet-highlight": "0.3.141",
|
|
72
|
+
"@hyperdrive.bot/fleet-protocol": "0.3.141",
|
|
73
|
+
"@hyperdrive.bot/fleet-relay": "0.3.141",
|
|
74
74
|
"@isaacs/ttlcache": "^2.1.4",
|
|
75
75
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
76
76
|
"@opencode-ai/sdk": "1.2.6",
|
|
Binary file
|