From 4cd9e76bd2fc03e98b747e736bc1a83f3392cb28 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 4 May 2026 10:21:52 +0700 Subject: [PATCH] Remove unnecessary type assertions across codebase Add oxlint-tsgolint and configure typescript/no-unnecessary-type-assertion to flag redundant `!` and `as Foo` casts. Type-aware mode is left off by default to keep `npm run lint` fast; the rule sits configured for when we turn type-aware on intentionally. Auto-fix removed ~283 redundant casts; two manual touch-ups: a real tsgolint false positive in split-container.tsx and a stale ChildProcess import after a double-cast collapsed. --- .oxlintrc.json | 4 + package-lock.json | 103 ++++++++++++++++++ package.json | 1 + packages/app/e2e/helpers/terminal-probes.ts | 10 +- .../app/e2e/terminal-keystroke-stress.spec.ts | 2 +- packages/app/src/app/_layout.tsx | 4 +- .../web/indexeddb-attachment-store.test.ts | 4 +- .../web/indexeddb-attachment-store.ts | 2 +- .../app/src/components/agent-status-bar.tsx | 2 +- .../src/components/browser-pane.electron.tsx | 2 +- .../combined-model-selector.test.ts | 4 +- .../components/combined-model-selector.tsx | 4 +- packages/app/src/components/composer.tsx | 13 +-- .../app/src/components/file-explorer-pane.tsx | 2 +- .../src/components/project-picker-modal.tsx | 4 +- .../components/provider-diagnostic-sheet.tsx | 6 +- .../sidebar-workspace-list.test.tsx | 2 +- .../src/components/sidebar-workspace-list.tsx | 2 +- packages/app/src/components/ui/combobox.tsx | 2 +- .../app/src/components/use-web-scrollbar.tsx | 4 +- packages/app/src/contexts/session-context.tsx | 8 +- packages/app/src/contexts/voice-context.tsx | 2 +- .../daemon/desktop-daemon-transport.ts | 2 +- .../src/dictation/dictation-stream-sender.ts | 2 +- .../src/hooks/use-agent-form-state.test.ts | 2 +- .../app/src/hooks/use-agent-form-state.ts | 6 +- .../app/src/hooks/use-audio-recorder.web.ts | 2 +- packages/app/src/hooks/use-command-center.ts | 2 +- .../hooks/use-dictation-audio-source.web.ts | 10 +- .../app/src/hooks/use-keyboard-shortcuts.ts | 2 +- packages/app/src/hooks/use-pr-pane-data.ts | 4 +- packages/app/src/hooks/use-settings.ts | 6 +- packages/app/src/panels/agent-panel.tsx | 2 +- packages/app/src/review/surface.test.tsx | 6 +- .../screens/project-settings-screen.test.tsx | 16 +-- .../screens/workspace/workspace-screen.tsx | 2 +- .../workspace/workspace-tab-layout.test.ts | 4 +- .../workspace/workspace-tab-model.test.ts | 2 +- .../src/stores/workspace-layout-actions.ts | 6 +- .../src/stores/workspace-layout-store.test.ts | 66 +++++------ packages/app/src/types/host-connection.ts | 7 +- .../app/src/utils/agent-directory-sync.ts | 4 +- packages/app/src/utils/agent-snapshots.ts | 3 +- .../app/src/utils/os-notifications.test.ts | 2 +- packages/app/src/utils/os-notifications.ts | 2 +- packages/app/src/voice/audio-engine.native.ts | 4 +- packages/app/src/voice/audio-engine.web.ts | 12 +- packages/app/src/voice/voice-runtime.ts | 2 +- packages/cli/src/commands/agent/archive.ts | 4 +- packages/cli/src/commands/agent/attach.ts | 4 +- packages/cli/src/commands/agent/import.ts | 4 +- packages/cli/src/commands/agent/inspect.ts | 4 +- packages/cli/src/commands/agent/reload.ts | 4 +- packages/cli/src/commands/agent/update.ts | 4 +- packages/cli/src/commands/agent/wait.ts | 4 +- packages/cli/src/commands/chat/post.ts | 2 +- packages/cli/src/commands/daemon/pair.ts | 2 +- .../src/commands/daemon/runtime-toolchain.ts | 2 +- packages/cli/src/commands/permit/allow.ts | 2 +- packages/cli/src/commands/provider/ls.ts | 2 +- packages/cli/src/output/table.ts | 2 +- packages/cli/src/utils/client.ts | 2 +- packages/cli/tests/run-all.ts | 2 +- packages/desktop/src/daemon/quit-lifecycle.ts | 2 +- .../examples/flow-api/App.tsx | 2 +- packages/relay/src/live-relay.e2e.test.ts | 2 +- .../client/daemon-client-runtime-metrics.ts | 2 +- .../daemon-client-websocket-transport.ts | 2 +- packages/server/src/client/daemon-client.ts | 2 +- .../src/server/agent/agent-manager.test.ts | 27 ++--- .../server/src/server/agent/agent-manager.ts | 12 +- .../server/agent/agent-projections.test.ts | 6 +- .../src/server/agent/agent-response-loop.ts | 4 +- .../src/server/agent/agent-timeline-store.ts | 16 +-- .../src/server/agent/mcp-server.test.ts | 2 +- .../server/src/server/agent/mcp-server.ts | 10 +- .../server/src/server/agent/mcp-shared.ts | 2 +- .../src/server/agent/model-resolver.test.ts | 2 +- .../src/server/agent/pcm16-resampler.ts | 6 +- .../server/agent/provider-launch-config.ts | 2 +- .../server/agent/provider-snapshot-manager.ts | 2 +- ...ude-agent.event-stream.integration.test.ts | 2 +- .../src/server/agent/providers/acp-agent.ts | 6 +- .../claude-agent-commands.real.e2e.test.ts | 3 +- .../server/agent/providers/claude-agent.ts | 8 +- .../providers/claude/claude-models.test.ts | 2 +- .../agent/providers/claude/claude-models.ts | 6 +- .../agent/providers/codex-app-server-agent.ts | 4 +- .../agent/providers/mock-load-test-agent.ts | 2 +- .../opencode-agent-commands.real.e2e.test.ts | 5 +- ...code-agent.error-handling.real.e2e.test.ts | 2 +- .../test-utils/session-stream-adapter.ts | 2 +- .../providers/tool-call-detail-primitives.ts | 2 +- .../server/agent/tool-name-normalization.ts | 12 +- .../src/server/agent/tts-manager.test.ts | 4 +- .../server/src/server/agent/tts-manager.ts | 2 +- .../daemon-e2e/live-preferences.e2e.test.ts | 4 +- ...encode-plan-and-questions.real.e2e.test.ts | 2 +- .../opencode-send-interrupt.real.e2e.test.ts | 2 +- .../daemon-e2e/permissions-claude.e2e.test.ts | 4 +- .../server/daemon-e2e/terminal.e2e.test.ts | 4 +- packages/server/src/server/daemon-keypair.ts | 2 +- packages/server/src/server/editor-targets.ts | 2 +- packages/server/src/server/json-utils.ts | 6 +- packages/server/src/server/logger.ts | 4 +- .../server/src/server/loop-service.test.ts | 10 +- packages/server/src/server/loop-service.ts | 2 +- packages/server/src/server/paseo-env.ts | 2 +- .../server/src/server/persistence-hooks.ts | 2 +- .../src/server/script-health-monitor.ts | 4 +- packages/server/src/server/session.ts | 12 +- .../src/server/session.workspaces.test.ts | 2 +- packages/server/src/server/speech/audio.ts | 8 +- .../providers/local/pocket/pocket-tts-onnx.ts | 16 +-- .../providers/local/sherpa/model-catalog.ts | 2 +- .../local/sherpa/model-downloader.ts | 2 +- .../local/sherpa/sherpa-parakeet-stt.test.ts | 4 +- .../providers/local/sherpa/sherpa-tts.ts | 2 +- .../src/server/test-utils/dictation-e2e.ts | 6 +- .../websocket-server.relay-reconnect.test.ts | 14 +-- .../server/src/server/websocket-server.ts | 8 +- .../server/src/server/workspace-directory.ts | 4 +- packages/server/src/tasks/task-store.ts | 4 +- .../src/terminal/terminal-output-coalescer.ts | 2 +- .../src/terminal/worker-terminal-manager.ts | 4 +- packages/server/src/utils/checkout-git.ts | 4 +- .../server/src/utils/directory-suggestions.ts | 4 +- packages/server/src/utils/worktree.ts | 2 +- scripts/measure-relay-latency.ts | 8 +- 129 files changed, 409 insertions(+), 323 deletions(-) diff --git a/.oxlintrc.json b/.oxlintrc.json index 7bc16962b..5b76813a6 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,5 +1,8 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", + "options": { + "typeAware": false + }, "plugins": ["react", "react-perf", "unicorn", "typescript", "oxc", "import", "promise"], "categories": { "correctness": "error", @@ -53,6 +56,7 @@ "typescript/no-explicit-any": "error", "typescript/prefer-as-const": "error", "typescript/no-this-alias": "error", + "typescript/no-unnecessary-type-assertion": "error", "typescript/consistent-type-definitions": ["error", "interface"], "import/no-unassigned-import": [ diff --git a/package-lock.json b/package-lock.json index 900d12cbc..6f29e4f1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "lefthook": "^2.1.6", "oxfmt": "0.46.0", "oxlint": "1.61.0", + "oxlint-tsgolint": "^0.22.1", "patch-package": "^8.0.1", "playwright": "^1.56.1", "typescript": "^5.9.3", @@ -10376,6 +10377,90 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/@oxlint-tsgolint/darwin-arm64": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-arm64/-/darwin-arm64-0.22.1.tgz", + "integrity": "sha512-4150Lpgc1YM09GcjA6GSrra1JoPjC7aOpfywLjWEY4vW0Sd1qKzqHF1WRaiw0/qUZ40OATYdv3aRd7ipPkWQbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint-tsgolint/darwin-x64": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-x64/-/darwin-x64-0.22.1.tgz", + "integrity": "sha512-vFWcPWYOgZs4HWcgS1EjUZg33NLcNfEYU49KGImmCfZWkflENrmBYV4HN/C0YeAPum6ZZ/goPSvQrB/cOD+NfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint-tsgolint/linux-arm64": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-arm64/-/linux-arm64-0.22.1.tgz", + "integrity": "sha512-6LiUpP0Zir3+29FvBm7Y28q/dBjSHqTZ5MhG1Ckw4fGhI4cAvbcwXaKvbjx1TP7rRmBNOoq/M5xdpHjTb+GAew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint-tsgolint/linux-x64": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-x64/-/linux-x64-0.22.1.tgz", + "integrity": "sha512-fuX1hEQfpHauUbXADsfqVhRzrUrGabzGXbj5wsp2vKhV5uk/Rze8Mba9GdjFGECzvXudMGqHqxB4r6jGRdhxVA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint-tsgolint/win32-arm64": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-arm64/-/win32-arm64-0.22.1.tgz", + "integrity": "sha512-8SZidAj+jrbZf9ZjBEYW0tiNZ+KasqB2zgW26qdiPpQSF/DzURnPmXz651IeA9YsmbVdHGIooEHUmev6QJdquA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint-tsgolint/win32-x64": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-x64/-/win32-x64-0.22.1.tgz", + "integrity": "sha512-QweSk9H5lFh5Y+WUf2Kq/OAN88V6+62ZwGhP38gqdRotI90luXSMkruFTj7Q2rYrzH4ZVNaSqx7NY8JpSfIzqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@oxlint/binding-android-arm-eabi": { "version": "1.61.0", "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.61.0.tgz", @@ -31174,6 +31259,24 @@ } } }, + "node_modules/oxlint-tsgolint": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/oxlint-tsgolint/-/oxlint-tsgolint-0.22.1.tgz", + "integrity": "sha512-YUSGSLUnoolsu8gxISEDio3q1rtsCozwfOzASUn3DT2mR2EeQ93uEEnen7s+6LpF+lyTQFln1pQfqwBh/fsVEg==", + "dev": true, + "license": "MIT", + "bin": { + "tsgolint": "bin/tsgolint.js" + }, + "optionalDependencies": { + "@oxlint-tsgolint/darwin-arm64": "0.22.1", + "@oxlint-tsgolint/darwin-x64": "0.22.1", + "@oxlint-tsgolint/linux-arm64": "0.22.1", + "@oxlint-tsgolint/linux-x64": "0.22.1", + "@oxlint-tsgolint/win32-arm64": "0.22.1", + "@oxlint-tsgolint/win32-x64": "0.22.1" + } + }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", diff --git a/package.json b/package.json index d49e2bbc2..482e31dd2 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,7 @@ "lefthook": "^2.1.6", "oxfmt": "0.46.0", "oxlint": "1.61.0", + "oxlint-tsgolint": "^0.22.1", "patch-package": "^8.0.1", "playwright": "^1.56.1", "typescript": "^5.9.3", diff --git a/packages/app/e2e/helpers/terminal-probes.ts b/packages/app/e2e/helpers/terminal-probes.ts index 389a20419..eab8b8ed0 100644 --- a/packages/app/e2e/helpers/terminal-probes.ts +++ b/packages/app/e2e/helpers/terminal-probes.ts @@ -204,8 +204,7 @@ export async function installTerminalRenderProbe(page: Page): Promise { if (next?.write && !next.__paseoRenderProbeWriteWrapped) { const originalWrite = next.write.bind(next); next.write = (data: string | Uint8Array, callback?: () => void) => { - const text = - typeof data === "string" ? data : new TextDecoder().decode(data as Uint8Array); + const text = typeof data === "string" ? data : new TextDecoder().decode(data); probe.writeCount += 1; const preview = text .replaceAll("\u001b", "\\x1b") @@ -424,7 +423,7 @@ export async function installTerminalKeystrokeStressProbe(page: Page): Promise firstAtOrAfter(this.inputFrames, keydown.at)?.at ?? null) .filter((at): at is number => at !== null) - .map((at, index) => at - this.keydowns[index]!.at); + .map((at, index) => at - this.keydowns[index].at); const inputFrameToOutputFrame = this.inputFrames .map((input) => { const output = firstAtOrAfter(this.outputFrames, input.at); @@ -663,8 +662,7 @@ export async function installTerminalKeystrokeStressProbe(page: Page): Promise void) => { - const text = - typeof data === "string" ? data : new TextDecoder().decode(data as Uint8Array); + const text = typeof data === "string" ? data : new TextDecoder().decode(data); const event: XtermWriteEvent = { at: performance.now(), committedAt: null, diff --git a/packages/app/e2e/terminal-keystroke-stress.spec.ts b/packages/app/e2e/terminal-keystroke-stress.spec.ts index 8e14a9ee8..e808e632a 100644 --- a/packages/app/e2e/terminal-keystroke-stress.spec.ts +++ b/packages/app/e2e/terminal-keystroke-stress.spec.ts @@ -278,7 +278,7 @@ async function measureDaemonBurstEcho( timeoutMs: STRESS_TIMEOUT_MS, }); - const latencies = sendTimes.map((sentAt, index) => outputTimesByByte[index]! - sentAt); + const latencies = sendTimes.map((sentAt, index) => outputTimesByByte[index] - sentAt); return { inputTextLength: inputText.length, inputFrameCount: sendTimes.length, diff --git a/packages/app/src/app/_layout.tsx b/packages/app/src/app/_layout.tsx index d82627d0a..3a9325b3b 100644 --- a/packages/app/src/app/_layout.tsx +++ b/packages/app/src/app/_layout.tsx @@ -422,7 +422,7 @@ function AppContainer({ const cycleTheme = useCallback(() => { const currentIndex = THEME_CYCLE_ORDER.indexOf(settings.theme as ThemeName); const nextIndex = (currentIndex + 1) % THEME_CYCLE_ORDER.length; - void updateSettings({ theme: THEME_CYCLE_ORDER[nextIndex]! }); + void updateSettings({ theme: THEME_CYCLE_ORDER[nextIndex] }); }, [settings.theme, updateSettings]); const isCompactLayout = useIsCompactFormFactor(); @@ -785,7 +785,7 @@ function AppWithSidebar({ children }: { children: ReactNode }) { if (hosts.some((host) => host.serverId === activeServerId)) { return; } - router.replace(mapPathnameToServer(pathname, hosts[0]!.serverId)); + router.replace(mapPathnameToServer(pathname, hosts[0].serverId)); }, [activeServerId, hosts, pathname, router]); // Parse selectedAgentKey directly from pathname diff --git a/packages/app/src/attachments/web/indexeddb-attachment-store.test.ts b/packages/app/src/attachments/web/indexeddb-attachment-store.test.ts index 618824277..9957241b4 100644 --- a/packages/app/src/attachments/web/indexeddb-attachment-store.test.ts +++ b/packages/app/src/attachments/web/indexeddb-attachment-store.test.ts @@ -22,9 +22,9 @@ class FakeRequest { class FakeObjectStore { constructor(private readonly onPut: (record: unknown) => void) {} - put(record: unknown): FakeRequest { + put(record: unknown): FakeRequest { this.onPut(record); - const request = new FakeRequest(); + const request = new FakeRequest(); queueMicrotask(() => request.emit("success")); return request; } diff --git a/packages/app/src/attachments/web/indexeddb-attachment-store.ts b/packages/app/src/attachments/web/indexeddb-attachment-store.ts index 2811c050e..f64231a7b 100644 --- a/packages/app/src/attachments/web/indexeddb-attachment-store.ts +++ b/packages/app/src/attachments/web/indexeddb-attachment-store.ts @@ -61,7 +61,7 @@ function runTx( const request = run(store); request.addEventListener("success", () => { - resolve(request.result as T); + resolve(request.result); }); request.addEventListener("error", () => { diff --git a/packages/app/src/components/agent-status-bar.tsx b/packages/app/src/components/agent-status-bar.tsx index 214c9fc37..fe2485d44 100644 --- a/packages/app/src/components/agent-status-bar.tsx +++ b/packages/app/src/components/agent-status-bar.tsx @@ -234,7 +234,7 @@ function buildFallbackAllProviderModels( map.set( provider, modelOptions.map((option) => ({ - provider: provider as AgentProvider, + provider: provider, id: option.id, label: option.label, })), diff --git a/packages/app/src/components/browser-pane.electron.tsx b/packages/app/src/components/browser-pane.electron.tsx index b144fcaee..df9efc155 100644 --- a/packages/app/src/components/browser-pane.electron.tsx +++ b/packages/app/src/components/browser-pane.electron.tsx @@ -461,7 +461,7 @@ export function BrowserPane({ }; const handleFaviconUpdated = (event: Event) => { const favicons = Array.isArray((event as Event & { favicons?: unknown[] }).favicons) - ? (((event as Event & { favicons?: string[] }).favicons as string[] | undefined) ?? []) + ? ((event as Event & { favicons?: string[] }).favicons ?? []) : []; updateBrowserRef.current(browserIdRef.current, { faviconUrl: favicons[0] ?? null }); }; diff --git a/packages/app/src/components/combined-model-selector.test.ts b/packages/app/src/components/combined-model-selector.test.ts index 75847f0ab..7d5671795 100644 --- a/packages/app/src/components/combined-model-selector.test.ts +++ b/packages/app/src/components/combined-model-selector.test.ts @@ -63,8 +63,8 @@ describe("combined model selector helpers", () => { }), ]); - expect(matchesSearch(rows[0]!, "claude")).toBe(true); - expect(matchesSearch(rows[1]!, "gpt-5.4")).toBe(true); + expect(matchesSearch(rows[0], "claude")).toBe(true); + expect(matchesSearch(rows[1], "gpt-5.4")).toBe(true); }); it("keeps the selected trigger label model-only", () => { diff --git a/packages/app/src/components/combined-model-selector.tsx b/packages/app/src/components/combined-model-selector.tsx index 967071ab5..9307e0863 100644 --- a/packages/app/src/components/combined-model-selector.tsx +++ b/packages/app/src/components/combined-model-selector.tsx @@ -622,7 +622,7 @@ export function CombinedModelSelector({ const singleProviderView = useMemo(() => { const providers = Array.from(allProviderModels.keys()); if (providers.length !== 1) return null; - const providerId = providers[0]!; + const providerId = providers[0]; const label = resolveProviderLabel(providerDefinitions, providerId); return { kind: "provider", providerId, providerLabel: label }; }, [allProviderModels, providerDefinitions]); @@ -655,7 +655,7 @@ export function CombinedModelSelector({ const handleSelect = useCallback( (provider: string, modelId: string) => { - onSelect(provider as AgentProvider, modelId); + onSelect(provider, modelId); setIsOpen(false); setSearchQuery(""); }, diff --git a/packages/app/src/components/composer.tsx b/packages/app/src/components/composer.tsx index 47fbed7d9..b0fed211a 100644 --- a/packages/app/src/components/composer.tsx +++ b/packages/app/src/components/composer.tsx @@ -160,20 +160,17 @@ function removeAttachmentAtIndex(prev: T[], index: } function buildCancelButtonStyle(isConnected: boolean, isCancellingAgent: boolean): object[] { - const disabled = - !isConnected || isCancellingAgent ? (styles.buttonDisabled as object) : undefined; - return [styles.cancelButton as object, disabled].filter((value): value is object => - Boolean(value), - ); + const disabled = !isConnected || isCancellingAgent ? styles.buttonDisabled : undefined; + return [styles.cancelButton, disabled].filter((value): value is object => Boolean(value)); } function buildRealtimeVoiceButtonStyle( hovered: boolean | undefined, voiceButtonDisabled: boolean, ): object[] { - const hoveredStyle = hovered ? (styles.iconButtonHovered as object) : undefined; - const disabledStyle = voiceButtonDisabled ? (styles.buttonDisabled as object) : undefined; - return [styles.realtimeVoiceButton as object, hoveredStyle, disabledStyle].filter( + const hoveredStyle = hovered ? styles.iconButtonHovered : undefined; + const disabledStyle = voiceButtonDisabled ? styles.buttonDisabled : undefined; + return [styles.realtimeVoiceButton, hoveredStyle, disabledStyle].filter( (value): value is object => Boolean(value), ); } diff --git a/packages/app/src/components/file-explorer-pane.tsx b/packages/app/src/components/file-explorer-pane.tsx index 93788bfef..ccff701c5 100644 --- a/packages/app/src/components/file-explorer-pane.tsx +++ b/packages/app/src/components/file-explorer-pane.tsx @@ -132,7 +132,7 @@ function TreeRowItem({ ); const handleCopy = useCallback(() => { - void onCopyPath(entry.path); + onCopyPath(entry.path); }, [onCopyPath, entry.path]); const handleDownload = useCallback(() => { diff --git a/packages/app/src/components/project-picker-modal.tsx b/packages/app/src/components/project-picker-modal.tsx index 91d92cd49..d94234439 100644 --- a/packages/app/src/components/project-picker-modal.tsx +++ b/packages/app/src/components/project-picker-modal.tsx @@ -29,7 +29,7 @@ interface PathRowProps { function PathRow({ path, active, onSelect }: PathRowProps) { const { theme } = useUnistyles(); const handlePress = useCallback(() => { - void onSelect(path); + onSelect(path); }, [onSelect, path]); const pressableStyle = useCallback( ({ hovered = false, pressed }: PressableStateCallbackType & { hovered?: boolean }) => [ @@ -172,7 +172,7 @@ export function ProjectPickerModal() { if (key === "Enter") { event.preventDefault(); if (options.length > 0 && activeIndex < options.length) { - void handleSelectPath(options[activeIndex]!); + void handleSelectPath(options[activeIndex]); } else if (query.trim()) { handleSubmitCustom(); } diff --git a/packages/app/src/components/provider-diagnostic-sheet.tsx b/packages/app/src/components/provider-diagnostic-sheet.tsx index b731cdc3f..4c4a47ac1 100644 --- a/packages/app/src/components/provider-diagnostic-sheet.tsx +++ b/packages/app/src/components/provider-diagnostic-sheet.tsx @@ -117,7 +117,7 @@ function CustomModelsSection(props: { }, }, }); - await refresh([provider as AgentProvider]); + await refresh([provider]); }, [patchConfig, provider, refresh], ); @@ -284,7 +284,7 @@ export function ProviderDiagnosticSheet({ } try { - const result = await client.getProviderDiagnostic(provider as AgentProvider); + const result = await client.getProviderDiagnostic(provider); setDiagnostic(result.diagnostic); } catch (err) { setDiagnostic(err instanceof Error ? err.message : "Failed to fetch diagnostic"); @@ -308,7 +308,7 @@ export function ProviderDiagnosticSheet({ if (!provider) { return; } - void Promise.all([refresh([provider as AgentProvider]), fetchDiagnostic()]).catch((err) => { + void Promise.all([refresh([provider]), fetchDiagnostic()]).catch((err) => { setDiagnostic(err instanceof Error ? err.message : "Failed to refresh provider"); }); }, [fetchDiagnostic, provider, refresh]); diff --git a/packages/app/src/components/sidebar-workspace-list.test.tsx b/packages/app/src/components/sidebar-workspace-list.test.tsx index 8b7257ea6..18ec795ca 100644 --- a/packages/app/src/components/sidebar-workspace-list.test.tsx +++ b/packages/app/src/components/sidebar-workspace-list.test.tsx @@ -351,7 +351,7 @@ describe("sidebar workspace render isolation", () => { act(() => { useSessionStore.getState().mergeWorkspaces(SERVER_ID, [ { - ...createWorkspaces()[1]!, + ...createWorkspaces()[1], status: "running", }, ]); diff --git a/packages/app/src/components/sidebar-workspace-list.tsx b/packages/app/src/components/sidebar-workspace-list.tsx index b26937f4b..aed70090c 100644 --- a/packages/app/src/components/sidebar-workspace-list.tsx +++ b/packages/app/src/components/sidebar-workspace-list.tsx @@ -439,7 +439,7 @@ function WorkspaceStatusIndicator({ ); } - let KindIcon: typeof ThemedMonitor | typeof ThemedFolderGit2 | null; + let KindIcon: typeof ThemedMonitor | null; if (workspaceKind === "local_checkout") KindIcon = ThemedMonitor; else if (workspaceKind === "worktree") KindIcon = ThemedFolderGit2; else KindIcon = null; diff --git a/packages/app/src/components/ui/combobox.tsx b/packages/app/src/components/ui/combobox.tsx index 610e106c1..06ba818f1 100644 --- a/packages/app/src/components/ui/combobox.tsx +++ b/packages/app/src/components/ui/combobox.tsx @@ -488,7 +488,7 @@ function handleDesktopEnterKey(input: DesktopKeyHandlerInput) { if (input.orderedVisibleOptions.length === 0) return; const { activeIndex, orderedVisibleOptions } = input; const index = activeIndex >= 0 && activeIndex < orderedVisibleOptions.length ? activeIndex : 0; - input.handleSelect(orderedVisibleOptions[index]!.id); + input.handleSelect(orderedVisibleOptions[index].id); } interface FloatingSizeSetters { diff --git a/packages/app/src/components/use-web-scrollbar.tsx b/packages/app/src/components/use-web-scrollbar.tsx index 5156fe66f..febdfbef6 100644 --- a/packages/app/src/components/use-web-scrollbar.tsx +++ b/packages/app/src/components/use-web-scrollbar.tsx @@ -140,9 +140,9 @@ export function useWebScrollViewScrollbar( const scrollable = scrollableRef.current; if (!scrollable) return; if ("scrollToOffset" in scrollable) { - (scrollable as FlatList).scrollToOffset({ offset, animated: false }); + scrollable.scrollToOffset({ offset, animated: false }); } else { - (scrollable as ScrollView).scrollTo({ y: offset, animated: false }); + scrollable.scrollTo({ y: offset, animated: false }); } }, [scrollableRef], diff --git a/packages/app/src/contexts/session-context.tsx b/packages/app/src/contexts/session-context.tsx index 3632c479f..b4a20e75b 100644 --- a/packages/app/src/contexts/session-context.tsx +++ b/packages/app/src/contexts/session-context.tsx @@ -14,11 +14,7 @@ import { type TimelineReducerSideEffect, } from "@/timeline/session-stream-reducers"; import { TIMELINE_FETCH_PAGE_SIZE } from "@/timeline/timeline-fetch-policy"; -import type { - AgentAttachment, - AgentStreamEventPayload, - SessionOutboundMessage, -} from "@server/shared/messages"; +import type { AgentAttachment, SessionOutboundMessage } from "@server/shared/messages"; import { parseServerInfoStatusPayload } from "@server/shared/messages"; import { buildAgentAttentionNotificationPayload, @@ -1201,7 +1197,7 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider if (message.type !== "agent_stream") return; const { agentId, event, timestamp, seq, epoch } = message.payload; const parsedTimestamp = new Date(timestamp); - const streamEvent = event as AgentStreamEventPayload; + const streamEvent = event; if ( event.type === "turn_started" || event.type === "turn_completed" || diff --git a/packages/app/src/contexts/voice-context.tsx b/packages/app/src/contexts/voice-context.tsx index aa4dae037..6c9d7af98 100644 --- a/packages/app/src/contexts/voice-context.tsx +++ b/packages/app/src/contexts/voice-context.tsx @@ -140,7 +140,7 @@ export function VoiceProvider({ children }: VoiceProviderProps) { runtimeRef.current = runtime; } - const engine = engineRef.current!; + const engine = engineRef.current; const runtime = runtimeRef.current!; useEffect(() => { diff --git a/packages/app/src/desktop/daemon/desktop-daemon-transport.ts b/packages/app/src/desktop/daemon/desktop-daemon-transport.ts index 46a98bcea..18b3f46f8 100644 --- a/packages/app/src/desktop/daemon/desktop-daemon-transport.ts +++ b/packages/app/src/desktop/daemon/desktop-daemon-transport.ts @@ -13,7 +13,7 @@ function encodeBinaryToBase64(data: Uint8Array | ArrayBuffer): string { const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data; let binary = ""; for (let index = 0; index < bytes.length; index += 1) { - binary += String.fromCharCode(bytes[index]!); + binary += String.fromCharCode(bytes[index]); } return globalThis.btoa(binary); } diff --git a/packages/app/src/dictation/dictation-stream-sender.ts b/packages/app/src/dictation/dictation-stream-sender.ts index 8729a8b3b..b22d9b3d4 100644 --- a/packages/app/src/dictation/dictation-stream-sender.ts +++ b/packages/app/src/dictation/dictation-stream-sender.ts @@ -110,7 +110,7 @@ export class DictationStreamSender { let sent = 0; while (this.sendSeq < this.segments.length) { const seq = this.sendSeq; - const audio = this.segments[seq]!; + const audio = this.segments[seq]; client.sendDictationStreamChunk(dictationId, seq, audio, this.format); this.sendSeq = seq + 1; sent += 1; diff --git a/packages/app/src/hooks/use-agent-form-state.test.ts b/packages/app/src/hooks/use-agent-form-state.test.ts index 5bb0f76a6..7c9c8145a 100644 --- a/packages/app/src/hooks/use-agent-form-state.test.ts +++ b/packages/app/src/hooks/use-agent-form-state.test.ts @@ -35,7 +35,7 @@ const TEST_CLAUDE_DEFINITION: AgentProviderDefinition = { function makeProviderMap( ...definitions: AgentProviderDefinition[] ): Map { - return new Map(definitions.map((d) => [d.id as AgentProvider, d])); + return new Map(definitions.map((d) => [d.id, d])); } const codexProviderMap = makeProviderMap(TEST_CODEX_DEFINITION); diff --git a/packages/app/src/hooks/use-agent-form-state.ts b/packages/app/src/hooks/use-agent-form-state.ts index df99f28ba..ed6931272 100644 --- a/packages/app/src/hooks/use-agent-form-state.ts +++ b/packages/app/src/hooks/use-agent-form-state.ts @@ -196,8 +196,8 @@ function resolveProvider(input: { if (initialValues?.provider && allowedProviderMap.has(initialValues.provider)) { return initialValues.provider; } - if (preferences?.provider && allowedProviderMap.has(preferences.provider as AgentProvider)) { - return preferences.provider as AgentProvider; + if (preferences?.provider && allowedProviderMap.has(preferences.provider)) { + return preferences.provider; } if (currentProvider && allowedProviderMap.size > 0 && !allowedProviderMap.has(currentProvider)) { return null; @@ -396,7 +396,7 @@ function buildProviderDefinitionMapForStatuses(args: { const matchingProviders = new Set( args.snapshotEntries - .filter((entry) => args.statuses.has(entry.status) && entry.enabled !== false) + .filter((entry) => args.statuses.has(entry.status) && entry.enabled) .map((entry) => entry.provider), ); diff --git a/packages/app/src/hooks/use-audio-recorder.web.ts b/packages/app/src/hooks/use-audio-recorder.web.ts index 4f4883c47..d8c967d1f 100644 --- a/packages/app/src/hooks/use-audio-recorder.web.ts +++ b/packages/app/src/hooks/use-audio-recorder.web.ts @@ -341,7 +341,7 @@ export function useAudioRecorder(config?: AudioCaptureConfig) { return () => { attemptGuard.cancel(); try { - void mediaRecorder.current?.stop(); + mediaRecorder.current?.stop(); } catch { // Ignore stop during unmount. } diff --git a/packages/app/src/hooks/use-command-center.ts b/packages/app/src/hooks/use-command-center.ts index 8f022804c..ed66bd968 100644 --- a/packages/app/src/hooks/use-command-center.ts +++ b/packages/app/src/hooks/use-command-center.ts @@ -332,7 +332,7 @@ export function useCommandCenter() { if (currentItems.length === 0) return; event.preventDefault(); const index = Math.max(0, Math.min(activeIndexRef.current, currentItems.length - 1)); - handleSelectItemRef.current(currentItems[index]!); + handleSelectItemRef.current(currentItems[index]); return; } diff --git a/packages/app/src/hooks/use-dictation-audio-source.web.ts b/packages/app/src/hooks/use-dictation-audio-source.web.ts index 27c4d3cfc..afb4b4449 100644 --- a/packages/app/src/hooks/use-dictation-audio-source.web.ts +++ b/packages/app/src/hooks/use-dictation-audio-source.web.ts @@ -68,7 +68,7 @@ const concatInt16 = (a: Int16Array, b: Int16Array): Int16Array => { const int16ToFloat32 = (input: Int16Array): Float32Array => { const out = new Float32Array(input.length); for (let i = 0; i < input.length; i += 1) { - out[i] = input[i]! / 32768; + out[i] = input[i] / 32768; } return out; }; @@ -209,8 +209,8 @@ export function useDictationAudioSource(config: DictationAudioSourceConfig): Dic const decodeAudioData = useCallback( async (context: AudioContext, buffer: ArrayBuffer): Promise => { const maybePromise = context.decodeAudioData(buffer); - if (maybePromise && typeof (maybePromise as Promise).then === "function") { - return maybePromise as Promise; + if (maybePromise && typeof maybePromise.then === "function") { + return maybePromise; } return await new Promise((resolve, reject) => { context.decodeAudioData(buffer, resolve, reject); @@ -276,7 +276,7 @@ export function useDictationAudioSource(config: DictationAudioSourceConfig): Dic }, }); - const stream = rawStream as MediaStream; + const stream = rawStream; const context = new AudioContextCtor(); @@ -347,7 +347,7 @@ export function useDictationAudioSource(config: DictationAudioSourceConfig): Dic const recorder = new RecorderCtor(stream, { mimeType: "audio/webm;codecs=opus", - } as MediaRecorderOptions) as MediaRecorder; + } as MediaRecorderOptions); const recorderRefs: RecorderRefs = { recorder, diff --git a/packages/app/src/hooks/use-keyboard-shortcuts.ts b/packages/app/src/hooks/use-keyboard-shortcuts.ts index 7518050b9..12056c9a6 100644 --- a/packages/app/src/hooks/use-keyboard-shortcuts.ts +++ b/packages/app/src/hooks/use-keyboard-shortcuts.ts @@ -260,7 +260,7 @@ export function useKeyboardShortcuts({ const handleCommandCenterToggle = (event: KeyboardEvent): boolean => { const store = useKeyboardShortcutsStore.getState(); if (!store.commandCenterOpen) { - const target = event.target instanceof Element ? (event.target as Element) : null; + const target = event.target instanceof Element ? event.target : null; const targetEl = target?.closest?.("textarea, input, [contenteditable='true']") ?? (target instanceof HTMLElement ? target : null); diff --git a/packages/app/src/hooks/use-pr-pane-data.ts b/packages/app/src/hooks/use-pr-pane-data.ts index c374dcbd2..3665e4888 100644 --- a/packages/app/src/hooks/use-pr-pane-data.ts +++ b/packages/app/src/hooks/use-pr-pane-data.ts @@ -86,7 +86,7 @@ export function usePrPaneData({ const checkoutPrStatus = useCheckoutPrStatusQuery({ serverId, cwd, enabled }); const status = checkoutPrStatus.status; const { prNumber, repoOwner, repoName } = extractPrRepoIdentity(status); - const githubFeaturesEnabled = checkoutPrStatus.githubFeaturesEnabled !== false; + const githubFeaturesEnabled = checkoutPrStatus.githubFeaturesEnabled; const unsupportedKey = prNumber === null ? null : timelineUnsupportedKey({ serverId, cwd, prNumber }); const timelineUnsupported = unsupportedKey ? unsupportedTimelineKeys.has(unsupportedKey) : false; @@ -100,7 +100,7 @@ export function usePrPaneData({ timelineUnsupported, }); - const timelineQuery = useQuery({ + const timelineQuery = useQuery({ queryKey: prPaneTimelineQueryKey({ serverId, cwd, prNumber }), queryFn: async () => { if (!daemonClient || prNumber === null || repoOwner === null || repoName === null) { diff --git a/packages/app/src/hooks/use-settings.ts b/packages/app/src/hooks/use-settings.ts index d569567c3..a0492bff9 100644 --- a/packages/app/src/hooks/use-settings.ts +++ b/packages/app/src/hooks/use-settings.ts @@ -235,16 +235,16 @@ export async function loadSettingsFromStorage(): Promise { function pickAppSettings(stored: Partial): Partial { const result: Partial = {}; if (typeof stored.theme === "string" && VALID_THEMES.has(stored.theme)) { - result.theme = stored.theme as AppSettings["theme"]; + result.theme = stored.theme; } if (stored.sendBehavior === "interrupt" || stored.sendBehavior === "queue") { result.sendBehavior = stored.sendBehavior; } if ( typeof stored.serviceUrlBehavior === "string" && - VALID_SERVICE_URL_BEHAVIORS.has(stored.serviceUrlBehavior as ServiceUrlBehavior) + VALID_SERVICE_URL_BEHAVIORS.has(stored.serviceUrlBehavior) ) { - result.serviceUrlBehavior = stored.serviceUrlBehavior as ServiceUrlBehavior; + result.serviceUrlBehavior = stored.serviceUrlBehavior; } return result; } diff --git a/packages/app/src/panels/agent-panel.tsx b/packages/app/src/panels/agent-panel.tsx index 633f588d6..4d4be6485 100644 --- a/packages/app/src/panels/agent-panel.tsx +++ b/packages/app/src/panels/agent-panel.tsx @@ -750,7 +750,7 @@ function ChatAgentContent({ }; }, []); - const isInitializing = agentId ? isInitializingFromMap !== false : false; + const isInitializing = agentId ? isInitializingFromMap : false; const isHistorySyncing = useMemo(() => { if (!agentId || !isInitializing) { return false; diff --git a/packages/app/src/review/surface.test.tsx b/packages/app/src/review/surface.test.tsx index 7c3f05c29..13e59f579 100644 --- a/packages/app/src/review/surface.test.tsx +++ b/packages/app/src/review/surface.test.tsx @@ -197,7 +197,7 @@ describe("useInlineReviewController", () => { body: "first comment", }); - act(() => result.current.onEditComment(reviewTarget, savedComment!)); + act(() => result.current.onEditComment(reviewTarget, savedComment)); expect(result.current.editor).toEqual({ target: reviewTarget, commentId: savedComment?.id, @@ -208,8 +208,8 @@ describe("useInlineReviewController", () => { const updatedComment = useReviewDraftStore.getState().drafts[firstKey]?.[0]; expect(updatedComment).toMatchObject({ id: savedComment?.id, body: "updated comment" }); - act(() => result.current.onEditComment(reviewTarget, updatedComment!)); - act(() => result.current.onDeleteComment(updatedComment!.id)); + act(() => result.current.onEditComment(reviewTarget, updatedComment)); + act(() => result.current.onDeleteComment(updatedComment.id)); expect(useReviewDraftStore.getState().drafts[firstKey]).toEqual([]); expect(result.current.editor).toBeNull(); diff --git a/packages/app/src/screens/project-settings-screen.test.tsx b/packages/app/src/screens/project-settings-screen.test.tsx index 09d6149a3..3af776c53 100644 --- a/packages/app/src/screens/project-settings-screen.test.tsx +++ b/packages/app/src/screens/project-settings-screen.test.tsx @@ -752,7 +752,7 @@ describe("ProjectSettingsScreen — save flow", () => { await flush(); expect(client.writeProjectConfig).toHaveBeenCalledTimes(1); - const callArg = client.writeProjectConfig.mock.calls[0]![0] as { + const callArg = client.writeProjectConfig.mock.calls[0][0] as { repoRoot: string; config: PaseoConfigRaw; expectedRevision: PaseoConfigRevision | null; @@ -767,7 +767,7 @@ describe("ProjectSettingsScreen — save flow", () => { // Subsequent saves use the freshly-returned revision. click(requireById("save-button")); await flush(); - const secondArg = client.writeProjectConfig.mock.calls[1]![0] as { + const secondArg = client.writeProjectConfig.mock.calls[1][0] as { expectedRevision: PaseoConfigRevision; }; expect(secondArg.expectedRevision).toEqual(newRevision); @@ -869,7 +869,7 @@ describe("ProjectSettingsScreen — round-trip semantics", () => { click(requireById("save-button")); await flush(); - const savedConfig = client.writeProjectConfig.mock.calls[0]![0]!.config as PaseoConfigRaw; + const savedConfig = client.writeProjectConfig.mock.calls[0][0]!.config as PaseoConfigRaw; // string stays string when edited in place expect(savedConfig.worktree?.setup).toBe("npm install\nnpm run prepare"); }); @@ -897,7 +897,7 @@ describe("ProjectSettingsScreen — round-trip semantics", () => { click(requireById("save-button")); await flush(); - const savedConfig = client.writeProjectConfig.mock.calls[0]![0]!.config as PaseoConfigRaw; + const savedConfig = client.writeProjectConfig.mock.calls[0][0]!.config as PaseoConfigRaw; expect(savedConfig.worktree?.teardown).toEqual(["docker compose down", "rm -rf .cache"]); }); @@ -920,7 +920,7 @@ describe("ProjectSettingsScreen — round-trip semantics", () => { click(requireById("save-button")); await flush(); - const savedConfig = client.writeProjectConfig.mock.calls[0]![0]!.config as PaseoConfigRaw; + const savedConfig = client.writeProjectConfig.mock.calls[0][0]!.config as PaseoConfigRaw; expect(savedConfig.worktree?.setup).toBe("npm install"); }); @@ -943,7 +943,7 @@ describe("ProjectSettingsScreen — round-trip semantics", () => { click(requireById("save-button")); await flush(); - const savedConfig = client.writeProjectConfig.mock.calls[0]![0]!.config as PaseoConfigRaw; + const savedConfig = client.writeProjectConfig.mock.calls[0][0]!.config as PaseoConfigRaw; expect(savedConfig.worktree?.setup).toEqual(["npm install", "npm run prepare"]); }); }); @@ -996,7 +996,7 @@ describe("ProjectSettingsScreen — scripts editor", () => { click(requireById("save-button")); await flush(); - const savedConfig = client.writeProjectConfig.mock.calls[0]![0]!.config as PaseoConfigRaw; + const savedConfig = client.writeProjectConfig.mock.calls[0][0]!.config as PaseoConfigRaw; const scriptKeys = Object.keys((savedConfig as Record).scripts ?? {}); // One of the two scripts was removed. expect(scriptKeys.length).toBe(1); @@ -1031,7 +1031,7 @@ describe("ProjectSettingsScreen — scripts editor", () => { click(requireById("save-button")); await flush(); - const savedConfig = client.writeProjectConfig.mock.calls[0]![0]!.config as PaseoConfigRaw; + const savedConfig = client.writeProjectConfig.mock.calls[0][0]!.config as PaseoConfigRaw; expect((savedConfig as Record).customTopLevel).toBe("preserved"); const worktreeRecord = (savedConfig.worktree ?? {}) as Record; expect(worktreeRecord.customWorktreeField).toBe("keep"); diff --git a/packages/app/src/screens/workspace/workspace-screen.tsx b/packages/app/src/screens/workspace/workspace-screen.tsx index 38df733bc..1ff7db7cd 100644 --- a/packages/app/src/screens/workspace/workspace-screen.tsx +++ b/packages/app/src/screens/workspace/workspace-screen.tsx @@ -1541,7 +1541,7 @@ function WorkspaceScreenContent({ if (!client || !workspaceDirectory) { throw new Error("Host is not connected"); } - return (await client.getCheckoutStatus(workspaceDirectory)) as CheckoutStatusPayload; + return await client.getCheckoutStatus(workspaceDirectory); }, staleTime: Infinity, refetchOnMount: false, diff --git a/packages/app/src/screens/workspace/workspace-tab-layout.test.ts b/packages/app/src/screens/workspace/workspace-tab-layout.test.ts index 22bdace19..2b608fc7c 100644 --- a/packages/app/src/screens/workspace/workspace-tab-layout.test.ts +++ b/packages/app/src/screens/workspace/workspace-tab-layout.test.ts @@ -68,7 +68,7 @@ describe("computeWorkspaceTabLayout", () => { expect(result.closeButtonPolicy).toBe("all"); expect(result.requiresHorizontalScrollFallback).toBe(false); expect(result.items.map((item) => item.width)).toEqual([60, 60, 60, 60]); - expect(result.items.every((item) => item.showLabel === false)).toBe(true); + expect(result.items.every((item) => !item.showLabel)).toBe(true); }); it("allows horizontal scroll only when icon-only tabs still cannot fit", () => { @@ -81,7 +81,7 @@ describe("computeWorkspaceTabLayout", () => { expect(result.closeButtonPolicy).toBe("all"); expect(result.requiresHorizontalScrollFallback).toBe(true); expect(result.items.map((item) => item.width)).toEqual([60, 60, 60, 60]); - expect(result.items.every((item) => item.showLabel === false)).toBe(true); + expect(result.items.every((item) => !item.showLabel)).toBe(true); }); it("returns empty layout details when there are no tabs", () => { diff --git a/packages/app/src/screens/workspace/workspace-tab-model.test.ts b/packages/app/src/screens/workspace/workspace-tab-model.test.ts index debf9a85a..5bfa56660 100644 --- a/packages/app/src/screens/workspace/workspace-tab-model.test.ts +++ b/packages/app/src/screens/workspace/workspace-tab-model.test.ts @@ -23,7 +23,7 @@ describe("deriveWorkspaceTabModel", () => { ]; const model = deriveWorkspaceTabModel({ - tabs: [uiTabs[0]!, uiTabs[2]!, uiTabs[1]!], + tabs: [uiTabs[0], uiTabs[2], uiTabs[1]], }); expect(model.tabs.map((tab) => tab.descriptor.tabId)).toEqual([ diff --git a/packages/app/src/stores/workspace-layout-actions.ts b/packages/app/src/stores/workspace-layout-actions.ts index ee7df82cb..2aae82a0d 100644 --- a/packages/app/src/stores/workspace-layout-actions.ts +++ b/packages/app/src/stores/workspace-layout-actions.ts @@ -526,7 +526,7 @@ function findNearestSiblingPaneId(root: SplitNodeInternal, paneId: string): stri for (let depth = path.length - 1; depth >= 0; depth -= 1) { const parentPath = path.slice(0, depth); - const childIndex = path[depth]!; + const childIndex = path[depth]; const parentNode = getNodeAtPath(root, parentPath); invariant(parentNode.kind === "group", "Expected parent group for pane lookup"); @@ -667,7 +667,7 @@ function removePaneByPath(root: SplitNodeInternal, path: number[]): SplitNodeInt } const parentPath = path.slice(0, -1); - const removeIndex = path[path.length - 1]!; + const removeIndex = path[path.length - 1]; const parentNode = getNodeAtPath(root, parentPath); invariant(parentNode.kind === "group", "Expected parent group while removing pane"); @@ -676,7 +676,7 @@ function removePaneByPath(root: SplitNodeInternal, path: number[]): SplitNodeInt const nextParentNode = nextParentChildren.length === 1 - ? nextParentChildren[0]! + ? nextParentChildren[0] : createGroupNode({ id: parentNode.group.id, direction: parentNode.group.direction, diff --git a/packages/app/src/stores/workspace-layout-store.test.ts b/packages/app/src/stores/workspace-layout-store.test.ts index 700d52cde..25c54343d 100644 --- a/packages/app/src/stores/workspace-layout-store.test.ts +++ b/packages/app/src/stores/workspace-layout-store.test.ts @@ -142,7 +142,7 @@ describe("workspace-layout-store tree transforms", () => { const nextRoot = insertSplit(root, "right", "tab-c", "right"); const nextGroup = expectGroup(nextRoot); - const nestedGroup = expectGroup(nextGroup.group.children[1]!); + const nestedGroup = expectGroup(nextGroup.group.children[1]); expect(nextGroup.group.direction).toBe("horizontal"); expect(nextGroup.group.children).toHaveLength(2); @@ -259,7 +259,7 @@ describe("workspace-layout-store actions", () => { kind: "file", path: "/repo/worktree/b.ts", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(firstTabId).toBe("file_/repo/worktree/a.ts"); expect(secondTabId).toBe("file_/repo/worktree/b.ts"); @@ -280,7 +280,7 @@ describe("workspace-layout-store actions", () => { kind: "setup", workspaceId: "ws-main", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; const pane = findPaneById(layout.root, "main")!; expect(agentTabId).toBe("agent_agent-1"); @@ -306,7 +306,7 @@ describe("workspace-layout-store actions", () => { kind: "file", path: "/repo/worktree/a.ts", }); - const layoutAfter = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layoutAfter = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; const pane = findPaneById(layoutAfter.root, "main")!; expect(duplicateTabId).toBe(firstTabId); @@ -380,7 +380,7 @@ describe("workspace-layout-store actions", () => { const firstTabId = store.openTabFocused(workspaceKey, { kind: "draft", draftId: "draft-1" }); const secondTabId = store.openTabFocused(workspaceKey, { kind: "draft", draftId: "draft-2" }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(firstTabId).toBe("draft-1"); expect(secondTabId).toBe("draft-2"); @@ -416,14 +416,14 @@ describe("workspace-layout-store actions", () => { kind: "draft", draftId: "draft-split", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(newPaneId).toBe("pane_77777777-7777-7777-7777-777777777777"); expect(draftTabId).toBe("draft-split"); expect(layout.focusedPaneId).toBe(newPaneId); expect(findPaneById(layout.root, "main")?.tabIds).toEqual(["file_/repo/worktree/a.ts"]); - expect(findPaneById(layout.root, newPaneId!)?.tabIds).toEqual([draftTabId!]); - expect(findPaneById(layout.root, newPaneId!)?.focusedTabId).toBe(draftTabId); + expect(findPaneById(layout.root, newPaneId)?.tabIds).toEqual([draftTabId!]); + expect(findPaneById(layout.root, newPaneId)?.focusedTabId).toBe(draftTabId); }); it("focusTab moves workspace focus to the pane containing the tab", () => { @@ -448,14 +448,14 @@ describe("workspace-layout-store actions", () => { }); store.focusTab(workspaceKey, fileTabId!); - let layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + let layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(layout.focusedPaneId).toBe("main"); store.focusTab(workspaceKey, terminalTabId!); layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; expect(splitPaneId).toBe("pane_bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"); expect(layout.focusedPaneId).toBe(splitPaneId); - expect(findPaneById(layout.root, splitPaneId!)?.focusedTabId).toBe(terminalTabId); + expect(findPaneById(layout.root, splitPaneId)?.focusedTabId).toBe(terminalTabId); }); it("convertDraftToAgent replaces the draft tab with a canonical agent tab in the same pane", () => { @@ -474,8 +474,8 @@ describe("workspace-layout-store actions", () => { }); const nextTabId = store.convertDraftToAgent(workspaceKey, secondTabId!, "agent-1"); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; - const splitPane = findPaneById(layout.root, splitPaneId!); + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; + const splitPane = findPaneById(layout.root, splitPaneId); const convertedTab = collectAllTabs(layout.root).find((tab) => tab.tabId === nextTabId); expect(splitPaneId).toBe("pane_12121212-1212-1212-1212-121212121212"); @@ -501,7 +501,7 @@ describe("workspace-layout-store actions", () => { kind: "file", path: "/repo/worktree/retargeted.ts", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(draftTabId).toBe("draft-retarget"); expect(nextTabId).toBe(draftTabId); @@ -541,7 +541,7 @@ describe("workspace-layout-store actions", () => { kind: "file", path: "/repo/worktree/existing.ts", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(existingFileTabId).toBe("file_/repo/worktree/existing.ts"); expect(draftTabId).toBe("draft-dup"); @@ -576,7 +576,7 @@ describe("workspace-layout-store actions", () => { kind: "agent", agentId: "agent-1", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(firstAgentTabId).toBe(firstDraftTabId); expect(nextTabId).toBe(firstDraftTabId); @@ -608,7 +608,7 @@ describe("workspace-layout-store actions", () => { }); store.reorderTabs(workspaceKey, [thirdTabId!, firstTabId!]); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(findPaneById(layout.root, "main")).toEqual({ id: "main", @@ -663,11 +663,11 @@ describe("workspace-layout-store actions", () => { store.moveTabToPane(workspaceKey, fourthTabId!, splitPaneId!); store.focusPane(workspaceKey, "main"); store.reorderTabsInPane(workspaceKey, splitPaneId!, [fourthTabId!, thirdTabId!]); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(splitPaneId).toBe("pane_34343434-3434-3434-3434-343434343434"); expect(layout.focusedPaneId).toBe("main"); - expect(findPaneById(layout.root, splitPaneId!)).toEqual({ + expect(findPaneById(layout.root, splitPaneId)).toEqual({ id: splitPaneId, tabIds: [fourthTabId!, thirdTabId!], focusedTabId: fourthTabId, @@ -705,7 +705,7 @@ describe("workspace-layout-store actions", () => { }); store.focusPane(workspaceKey, "main"); - let layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + let layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(layout.focusedPaneId).toBe("main"); store.focusPane(workspaceKey, splitPaneId!); @@ -734,7 +734,7 @@ describe("workspace-layout-store actions", () => { }); store.closeTab(workspaceKey, secondTabId!); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(splitPaneId).toBe("pane_cccccccc-cccc-cccc-cccc-cccccccccccc"); expect(layout.focusedPaneId).toBe("main"); @@ -782,7 +782,7 @@ describe("workspace-layout-store actions", () => { position: "bottom", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(pane1).toBe("pane_11111111-1111-1111-1111-111111111111"); expect(pane2).toBe("pane_33333333-3333-3333-3333-333333333333"); expect(pane3).toBe("pane_55555555-5555-5555-5555-555555555555"); @@ -812,11 +812,11 @@ describe("workspace-layout-store actions", () => { }); store.moveTabToPane(workspaceKey, leftTabId!, splitPaneId!); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(layout.focusedPaneId).toBe(splitPaneId); expect(collectAllPanes(layout.root).map((pane) => pane.id)).toEqual([splitPaneId!]); - expect(findPaneById(layout.root, splitPaneId!)?.tabIds).toEqual([ + expect(findPaneById(layout.root, splitPaneId)?.tabIds).toEqual([ "file_/repo/worktree/b.ts", "file_/repo/worktree/a.ts", ]); @@ -852,7 +852,7 @@ describe("workspace-layout-store actions", () => { }); store.closeTab(workspaceKey, secondTabId!); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; const rootGroup = expectGroup(layout.root); expect(paneBId).toBe("pane_78787878-7878-7878-7878-787878787878"); @@ -910,7 +910,7 @@ describe("workspace-layout-store actions", () => { kind: "file", path: "/repo/worktree/b.ts", }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(splitPaneId).toBe("pane_abababab-abab-abab-abab-abababababab"); expect(duplicateTabId).toBe(secondTabId); @@ -946,14 +946,14 @@ describe("workspace-layout-store actions", () => { position: "right", }); - const splitRoot = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!.root; + const splitRoot = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey].root; const splitGroup = expectGroup(splitRoot); - const nestedGroup = expectGroup(splitGroup.group.children[1]!); + const nestedGroup = expectGroup(splitGroup.group.children[1]); store.resizeSplit(workspaceKey, nestedGroup.group.id, [0.01, 0.99]); - const resizedRoot = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!.root; + const resizedRoot = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey].root; const resizedGroup = expectGroup(resizedRoot); - const resizedNestedGroup = expectGroup(resizedGroup.group.children[1]!); + const resizedNestedGroup = expectGroup(resizedGroup.group.children[1]); const total = resizedNestedGroup.group.sizes.reduce((sum, size) => sum + size, 0); expect(rightPaneId).toBe("pane_eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee"); @@ -969,7 +969,7 @@ describe("workspace-layout-store actions", () => { const tabId = store.openTabFocused(workspaceKey, { kind: "draft", draftId: "draft-1" }); store.closeTab(workspaceKey, tabId!); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(layout).toEqual(createDefaultLayout()); }); @@ -1065,7 +1065,7 @@ describe("workspace-layout-store actions", () => { }); const nextTabId = store.convertDraftToAgent(workspaceKey, draftTabId!, "agent-1"); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(splitPaneId).toBe("pane_67676767-6767-6767-6767-676767676767"); expect(nextTabId).toBe("agent_agent-1"); @@ -1129,7 +1129,7 @@ describe("workspace-layout-store actions", () => { hasActivePendingDraftCreate: false, }); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; const tabs = collectAllTabs(layout.root); expect(tabs.map((tab) => tab.tabId)).toEqual([ @@ -1189,7 +1189,7 @@ describe("workspace-layout-store actions", () => { }); const tabs = useWorkspaceLayoutStore.getState().getWorkspaceTabs(workspaceKey); - const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]!; + const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey]; expect(tabs.map((tab) => tab.tabId)).toEqual(["terminal_term-script", "terminal_term-manual"]); expect(findPaneById(layout.root, layout.focusedPaneId)?.focusedTabId).toBe(scriptTabId); }); diff --git a/packages/app/src/types/host-connection.ts b/packages/app/src/types/host-connection.ts index 6cbcb3c4a..4c6f72b75 100644 --- a/packages/app/src/types/host-connection.ts +++ b/packages/app/src/types/host-connection.ts @@ -134,9 +134,8 @@ export function upsertHostConnectionInProfiles(input: { return [...existing, profile]; } - const matchedProfiles = matchingIndexes.map((index) => existing[index]!); - const prev = - matchedProfiles.find((daemon) => daemon.serverId === serverId) ?? matchedProfiles[0]!; + const matchedProfiles = matchingIndexes.map((index) => existing[index]); + const prev = matchedProfiles.find((daemon) => daemon.serverId === serverId) ?? matchedProfiles[0]; const nextConnections = dedupeHostConnections([ ...matchedProfiles.flatMap((daemon) => daemon.connections), input.connection, @@ -180,7 +179,7 @@ export function upsertHostConnectionInProfiles(input: { updatedAt: now, }; - const firstIndex = matchingIndexes[0]!; + const firstIndex = matchingIndexes[0]; const matchingIndexSet = new Set(matchingIndexes); const next = existing.filter((_daemon, index) => !matchingIndexSet.has(index)); next.splice(firstIndex, 0, nextProfile); diff --git a/packages/app/src/utils/agent-directory-sync.ts b/packages/app/src/utils/agent-directory-sync.ts index 1c5bb28fb..cd67253f4 100644 --- a/packages/app/src/utils/agent-directory-sync.ts +++ b/packages/app/src/utils/agent-directory-sync.ts @@ -1,9 +1,9 @@ -import type { FetchAgentHistoryEntry, FetchAgentsEntry } from "@server/client/daemon-client"; +import type { FetchAgentsEntry } from "@server/client/daemon-client"; import { type Agent, useSessionStore } from "@/stores/session-store"; import { derivePendingPermissionKey, normalizeAgentSnapshot } from "@/utils/agent-snapshots"; import { resolveProjectPlacement } from "@/utils/project-placement"; -type AgentDirectoryFetchEntry = FetchAgentsEntry | FetchAgentHistoryEntry; +type AgentDirectoryFetchEntry = FetchAgentsEntry; interface PendingPermissionEntry { key: string; diff --git a/packages/app/src/utils/agent-snapshots.ts b/packages/app/src/utils/agent-snapshots.ts index 9b9f5691f..341273a98 100644 --- a/packages/app/src/utils/agent-snapshots.ts +++ b/packages/app/src/utils/agent-snapshots.ts @@ -1,4 +1,3 @@ -import type { AgentLifecycleStatus } from "@server/shared/agent-lifecycle"; import type { AgentSnapshotPayload } from "@server/shared/messages"; import type { AgentPermissionRequest } from "@server/server/agent/agent-sdk-types"; @@ -31,7 +30,7 @@ export function normalizeAgentSnapshot(snapshot: AgentSnapshotPayload, serverId: serverId, id: snapshot.id, provider: snapshot.provider, - status: snapshot.status as AgentLifecycleStatus, + status: snapshot.status, createdAt, updatedAt, lastUserMessageAt, diff --git a/packages/app/src/utils/os-notifications.test.ts b/packages/app/src/utils/os-notifications.test.ts index bdd5e1c51..e570a4c59 100644 --- a/packages/app/src/utils/os-notifications.test.ts +++ b/packages/app/src/utils/os-notifications.test.ts @@ -148,7 +148,7 @@ describe("sendOsNotification", () => { clicked.clickListeners[0]?.({} as Event); expect(dispatchEvent).toHaveBeenCalledTimes(1); - const event = dispatchEvent.mock.calls[0]?.[0] as unknown as { + const event = dispatchEvent.mock.calls[0]?.[0] as { type?: string; detail?: { data?: Record }; }; diff --git a/packages/app/src/utils/os-notifications.ts b/packages/app/src/utils/os-notifications.ts index 353f19513..3d5823b90 100644 --- a/packages/app/src/utils/os-notifications.ts +++ b/packages/app/src/utils/os-notifications.ts @@ -132,7 +132,7 @@ function dispatchWebNotificationClick(detail: WebNotificationClickDetail): boole cancelable: true, }, ); - return dispatch(event) === false; + return !dispatch(event); } function fallbackNavigateToNotificationTarget(data: Record | undefined): void { diff --git a/packages/app/src/voice/audio-engine.native.ts b/packages/app/src/voice/audio-engine.native.ts index d42f80d53..0f543be86 100644 --- a/packages/app/src/voice/audio-engine.native.ts +++ b/packages/app/src/voice/audio-engine.native.ts @@ -38,8 +38,8 @@ function resamplePcm16(pcm: Uint8Array, fromRate: number, toRate: number): Uint8 if (i + 1 >= pcm.length) { return 0; } - const lo = pcm[i]!; - const hi = pcm[i + 1]!; + const lo = pcm[i]; + const hi = pcm[i + 1]; let value = (hi << 8) | lo; if (value & 0x8000) { value = value - 0x10000; diff --git a/packages/app/src/voice/audio-engine.web.ts b/packages/app/src/voice/audio-engine.web.ts index d6b17c609..0453c0ae3 100644 --- a/packages/app/src/voice/audio-engine.web.ts +++ b/packages/app/src/voice/audio-engine.web.ts @@ -39,7 +39,7 @@ function resampleToPcm16(input: Float32Array, inputRate: number, outputRate: num const i0 = Math.floor(sourceIndex); const i1 = Math.min(input.length - 1, i0 + 1); const frac = sourceIndex - i0; - const sample = input[i0]! * (1 - frac) + input[i1]! * frac; + const sample = input[i0] * (1 - frac) + input[i1] * frac; output[i] = floatToInt16(sample); } @@ -64,8 +64,8 @@ function pcm16LeToAudioBuffer( const audioBuffer = context.createBuffer(1, sampleCount, sampleRate); const channel = audioBuffer.getChannelData(0); for (let i = 0; i < sampleCount; i += 1) { - const lo = bytes[i * 2]!; - const hi = bytes[i * 2 + 1]!; + const lo = bytes[i * 2]; + const hi = bytes[i * 2 + 1]; let value = (hi << 8) | lo; if (value & 0x8000) { value -= 0x10000; @@ -77,8 +77,8 @@ function pcm16LeToAudioBuffer( async function decodeAudioData(context: AudioContext, buffer: ArrayBuffer): Promise { const maybePromise = context.decodeAudioData(buffer.slice(0)); - if (maybePromise && typeof (maybePromise as Promise).then === "function") { - return maybePromise as Promise; + if (maybePromise && typeof maybePromise.then === "function") { + return maybePromise; } return await new Promise((resolve, reject) => { context.decodeAudioData(buffer.slice(0), resolve, reject); @@ -323,7 +323,7 @@ export function createAudioEngine( const input = event.inputBuffer.getChannelData(0); let sumSquares = 0; for (let i = 0; i < input.length; i += 1) { - const sample = input[i]!; + const sample = input[i]; sumSquares += sample * sample; } const rms = Math.sqrt(sumSquares / Math.max(1, input.length)); diff --git a/packages/app/src/voice/voice-runtime.ts b/packages/app/src/voice/voice-runtime.ts index 6a5d782ee..538ad583a 100644 --- a/packages/app/src/voice/voice-runtime.ts +++ b/packages/app/src/voice/voice-runtime.ts @@ -295,7 +295,7 @@ export function createVoiceRuntime(deps: VoiceRuntimeDeps): VoiceRuntime { function activateNextPlaybackGroup(): void { while (playback.orderedGroupIds.length > 0) { - const groupId = playback.orderedGroupIds[0]!; + const groupId = playback.orderedGroupIds[0]; if (playback.groups.has(groupId)) { playback.activeGroupId = groupId; return; diff --git a/packages/cli/src/commands/agent/archive.ts b/packages/cli/src/commands/agent/archive.ts index 581f70591..83293a75e 100644 --- a/packages/cli/src/commands/agent/archive.ts +++ b/packages/cli/src/commands/agent/archive.ts @@ -44,7 +44,7 @@ export async function runArchiveCommand( options: AgentArchiveOptions, _command: Command, ): Promise { - const host = getDaemonHost({ host: options.host as string | undefined }); + const host = getDaemonHost({ host: options.host }); // Validate arguments if (!agentIdArg || agentIdArg.trim().length === 0) { @@ -58,7 +58,7 @@ export async function runArchiveCommand( let client: DaemonClient; try { - client = await connectToDaemon({ host: options.host as string | undefined }); + client = await connectToDaemon({ host: options.host }); } catch (err) { const message = err instanceof Error ? err.message : String(err); const error: CommandError = { diff --git a/packages/cli/src/commands/agent/attach.ts b/packages/cli/src/commands/agent/attach.ts index d148568dc..a9628155a 100644 --- a/packages/cli/src/commands/agent/attach.ts +++ b/packages/cli/src/commands/agent/attach.ts @@ -105,7 +105,7 @@ export async function runAttachCommand( options: AgentAttachOptions, _command: Command, ): Promise { - const host = getDaemonHost({ host: options.host as string | undefined }); + const host = getDaemonHost({ host: options.host }); if (!id) { console.error("Error: Agent ID required"); @@ -115,7 +115,7 @@ export async function runAttachCommand( let client: DaemonClient; try { - client = await connectToDaemon({ host: options.host as string | undefined }); + client = await connectToDaemon({ host: options.host }); } catch (err) { const message = err instanceof Error ? err.message : String(err); console.error(`Error: Cannot connect to daemon at ${host}: ${message}`); diff --git a/packages/cli/src/commands/agent/import.ts b/packages/cli/src/commands/agent/import.ts index 91ecc134e..f0d2e30c0 100644 --- a/packages/cli/src/commands/agent/import.ts +++ b/packages/cli/src/commands/agent/import.ts @@ -113,7 +113,7 @@ export async function runImportCommand( options: AgentImportOptions, _command: Command, ): Promise { - const host = getDaemonHost({ host: options.host as string | undefined }); + const host = getDaemonHost({ host: options.host }); const sessionId = sessionIdArg.trim(); if (!sessionId) { throw { @@ -134,7 +134,7 @@ export async function runImportCommand( } const labels = parseImportLabels(options.label); - const client = await connectToDaemonOrThrow(options.host as string | undefined, host); + const client = await connectToDaemonOrThrow(options.host, host); try { const agent = await client.importAgent({ diff --git a/packages/cli/src/commands/agent/inspect.ts b/packages/cli/src/commands/agent/inspect.ts index e305555ca..d3fbd007b 100644 --- a/packages/cli/src/commands/agent/inspect.ts +++ b/packages/cli/src/commands/agent/inspect.ts @@ -216,7 +216,7 @@ export async function runInspectCommand( options: AgentInspectOptions, _command: Command, ): Promise { - const host = getDaemonHost({ host: options.host as string | undefined }); + const host = getDaemonHost({ host: options.host }); // Validate arguments if (!agentIdArg || agentIdArg.trim().length === 0) { @@ -230,7 +230,7 @@ export async function runInspectCommand( let client; try { - client = await connectToDaemon({ host: options.host as string | undefined }); + client = await connectToDaemon({ host: options.host }); } catch (err) { const message = err instanceof Error ? err.message : String(err); const error: CommandError = { diff --git a/packages/cli/src/commands/agent/reload.ts b/packages/cli/src/commands/agent/reload.ts index 653376a17..eed6a2dda 100644 --- a/packages/cli/src/commands/agent/reload.ts +++ b/packages/cli/src/commands/agent/reload.ts @@ -40,7 +40,7 @@ export async function runReloadCommand( options: AgentReloadOptions, _command: Command, ): Promise { - const host = getDaemonHost({ host: options.host as string | undefined }); + const host = getDaemonHost({ host: options.host }); if (!agentIdArg || agentIdArg.trim().length === 0) { const error: CommandError = { @@ -53,7 +53,7 @@ export async function runReloadCommand( let client: DaemonClient; try { - client = await connectToDaemon({ host: options.host as string | undefined }); + client = await connectToDaemon({ host: options.host }); } catch (err) { const message = err instanceof Error ? err.message : String(err); const error: CommandError = { diff --git a/packages/cli/src/commands/agent/update.ts b/packages/cli/src/commands/agent/update.ts index eae00a4fc..b531fadf6 100644 --- a/packages/cli/src/commands/agent/update.ts +++ b/packages/cli/src/commands/agent/update.ts @@ -86,7 +86,7 @@ export async function runUpdateCommand( options: AgentUpdateOptions, _command: Command, ): Promise { - const host = getDaemonHost({ host: options.host as string | undefined }); + const host = getDaemonHost({ host: options.host }); // Validate arguments if (!agentIdArg || agentIdArg.trim().length === 0) { @@ -120,7 +120,7 @@ export async function runUpdateCommand( let client; try { - client = await connectToDaemon({ host: options.host as string | undefined }); + client = await connectToDaemon({ host: options.host }); } catch (err) { const message = err instanceof Error ? err.message : String(err); const error: CommandError = { diff --git a/packages/cli/src/commands/agent/wait.ts b/packages/cli/src/commands/agent/wait.ts index c2846d0bf..9db46dc19 100644 --- a/packages/cli/src/commands/agent/wait.ts +++ b/packages/cli/src/commands/agent/wait.ts @@ -139,7 +139,7 @@ export async function runWaitCommand( options: AgentWaitOptions, _command: Command, ): Promise> { - const host = getDaemonHost({ host: options.host as string | undefined }); + const host = getDaemonHost({ host: options.host }); if (!agentIdArg || agentIdArg.trim().length === 0) { throw { @@ -153,7 +153,7 @@ export async function runWaitCommand( let client; try { - client = await connectToDaemon({ host: options.host as string | undefined }); + client = await connectToDaemon({ host: options.host }); } catch (err) { const message = err instanceof Error ? err.message : String(err); const error: CommandError = { diff --git a/packages/cli/src/commands/chat/post.ts b/packages/cli/src/commands/chat/post.ts index e46049d82..abf8bdbbb 100644 --- a/packages/cli/src/commands/chat/post.ts +++ b/packages/cli/src/commands/chat/post.ts @@ -32,7 +32,7 @@ export async function runPostCommand( ]); return { type: "single", - data: message!, + data: message, schema: chatMessageSchema, }; } catch (err) { diff --git a/packages/cli/src/commands/daemon/pair.ts b/packages/cli/src/commands/daemon/pair.ts index 647a98ba6..e96636fdc 100644 --- a/packages/cli/src/commands/daemon/pair.ts +++ b/packages/cli/src/commands/daemon/pair.ts @@ -12,7 +12,7 @@ export function pairCommand(): Command { return addJsonOption(new Command("pair").description("Print the daemon pairing QR code and link")) .option("--home ", "Paseo home directory (default: ~/.paseo)") .action(async (_options: PairOptions, command: Command) => { - await runPairCommand(command.optsWithGlobals() as PairOptions); + await runPairCommand(command.optsWithGlobals()); }); } diff --git a/packages/cli/src/commands/daemon/runtime-toolchain.ts b/packages/cli/src/commands/daemon/runtime-toolchain.ts index 37b182bb5..32357372a 100644 --- a/packages/cli/src/commands/daemon/runtime-toolchain.ts +++ b/packages/cli/src/commands/daemon/runtime-toolchain.ts @@ -84,7 +84,7 @@ async function resolveNodePathFromPidWindows(pid: number): Promise p.id === reqId || p.id.startsWith(reqId!)); + const permission = pendingPermissions.find((p) => p.id === reqId || p.id.startsWith(reqId)); if (!permission) { await client.close(); const error: CommandError = { diff --git a/packages/cli/src/commands/provider/ls.ts b/packages/cli/src/commands/provider/ls.ts index a529ec28e..21adb6476 100644 --- a/packages/cli/src/commands/provider/ls.ts +++ b/packages/cli/src/commands/provider/ls.ts @@ -76,7 +76,7 @@ export async function runLsCommand( provider: entry.provider, label: entry.label ?? entry.provider, status: entry.status === "ready" ? "available" : entry.status, - enabled: entry.enabled === false ? "Disabled" : "Enabled", + enabled: !entry.enabled ? "Disabled" : "Enabled", defaultMode: entry.defaultModeId ?? "default", modes: (entry.modes ?? []).map((mode) => mode.label).join(", "), })), diff --git a/packages/cli/src/output/table.ts b/packages/cli/src/output/table.ts index 1190192ad..4ec69efc1 100644 --- a/packages/cli/src/output/table.ts +++ b/packages/cli/src/output/table.ts @@ -137,7 +137,7 @@ export function renderTable(result: AnyCommandResult, options: OutputOptio return ""; } - const columns = schema.columns as ColumnDef[]; + const columns = schema.columns; const includeHeaders = !options.noHeaders; const widths = calculateWidths(data, columns, includeHeaders); diff --git a/packages/cli/src/utils/client.ts b/packages/cli/src/utils/client.ts index e30b5f7f9..3f724981b 100644 --- a/packages/cli/src/utils/client.ts +++ b/packages/cli/src/utils/client.ts @@ -342,7 +342,7 @@ export async function connectToDaemon(options?: ConnectOptions): Promise { async function runRemainingTests(index: number): Promise { if (index >= testFiles.length) return; - const testFile = testFiles[index] as string; + const testFile = testFiles[index]; const outcome = await runSingleTest(testFile); if (outcome.status === "passed") { passed++; diff --git a/packages/desktop/src/daemon/quit-lifecycle.ts b/packages/desktop/src/daemon/quit-lifecycle.ts index 247ca2b3f..879f59778 100644 --- a/packages/desktop/src/daemon/quit-lifecycle.ts +++ b/packages/desktop/src/daemon/quit-lifecycle.ts @@ -22,7 +22,7 @@ export interface StopOnQuitDeps { } export function shouldStopDesktopManagedDaemonOnQuit(settings: QuitLifecycleSettings): boolean { - return settings.daemon.keepRunningAfterQuit === false; + return !settings.daemon.keepRunningAfterQuit; } export async function stopDesktopManagedDaemonOnQuitIfNeeded( diff --git a/packages/expo-two-way-audio/examples/flow-api/App.tsx b/packages/expo-two-way-audio/examples/flow-api/App.tsx index 712660d91..f67d96ebd 100644 --- a/packages/expo-two-way-audio/examples/flow-api/App.tsx +++ b/packages/expo-two-way-audio/examples/flow-api/App.tsx @@ -91,7 +91,7 @@ export function FlowTest() { for (const result of data.results as { alternatives: Array; }[]) { - for (const alternative of result.alternatives as Array) { + for (const alternative of result.alternatives) { console.log(alternative.content); } } diff --git a/packages/relay/src/live-relay.e2e.test.ts b/packages/relay/src/live-relay.e2e.test.ts index 8fb521b46..0f656f20a 100644 --- a/packages/relay/src/live-relay.e2e.test.ts +++ b/packages/relay/src/live-relay.e2e.test.ts @@ -177,7 +177,7 @@ describe("Live relay (relay.paseo.sh) E2E", () => { const plaintextFromDaemon = "hello-from-daemon"; const ciphertextFromDaemon = await encrypt(daemonSharedKey, plaintextFromDaemon); - daemonWs!.send(Buffer.from(ciphertextFromDaemon)); + daemonWs.send(Buffer.from(ciphertextFromDaemon)); const clientReceivedCiphertext = await waitForOnceMessage( clientWs, diff --git a/packages/server/src/client/daemon-client-runtime-metrics.ts b/packages/server/src/client/daemon-client-runtime-metrics.ts index 2a71008ae..720f256f9 100644 --- a/packages/server/src/client/daemon-client-runtime-metrics.ts +++ b/packages/server/src/client/daemon-client-runtime-metrics.ts @@ -138,7 +138,7 @@ export class DaemonClientRuntimeMetrics { private pruneBuckets(now: number): void { const cutoff = now - this.windowMs; - while (this.buckets.length > 0 && this.buckets[0]!.endedAt < cutoff) { + while (this.buckets.length > 0 && this.buckets[0].endedAt < cutoff) { this.buckets.shift(); } } diff --git a/packages/server/src/client/daemon-client-websocket-transport.ts b/packages/server/src/client/daemon-client-websocket-transport.ts index 59c9b93aa..a4c785da4 100644 --- a/packages/server/src/client/daemon-client-websocket-transport.ts +++ b/packages/server/src/client/daemon-client-websocket-transport.ts @@ -128,7 +128,7 @@ export function bindWsHandler( } }; } - const prop = `on${event}` as "onopen" | "onclose" | "onerror" | "onmessage"; + const prop = `on${event}`; const wsRecord = ws as unknown as Record; const previous = wsRecord[prop]; wsRecord[prop] = handler; diff --git a/packages/server/src/client/daemon-client.ts b/packages/server/src/client/daemon-client.ts index 01e37b940..181342e28 100644 --- a/packages/server/src/client/daemon-client.ts +++ b/packages/server/src/client/daemon-client.ts @@ -1124,7 +1124,7 @@ export class DaemonClient { return this.subscribe(arg1); } - const type = arg1 as SessionOutboundMessage["type"]; + const type = arg1; const handler = arg2 as (message: SessionOutboundMessage) => void; if (!this.messageHandlers.has(type)) { diff --git a/packages/server/src/server/agent/agent-manager.test.ts b/packages/server/src/server/agent/agent-manager.test.ts index ca078559c..a8d6698ca 100644 --- a/packages/server/src/server/agent/agent-manager.test.ts +++ b/packages/server/src/server/agent/agent-manager.test.ts @@ -1833,7 +1833,7 @@ test("fetchTimeline returns a bounded reset window when cursor epoch is stale", direction: "after", cursor: { epoch: "stale-epoch", - seq: baseline.rows[baseline.rows.length - 1]!.seq, + seq: baseline.rows[baseline.rows.length - 1].seq, }, limit: 1, }); @@ -2613,7 +2613,7 @@ test("replaceAgentRun does not emit idle or resolve waiters between interrupted }, []); expect(runningIndexes.length).toBeGreaterThanOrEqual(2); - const firstReplacementRunningIndex = runningIndexes[1]!; + const firstReplacementRunningIndex = runningIndexes[1]; expect(lifecycleUpdates.slice(0, firstReplacementRunningIndex).includes("idle")).toBe(false); allowSecondRunToEnd.resolve(); @@ -4766,11 +4766,10 @@ test("hydrateTimeline suppresses only matching canonical user_message messageId" const timeline = manager.getTimeline(snapshot.id); const userMessages = timeline.filter((item) => item.type === "user_message"); expect(userMessages).toHaveLength(2); - expect( - userMessages.map( - (item) => (item as Extract).messageId, - ), - ).toEqual(["msg_client_hello", "msg_provider_distinct"]); + expect(userMessages.map((item) => item.messageId)).toEqual([ + "msg_client_hello", + "msg_provider_distinct", + ]); expect(userMessages.map((item) => item.text)).toEqual(["hello from user", "hello from user"]); }); @@ -4815,11 +4814,11 @@ test("recordUserMessage normalizes blank/whitespace messageId to undefined", asy expect(userMessages).toHaveLength(3); // Empty string → undefined (not empty string) - expect(userMessages[0]!.messageId).toBeUndefined(); + expect(userMessages[0].messageId).toBeUndefined(); // Whitespace → undefined - expect(userMessages[1]!.messageId).toBeUndefined(); + expect(userMessages[1].messageId).toBeUndefined(); // Valid → preserved - expect(userMessages[2]!.messageId).toBe("msg_valid_123"); + expect(userMessages[2].messageId).toBe("msg_valid_123"); }); test("recordUserMessage preserves provided messageId in timeline item and dispatched event", async () => { @@ -4942,9 +4941,7 @@ test("live provider user_message echo is suppressed when recordUserMessage was c // Should be exactly 1 (canonical), not 2 (canonical + provider echo) expect(userMessages).toHaveLength(1); // The canonical one must carry the client messageId for optimistic matching - expect((userMessages[0] as Extract).messageId).toBe( - "msg_client_echo_1", - ); + expect(userMessages[0].messageId).toBe("msg_client_echo_1"); // Assistant messages from the run should still appear const assistantMessages = timeline.filter((item) => item.type === "assistant_message"); @@ -5135,9 +5132,7 @@ test("provider user_message is NOT suppressed when no prior recordUserMessage", // Provider's user_message should be recorded (no canonical to dedup against) expect(userMessages).toHaveLength(1); - expect((userMessages[0] as Extract).text).toBe( - "continuation prompt", - ); + expect(userMessages[0].text).toBe("continuation prompt"); }); test("replaceAgentRun succeeds when foreground turn terminal event is never delivered", async () => { diff --git a/packages/server/src/server/agent/agent-manager.ts b/packages/server/src/server/agent/agent-manager.ts index 72ddab85a..14da6eb92 100644 --- a/packages/server/src/server/agent/agent-manager.ts +++ b/packages/server/src/server/agent/agent-manager.ts @@ -1301,7 +1301,7 @@ export class AgentManager { throw new Error(`Agent ${agentId} already has an active run`); } - const agent = existingAgent as ActiveManagedAgent; + const agent = existingAgent; agent.pendingReplacement = false; agent.lastError = undefined; @@ -1361,7 +1361,7 @@ export class AgentManager { } private finalizeForegroundTurn(agent: ActiveManagedAgent, turnId?: string): void { - const mutableAgent = agent as ActiveManagedAgent; + const mutableAgent = agent; if (turnId) { this.foregroundRuns.rememberFinalizedTurn(mutableAgent, turnId); } @@ -1430,7 +1430,7 @@ export class AgentManager { } catch (error) { const latest = this.agents.get(agentId); if (latest) { - const latestActive = latest as ActiveManagedAgent; + const latestActive = latest; latestActive.pendingReplacement = false; if (!latestActive.activeForegroundTurnId && latestActive.lifecycle === "running") { (latestActive as ActiveManagedAgent).lifecycle = "idle"; @@ -1502,7 +1502,7 @@ export class AgentManager { if (options?.signal) { abortHandler = () => - finishErr(createAbortError(options.signal!, "wait_for_agent_start aborted")); + finishErr(createAbortError(options.signal, "wait_for_agent_start aborted")); options.signal.addEventListener("abort", abortHandler, { once: true }); } @@ -2636,7 +2636,7 @@ export class AgentManager { "handleStreamEvent: turn_canceled", ); if (!isForegroundEvent && !agent.pendingReplacement) { - (agent as ActiveManagedAgent).lifecycle = "idle"; + agent.lifecycle = "idle"; } agent.lastError = undefined; this.resolvePendingPermissionsForAgent(agent, event.provider, options, "Interrupted"); @@ -2661,7 +2661,7 @@ export class AgentManager { "handleStreamEvent: turn_started", ); if (!isForegroundEvent) { - (agent as ActiveManagedAgent).lifecycle = "running"; + agent.lifecycle = "running"; this.emitState(agent); } } diff --git a/packages/server/src/server/agent/agent-projections.test.ts b/packages/server/src/server/agent/agent-projections.test.ts index f9f4f3b8a..62a329215 100644 --- a/packages/server/src/server/agent/agent-projections.test.ts +++ b/packages/server/src/server/agent/agent-projections.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { AGENT_LIFECYCLE_STATUSES, type AgentLifecycleStatus } from "./agent-manager.js"; +import { AGENT_LIFECYCLE_STATUSES } from "./agent-manager.js"; import { toAgentPayload, toStoredAgentRecord, type ManagedAgent } from "./agent-projections.js"; import type { AgentSession } from "./agent-sdk-types.js"; import type { @@ -203,7 +203,7 @@ describe("toStoredAgentRecord", () => { it("propagates lifecycle status for all states", () => { for (const status of AGENT_LIFECYCLE_STATUSES) { - const agent = createManagedAgent({ lifecycle: status as AgentLifecycleStatus }); + const agent = createManagedAgent({ lifecycle: status }); const record = toStoredAgentRecord(agent); expect(record.lastStatus).toBe(status); } @@ -301,7 +301,7 @@ describe("toAgentPayload", () => { it("propagates lifecycle status for all states", () => { for (const status of AGENT_LIFECYCLE_STATUSES) { - const agent = createManagedAgent({ lifecycle: status as AgentLifecycleStatus }); + const agent = createManagedAgent({ lifecycle: status }); const payload = toAgentPayload(agent); expect(payload.status).toBe(status); } diff --git a/packages/server/src/server/agent/agent-response-loop.ts b/packages/server/src/server/agent/agent-response-loop.ts index 7c6b2435d..79b3ca4a9 100644 --- a/packages/server/src/server/agent/agent-response-loop.ts +++ b/packages/server/src/server/agent/agent-response-loop.ts @@ -214,14 +214,14 @@ function tryParseJson(candidate: string): string | null { } function extractBalancedJsonCandidate(source: string, start: number): string | null { - const open = source[start]!; + const open = source[start]; const close = open === "{" ? "}" : "]"; let depth = 0; let inString = false; let escaped = false; for (let i = start; i < source.length; i += 1) { - const ch = source[i]!; + const ch = source[i]; if (inString) { if (escaped) { diff --git a/packages/server/src/server/agent/agent-timeline-store.ts b/packages/server/src/server/agent/agent-timeline-store.ts index 17bcde1a6..4608956c5 100644 --- a/packages/server/src/server/agent/agent-timeline-store.ts +++ b/packages/server/src/server/agent/agent-timeline-store.ts @@ -58,7 +58,7 @@ function fetchTail(ctx: FetchContext): AgentTimelineFetchResult { staleCursor: false, gap: false, window, - hasOlder: selected.length > 0 && selected[0]!.seq > minSeq, + hasOlder: selected.length > 0 && selected[0].seq > minSeq, hasNewer: false, rows: selected.map(cloneRow), }; @@ -93,7 +93,7 @@ function fetchAfter(ctx: FetchContext): AgentTimelineFetchResult { staleCursor: false, gap: false, window, - hasOlder: selected[0]!.seq > minSeq, + hasOlder: selected[0].seq > minSeq, hasNewer: Boolean(lastSelected && lastSelected.seq < maxSeq), rows: selected.map(cloneRow), }; @@ -115,7 +115,7 @@ function fetchBefore(ctx: FetchContext): AgentTimelineFetchResult { staleCursor: false, gap: false, window, - hasOlder: selected.length > 0 && selected[0]!.seq > minSeq, + hasOlder: selected.length > 0 && selected[0].seq > minSeq, hasNewer: endExclusive >= 0, rows: selected.map(cloneRow), }; @@ -137,7 +137,7 @@ function fetchReset( staleCursor: flags.staleCursor, gap: flags.gap, window, - hasOlder: rows.length > 0 && rows[0]!.seq > minSeq, + hasOlder: rows.length > 0 && rows[0].seq > minSeq, hasNewer: false, rows, }; @@ -155,7 +155,7 @@ export class InMemoryAgentTimelineStore { const rows = options?.rows?.length ? options.rows.map(cloneRow) : this.buildRowsFromItems(options?.items ?? [], options?.nextSeq ?? 1, timestamp); - const nextSeq = options?.nextSeq ?? (rows.length ? rows[rows.length - 1]!.seq + 1 : 1); + const nextSeq = options?.nextSeq ?? (rows.length ? rows[rows.length - 1].seq + 1 : 1); this.states.set(agentId, { epoch: options?.epoch ?? randomUUID(), rows, @@ -188,8 +188,8 @@ export class InMemoryAgentTimelineStore { ? DEFAULT_TIMELINE_FETCH_LIMIT : Math.max(0, Math.floor(requestedLimit)); const cursor = options?.cursor; - const minSeq = state.rows.length ? state.rows[0]!.seq : 0; - const maxSeq = state.rows.length ? state.rows[state.rows.length - 1]!.seq : 0; + const minSeq = state.rows.length ? state.rows[0].seq : 0; + const maxSeq = state.rows.length ? state.rows[state.rows.length - 1].seq : 0; const selectAll = limit === 0; const window = { @@ -265,7 +265,7 @@ export class InMemoryAgentTimelineStore { const rows = this.requireState(agentId).rows; const chunks: string[] = []; for (let i = rows.length - 1; i >= 0; i -= 1) { - const item = rows[i]!.item; + const item = rows[i].item; if (item.type !== "assistant_message") { if (chunks.length > 0) { break; diff --git a/packages/server/src/server/agent/mcp-server.test.ts b/packages/server/src/server/agent/mcp-server.test.ts index e0434a52d..91963502a 100644 --- a/packages/server/src/server/agent/mcp-server.test.ts +++ b/packages/server/src/server/agent/mcp-server.test.ts @@ -141,7 +141,7 @@ function createTestDeps(): TestDeps { } function createProviderDefinition(overrides: Partial): ProviderDefinition { - const provider = (overrides.id ?? "claude") as AgentProvider; + const provider = overrides.id ?? "claude"; return { id: provider, label: "Claude", diff --git a/packages/server/src/server/agent/mcp-server.ts b/packages/server/src/server/agent/mcp-server.ts index 57d774f3e..d479c1c64 100644 --- a/packages/server/src/server/agent/mcp-server.ts +++ b/packages/server/src/server/agent/mcp-server.ts @@ -168,9 +168,7 @@ function resolveRegisteredProviderIds( agentManager: AgentManager, providerRegistry: Record | null | undefined, ): AgentProvider[] { - return providerRegistry - ? (Object.keys(providerRegistry) as AgentProvider[]) - : agentManager.getRegisteredProviderIds(); + return providerRegistry ? Object.keys(providerRegistry) : agentManager.getRegisteredProviderIds(); } interface ProviderSummary { @@ -239,7 +237,7 @@ function resolveScheduleProviderAndModel(params: { const providerInput = params.provider?.trim() || params.defaultProvider; const slashIndex = providerInput.indexOf("/"); if (slashIndex === -1) { - return { provider: providerInput as AgentProvider }; + return { provider: providerInput }; } const provider = providerInput.slice(0, slashIndex).trim(); @@ -249,7 +247,7 @@ function resolveScheduleProviderAndModel(params: { } return { - provider: provider as AgentProvider, + provider: provider, model, }; } @@ -447,7 +445,7 @@ export async function createAgentMcpServer(options: AgentMcpServerOptions): Prom const resolvedProviderModel = resolveScheduleProviderAndModel({ provider: params?.provider, - defaultProvider: params.provider as AgentProvider, + defaultProvider: params.provider, }); return { type: "new-agent" as const, diff --git a/packages/server/src/server/agent/mcp-shared.ts b/packages/server/src/server/agent/mcp-shared.ts index 286fc526a..420a58ce7 100644 --- a/packages/server/src/server/agent/mcp-shared.ts +++ b/packages/server/src/server/agent/mcp-shared.ts @@ -86,7 +86,7 @@ export function resolveRequiredProviderModel( } return { - provider: provider as AgentProvider, + provider: provider, model, }; } diff --git a/packages/server/src/server/agent/model-resolver.test.ts b/packages/server/src/server/agent/model-resolver.test.ts index 4502f347a..8985bec31 100644 --- a/packages/server/src/server/agent/model-resolver.test.ts +++ b/packages/server/src/server/agent/model-resolver.test.ts @@ -5,7 +5,7 @@ import { resolveAgentModel } from "./model-resolver.js"; vi.mock("./provider-registry.js", () => ({ buildProviderRegistry: vi.fn(), - isProviderEnabled: vi.fn((definition: { enabled: boolean }) => definition.enabled === true), + isProviderEnabled: vi.fn((definition: { enabled: boolean }) => definition.enabled), })); import { buildProviderRegistry } from "./provider-registry.js"; diff --git a/packages/server/src/server/agent/pcm16-resampler.ts b/packages/server/src/server/agent/pcm16-resampler.ts index dd8233520..0d4fa7a55 100644 --- a/packages/server/src/server/agent/pcm16-resampler.ts +++ b/packages/server/src/server/agent/pcm16-resampler.ts @@ -51,8 +51,8 @@ export class Pcm16MonoResampler { while (this.pos < maxPos) { const i = Math.floor(this.pos); const frac = this.pos - i; - const s0 = src[i]!; - const s1 = src[i + 1]!; + const s0 = src[i]; + const s1 = src[i + 1]; const sample = s0 + (s1 - s0) * frac; const clamped = Math.max(-1, Math.min(1, sample)); const int16 = Math.round(clamped * 32767); @@ -61,7 +61,7 @@ export class Pcm16MonoResampler { } // Keep the last input sample as carry for the next chunk. - const lastInput = srcChunk[srcChunk.length - 1]!; + const lastInput = srcChunk[srcChunk.length - 1]; this.carrySample = lastInput; // Shift position so next chunk (which will include carry sample) continues smoothly. diff --git a/packages/server/src/server/agent/provider-launch-config.ts b/packages/server/src/server/agent/provider-launch-config.ts index 9b7fc042a..617e56bf0 100644 --- a/packages/server/src/server/agent/provider-launch-config.ts +++ b/packages/server/src/server/agent/provider-launch-config.ts @@ -112,7 +112,7 @@ export async function resolveProviderCommandPrefix( } return { - command: commandConfig.argv[0]!, + command: commandConfig.argv[0], args: commandConfig.argv.slice(1), }; } diff --git a/packages/server/src/server/agent/provider-snapshot-manager.ts b/packages/server/src/server/agent/provider-snapshot-manager.ts index 22991c8ba..c0fadf059 100644 --- a/packages/server/src/server/agent/provider-snapshot-manager.ts +++ b/packages/server/src/server/agent/provider-snapshot-manager.ts @@ -389,7 +389,7 @@ export class ProviderSnapshotManager { } private getProviderIds(): AgentProvider[] { - return Object.keys(this.providerRegistry) as AgentProvider[]; + return Object.keys(this.providerRegistry); } private resolveRefreshProviders(providers?: AgentProvider[]): AgentProvider[] | undefined { diff --git a/packages/server/src/server/agent/providers/__tests__/claude-agent.event-stream.integration.test.ts b/packages/server/src/server/agent/providers/__tests__/claude-agent.event-stream.integration.test.ts index efc2f3aef..f88e0a365 100644 --- a/packages/server/src/server/agent/providers/__tests__/claude-agent.event-stream.integration.test.ts +++ b/packages/server/src/server/agent/providers/__tests__/claude-agent.event-stream.integration.test.ts @@ -317,7 +317,7 @@ test("Test 4: Autonomous run", async () => { return; } - const autoTurnId = autoStarts[0]!.turnId; + const autoTurnId = autoStarts[0].turnId; expect(fgTurnId).not.toBe(autoTurnId); // Autonomous turn reaches terminal diff --git a/packages/server/src/server/agent/providers/acp-agent.ts b/packages/server/src/server/agent/providers/acp-agent.ts index 214b2f613..690e9b817 100644 --- a/packages/server/src/server/agent/providers/acp-agent.ts +++ b/packages/server/src/server/agent/providers/acp-agent.ts @@ -653,14 +653,14 @@ export class ACPAgentClient implements AgentClient { { logger: this.logger, provider: this.provider }, ); const connection = new ClientSideConnection(() => this.buildProbeClient(), stream); - const initialize = (await Promise.race([ + const initialize = await Promise.race([ connection.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: ACP_CLIENT_CAPABILITIES, clientInfo: { name: "Paseo", version: "dev" }, }), spawnErrorPromise, - ])) as InitializeResponse; + ]); return { child, connection, initialize }; } @@ -2093,7 +2093,7 @@ function mergeToolSnapshot( ): ACPToolSnapshot { return { toolCallId, - title: (update.title ?? previous?.title ?? toolCallId) as string, + title: update.title ?? previous?.title ?? toolCallId, kind: update.kind ?? previous?.kind ?? null, status: update.status ?? previous?.status ?? null, content: coalesceDefined(update.content, previous?.content, null), diff --git a/packages/server/src/server/agent/providers/claude-agent-commands.real.e2e.test.ts b/packages/server/src/server/agent/providers/claude-agent-commands.real.e2e.test.ts index 8feb0c95e..e8dc59a8c 100644 --- a/packages/server/src/server/agent/providers/claude-agent-commands.real.e2e.test.ts +++ b/packages/server/src/server/agent/providers/claude-agent-commands.real.e2e.test.ts @@ -1,7 +1,6 @@ import { beforeAll, beforeEach, describe, expect, test } from "vitest"; import pino from "pino"; -import type { AgentSlashCommand } from "../agent-sdk-types.js"; import { isCommandAvailable } from "../../../utils/executable.js"; import { ClaudeAgentClient } from "./claude-agent.js"; @@ -40,7 +39,7 @@ describe("claude agent commands contract (real)", () => { expect(commands.map((command) => command.name)).toContain("rewind"); for (const command of commands) { - const typed = command as AgentSlashCommand; + const typed = command; expect(typeof typed.name).toBe("string"); expect(typed.name.length).toBeGreaterThan(0); expect(typed.name.startsWith("/")).toBe(false); diff --git a/packages/server/src/server/agent/providers/claude-agent.ts b/packages/server/src/server/agent/providers/claude-agent.ts index 74efbdf6d..794f2f956 100644 --- a/packages/server/src/server/agent/providers/claude-agent.ts +++ b/packages/server/src/server/agent/providers/claude-agent.ts @@ -295,7 +295,7 @@ function resolveClaudeSpawnCommand( } return { - command: commandConfig.argv[0]!, + command: commandConfig.argv[0], args: [...commandConfig.argv.slice(1), ...spawnOptions.args], }; } @@ -459,7 +459,7 @@ function normalizeForDeterministicString(value: unknown, seen: WeakSet): return value.map((entry) => normalizeForDeterministicString(entry, seen)); } if (typeof value === "object") { - const objectValue = value as object; + const objectValue = value; if (seen.has(objectValue)) { return "[circular]"; } @@ -1340,7 +1340,7 @@ async function resolveClaudeVersion( try { if (command?.mode === "replace") { const { stdout } = await execCommand( - command.argv[0]!, + command.argv[0], [...command.argv.slice(1), "--version"], { ...envSpec, timeout: 5_000 }, ); @@ -1392,7 +1392,7 @@ async function resolveClaudeAuth( try { let result: { stdout: string; stderr: string }; if (command?.mode === "replace") { - result = await run(command.argv[0]!, [...command.argv.slice(1), "auth", "status"]); + result = await run(command.argv[0], [...command.argv.slice(1), "auth", "status"]); } else { const executable = await findExecutable("claude"); if (!executable) { diff --git a/packages/server/src/server/agent/providers/claude/claude-models.test.ts b/packages/server/src/server/agent/providers/claude/claude-models.test.ts index 6d1e8a49a..0da2b8fa2 100644 --- a/packages/server/src/server/agent/providers/claude/claude-models.test.ts +++ b/packages/server/src/server/agent/providers/claude/claude-models.test.ts @@ -19,7 +19,7 @@ describe("getClaudeModels", () => { const models = getClaudeModels(); const defaults = models.filter((m) => m.isDefault); expect(defaults).toHaveLength(1); - expect(defaults[0]!.id).toBe("claude-opus-4-6"); + expect(defaults[0].id).toBe("claude-opus-4-6"); }); it("returns fresh copies each call", () => { diff --git a/packages/server/src/server/agent/providers/claude/claude-models.ts b/packages/server/src/server/agent/providers/claude/claude-models.ts index 28f6ba335..f38170223 100644 --- a/packages/server/src/server/agent/providers/claude/claude-models.ts +++ b/packages/server/src/server/agent/providers/claude/claude-models.ts @@ -87,9 +87,9 @@ export function normalizeClaudeRuntimeModelId(value: string | null | undefined): return null; } - const family = runtimeMatch[1]!.toLowerCase(); - const major = runtimeMatch[2]!; - const minor = runtimeMatch[3]!; + const family = runtimeMatch[1].toLowerCase(); + const major = runtimeMatch[2]; + const minor = runtimeMatch[3]; const suffix = runtimeMatch[4] ?? ""; return `claude-${family}-${major}-${minor}${suffix}`; } diff --git a/packages/server/src/server/agent/providers/codex-app-server-agent.ts b/packages/server/src/server/agent/providers/codex-app-server-agent.ts index e0bf6221f..63ee400a7 100644 --- a/packages/server/src/server/agent/providers/codex-app-server-agent.ts +++ b/packages/server/src/server/agent/providers/codex-app-server-agent.ts @@ -289,14 +289,14 @@ function tokenizeCommandArgs(args: string): string[] { let current = ""; let quote: "'" | '"' | null = null; for (let i = 0; i < args.length; i += 1) { - const ch = args[i]!; + const ch = args[i]; if (quote) { if (ch === quote) { quote = null; continue; } if (ch === "\\" && i + 1 < args.length) { - const next = args[i + 1]!; + const next = args[i + 1]; if (next === quote || next === "\\" || next === "n" || next === "t") { i += 1; current += decodeEscapedChar(next); diff --git a/packages/server/src/server/agent/providers/mock-load-test-agent.ts b/packages/server/src/server/agent/providers/mock-load-test-agent.ts index 161d3648a..9fb67e8e9 100644 --- a/packages/server/src/server/agent/providers/mock-load-test-agent.ts +++ b/packages/server/src/server/agent/providers/mock-load-test-agent.ts @@ -130,7 +130,7 @@ function resolveModelProfile(modelId: string | null | undefined): { durationMs: number; intervalMs: number; } { - const model = MODELS.find((entry) => entry.id === modelId) ?? MODELS[0]!; + const model = MODELS.find((entry) => entry.id === modelId) ?? MODELS[0]; const metadata = model.metadata ?? {}; return { modelId: model.id, diff --git a/packages/server/src/server/agent/providers/opencode-agent-commands.real.e2e.test.ts b/packages/server/src/server/agent/providers/opencode-agent-commands.real.e2e.test.ts index c54264978..f3368fc30 100644 --- a/packages/server/src/server/agent/providers/opencode-agent-commands.real.e2e.test.ts +++ b/packages/server/src/server/agent/providers/opencode-agent-commands.real.e2e.test.ts @@ -1,7 +1,6 @@ import { beforeAll, beforeEach, describe, expect, test } from "vitest"; import pino from "pino"; -import type { AgentSlashCommand } from "../agent-sdk-types.js"; import { isCommandAvailable } from "../../../utils/executable.js"; import { OpenCodeAgentClient } from "./opencode-agent.js"; @@ -36,7 +35,7 @@ describe("opencode agent commands contract (real)", () => { expect(commands.length).toBeGreaterThan(0); for (const command of commands) { - const typed = command as AgentSlashCommand; + const typed = command; expect(typeof typed.name).toBe("string"); expect(typed.name.length).toBeGreaterThan(0); expect(typed.name.startsWith("/")).toBe(false); @@ -63,7 +62,7 @@ describe("opencode agent commands contract (real)", () => { expect(commands.length).toBeGreaterThan(0); // Pick the first available command and send it without arguments. - const command = commands[0]!; + const command = commands[0]; const events: Array<{ type: string }> = []; session.subscribe((event) => events.push(event)); diff --git a/packages/server/src/server/agent/providers/opencode-agent.error-handling.real.e2e.test.ts b/packages/server/src/server/agent/providers/opencode-agent.error-handling.real.e2e.test.ts index 3874568c2..356219afa 100644 --- a/packages/server/src/server/agent/providers/opencode-agent.error-handling.real.e2e.test.ts +++ b/packages/server/src/server/agent/providers/opencode-agent.error-handling.real.e2e.test.ts @@ -168,7 +168,7 @@ describe("opencode agent error handling (real)", () => { const terminal = events.find(isTerminalEvent); expect(terminal).toBeDefined(); expect(terminal!.type).toBe("turn_failed"); - expect((terminal!.type === "turn_failed" ? terminal!.error : "").toLowerCase()).toMatch( + expect((terminal!.type === "turn_failed" ? terminal.error : "").toLowerCase()).toMatch( /insufficient balance|resource package|recharge/, ); } finally { diff --git a/packages/server/src/server/agent/providers/test-utils/session-stream-adapter.ts b/packages/server/src/server/agent/providers/test-utils/session-stream-adapter.ts index e191c2164..6178de165 100644 --- a/packages/server/src/server/agent/providers/test-utils/session-stream-adapter.ts +++ b/packages/server/src/server/agent/providers/test-utils/session-stream-adapter.ts @@ -46,7 +46,7 @@ export async function* streamSession( turnId = result.turnId; for (let idx = queue.length - 1; idx >= 0; idx -= 1) { - if (!matchesTurn(queue[idx]!)) { + if (!matchesTurn(queue[idx])) { queue.splice(idx, 1); } } diff --git a/packages/server/src/server/agent/providers/tool-call-detail-primitives.ts b/packages/server/src/server/agent/providers/tool-call-detail-primitives.ts index 6ee9e0008..ab4dce148 100644 --- a/packages/server/src/server/agent/providers/tool-call-detail-primitives.ts +++ b/packages/server/src/server/agent/providers/tool-call-detail-primitives.ts @@ -703,7 +703,7 @@ export function toShellToolDetail( export function toReadToolDetail( input: ParsedToolReadInput | null, - output: ParsedToolReadOutput | ParsedToolReadOutputWithPath | null, + output: ParsedToolReadOutput | null, options?: { normalizePath?: NormalizePathFn }, ): ToolCallDetail | undefined { const filePath = normalizeDetailPath(input?.filePath ?? output?.filePath, options?.normalizePath); diff --git a/packages/server/src/server/agent/tool-name-normalization.ts b/packages/server/src/server/agent/tool-name-normalization.ts index a920305d1..ceb4e0496 100644 --- a/packages/server/src/server/agent/tool-name-normalization.ts +++ b/packages/server/src/server/agent/tool-name-normalization.ts @@ -12,7 +12,7 @@ export function tokenizeToolName(name: string): string[] { export function getToolLeafName(name: string): string | null { const tokens = tokenizeToolName(name); - return tokens.length > 0 ? tokens[tokens.length - 1]! : null; + return tokens.length > 0 ? tokens[tokens.length - 1] : null; } export function isSpeakToolName(name: string): boolean { @@ -33,7 +33,7 @@ export function isLikelyNamespacedToolName(name: string): boolean { if (segments.length >= 3) { return true; } - if (segments.length === 2 && segments[1]!.includes("_")) { + if (segments.length === 2 && segments[1].includes("_")) { return true; } return false; @@ -49,11 +49,11 @@ export function isPaseoToolName(name: string): boolean { return ( segments.length >= 3 && segments[0] === "mcp" && - (segments[1] === "paseo" || segments[1]!.startsWith("paseo_")) + (segments[1] === "paseo" || segments[1].startsWith("paseo_")) ); } if (normalized.includes(".")) { - const firstSegment = normalized.split(".")[0]!; + const firstSegment = normalized.split(".")[0]; return firstSegment === "paseo" || firstSegment.startsWith("paseo_"); } return false; @@ -66,14 +66,14 @@ export function getPaseoToolLeafName(name: string): string | null { if ( segments.length >= 3 && segments[0] === "mcp" && - (segments[1] === "paseo" || segments[1]!.startsWith("paseo_")) + (segments[1] === "paseo" || segments[1].startsWith("paseo_")) ) { return segments.slice(2).join("__"); } return null; } if (normalized.includes(".")) { - const firstSegment = normalized.split(".")[0]!; + const firstSegment = normalized.split(".")[0]; if (firstSegment === "paseo" || firstSegment.startsWith("paseo_")) { return normalized.split(".").slice(1).join("."); } diff --git a/packages/server/src/server/agent/tts-manager.test.ts b/packages/server/src/server/agent/tts-manager.test.ts index 90cbd6483..6dfc19830 100644 --- a/packages/server/src/server/agent/tts-manager.test.ts +++ b/packages/server/src/server/agent/tts-manager.test.ts @@ -83,8 +83,8 @@ describe("TTSManager", () => { expect(calls.length).toBeGreaterThan(1); expect(calls.every((text) => text.length <= 260)).toBe(true); - expect(calls[0]!.length).toBeLessThanOrEqual(120); - expect(calls.slice(1).some((text) => text.length > calls[0]!.length)).toBe(true); + expect(calls[0].length).toBeLessThanOrEqual(120); + expect(calls.slice(1).some((text) => text.length > calls[0].length)).toBe(true); }); it("prefetches the next segment before current playback completes", async () => { diff --git a/packages/server/src/server/agent/tts-manager.ts b/packages/server/src/server/agent/tts-manager.ts index deec85e6f..ee6c74701 100644 --- a/packages/server/src/server/agent/tts-manager.ts +++ b/packages/server/src/server/agent/tts-manager.ts @@ -181,7 +181,7 @@ export class TTSManager { const scheduleNextSegments = () => { while (nextSegmentToSchedule < segments.length && inflight.size < TTS_PREFETCH_SEGMENTS) { - const segment = segments[nextSegmentToSchedule]!; + const segment = segments[nextSegmentToSchedule]; inflight.set(segment.index, this.scheduleSegmentSynthesis(segment, abortSignal)); nextSegmentToSchedule += 1; } diff --git a/packages/server/src/server/daemon-e2e/live-preferences.e2e.test.ts b/packages/server/src/server/daemon-e2e/live-preferences.e2e.test.ts index c8fa1e986..06ba99469 100644 --- a/packages/server/src/server/daemon-e2e/live-preferences.e2e.test.ts +++ b/packages/server/src/server/daemon-e2e/live-preferences.e2e.test.ts @@ -44,7 +44,7 @@ function pickTwoDistinctModels(models: Array<{ id: string }>): [string, string] if (ids.length < 2) { throw new Error(`Need at least 2 models to test switching; got ${ids.length}`); } - return [ids[0]!, ids[1]!]; + return [ids[0], ids[1]]; } function isBinaryInstalled(binary: string): boolean { @@ -127,7 +127,7 @@ test("live thinking switching works for Claude (off -> on)", async () => { if (!modelList.models || modelList.models.length === 0) { throw new Error("No Claude models returned"); } - const modelId = modelList.models[0]!.id; + const modelId = modelList.models[0].id; const agent = await ctx.client.createAgent({ provider: "claude", diff --git a/packages/server/src/server/daemon-e2e/opencode-plan-and-questions.real.e2e.test.ts b/packages/server/src/server/daemon-e2e/opencode-plan-and-questions.real.e2e.test.ts index 38edd2b4e..4307ff29f 100644 --- a/packages/server/src/server/daemon-e2e/opencode-plan-and-questions.real.e2e.test.ts +++ b/packages/server/src/server/daemon-e2e/opencode-plan-and-questions.real.e2e.test.ts @@ -20,7 +20,7 @@ function pickOpenCodeModel( const preferred = models.find((model) => preferences.some((fragment) => model.id.includes(fragment)), ); - return preferred?.id ?? models[0]!.id; + return preferred?.id ?? models[0].id; } async function createHarness(): Promise<{ diff --git a/packages/server/src/server/daemon-e2e/opencode-send-interrupt.real.e2e.test.ts b/packages/server/src/server/daemon-e2e/opencode-send-interrupt.real.e2e.test.ts index e7d2b7490..a991c1f1d 100644 --- a/packages/server/src/server/daemon-e2e/opencode-send-interrupt.real.e2e.test.ts +++ b/packages/server/src/server/daemon-e2e/opencode-send-interrupt.real.e2e.test.ts @@ -36,7 +36,7 @@ function pickOpenCodeModel( const preferred = models.find((model) => preferences.some((fragment) => model.id.includes(fragment)), ); - return preferred?.id ?? models[0]!.id; + return preferred?.id ?? models[0].id; } function hasRunningBashToolCall(messages: SessionOutboundMessage[], agentId: string): boolean { diff --git a/packages/server/src/server/daemon-e2e/permissions-claude.e2e.test.ts b/packages/server/src/server/daemon-e2e/permissions-claude.e2e.test.ts index 15692494b..05164a099 100644 --- a/packages/server/src/server/daemon-e2e/permissions-claude.e2e.test.ts +++ b/packages/server/src/server/daemon-e2e/permissions-claude.e2e.test.ts @@ -46,7 +46,7 @@ describe("daemon E2E - permission flow: Claude", () => { const permissionState = await ctx.client.waitForFinish(agent.id, 5_000); expect(permissionState.status).toBe("permission"); expect(permissionState.final?.pendingPermissions?.length).toBeGreaterThan(0); - const permission = permissionState.final!.pendingPermissions[0]!; + const permission = permissionState.final!.pendingPermissions[0]; await ctx.client.respondToPermission(agent.id, permission.id, { behavior: "allow" }); @@ -93,7 +93,7 @@ describe("daemon E2E - permission flow: Claude", () => { const permissionState = await ctx.client.waitForFinish(agent.id, 5_000); expect(permissionState.status).toBe("permission"); expect(permissionState.final?.pendingPermissions?.length).toBeGreaterThan(0); - const permission = permissionState.final!.pendingPermissions[0]!; + const permission = permissionState.final!.pendingPermissions[0]; await ctx.client.respondToPermission(agent.id, permission.id, { behavior: "deny", diff --git a/packages/server/src/server/daemon-e2e/terminal.e2e.test.ts b/packages/server/src/server/daemon-e2e/terminal.e2e.test.ts index 0018e68e8..8217ea782 100644 --- a/packages/server/src/server/daemon-e2e/terminal.e2e.test.ts +++ b/packages/server/src/server/daemon-e2e/terminal.e2e.test.ts @@ -503,7 +503,7 @@ function summarizeTerminalOutputCadence(input: { }): TerminalOutputCadenceSummary { const gaps = input.frames .slice(1) - .map((frame, index) => frame.receivedAtMs - input.frames[index]!.receivedAtMs) + .map((frame, index) => frame.receivedAtMs - input.frames[index].receivedAtMs) .sort((a, b) => a - b); const p95Index = gaps.length === 0 ? -1 : Math.min(gaps.length - 1, Math.ceil(gaps.length * 0.95) - 1); @@ -512,7 +512,7 @@ function summarizeTerminalOutputCadence(input: { return { frameCount: input.frames.length, maxGapMs: gaps.at(-1) ?? 0, - p95GapMs: p95Index === -1 ? 0 : gaps[p95Index]!, + p95GapMs: p95Index === -1 ? 0 : gaps[p95Index], lastOutputAfterStopMs: lastFrame ? lastFrame.receivedAtMs - input.stoppedAtMs : 0, payloadBytes: input.frames.map((frame) => frame.payloadBytes), }; diff --git a/packages/server/src/server/daemon-keypair.ts b/packages/server/src/server/daemon-keypair.ts index 9b42627bd..301da2452 100644 --- a/packages/server/src/server/daemon-keypair.ts +++ b/packages/server/src/server/daemon-keypair.ts @@ -37,7 +37,7 @@ export async function loadOrCreateDaemonKeyPair( if (existsSync(filePath)) { try { const raw = readFileSync(filePath, "utf8"); - const parsed = KeyPairSchema.parse(JSON.parse(raw)) as StoredKeyPair; + const parsed = KeyPairSchema.parse(JSON.parse(raw)); const publicKey = importPublicKey(parsed.publicKeyB64); const secretKey = importSecretKey(parsed.secretKeyB64); diff --git a/packages/server/src/server/editor-targets.ts b/packages/server/src/server/editor-targets.ts index 75cbdb3d8..2e113b7fe 100644 --- a/packages/server/src/server/editor-targets.ts +++ b/packages/server/src/server/editor-targets.ts @@ -83,7 +83,7 @@ export async function listAvailableEditorTargets( const results: EditorTargetDescriptorPayload[] = []; for (let i = 0; i < supportedTargets.length; i += 1) { if (!executables[i]) continue; - const target = supportedTargets[i]!; + const target = supportedTargets[i]; results.push({ id: target.id, label: target.label, diff --git a/packages/server/src/server/json-utils.ts b/packages/server/src/server/json-utils.ts index 0f9b2d8c0..3aaf2885e 100644 --- a/packages/server/src/server/json-utils.ts +++ b/packages/server/src/server/json-utils.ts @@ -41,15 +41,15 @@ export function ensureValidJson(value: T): T { } if (typeof current === "object") { - if (seen.has(current as object)) { + if (seen.has(current)) { throw new Error("Cannot serialize circular structure to JSON"); } - seen.add(current as object); + seen.add(current); const obj: Record = {}; for (const [key, val] of Object.entries(current as Record)) { obj[key] = sanitize(val); } - seen.delete(current as object); + seen.delete(current); return obj; } diff --git a/packages/server/src/server/logger.ts b/packages/server/src/server/logger.ts index 024aa5280..669ed4e69 100644 --- a/packages/server/src/server/logger.ts +++ b/packages/server/src/server/logger.ts @@ -98,11 +98,11 @@ function normalizeLoggerConfigInput(config: LoggerConfigInput): PersistedConfig } if ("log" in config) { - return config as PersistedConfig; + return config; } if ("level" in config || "format" in config) { - const legacy = config as LegacyLogConfig; + const legacy = config; return { log: { ...(legacy.level ? { level: legacy.level } : {}), diff --git a/packages/server/src/server/loop-service.test.ts b/packages/server/src/server/loop-service.test.ts index 1e0d9bed6..31ec361b2 100644 --- a/packages/server/src/server/loop-service.test.ts +++ b/packages/server/src/server/loop-service.test.ts @@ -376,15 +376,15 @@ describe("LoopService", () => { expect(finalLoop.archive).toBe(true); expect(iteration?.workerAgentId).toBeTruthy(); expect(iteration?.verifierAgentId).toBeTruthy(); - expect(archivedAgentIds).toEqual([iteration!.workerAgentId!, iteration!.verifierAgentId!]); + expect(archivedAgentIds).toEqual([iteration.workerAgentId!, iteration.verifierAgentId!]); await storage.flush(); - await expect(storage.get(iteration!.workerAgentId!)).resolves.toMatchObject({ - id: iteration!.workerAgentId!, + await expect(storage.get(iteration.workerAgentId!)).resolves.toMatchObject({ + id: iteration.workerAgentId!, archivedAt: expect.any(String), internal: true, }); - await expect(storage.get(iteration!.verifierAgentId!)).resolves.toMatchObject({ - id: iteration!.verifierAgentId!, + await expect(storage.get(iteration.verifierAgentId!)).resolves.toMatchObject({ + id: iteration.verifierAgentId!, archivedAt: expect.any(String), internal: true, }); diff --git a/packages/server/src/server/loop-service.ts b/packages/server/src/server/loop-service.ts index cf82851d6..4c7bc741b 100644 --- a/packages/server/src/server/loop-service.ts +++ b/packages/server/src/server/loop-service.ts @@ -870,7 +870,7 @@ export class LoopService { record.id.startsWith(trimmed), ); if (matches.length === 1) { - return matches[0]!; + return matches[0]; } if (matches.length > 1) { throw new Error(`Loop id prefix is ambiguous: ${trimmed}`); diff --git a/packages/server/src/server/paseo-env.ts b/packages/server/src/server/paseo-env.ts index 208634fb0..a73a59d87 100644 --- a/packages/server/src/server/paseo-env.ts +++ b/packages/server/src/server/paseo-env.ts @@ -19,7 +19,7 @@ type ExternalProcessEnv = NodeJS.ProcessEnv & Record; let resolvedProcessExecPath: string | undefined; function buildInternalProcessEnv(baseEnv: T): T { - return { ...baseEnv } as T; + return { ...baseEnv }; } function buildExternalProcessEnv( diff --git a/packages/server/src/server/persistence-hooks.ts b/packages/server/src/server/persistence-hooks.ts index b5785cd2d..ca10186de 100644 --- a/packages/server/src/server/persistence-hooks.ts +++ b/packages/server/src/server/persistence-hooks.ts @@ -124,7 +124,7 @@ function hasRegisteredProvider(registeredProviders: RegisteredProviders, value: if (isProviderRegistry(registeredProviders)) { return Object.prototype.hasOwnProperty.call(registeredProviders, value); } - return new Set(registeredProviders).has(value as AgentProvider); + return new Set(registeredProviders).has(value); } export function isRegisteredProvider( diff --git a/packages/server/src/server/script-health-monitor.ts b/packages/server/src/server/script-health-monitor.ts index 6da0f7cfd..04c76423a 100644 --- a/packages/server/src/server/script-health-monitor.ts +++ b/packages/server/src/server/script-health-monitor.ts @@ -105,8 +105,8 @@ export class ScriptHealthMonitor { probeTargets.map(({ route }) => this.probeRoute(route.port)), ); for (let i = 0; i < probeTargets.length; i += 1) { - const { route, state } = probeTargets[i]!; - const isHealthy = healthResults[i]!; + const { route, state } = probeTargets[i]; + const isHealthy = healthResults[i]; const previousHealth = state.health; if (isHealthy) { diff --git a/packages/server/src/server/session.ts b/packages/server/src/server/session.ts index 96f54bf80..baf6d16b5 100644 --- a/packages/server/src/server/session.ts +++ b/packages/server/src/server/session.ts @@ -1402,7 +1402,7 @@ export class Session { } private getRegisteredProviderIds(): AgentProvider[] { - return Object.keys(this.getProviderRegistry()) as AgentProvider[]; + return Object.keys(this.getProviderRegistry()); } private buildStoredAgentPayload( @@ -2382,7 +2382,7 @@ export class Session { ); const agents = []; for (let i = 0; i < archiveResults.length; i += 1) { - const result = archiveResults[i]!; + const result = archiveResults[i]; if (result.status === "fulfilled") { agents.push(result.value); } else { @@ -3282,9 +3282,7 @@ export class Session { throw new Error(`Agent not found: ${agentId}`); } const providerRegistry = this.getProviderRegistry(); - if ( - !isStoredAgentProviderAvailable(record, Object.keys(providerRegistry) as AgentProvider[]) - ) { + if (!isStoredAgentProviderAvailable(record, Object.keys(providerRegistry))) { throw new Error(`Agent ${agentId} references unavailable provider '${record.provider}'`); } const handle = toAgentPersistenceHandle(providerRegistry, record.persistence); @@ -5831,7 +5829,7 @@ export class Session { ), ); for (let i = 0; i < pairs.length; i += 1) { - placementsByCwd.set(normalizePersistedWorkspaceId(pairs[i]!.workspace.cwd), placements[i]!); + placementsByCwd.set(normalizePersistedWorkspaceId(pairs[i].workspace.cwd), placements[i]); } return placementsByCwd; @@ -7727,7 +7725,7 @@ export class Session { ); const combinedAudio = Buffer.concat(pendingSegments.map((segment) => segment.audio)); - const combinedFormat = pendingSegments[pendingSegments.length - 1]!.format; + const combinedFormat = pendingSegments[pendingSegments.length - 1].format; await this.processAudio(combinedAudio, combinedFormat); } diff --git a/packages/server/src/server/session.workspaces.test.ts b/packages/server/src/server/session.workspaces.test.ts index 42dcbf3a0..8903b8728 100644 --- a/packages/server/src/server/session.workspaces.test.ts +++ b/packages/server/src/server/session.workspaces.test.ts @@ -3809,7 +3809,7 @@ test("subscribed fetch_workspaces includes git enrichment in the initial snapsho session.workspaceRegistry.list = async () => [gitWorkspace, directoryWorkspace]; session.reconcileAndEmitWorkspaceUpdates = vi.fn(async () => {}); session.describeWorkspaceRecord = vi.fn( - async (workspace: typeof gitWorkspace | typeof directoryWorkspace, project: unknown) => { + async (workspace: typeof gitWorkspace, project: unknown) => { if (workspace.workspaceId === gitWorkspace.workspaceId) { expect(project).toEqual(gitProject); return baselineGitDescriptor; diff --git a/packages/server/src/server/speech/audio.ts b/packages/server/src/server/speech/audio.ts index d44c97b76..6ffd28a49 100644 --- a/packages/server/src/server/speech/audio.ts +++ b/packages/server/src/server/speech/audio.ts @@ -59,7 +59,7 @@ export function parsePcmRateFromFormat( if (!match) { return fallback; } - const rate = Number.parseInt(match[1]!, 10); + const rate = Number.parseInt(match[1], 10); return Number.isFinite(rate) && rate > 0 ? rate : fallback; } @@ -73,7 +73,7 @@ export function pcm16lePeakAbs(pcm16le: Buffer): number { const samples = new Int16Array(pcm16le.buffer, pcm16le.byteOffset, pcm16le.byteLength / 2); let peak = 0; for (let i = 0; i < samples.length; i += 1) { - const v = samples[i]!; + const v = samples[i]; const abs = v < 0 ? -v : v; if (abs > peak) { peak = abs; @@ -92,7 +92,7 @@ export function pcm16leToFloat32(pcm16le: Buffer, gain: number = 1): Float32Arra const int16 = new Int16Array(pcm16le.buffer, pcm16le.byteOffset, pcm16le.byteLength / 2); const out = new Float32Array(int16.length); for (let i = 0; i < int16.length; i += 1) { - const v = (int16[i]! / 32768.0) * gain; + const v = (int16[i] / 32768.0) * gain; out[i] = Math.max(-1, Math.min(1, v)); } return out; @@ -101,7 +101,7 @@ export function pcm16leToFloat32(pcm16le: Buffer, gain: number = 1): Float32Arra export function float32ToPcm16le(samples: Float32Array): Buffer { const out = new Int16Array(samples.length); for (let i = 0; i < samples.length; i += 1) { - const clamped = Math.max(-1, Math.min(1, samples[i]!)); + const clamped = Math.max(-1, Math.min(1, samples[i])); out[i] = Math.round(clamped * 32767); } return Buffer.from(out.buffer, out.byteOffset, out.byteLength); diff --git a/packages/server/src/server/speech/providers/local/pocket/pocket-tts-onnx.ts b/packages/server/src/server/speech/providers/local/pocket/pocket-tts-onnx.ts index 6a7e7c668..ae4ab9bc0 100644 --- a/packages/server/src/server/speech/providers/local/pocket/pocket-tts-onnx.ts +++ b/packages/server/src/server/speech/providers/local/pocket/pocket-tts-onnx.ts @@ -78,7 +78,7 @@ function getSessionInputMeta( function toBigInt64(values: number[]): BigInt64Array { const out = new BigInt64Array(values.length); for (let i = 0; i < values.length; i += 1) { - out[i] = BigInt(values[i]!); + out[i] = BigInt(values[i]); } return out; } @@ -101,8 +101,8 @@ function normalizeTextForPocket(text: string): string { if (out.length > 0 && /[A-Za-z0-9]$/.test(out)) { out = `${out}.`; } - if (out.length > 0 && /[a-z]/.test(out[0]!)) { - out = out[0]!.toUpperCase() + out.slice(1); + if (out.length > 0 && /[a-z]/.test(out[0])) { + out = out[0].toUpperCase() + out.slice(1); } return out; } @@ -452,8 +452,8 @@ class PocketTtsOnnxEngine { const outputNames = (this.flowLmMain as unknown as { outputNames?: string[] }).outputNames; const resStepRecord = resStep as unknown as Record; - const conditioningName = outputNames?.[0] ?? Object.keys(resStepRecord)[0]!; - const eosName = outputNames?.[1] ?? Object.keys(resStepRecord)[1]!; + const conditioningName = outputNames?.[0] ?? Object.keys(resStepRecord)[0]; + const eosName = outputNames?.[1] ?? Object.keys(resStepRecord)[1]; const conditioning = resStepRecord[conditioningName]; const eos = resStepRecord[eosName]; @@ -463,7 +463,7 @@ class PocketTtsOnnxEngine { updateStateFromOutputs(state, resStepRecord); const eosData = tensorDataFloat32(eos); - if (eosData[0]! > -4.0 && eosStep === null) { + if (eosData[0] > -4.0 && eosStep === null) { eosStep = step; } if (eosStep !== null && step >= eosStep + this.framesAfterEos) { @@ -495,7 +495,7 @@ class PocketTtsOnnxEngine { if (!flowTensor) throw new Error("PocketTTS flow_lm_flow: missing output"); const delta = tensorDataFloat32(flowTensor); for (let i = 0; i < x.length; i += 1) { - x[i] = x[i]! + delta[i]! * dt; + x[i] = x[i] + delta[i] * dt; } } @@ -512,7 +512,7 @@ class PocketTtsOnnxEngine { const frameCount = frames.length; const flattened = new Float32Array(frameCount * 32); for (let i = 0; i < frameCount; i += 1) { - flattened.set(frames[i]!, i * 32); + flattened.set(frames[i], i * 32); } const latent = new ort.Tensor("float32", flattened, [1, frameCount, 32]); diff --git a/packages/server/src/server/speech/providers/local/sherpa/model-catalog.ts b/packages/server/src/server/speech/providers/local/sherpa/model-catalog.ts index 1ac6e2126..b651b70bb 100644 --- a/packages/server/src/server/speech/providers/local/sherpa/model-catalog.ts +++ b/packages/server/src/server/speech/providers/local/sherpa/model-catalog.ts @@ -187,7 +187,7 @@ function createAliasedModelIdSchema(params: { message: "Invalid model id", }, ) - .transform((value) => params.aliases[value] ?? (value as T)); + .transform((value) => params.aliases[value] ?? value); } const STT_MODEL_ALIASES = buildAliasMap(LOCAL_STT_MODEL_IDS); diff --git a/packages/server/src/server/speech/providers/local/sherpa/model-downloader.ts b/packages/server/src/server/speech/providers/local/sherpa/model-downloader.ts index 1cb4838aa..2c9b6ae98 100644 --- a/packages/server/src/server/speech/providers/local/sherpa/model-downloader.ts +++ b/packages/server/src/server/speech/providers/local/sherpa/model-downloader.ts @@ -218,7 +218,7 @@ export async function ensureSherpaOnnxModels(options: { ), ); for (let i = 0; i < uniq.length; i += 1) { - out[uniq[i]!] = paths[i]!; + out[uniq[i]] = paths[i]!; } return out as Record; } diff --git a/packages/server/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.test.ts b/packages/server/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.test.ts index bd2174870..51ae5c5a4 100644 --- a/packages/server/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.test.ts +++ b/packages/server/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.test.ts @@ -79,12 +79,12 @@ describe("SherpaOnnxParakeetSTT session", () => { expect(transcripts).toHaveLength(2); expect(transcripts).toEqual([ expect.objectContaining({ - segmentId: committed[0]!.segmentId, + segmentId: committed[0].segmentId, transcript: "first", isFinal: true, }), expect.objectContaining({ - segmentId: committed[1]!.segmentId, + segmentId: committed[1].segmentId, transcript: "second", isFinal: true, }), diff --git a/packages/server/src/server/speech/providers/local/sherpa/sherpa-tts.ts b/packages/server/src/server/speech/providers/local/sherpa/sherpa-tts.ts index 1d6f4ac3f..12a25f485 100644 --- a/packages/server/src/server/speech/providers/local/sherpa/sherpa-tts.ts +++ b/packages/server/src/server/speech/providers/local/sherpa/sherpa-tts.ts @@ -119,7 +119,7 @@ export class SherpaOnnxTTS implements TextToSpeechProvider { if (audio && audio.samples instanceof Float32Array) { rawSamples = audio.samples; } else if (audio && Array.isArray(audio.samples)) { - rawSamples = Float32Array.from(audio.samples as number[]); + rawSamples = Float32Array.from(audio.samples); } // Copy to avoid "External buffers are not allowed" when sherpa-onnx // returns a Float32Array backed by native memory. diff --git a/packages/server/src/server/test-utils/dictation-e2e.ts b/packages/server/src/server/test-utils/dictation-e2e.ts index 3361c7022..a879cd255 100644 --- a/packages/server/src/server/test-utils/dictation-e2e.ts +++ b/packages/server/src/server/test-utils/dictation-e2e.ts @@ -92,7 +92,7 @@ export async function findLargestDebugWavFixture(): Promise { } const stats = await Promise.all(wavPaths.map((full) => fs.stat(full))); for (let i = 0; i < wavPaths.length; i += 1) { - files.push({ filePath: wavPaths[i]!, size: stats[i]!.size }); + files.push({ filePath: wavPaths[i], size: stats[i].size }); } currentLevel = nextLevel; } @@ -101,7 +101,7 @@ export async function findLargestDebugWavFixture(): Promise { throw new Error(`No .wav files found under ${base}`); } files.sort((a, b) => b.size - a.size); - return files[0]!.filePath; + return files[0].filePath; } export function normalizeTranscript(text: string): string { @@ -130,7 +130,7 @@ function levenshteinDistanceWords(a: string[], b: string[]): number { } for (let j = 0; j <= n; j += 1) prev[j] = cur[j]!; } - return prev[n]!; + return prev[n]; } export function wordSimilarity(aText: string, bText: string): number { diff --git a/packages/server/src/server/websocket-server.relay-reconnect.test.ts b/packages/server/src/server/websocket-server.relay-reconnect.test.ts index df9b95c16..0a0ba9d29 100644 --- a/packages/server/src/server/websocket-server.relay-reconnect.test.ts +++ b/packages/server/src/server/websocket-server.relay-reconnect.test.ts @@ -386,7 +386,7 @@ describe("relay external socket reconnect behavior", () => { clientId, }); expect(sessionMock.instances).toHaveLength(1); - const session = sessionMock.instances[0]!; + const session = sessionMock.instances[0]; socket1.emit("close", 1006, ""); await vi.advanceTimersByTimeAsync(1_000); @@ -425,7 +425,7 @@ describe("relay external socket reconnect behavior", () => { await Promise.resolve(); expect(sessionMock.instances).toHaveLength(1); - const session = sessionMock.instances[0]!; + const session = sessionMock.instances[0]; expect(session.args.clientCapabilities).toEqual({ [CLIENT_CAPS.reasoningMergeEnum]: true, }); @@ -542,7 +542,7 @@ describe("relay external socket reconnect behavior", () => { clientId, }); expect(sessionMock.instances).toHaveLength(1); - const session = sessionMock.instances[0]!; + const session = sessionMock.instances[0]; socket1.emit("close", 1006, ""); await vi.advanceTimersByTimeAsync(1_000); @@ -573,7 +573,7 @@ describe("relay external socket reconnect behavior", () => { clientId, }); expect(sessionMock.instances).toHaveLength(1); - const session = sessionMock.instances[0]!; + const session = sessionMock.instances[0]; const relaySocket = new MockSocket(); await attachRelayAndHello({ @@ -617,7 +617,7 @@ describe("relay external socket reconnect behavior", () => { clientId, }); expect(sessionMock.instances).toHaveLength(1); - const session = sessionMock.instances[0]!; + const session = sessionMock.instances[0]; socket1.emit("close", 1006, ""); await vi.advanceTimersByTimeAsync(90_000); @@ -721,7 +721,7 @@ describe("relay external socket reconnect behavior", () => { clientId: "cid-binary-inbound", }); expect(sessionMock.instances).toHaveLength(1); - const session = sessionMock.instances[0]!; + const session = sessionMock.instances[0]; socket.emit( "message", @@ -758,7 +758,7 @@ describe("relay external socket reconnect behavior", () => { clientId: "cid-binary-outbound", }); expect(sessionMock.instances).toHaveLength(1); - const session = sessionMock.instances[0]!; + const session = sessionMock.instances[0]; const onBinaryMessage = session.args.onBinaryMessage as | ((frame: Uint8Array) => void) diff --git a/packages/server/src/server/websocket-server.ts b/packages/server/src/server/websocket-server.ts index c8d362a05..d4ef8bee1 100644 --- a/packages/server/src/server/websocket-server.ts +++ b/packages/server/src/server/websocket-server.ts @@ -248,7 +248,7 @@ function bufferFromWsData(data: Buffer | ArrayBuffer | Buffer[] | string): Buffe ); } if (Buffer.isBuffer(data)) return data; - return Buffer.from(data as ArrayBuffer); + return Buffer.from(data); } interface WebSocketLike { @@ -1653,9 +1653,9 @@ export class VoiceAssistantWebSocketServer { if (latencies.length === 0) continue; latencies.sort((a, b) => a - b); const count = latencies.length; - const minMs = Math.round(latencies[0]!); - const maxMs = Math.round(latencies[count - 1]!); - const p50Ms = Math.round(latencies[Math.floor(count / 2)]!); + const minMs = Math.round(latencies[0]); + const maxMs = Math.round(latencies[count - 1]); + const p50Ms = Math.round(latencies[Math.floor(count / 2)]); const totalMs = Math.round(latencies.reduce((sum, v) => sum + v, 0)); stats.push({ type, count, minMs, maxMs, p50Ms, totalMs }); } diff --git a/packages/server/src/server/workspace-directory.ts b/packages/server/src/server/workspace-directory.ts index 20d7620e4..10baebb77 100644 --- a/packages/server/src/server/workspace-directory.ts +++ b/packages/server/src/server/workspace-directory.ts @@ -176,9 +176,9 @@ export class WorkspaceDirectory { ), ); for (let i = 0; i < includedWorkspaces.length; i += 1) { - const workspaceId = includedWorkspaces[i]!.workspaceId; + const workspaceId = includedWorkspaces[i].workspaceId; descriptorsByWorkspaceId.set(workspaceId, { - ...workspaceDescriptors[i]!, + ...workspaceDescriptors[i], archivingAt: this.archivingByWorkspaceId.get(workspaceId) ?? null, }); } diff --git a/packages/server/src/tasks/task-store.ts b/packages/server/src/tasks/task-store.ts index c94aab27f..320ed0df7 100644 --- a/packages/server/src/tasks/task-store.ts +++ b/packages/server/src/tasks/task-store.ts @@ -1,7 +1,7 @@ import { readdir, readFile, writeFile, mkdir, unlink } from "node:fs/promises"; import { join } from "node:path"; import { randomBytes } from "node:crypto"; -import type { Task, TaskStore, CreateTaskOptions, TaskStatus, AgentType } from "./types.js"; +import type { Task, TaskStore, CreateTaskOptions, TaskStatus } from "./types.js"; function generateId(): string { return randomBytes(4).toString("hex"); @@ -128,7 +128,7 @@ function parseTask(content: string): Task { } taskBody = taskBody.trim(); - const assignee = getValue("assignee") as AgentType | ""; + const assignee = getValue("assignee"); const parentId = getValue("parentId"); const priorityStr = getValue("priority"); const priority = priorityStr ? parseInt(priorityStr, 10) : undefined; diff --git a/packages/server/src/terminal/terminal-output-coalescer.ts b/packages/server/src/terminal/terminal-output-coalescer.ts index f7ef2ed68..0005eb995 100644 --- a/packages/server/src/terminal/terminal-output-coalescer.ts +++ b/packages/server/src/terminal/terminal-output-coalescer.ts @@ -58,7 +58,7 @@ export class TerminalOutputCoalescer { } const payload = - this.chunks.length === 1 ? this.chunks[0]! : Buffer.concat(this.chunks, this.bytes); + this.chunks.length === 1 ? this.chunks[0] : Buffer.concat(this.chunks, this.bytes); const bytes = this.bytes; const chars = this.chars; this.clearPending(); diff --git a/packages/server/src/terminal/worker-terminal-manager.ts b/packages/server/src/terminal/worker-terminal-manager.ts index 3e99371fb..2fa7a92c2 100644 --- a/packages/server/src/terminal/worker-terminal-manager.ts +++ b/packages/server/src/terminal/worker-terminal-manager.ts @@ -1,4 +1,4 @@ -import { fork, type ChildProcess } from "node:child_process"; +import { fork } from "node:child_process"; import { fileURLToPath } from "node:url"; import { randomUUID } from "node:crypto"; import type { TerminalState } from "../shared/messages.js"; @@ -109,7 +109,7 @@ function forkTerminalWorker(): TerminalWorkerProcess { execArgv: resolveWorkerExecArgv(), serialization: "advanced", stdio: ["ignore", "ignore", "inherit", "ipc"], - }) as ChildProcess as TerminalWorkerProcess; + }) as TerminalWorkerProcess; } export function createWorkerTerminalManager( diff --git a/packages/server/src/utils/checkout-git.ts b/packages/server/src/utils/checkout-git.ts index 009e8f9f5..cc6151b76 100644 --- a/packages/server/src/utils/checkout-git.ts +++ b/packages/server/src/utils/checkout-git.ts @@ -1478,11 +1478,11 @@ function parseCheckoutShortstat(text: string): CheckoutShortstat | null { let deletions = 0; const addMatch = trimmed.match(/(\d+)\s+insertion/); if (addMatch) { - additions = Number.parseInt(addMatch[1]!, 10); + additions = Number.parseInt(addMatch[1], 10); } const delMatch = trimmed.match(/(\d+)\s+deletion/); if (delMatch) { - deletions = Number.parseInt(delMatch[1]!, 10); + deletions = Number.parseInt(delMatch[1], 10); } if (additions === 0 && deletions === 0) { diff --git a/packages/server/src/utils/directory-suggestions.ts b/packages/server/src/utils/directory-suggestions.ts index 08b180fa3..f89279362 100644 --- a/packages/server/src/utils/directory-suggestions.ts +++ b/packages/server/src/utils/directory-suggestions.ts @@ -889,7 +889,7 @@ function pruneDirectoryListCache(): void { } while (directoryListCache.size > DIRECTORY_LIST_CACHE_MAX_ENTRIES) { - const oldestKey = directoryListCache.keys().next().value as string | undefined; + const oldestKey = directoryListCache.keys().next().value; if (!oldestKey) { return; } @@ -910,7 +910,7 @@ function pruneWorkspaceEntryListCache(): void { } while (workspaceEntryListCache.size > DIRECTORY_LIST_CACHE_MAX_ENTRIES) { - const oldestKey = workspaceEntryListCache.keys().next().value as string | undefined; + const oldestKey = workspaceEntryListCache.keys().next().value; if (!oldestKey) { return; } diff --git a/packages/server/src/utils/worktree.ts b/packages/server/src/utils/worktree.ts index 18c69dece..71c6ab618 100644 --- a/packages/server/src/utils/worktree.ts +++ b/packages/server/src/utils/worktree.ts @@ -901,7 +901,7 @@ export async function isPaseoOwnedWorktreeCwd( }; } - const worktreesRoot = join(paseoHome, "worktrees", parts[0]!); + const worktreesRoot = join(paseoHome, "worktrees", parts[0]); return { allowed: true, ...(repoRoot !== undefined ? { repoRoot } : {}), diff --git a/scripts/measure-relay-latency.ts b/scripts/measure-relay-latency.ts index f8dcb3f0a..a9335d7f9 100644 --- a/scripts/measure-relay-latency.ts +++ b/scripts/measure-relay-latency.ts @@ -62,10 +62,10 @@ async function measurePings( const sorted = [...results].sort((a, b) => a - b); const avg = results.reduce((a, b) => a + b, 0) / results.length; - const min = sorted[0]!; - const max = sorted[sorted.length - 1]!; - const p50 = sorted[Math.floor(sorted.length * 0.5)]!; - const p95 = sorted[Math.floor(sorted.length * 0.95)]!; + const min = sorted[0]; + const max = sorted[sorted.length - 1]; + const p50 = sorted[Math.floor(sorted.length * 0.5)]; + const p95 = sorted[Math.floor(sorted.length * 0.95)]; console.log(`\n${label}:`); console.log(` samples: ${count} (after ${warmup} warmup)`);