From 50d77641503aae471560e57848f9b46035d8f20e Mon Sep 17 00:00:00 2001 From: Zhou Yurui Date: Tue, 5 May 2026 12:56:20 +0800 Subject: [PATCH 1/2] fix(app): defer history sync catch-up to user-visible panels (#741) On macOS unlock after extended display sleep, every mounted AgentPanel would simultaneously revalidate its timeline, saturating the renderer's JS main thread and freezing the UI to mouse and keyboard input. - Coalesce repeated onAppResumed signals (visibilitychange + AppState). - Make bumpHistorySyncGeneration consumers lazy: defer ensureAgentIsInitialized until the panel becomes user-visible. - Only bump generation on WS reconnect when offline duration exceeded HISTORY_STALE_AFTER_MS. - Cancel rAF chains in use-bottom-anchor-controller and web-focus when the document becomes hidden, so they don't accumulate while the renderer is occluded. Fixes #741 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../use-bottom-anchor-controller.ts | 36 +++++++++++++++++++ packages/app/src/contexts/session-context.tsx | 26 +++++++++++++- packages/app/src/panels/agent-panel.tsx | 8 +++++ packages/app/src/runtime/host-runtime.ts | 23 +++++++++++- packages/app/src/utils/web-focus.ts | 19 ++++++++-- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/packages/app/src/components/use-bottom-anchor-controller.ts b/packages/app/src/components/use-bottom-anchor-controller.ts index 00fe07a2f..66525ed37 100644 --- a/packages/app/src/components/use-bottom-anchor-controller.ts +++ b/packages/app/src/components/use-bottom-anchor-controller.ts @@ -110,19 +110,53 @@ const MAX_VERIFICATION_RETRIES = 3; const WEB_PARTIAL_VIRTUALIZED_CONFIRMATION_DELAY_FRAMES = 1; const USER_SCROLL_AWAY_DELTA_PX = 24; +// Active rAF handles are tracked so that when the document is hidden (e.g. macOS +// display sleep) we can cancel every pending recursive chain. Otherwise Chromium +// throttles rAF while occluded and the chains pile up, draining the JS thread on +// resume. +const activeRafHandles = new Set(); +let visibilityListenerAttached = false; + +function ensureRafVisibilityListener(): void { + if (visibilityListenerAttached) { + return; + } + if (typeof document === "undefined") { + return; + } + visibilityListenerAttached = true; + document.addEventListener("visibilitychange", () => { + if (document.visibilityState !== "hidden") { + return; + } + for (const handle of activeRafHandles) { + handle.cancelled = true; + if (handle.rafId !== null) { + cancelAnimationFrame(handle.rafId); + handle.rafId = null; + } + } + activeRafHandles.clear(); + }); +} + function scheduleAnimationFrameWithDelay(input: { callback: () => void; delayFrames?: number; }): ScheduledFrameHandle { + ensureRafVisibilityListener(); + const handle: ScheduledFrameHandle = { cancelled: false, rafId: null, remainingFrames: Math.max(0, input.delayFrames ?? 0), callback: input.callback, }; + activeRafHandles.add(handle); const tick = () => { if (handle.cancelled) { + activeRafHandles.delete(handle); return; } if (handle.remainingFrames > 0) { @@ -131,6 +165,7 @@ function scheduleAnimationFrameWithDelay(input: { return; } handle.rafId = null; + activeRafHandles.delete(handle); input.callback(); }; @@ -148,6 +183,7 @@ function cancelScheduledAnimationFrame(handle: unknown): void { cancelAnimationFrame(scheduled.rafId); scheduled.rafId = null; } + activeRafHandles.delete(scheduled); } function deriveVerificationBlockedReason(input: { diff --git a/packages/app/src/contexts/session-context.tsx b/packages/app/src/contexts/session-context.tsx index 30e071029..9953d3628 100644 --- a/packages/app/src/contexts/session-context.tsx +++ b/packages/app/src/contexts/session-context.tsx @@ -78,6 +78,7 @@ export type { const HISTORY_STALE_AFTER_MS = 60_000; const AUTHORITATIVE_REVALIDATION_DEBOUNCE_MS = 300; +const APP_RESUMED_COALESCE_WINDOW_MS = 250; function hasAgentUsageChanged( incomingUsage: Agent["lastUsage"] | undefined, @@ -498,6 +499,8 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider const revalidationTimerRef = useRef | null>(null); const revalidationInFlightRef = useRef | null>(null); const revalidationQueuedRef = useRef(false); + const appResumedTimerRef = useRef | null>(null); + const appResumedPendingAwayMsRef = useRef(0); const wasConnectedRef = useRef(isConnected); const audioOutputBuffersRef = useRef>(new Map()); const activeAudioGroupsRef = useRef>(new Set()); @@ -744,7 +747,7 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider }, AUTHORITATIVE_REVALIDATION_DEBOUNCE_MS); }, [client, flushAuthoritativeRevalidation, isConnected]); - const handleAppResumed = useCallback( + const runAppResumedEffects = useCallback( (awayMs: number) => { scheduleAuthoritativeRevalidation(); @@ -772,6 +775,24 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider [bumpHistorySyncGeneration, client, scheduleAuthoritativeRevalidation, serverId], ); + // Coalesce burst of resume signals: AppState change + visibilitychange + WS + // online transition can fire within milliseconds of each other on macOS unlock. + const handleAppResumed = useCallback( + (awayMs: number) => { + appResumedPendingAwayMsRef.current = Math.max(appResumedPendingAwayMsRef.current, awayMs); + if (appResumedTimerRef.current) { + return; + } + appResumedTimerRef.current = setTimeout(() => { + appResumedTimerRef.current = null; + const coalescedAwayMs = appResumedPendingAwayMsRef.current; + appResumedPendingAwayMsRef.current = 0; + runAppResumedEffects(coalescedAwayMs); + }, APP_RESUMED_COALESCE_WINDOW_MS); + }, + [runAppResumedEffects], + ); + // Client activity tracking (heartbeat, push token registration) useClientActivity({ client, focusedAgentId, onAppResumed: handleAppResumed }); usePushTokenRegistration({ client, serverId }); @@ -1159,6 +1180,9 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider if (revalidationTimerRef.current) { clearTimeout(revalidationTimerRef.current); } + if (appResumedTimerRef.current) { + clearTimeout(appResumedTimerRef.current); + } }; }, []); diff --git a/packages/app/src/panels/agent-panel.tsx b/packages/app/src/panels/agent-panel.tsx index 4d4be6485..c9a48c7a1 100644 --- a/packages/app/src/panels/agent-panel.tsx +++ b/packages/app/src/panels/agent-panel.tsx @@ -846,6 +846,13 @@ function ChatAgentContent({ if (!isConnected || !hasSession) { return; } + // Defer the bump-driven catch-up to user-visible panels so a single + // resume event doesn't fan out to every mounted panel at once. + // Background panels pick up the catch-up via the focus effect when + // they later become user-visible. + if (!isPaneFocused) { + return; + } const shouldSyncOnEntry = needsAuthoritativeSync || isNative; if (!shouldSyncOnEntry) { return; @@ -857,6 +864,7 @@ function ChatAgentContent({ ensureInitializedWithSyncErrorHandling, hasSession, isConnected, + isPaneFocused, needsAuthoritativeSync, ]); diff --git a/packages/app/src/runtime/host-runtime.ts b/packages/app/src/runtime/host-runtime.ts index 351b5a1fc..017e466b9 100644 --- a/packages/app/src/runtime/host-runtime.ts +++ b/packages/app/src/runtime/host-runtime.ts @@ -1196,6 +1196,10 @@ function rekeyMap(map: Map, oldKey: string, newKey: string): void map.set(newKey, value); } +// Mirrors HISTORY_STALE_AFTER_MS in session-context. Reconnects faster than this +// threshold do not invalidate per-panel timeline caches. +const HISTORY_STALE_AFTER_MS = 60_000; + export class HostRuntimeStore { private controllers = new Map(); private serverListeners = new Map void>>(); @@ -1206,6 +1210,7 @@ export class HostRuntimeStore { private hosts: HostProfile[] = []; private deps: HostRuntimeControllerDeps; private lastConnectionStatusByServer = new Map(); + private offlineSinceByServer = new Map(); private agentDirectoryBootstrapInFlight = new Map>(); private bootStarted = false; @@ -1365,6 +1370,7 @@ export class HostRuntimeStore { controller.adoptReconciledServerId(newServerId); rekeyMap(this.lastConnectionStatusByServer, oldServerId, newServerId); + rekeyMap(this.offlineSinceByServer, oldServerId, newServerId); rekeyMap(this.agentDirectoryBootstrapInFlight, oldServerId, newServerId); const listeners = this.serverListeners.get(oldServerId); @@ -1597,6 +1603,7 @@ export class HostRuntimeStore { } this.controllers.delete(serverId); this.lastConnectionStatusByServer.delete(serverId); + this.offlineSinceByServer.delete(serverId); this.agentDirectoryBootstrapInFlight.delete(serverId); void controller.stop(); this.emit(serverId); @@ -1648,6 +1655,7 @@ export class HostRuntimeStore { const controller = this.controllers.get(serverId); if (!controller) { this.lastConnectionStatusByServer.delete(serverId); + this.offlineSinceByServer.delete(serverId); this.agentDirectoryBootstrapInFlight.delete(serverId); return; } @@ -1656,8 +1664,21 @@ export class HostRuntimeStore { this.lastConnectionStatusByServer.set(serverId, snapshot.connectionStatus); const didTransitionOnline = snapshot.connectionStatus === "online" && previousStatus !== "online"; + const wasPreviouslyOnline = previousStatus === "online"; + if (snapshot.connectionStatus !== "online" && wasPreviouslyOnline) { + this.offlineSinceByServer.set(serverId, Date.now()); + } if (didTransitionOnline) { - useSessionStore.getState().bumpHistorySyncGeneration(serverId); + const offlineSince = this.offlineSinceByServer.get(serverId); + this.offlineSinceByServer.delete(serverId); + // Skip the bump on quick blips — only invalidate panel timeline caches + // when the offline window crossed the staleness threshold. The first + // online transition (no prior offline timestamp) still bumps so a fresh + // boot syncs once. + const offlineDurationMs = offlineSince === undefined ? Infinity : Date.now() - offlineSince; + if (offlineDurationMs >= HISTORY_STALE_AFTER_MS) { + useSessionStore.getState().bumpHistorySyncGeneration(serverId); + } } // Runtime owns directory bootstrap policy, including reconnect and delayed diff --git a/packages/app/src/utils/web-focus.ts b/packages/app/src/utils/web-focus.ts index 02350fdcd..2ab8a42d2 100644 --- a/packages/app/src/utils/web-focus.ts +++ b/packages/app/src/utils/web-focus.ts @@ -15,6 +15,19 @@ export function focusWithRetries({ }: FocusWithRetriesOptions): () => void { let cancelled = false; const deadlineMs = Date.now() + timeoutMs; + const doc = typeof document === "undefined" ? null : document; + + const handleVisibilityChange = () => { + if (doc?.visibilityState === "hidden") { + cancelled = true; + } + }; + doc?.addEventListener("visibilitychange", handleVisibilityChange); + + const cancel = () => { + cancelled = true; + doc?.removeEventListener("visibilitychange", handleVisibilityChange); + }; const tick = () => { if (cancelled) return; @@ -27,11 +40,13 @@ export function focusWithRetries({ if (isFocused()) { onSuccess?.(); + cancel(); return; } if (Date.now() >= deadlineMs) { onTimeout?.(); + cancel(); return; } @@ -42,7 +57,5 @@ export function focusWithRetries({ tick(); - return () => { - cancelled = true; - }; + return cancel; } From 0b2a14577b1ddbf736ddd070636c95e073af7fcc Mon Sep 17 00:00:00 2001 From: Zhou Yurui Date: Tue, 5 May 2026 15:06:26 +0800 Subject: [PATCH 2/2] feat(server): add Claude Code auto mode (#747) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose Anthropic's classifier-driven auto permission tier as a selectable mode for Claude agents. Refuses upfront when the agent env routes through Bedrock or Vertex, since auto mode is Anthropic-API-only. - Bump @anthropic-ai/claude-agent-sdk 0.2.71 -> 0.2.128 ('auto' lands in the public PermissionMode union from 0.2.91) - Pin @modelcontextprotocol/sdk to 1.27.1 — 1.29.0 has a zod 4 type regression (ZodNumber not assignable to AnySchema, deep instantiation) - Widen zod range to ^3.23.8 || ^4.0.0 to match the resolved 4.3.6 - Rename internal TurnState literal "autonomous" -> "background" so logs and types don't collide with Anthropic's auto permission tier - Drop an @ts-expect-error directive that's no longer needed after the SDK type updates Co-Authored-By: Claude Opus 4.7 (1M context) --- package-lock.json | 736 +++++++----------- packages/app/package.json | 2 +- packages/desktop/package.json | 2 +- packages/server/package.json | 6 +- .../server/agent/create-agent-mode.test.ts | 2 +- .../src/server/agent/provider-manifest.ts | 8 + .../providers/claude-agent.redesign.test.ts | 2 +- .../server/agent/providers/claude-agent.ts | 47 +- 8 files changed, 348 insertions(+), 457 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6f29e4f1f..620f692a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -107,28 +107,155 @@ } }, "node_modules/@anthropic-ai/claude-agent-sdk": { - "version": "0.2.71", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.71.tgz", - "integrity": "sha512-pIsQJnM7Y+cJHL7aFY6SCCW3FIni218gVEpPqG8XGowfYxboFNBbNssWiUNRwthT8bp9jypcX7q5kx0Xsw14xg==", + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.2.128.tgz", + "integrity": "sha512-KI7H9bocPahGDrrQGME5Eh5a4RTqGrN1fQ69uLs6Ik4icXBZXouCx4Ecum450jMVy58myeh9ahYYLlpDAbQXPA==", "license": "SEE LICENSE IN README.md", + "dependencies": { + "@anthropic-ai/sdk": "^0.81.0", + "@modelcontextprotocol/sdk": "^1.29.0" + }, "engines": { "node": ">=18.0.0" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "^0.34.2", - "@img/sharp-darwin-x64": "^0.34.2", - "@img/sharp-linux-arm": "^0.34.2", - "@img/sharp-linux-arm64": "^0.34.2", - "@img/sharp-linux-x64": "^0.34.2", - "@img/sharp-linuxmusl-arm64": "^0.34.2", - "@img/sharp-linuxmusl-x64": "^0.34.2", - "@img/sharp-win32-arm64": "^0.34.2", - "@img/sharp-win32-x64": "^0.34.2" + "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.2.128", + "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.2.128", + "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.2.128", + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.2.128", + "@anthropic-ai/claude-agent-sdk-linux-x64": "0.2.128", + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.2.128", + "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.2.128", + "@anthropic-ai/claude-agent-sdk-win32-x64": "0.2.128" }, "peerDependencies": { "zod": "^4.0.0" } }, + "node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.2.128.tgz", + "integrity": "sha512-RAzmB1ls+GWA/YiyfZLWdFYmj3md5emk7mCEeiKSKl2UN4i+tDWy2m/hjIvMFIzBqJJeGmZZSMnf3S0sL/GbhQ==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.2.128.tgz", + "integrity": "sha512-dDPJHxUhL2sgIB8Q2AnBi4xsApImeW0zf1nbL7gBNSc9RWhGoGQAbPm0KaQ7/03jdom30z1VT5VMhQ5KeEYOIw==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.2.128.tgz", + "integrity": "sha512-+GbB33eJSlZUWs84nsibY2nyAFQT96WYLGCteVn62Vv6ZK90NrZsm7lwurjw7oYNnvpzXorhZ2/XpQnWvOK6aQ==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.2.128.tgz", + "integrity": "sha512-ZCZEg42St0SCMMZFCvEtkF1LBFMYBxJRXzRno+12vOYYhC6R0l8jPjlgA2ZkN2Lb+TCEOO3fjeWJdZLL/NDM4w==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.2.128.tgz", + "integrity": "sha512-aBBXD6OLN/lq9S1p+BNjuEml0lYIoHunFdzFl49B0fsxEAnz1RfJDrpSNpIUAaL5FMZIaFvLqXtbFRy41N2fxg==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.2.128.tgz", + "integrity": "sha512-sUSJEtvEt2iiMvgUuBGmBJjLhwHxDKOxVBSsXZaY46KAv3ZwLtLuc5xv2XFHId1B5+nMh7b7mr+HAiBmbMUODA==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.2.128.tgz", + "integrity": "sha512-9Ao2J5KgfkfKxUZK3dbQEGonPYcbUyn7Cn7ykZuP91FN/5ux3Tz90YRJW6UtZdWHoDkmFF0FS8P/jiZuyWPLfw==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": { + "version": "0.2.128", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.2.128.tgz", + "integrity": "sha512-7oxPkgjw1vPZbx6+Qwt9mGouqfpRz5jDcuQ37koayzMdTVzmgCsKAqqbJSpOQfkFGv6gTjcrLWBlk3oapZfBYA==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.md", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/sdk": { + "version": "0.81.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.81.0.tgz", + "integrity": "sha512-D4K5PvEV6wPiRtVlVsJHIUhHAmOZ6IT/I9rKlTf84gR7GyyAurPJK7z9BOf/AZqC5d1DhYQGJNKRmV+q8dGhgw==", + "license": "MIT", + "dependencies": { + "json-schema-to-ts": "^3.1.1" + }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, "node_modules/@anthropic-ai/sdk": { "version": "0.90.0", "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.90.0.tgz", @@ -3952,45 +4079,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@electron/windows-sign": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", - "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "peer": true, - "dependencies": { - "cross-dirname": "^0.1.0", - "debug": "^4.3.4", - "fs-extra": "^11.1.1", - "minimist": "^1.2.8", - "postject": "^1.0.0-alpha.6" - }, - "bin": { - "electron-windows-sign": "bin/electron-windows-sign.js" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/windows-sign/node_modules/fs-extra": { - "version": "11.3.4", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", - "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/@emnapi/core": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", @@ -7249,12 +7337,10 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", - "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "version": "1.19.14", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", + "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=18.14.1" }, @@ -8985,12 +9071,10 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", - "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", + "integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", @@ -9031,8 +9115,6 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" @@ -9042,12 +9124,10 @@ } }, "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -9064,8 +9144,6 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -9083,8 +9161,6 @@ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", @@ -9105,12 +9181,10 @@ } }, "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=18" }, @@ -9124,8 +9198,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=6.6.0" } @@ -9135,8 +9207,6 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -9175,33 +9245,11 @@ "url": "https://opencollective.com/express" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "ip-address": "10.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/express-rate-limit" - }, - "peerDependencies": { - "express": ">= 4.11" - } - }, "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", @@ -9223,8 +9271,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -9234,8 +9280,6 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -9252,8 +9296,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -9263,8 +9305,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=18" }, @@ -9277,8 +9317,6 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "mime-db": "^1.54.0" }, @@ -9295,8 +9333,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -9306,8 +9342,6 @@ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", @@ -9323,8 +9357,6 @@ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", @@ -9351,8 +9383,6 @@ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", @@ -9372,8 +9402,6 @@ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", @@ -18281,15 +18309,6 @@ "dev": true, "license": "MIT" }, - "node_modules/cross-dirname": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz", - "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/cross-env": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", @@ -19598,19 +19617,6 @@ "node": ">=14.0.0" } }, - "node_modules/electron-builder-squirrel-windows": { - "version": "26.8.1", - "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.8.1.tgz", - "integrity": "sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "app-builder-lib": "26.8.1", - "builder-util": "26.8.1", - "electron-winstaller": "5.4.0" - } - }, "node_modules/electron-builder/node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -19688,159 +19694,6 @@ "tiny-typed-emitter": "^2.1.0" } }, - "node_modules/electron-winstaller": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", - "integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@electron/asar": "^3.2.1", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.21", - "temp": "^0.9.0" - }, - "engines": { - "node": ">=8.0.0" - }, - "optionalDependencies": { - "@electron/windows-sign": "^1.1.2" - } - }, - "node_modules/electron-winstaller/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/electron-winstaller/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/electron-winstaller/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/electron-winstaller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "peer": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-winstaller/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/electron-winstaller/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/electron-winstaller/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/electron-winstaller/node_modules/temp": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "mkdirp": "^0.5.1", - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/electron-winstaller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/electron/node_modules/@types/node": { "version": "24.12.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", @@ -23611,10 +23464,13 @@ } }, "node_modules/express-rate-limit": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", - "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.0.tgz", + "integrity": "sha512-XKhFohWaSBdVJNTi5TaHziqnPkv04I9UQV6q1Wy7Ui6GGQZVW12ojDFwqer14EvCXxjvPG0CyWXx7cAXpALB4Q==", "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, "engines": { "node": ">= 16" }, @@ -25418,12 +25274,10 @@ "license": "MIT" }, "node_modules/hono": { - "version": "4.12.8", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz", - "integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==", + "version": "4.12.16", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.16.tgz", + "integrity": "sha512-jN0ZewiNAWSe5khM3EyCmBb250+b40wWbwNILNfEvq84VREWwOIkuUsFONk/3i3nqkz7Oe1PcpM2mwQEK2L9Kg==", "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=16.9.0" } @@ -27237,12 +27091,10 @@ "license": "MIT" }, "node_modules/jose": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz", - "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", + "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", "license": "MIT", - "optional": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/panva" } @@ -27553,9 +27405,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause", - "optional": true, - "peer": true + "license": "BSD-2-Clause" }, "node_modules/json-stable-stringify": { "version": "1.3.0", @@ -32087,36 +31937,6 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, - "node_modules/postject": { - "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", - "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "commander": "^9.4.0" - }, - "bin": { - "postject": "dist/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/postject/node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -34155,9 +33975,9 @@ } }, "node_modules/router/node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -38618,7 +38438,7 @@ "react-native-worklets": "0.5.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.6.0", - "zod": "^3.23.8", + "zod": "^3.23.8 || ^4.0.0", "zustand": "^5.0.9" }, "devDependencies": { @@ -38727,7 +38547,7 @@ "electron-log": "^5.4.3", "electron-updater": "^6.6.2", "ws": "^8.14.2", - "zod": "^3.23.8" + "zod": "^3.23.8 || ^4.0.0" }, "devDependencies": { "@types/node": "24.6.0", @@ -38848,14 +38668,14 @@ "version": "0.1.69", "dependencies": { "@agentclientprotocol/sdk": "^0.17.1", - "@anthropic-ai/claude-agent-sdk": "^0.2.11", + "@anthropic-ai/claude-agent-sdk": "^0.2.128", "@getpaseo/highlight": "0.1.69", "@getpaseo/relay": "0.1.69", "@isaacs/ttlcache": "^2.1.4", "@mariozechner/pi-agent-core": "^0.70.2", "@mariozechner/pi-ai": "^0.70.2", "@mariozechner/pi-coding-agent": "^0.70.2", - "@modelcontextprotocol/sdk": "^1.20.1", + "@modelcontextprotocol/sdk": "1.27.1", "@opencode-ai/sdk": "1.2.6", "@sctg/sentencepiece-js": "^1.1.0", "@xterm/headless": "^6.0.0", @@ -38881,7 +38701,7 @@ "uuid": "^9.0.1", "which": "^5.0.0", "ws": "^8.14.2", - "zod": "^3.23.8", + "zod": "^3.23.8 || ^4.0.0", "zod-to-json-schema": "^3.25.1" }, "devDependencies": { @@ -38908,57 +38728,59 @@ } }, "packages/server/node_modules/@modelcontextprotocol/sdk": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.20.1.tgz", - "integrity": "sha512-j/P+yuxXfgxb+mW7OEoRCM3G47zCTDqUPivJo/VzpjbG8I9csTXtOprCf5FfOfHK4whOJny0aHuBEON+kS7CCA==", + "version": "1.27.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", + "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", "license": "MIT", "dependencies": { - "ajv": "^6.12.6", + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", - "express": "^5.0.1", - "express-rate-limit": "^7.5.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" }, "engines": { "node": ">=18" - } - }, - "packages/server/node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } } }, "packages/server/node_modules/@modelcontextprotocol/sdk/node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.2.0", + "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", + "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", @@ -38988,12 +38810,6 @@ "url": "https://opencollective.com/express" } }, - "packages/server/node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, "packages/server/node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -39023,6 +38839,23 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "packages/server/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "packages/server/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", @@ -39036,35 +38869,40 @@ } }, "packages/server/node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", - "debug": "^4.4.0", + "debug": "^4.4.3", "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", + "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "packages/server/node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "packages/server/node_modules/cookie-signature": { @@ -39077,9 +38915,9 @@ } }, "packages/server/node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -39090,7 +38928,11 @@ "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "packages/server/node_modules/fresh": { @@ -39102,6 +38944,22 @@ "node": ">= 0.8" } }, + "packages/server/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "packages/server/node_modules/isexe": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", @@ -39133,15 +38991,19 @@ } }, "packages/server/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "packages/server/node_modules/negotiator": { @@ -39183,48 +39045,36 @@ "node": ">= 0.10" } }, - "packages/server/node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "packages/server/node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { - "debug": "^4.3.5", + "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", - "statuses": "^2.0.1" + "statuses": "^2.0.2" }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "packages/server/node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", @@ -39234,6 +39084,10 @@ }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "packages/server/node_modules/strip-ansi": { @@ -39340,24 +39194,24 @@ } }, "packages/website/node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", + "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "packages/website/node_modules/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", + "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.4" + "react": "^19.2.5" } }, "packages/website/node_modules/scheduler": { diff --git a/packages/app/package.json b/packages/app/package.json index 98aec02d2..d4e0f975d 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -95,7 +95,7 @@ "react-native-worklets": "0.5.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.6.0", - "zod": "^3.23.8", + "zod": "^3.23.8 || ^4.0.0", "zustand": "^5.0.9" }, "devDependencies": { diff --git a/packages/desktop/package.json b/packages/desktop/package.json index b4c0458e8..e7b603070 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -28,7 +28,7 @@ "electron-log": "^5.4.3", "electron-updater": "^6.6.2", "ws": "^8.14.2", - "zod": "^3.23.8" + "zod": "^3.23.8 || ^4.0.0" }, "devDependencies": { "@types/node": "24.6.0", diff --git a/packages/server/package.json b/packages/server/package.json index f26ce7872..6583a0957 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -57,14 +57,14 @@ }, "dependencies": { "@agentclientprotocol/sdk": "^0.17.1", - "@anthropic-ai/claude-agent-sdk": "^0.2.11", + "@anthropic-ai/claude-agent-sdk": "^0.2.128", "@getpaseo/highlight": "0.1.69", "@getpaseo/relay": "0.1.69", "@isaacs/ttlcache": "^2.1.4", "@mariozechner/pi-agent-core": "^0.70.2", "@mariozechner/pi-ai": "^0.70.2", "@mariozechner/pi-coding-agent": "^0.70.2", - "@modelcontextprotocol/sdk": "^1.20.1", + "@modelcontextprotocol/sdk": "1.27.1", "@opencode-ai/sdk": "1.2.6", "@sctg/sentencepiece-js": "^1.1.0", "@xterm/headless": "^6.0.0", @@ -90,7 +90,7 @@ "uuid": "^9.0.1", "which": "^5.0.0", "ws": "^8.14.2", - "zod": "^3.23.8", + "zod": "^3.23.8 || ^4.0.0", "zod-to-json-schema": "^3.25.1" }, "devDependencies": { diff --git a/packages/server/src/server/agent/create-agent-mode.test.ts b/packages/server/src/server/agent/create-agent-mode.test.ts index 2045c3bd5..73a6e5122 100644 --- a/packages/server/src/server/agent/create-agent-mode.test.ts +++ b/packages/server/src/server/agent/create-agent-mode.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "vitest"; import { resolveAndValidateCreateAgentMode } from "./create-agent-mode.js"; -const CLAUDE_MODES = ["default", "acceptEdits", "plan", "bypassPermissions"]; +const CLAUDE_MODES = ["default", "acceptEdits", "auto", "plan", "bypassPermissions"]; const OPENCODE_MODES = ["build", "full-access", "plan"]; const CODEX_MODES = ["auto", "full-access"]; diff --git a/packages/server/src/server/agent/provider-manifest.ts b/packages/server/src/server/agent/provider-manifest.ts index 3edb52a7a..c38369787 100644 --- a/packages/server/src/server/agent/provider-manifest.ts +++ b/packages/server/src/server/agent/provider-manifest.ts @@ -45,6 +45,14 @@ const CLAUDE_MODES: AgentProviderModeDefinition[] = [ icon: "ShieldAlert", colorTier: "moderate", }, + { + id: "auto", + label: "Auto Mode", + description: + "Classifier-driven approvals. Falls back to prompting after repeated denials. Requires Max/Team/Enterprise plan.", + icon: "ShieldAlert", + colorTier: "moderate", + }, { id: "plan", label: "Plan Mode", diff --git a/packages/server/src/server/agent/providers/claude-agent.redesign.test.ts b/packages/server/src/server/agent/providers/claude-agent.redesign.test.ts index 12b6cfca2..01ff9e05f 100644 --- a/packages/server/src/server/agent/providers/claude-agent.redesign.test.ts +++ b/packages/server/src/server/agent/providers/claude-agent.redesign.test.ts @@ -958,7 +958,7 @@ test("plan approval exposes a resume-bypass action and can return to bypassPermi test("reuses one autonomous run for unbound stream_event bursts with no foreground run", async () => { const session = await createSession(); const internal: { - turnState: "idle" | "foreground" | "autonomous"; + turnState: "idle" | "foreground" | "background"; nextTurnOrdinal: number; routeSdkMessageFromPump: (message: Record) => void; autonomousTurn: { id: string } | null; diff --git a/packages/server/src/server/agent/providers/claude-agent.ts b/packages/server/src/server/agent/providers/claude-agent.ts index 2b15643a6..30677b262 100644 --- a/packages/server/src/server/agent/providers/claude-agent.ts +++ b/packages/server/src/server/agent/providers/claude-agent.ts @@ -169,7 +169,10 @@ function isImageMimeType( ); } -type TurnState = "idle" | "foreground" | "autonomous"; +// Paseo's internal turn-state discriminator. Distinct from Anthropic's "auto" +// permission mode: "background" here means a non-user-initiated turn (wake-up, +// scheduled run, push-triggered), not a permission tier. +type TurnState = "idle" | "foreground" | "background"; interface EventIdentifiers { taskId: string | null; @@ -207,6 +210,12 @@ const DEFAULT_MODES: AgentMode[] = [ label: "Accept File Edits", description: "Automatically approves edit-focused tools without prompting", }, + { + id: "auto", + label: "Auto Mode", + description: + "Classifier-driven approvals. Falls back to prompting after repeated denials. Requires Max/Team/Enterprise plan.", + }, { id: "plan", label: "Plan Mode", @@ -734,6 +743,22 @@ function isPermissionMode(value: string | undefined): value is PermissionMode { return typeof value === "string" && VALID_CLAUDE_MODES.has(value); } +// Auto mode requires direct Anthropic API; Bedrock and Vertex are unsupported. +// Returns the ineligible transport label if the env routes Claude Code through +// one of those, else null. Per-agent launchEnv overrides process.env so an +// explicit "0" disables the inherited setting. +function detectIneligibleAutoModeTransport( + launchEnv: Record | undefined, +): "AWS Bedrock" | "GCP Vertex AI" | null { + const isTruthy = (v: string | undefined): boolean => + v !== undefined && v !== "" && v !== "0" && v.toLowerCase() !== "false"; + const resolve = (key: string): string | undefined => + launchEnv && key in launchEnv ? launchEnv[key] : process.env[key]; + if (isTruthy(resolve("CLAUDE_CODE_USE_BEDROCK"))) return "AWS Bedrock"; + if (isTruthy(resolve("CLAUDE_CODE_USE_VERTEX"))) return "GCP Vertex AI"; + return null; +} + function coerceSessionMetadata(metadata: AgentMetadata | undefined): Partial { if (!isMetadata(metadata)) { return {}; @@ -1784,6 +1809,15 @@ class ClaudeAgentSession implements AgentSession { ); } + if (modeId === "auto") { + const ineligible = detectIneligibleAutoModeTransport(this.launchEnv); + if (ineligible) { + throw new Error( + `Auto mode is not supported on ${ineligible}. Use the Anthropic API endpoint, or pick a different mode.`, + ); + } + } + const normalized = isPermissionMode(modeId) ? modeId : "default"; const previousMode = this.currentMode; const activeQuery = await this.ensureQuery(); @@ -2243,11 +2277,6 @@ class ClaudeAgentSession implements AgentSession { ? this.config.thinkingOptionId : undefined; if (thinkingOptionId && isClaudeThinkingEffort(thinkingOptionId)) { - if (thinkingOptionId === "xhigh") { - // "xhigh" is accepted by Claude Opus 4.7 but not yet in the SDK type definitions - // @ts-expect-error -- SDK 0.2.71 effort type doesn't include "xhigh" yet - return { thinking: { type: "adaptive" }, effort: thinkingOptionId }; - } return { thinking: { type: "adaptive" }, effort: thinkingOptionId }; } return { thinking: undefined, effort: undefined }; @@ -2421,7 +2450,7 @@ class ClaudeAgentSession implements AgentSession { return; } if (this.autonomousTurn) { - this.transitionTurnState("autonomous", reason); + this.transitionTurnState("background", reason); return; } this.transitionTurnState("idle", reason); @@ -2486,7 +2515,7 @@ class ClaudeAgentSession implements AgentSession { } } - private createTurnId(owner: "foreground" | "autonomous"): string { + private createTurnId(owner: "foreground" | "background"): string { return `${owner}-turn-${this.nextTurnOrdinal++}`; } @@ -2599,7 +2628,7 @@ class ClaudeAgentSession implements AgentSession { return; } this.autonomousTurn = { - id: this.createTurnId("autonomous"), + id: this.createTurnId("background"), }; this.notifySubscribers({ type: "turn_started", provider: "claude" }); this.syncTurnState("autonomous turn started");