Skip to content

refactor(relay): collapse the duplicated FrameDecoder into one shared module - #12078

Merged
nwparker merged 1 commit into
stablyai:mainfrom
nwparker:nwparker/slim-dedupe-frame-decoder
Aug 2, 2026
Merged

refactor(relay): collapse the duplicated FrameDecoder into one shared module#12078
nwparker merged 1 commit into
stablyai:mainfrom
nwparker:nwparker/slim-dedupe-frame-decoder

Conversation

@nwparker

@nwparker nwparker commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Stacked on #12077.

What

src/relay/relay-frame-decoder.ts and src/main/ssh/relay-frame-decoder.ts were 264 identical lines apart from a single default: the relay writes decode faults to stderr when no handler is supplied, the SSH side stays silent.

$ diff src/relay/relay-frame-decoder.ts src/main/ssh/relay-frame-decoder.ts
# only the import depth and:
-  private onError: (err: Error) => void
+  private onError: ((err: Error) => void) | null
-  this.onError = onError ?? ((error) => process.stderr.write(`[relay] ${error.message}\n`))
+  this.onError = onError ?? null

Two copies of the wire-framing logic is exactly the shape where a protocol fix lands in one and silently not the other.

3 files changed, +23 / −255.

How

The decoder's contract (relay-frame-decoder-contract.ts) and buffer (relay-frame-buffer.ts) already live in src/shared/ and are already consumed by both sides — only the class body had been copy-pasted. So the class joins them in src/shared/relay-frame-decoder.ts.

  • The relay keeps a thin subclass supplying its stderr default. This matters: relay.ts, protocol-handshake.test.ts and relay-handshake-roundtrip.test.ts all construct FrameDecoder without an onError, so collapsing to a single null default would have silently swallowed relay decode errors.
  • The SSH copy is deleted; src/main/ssh/relay-protocol.ts imports from shared directly.

No behaviour change on either side.

Checks

  • pnpm typecheck — passes
  • 102 tests across the 9 framing / backpressure / handshake / integration suites — all pass
  • pnpm build:relay — builds clean for all six platform targets (linux-x64/arm64, darwin-x64/arm64, win32-x64/arm64) plus the WSL hook relay

That last one is the real check here: src/relay/protocol.ts is documented as "self-contained… no Electron dependencies. Deployed standalone to remote hosts." Pulling the class into src/shared respects that — esbuild already bundles src/shared into the relay, and the standalone bundle gains no new dependencies.

Context

This was the largest clone jscpd found in the tree. Overall duplication measures 0.13%, so there is no broader copy-paste problem to chase — this one was just genuinely worth collapsing.

Made with Orca 🐋

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 900c8b0c-8944-429d-a33c-6cda4851ad95

📥 Commits

Reviewing files that changed from the base of the PR and between ddae63a and db0f74d.

📒 Files selected for processing (3)
  • src/main/ssh/relay-protocol.ts
  • src/relay/relay-frame-decoder.ts
  • src/shared/relay-frame-decoder.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/ssh/relay-protocol.ts
  • src/relay/relay-frame-decoder.ts
  • src/shared/relay-frame-decoder.ts

📝 Walkthrough

Walkthrough

The relay frame decoder now extends the shared decoder and forwards callbacks and options to it. Relay-specific constants, contracts, and buffer exports now reference shared modules. Relay protocol runtime imports and type exports now use the shared decoder module. Missing error handlers continue to write errors to stderr.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the refactor and testing, but it omits the required Screenshots, AI Review Report, Security Audit, and Notes sections. Add the missing template sections, including the required cross-platform AI review confirmation and security audit findings.
Docstring Coverage ⚠️ Warning Docstring coverage is 26.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: consolidating duplicated relay FrameDecoder implementations into one shared module.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nwparker
nwparker force-pushed the nwparker/slim-dedupe-frame-decoder branch 2 times, most recently from b4108c1 to ddae63a Compare August 2, 2026 07:34
@greptile-apps

greptile-apps Bot commented Aug 2, 2026

Copy link
Copy Markdown

Greptile Summary

This PR collapses two nearly identical 264-line FrameDecoder implementations — one in src/relay/ and one in src/main/ssh/ — into a single canonical class in src/shared/relay-frame-decoder.ts. The sole behavioral difference (relay defaults onError to stderr; SSH side defaults to null) is preserved via a thin subclass in src/relay/relay-frame-decoder.ts.

  • Shared canonical decoder (src/shared/relay-frame-decoder.ts): the former SSH-side file is renamed/moved here with only import-path adjustments; all constants, types, and class members are unchanged.
  • Relay thin subclass (src/relay/relay-frame-decoder.ts): replaces ~230 lines of duplicated logic with a single-constructor class that wires in the stderr fallback, re-exporting all constants and types so callers see no API change.
  • SSH protocol import fix (src/main/ssh/relay-protocol.ts): updated to import directly from ../../shared/relay-frame-decoder, which is now the canonical location.

Confidence Score: 5/5

Safe to merge — pure refactor with no logic changes on either the relay or SSH decode path.

All 264 lines of decoding logic are unchanged; only the file location and import paths moved. The one behavioral difference between the two sides (relay writes to stderr on missing handler, SSH stays silent) is correctly preserved through the thin subclass. The relay bundle gains no new runtime dependencies, and the re-exports in both files keep the public API identical for existing callers.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
src/shared/relay-frame-decoder.ts Former SSH-side implementation moved to shared; only import paths changed (relative → same-directory). Logic, constants, and types are identical to the original.
src/relay/relay-frame-decoder.ts Reduced from 264 lines to a 32-line thin subclass; extends the shared decoder and supplies the relay’s stderr error default. All constants and types are re-exported to preserve the existing public API.
src/main/ssh/relay-protocol.ts Import paths updated from the deleted local relay-frame-decoder to the new shared location; no logic changes.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class SharedFrameDecoder {
        <<src/shared/relay-frame-decoder.ts>>
        -buffer: RelayFrameBuffer
        -onError: ((err: Error) => void) | null
        -onFrame: (frame: DecodedFrame) => void
        +constructor(onFrame, onError?, options?)
        +feed(chunk: Buffer | Uint8Array): void
        +reset(): void
        +drain(): Buffer
        -drainTurn(): void
        -scheduleContinuation(): void
    }

    class RelayFrameDecoder {
        <<src/relay/relay-frame-decoder.ts>>
        +constructor(onFrame, onError?, options?)
    }

    class SshRelayProtocol {
        <<src/main/ssh/relay-protocol.ts>>
    }

    SharedFrameDecoder <|-- RelayFrameDecoder : extends (adds stderr default)
    SshRelayProtocol ..> SharedFrameDecoder : imports & re-exports
Loading

Reviews (2): Last reviewed commit: "refactor(relay): collapse the duplicated..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
config/knip.json (1)

39-40: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Fail the audit on stale configuration hints.

The explicit entry and project globs can become stale after a path rename. Knip reports no-match and redundant patterns as warnings by default. Without treatConfigHintsAsErrors, the audit can succeed after its analysis scope has narrowed. (knip.dev)

Proposed fix
-  "includeEntryExports": false
+  "includeEntryExports": false,
+  "treatConfigHintsAsErrors": true
package.json (1)

19-19: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pin one Knip patch across the schema and audit command.

Both files use the moving @5 tag. pnpm dlx fetches the package from the registry at invocation, so the audit implementation and schema can drift. Pin one reviewed patch in the lockfile and use it in both locations. (pnpm.io)

  • package.json#L19-L19: replace pnpm dlx knip@5 with a local exact-version knip invocation.
  • config/knip.json#L2-L2: point $schema at the same exact Knip patch.
src/main/ssh/relay-protocol.ts (1)

14-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Align the type contract imports to reduce drift risk.

relay-protocol.ts imports DecodedFrame and FrameDecoderOptions from ../../shared/relay-frame-decoder, while src/relay/relay-frame-decoder.ts imports them from ../shared/relay-frame-decoder-contract. Consolidate the contract imports, checking src/shared/relay-frame-decoder.ts at lines 6 and 17-20 to see whether it re-exports the shared contract types.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e4679e43-1b78-4bbf-9489-7803da119470

📥 Commits

Reviewing files that changed from the base of the PR and between 711491b and b4108c1.

📒 Files selected for processing (148)
  • config/knip.json
  • package.json
  • src/cli/runtime/environments.ts
  • src/main/ai-vault/session-scanner-opencode-sqlite-worker-protocol.ts
  • src/main/claude-usage/scanner.ts
  • src/main/codex-usage/scanner.ts
  • src/main/computer/macos-native-provider-paths.ts
  • src/main/daemon/terminal-private-mode-tracker.ts
  • src/main/emulator/android/android-input-mapping.ts
  • src/main/emulator/emulator-types.ts
  • src/main/git/git-username.ts
  • src/main/git/repo.ts
  • src/main/github/github-api-repository.ts
  • src/main/github/github-enterprise-repository.ts
  • src/main/github/project-view.ts
  • src/main/github/project-view/internals.ts
  • src/main/gitlab/gl-utils.ts
  • src/main/ipc/feedback-image-attachments.ts
  • src/main/ipc/parcel-watcher-host-subscriptions.ts
  • src/main/ipc/parcel-watcher-process.ts
  • src/main/ipc/runtime-environment-request-connections.ts
  • src/main/ipc/worktree-change-invalidators.ts
  • src/main/observability/index.ts
  • src/main/observability/instrumentation.ts
  • src/main/observability/redactor.ts
  • src/main/pi/prefill-extension-source.ts
  • src/main/pi/titlebar-extension-service.ts
  • src/main/plugins/plugin-enablement.ts
  • src/main/providers/pty-process-list-admission.ts
  • src/main/providers/types.ts
  • src/main/rate-limits/grok-auth.ts
  • src/main/runtime/orca-runtime-emulator.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/orchestration/groups.ts
  • src/main/runtime/rpc/schemas.ts
  • src/main/shell-ready-marker-scanner.ts
  • src/main/ssh/relay-protocol.ts
  • src/main/ssh/sftp-namespace-resolution.ts
  • src/main/ssh/sftp-upload.ts
  • src/main/ssh/ssh-pty-consumer-session.ts
  • src/main/ssh/ssh-relay-session-managed-hooks.test.ts
  • src/main/ssh/ssh-relay-session.test.ts
  • src/main/system-fonts.ts
  • src/main/telemetry/client.ts
  • src/relay/fs-handler-file-read.ts
  • src/relay/relay-frame-decoder.ts
  • src/renderer/src/components/automations/automation-page-parts.tsx
  • src/renderer/src/components/browser-pane/browser-automation-visibility.ts
  • src/renderer/src/components/browser-pane/browser-page-zoom.ts
  • src/renderer/src/components/dashboard/useDashboardData.ts
  • src/renderer/src/components/editor/NotesSendMenu.test.tsx
  • src/renderer/src/components/editor/ReviewNotesSendMenuContent.test.tsx
  • src/renderer/src/components/editor/markdown-round-trip.ts
  • src/renderer/src/components/emulator-pane/emulator-keyboard-paste.ts
  • src/renderer/src/components/emulator-pane/emulator-pane-types.ts
  • src/renderer/src/components/github-project/column-widths.ts
  • src/renderer/src/components/github/github-issue-comment-helpers.ts
  • src/renderer/src/components/linear-issue-workspace-text.ts
  • src/renderer/src/components/native-chat/native-chat-composer-state.ts
  • src/renderer/src/components/onboarding/use-onboarding-flow.ts
  • src/renderer/src/components/repo/repo-icon.tsx
  • src/renderer/src/components/right-sidebar/CreateHostedReviewComposer.tsx
  • src/renderer/src/components/right-sidebar/commit-failure-dialog-state.ts
  • src/renderer/src/components/right-sidebar/file-explorer-operation-owner.ts
  • src/renderer/src/components/right-sidebar/file-explorer-runtime-owner-boundary.test.ts
  • src/renderer/src/components/right-sidebar/push-failure-summary.ts
  • src/renderer/src/components/right-sidebar/source-control-active-open-file-keys.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.test.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-push-failure-launch.ts
  • src/renderer/src/components/right-sidebar/source-control-create-pr-intent-state.ts
  • src/renderer/src/components/right-sidebar/source-control-primary-action-types.ts
  • src/renderer/src/components/settings/SettingsConstants.ts
  • src/renderer/src/components/settings/general-search.ts
  • src/renderer/src/components/settings/terminal-windows-search.ts
  • src/renderer/src/components/sidebar/WorktreeCardHelpers.tsx
  • src/renderer/src/components/sidebar/WorktreeCardPorts.tsx
  • src/renderer/src/components/sidebar/create-project-defaults.ts
  • src/renderer/src/components/sidebar/project-header-drop.ts
  • src/renderer/src/components/sidebar/sidebar-host-options.ts
  • src/renderer/src/components/sidebar/sidebar-nav-controls.tsx
  • src/renderer/src/components/sidebar/workspace-kanban-card-drag-preview-dom.ts
  • src/renderer/src/components/tab-bar/shell-icons.tsx
  • src/renderer/src/components/tab-bar/tab-create-entry-path-validation.ts
  • src/renderer/src/components/tab-group/tab-drag-context.tsx
  • src/renderer/src/components/terminal-pane/pty-delivery-interest.ts
  • src/renderer/src/components/terminal-pane/pty-pre-handler-buffer.ts
  • src/renderer/src/components/terminal-pane/terminal-hidden-delivery-gate.ts
  • src/renderer/src/components/terminal/terminal-tab-actions.ts
  • src/renderer/src/constants/terminal.ts
  • src/renderer/src/hooks/useAutomationDispatchEvents.test.ts
  • src/renderer/src/hooks/useIssueMetadata.ts
  • src/renderer/src/hooks/useShortcutLabel.ts
  • src/renderer/src/lib/active-agent-note-send.ts
  • src/renderer/src/lib/active-agent-note-target.ts
  • src/renderer/src/lib/agent-hibernation-coordinator.ts
  • src/renderer/src/lib/agent-paste-draft.ts
  • src/renderer/src/lib/crash-diagnostics.test.ts
  • src/renderer/src/lib/crash-diagnostics.ts
  • src/renderer/src/lib/ensure-simulator-tab.ts
  • src/renderer/src/lib/keyboard-layout/input-source-id.ts
  • src/renderer/src/lib/keyboard-layout/option-as-alt-probe.ts
  • src/renderer/src/lib/open-mobile-emulator-tab.test.ts
  • src/renderer/src/lib/repo-slug-index.ts
  • src/renderer/src/lib/setup-script-status.ts
  • src/renderer/src/lib/workspace-port-actions.ts
  • src/renderer/src/store/slices/runtime-detected-agents.ts
  • src/shared/agent-session-host-authority.ts
  • src/shared/agent-session-option-catalog.ts
  • src/shared/commit-message-generation.ts
  • src/shared/custom-pet-media-limits.ts
  • src/shared/daemon-audit-eligibility.ts
  • src/shared/daemon-lifecycle-telemetry.ts
  • src/shared/ephemeral-vm-recipes.ts
  • src/shared/ephemeral-vm-runtimes.ts
  • src/shared/folder-workspaces.ts
  • src/shared/hermes-run-output-limits.ts
  • src/shared/hermes-run-ref-retention.ts
  • src/shared/hosted-review.ts
  • src/shared/html-to-pdf-memory-limit.ts
  • src/shared/left-sidebar-appearance.ts
  • src/shared/linear-agent-access.ts
  • src/shared/linux-proc-port-scan-limits.ts
  • src/shared/native-file-drop.ts
  • src/shared/persisted-state-file-bounds.ts
  • src/shared/pr-refresh-memory-limits.ts
  • src/shared/pty-source-credit-contract.ts
  • src/shared/relay-frame-decoder.ts
  • src/shared/relay-json-admission.ts
  • src/shared/remote-runtime-memory-limits.ts
  • src/shared/remote-runtime-shared-control-state.ts
  • src/shared/remote-workspace-types.ts
  • src/shared/runtime-bootstrap.ts
  • src/shared/runtime-environments.ts
  • src/shared/runtime-types.ts
  • src/shared/serve-update-handoff.ts
  • src/shared/source-control-create-review-intent.ts
  • src/shared/ssh-retained-payload-admission.ts
  • src/shared/task-source-context.ts
  • src/shared/telemetry-events.ts
  • src/shared/terminal-custom-themes.ts
  • src/shared/terminal-scrollback-policy.ts
  • src/shared/terminal-size-limits.ts
  • src/shared/terminal-title-display.ts
  • src/shared/terminal-title-status.ts
  • src/shared/work-items.ts
  • src/shared/workspace-scope.ts
  • src/shared/wsl-hook-relay-contract.ts
💤 Files with no reviewable changes (123)
  • src/main/gitlab/gl-utils.ts
  • src/renderer/src/components/settings/SettingsConstants.ts
  • src/renderer/src/lib/keyboard-layout/input-source-id.ts
  • src/shared/workspace-scope.ts
  • src/renderer/src/components/tab-group/tab-drag-context.tsx
  • src/shared/html-to-pdf-memory-limit.ts
  • src/renderer/src/lib/agent-hibernation-coordinator.ts
  • src/renderer/src/components/sidebar/project-header-drop.ts
  • src/main/ipc/worktree-change-invalidators.ts
  • src/renderer/src/components/terminal-pane/terminal-hidden-delivery-gate.ts
  • src/shared/relay-json-admission.ts
  • src/main/ipc/feedback-image-attachments.ts
  • src/main/codex-usage/scanner.ts
  • src/cli/runtime/environments.ts
  • src/main/telemetry/client.ts
  • src/main/github/project-view/internals.ts
  • src/renderer/src/lib/active-agent-note-send.ts
  • src/main/observability/index.ts
  • src/renderer/src/lib/workspace-port-actions.ts
  • src/renderer/src/lib/crash-diagnostics.ts
  • src/shared/pr-refresh-memory-limits.ts
  • src/renderer/src/constants/terminal.ts
  • src/main/github/github-api-repository.ts
  • src/renderer/src/components/settings/general-search.ts
  • src/main/git/git-username.ts
  • src/renderer/src/components/right-sidebar/commit-failure-dialog-state.ts
  • src/main/ssh/sftp-upload.ts
  • src/shared/terminal-custom-themes.ts
  • src/renderer/src/lib/keyboard-layout/option-as-alt-probe.ts
  • src/main/runtime/rpc/schemas.ts
  • src/renderer/src/components/sidebar/create-project-defaults.ts
  • src/main/runtime/orchestration/groups.ts
  • src/renderer/src/components/github-project/column-widths.ts
  • src/renderer/src/components/settings/terminal-windows-search.ts
  • src/renderer/src/components/right-sidebar/source-control-active-open-file-keys.ts
  • src/renderer/src/components/native-chat/native-chat-composer-state.ts
  • src/shared/terminal-title-display.ts
  • src/renderer/src/components/right-sidebar/file-explorer-operation-owner.ts
  • src/shared/ssh-retained-payload-admission.ts
  • src/renderer/src/components/repo/repo-icon.tsx
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.ts
  • src/main/daemon/terminal-private-mode-tracker.ts
  • src/main/rate-limits/grok-auth.ts
  • src/renderer/src/components/terminal-pane/pty-pre-handler-buffer.ts
  • src/main/pi/titlebar-extension-service.ts
  • src/shared/remote-runtime-memory-limits.ts
  • src/shared/pty-source-credit-contract.ts
  • src/shared/remote-runtime-shared-control-state.ts
  • src/shared/agent-session-host-authority.ts
  • src/renderer/src/components/terminal-pane/pty-delivery-interest.ts
  • src/shared/linux-proc-port-scan-limits.ts
  • src/renderer/src/components/emulator-pane/emulator-pane-types.ts
  • src/shared/agent-session-option-catalog.ts
  • src/main/ipc/parcel-watcher-host-subscriptions.ts
  • src/shared/wsl-hook-relay-contract.ts
  • src/main/emulator/emulator-types.ts
  • src/main/github/github-enterprise-repository.ts
  • src/main/ssh/ssh-pty-consumer-session.ts
  • src/renderer/src/store/slices/runtime-detected-agents.ts
  • src/main/ssh/ssh-relay-session.test.ts
  • src/shared/remote-workspace-types.ts
  • src/shared/terminal-title-status.ts
  • src/main/shell-ready-marker-scanner.ts
  • src/renderer/src/components/browser-pane/browser-page-zoom.ts
  • src/main/plugins/plugin-enablement.ts
  • src/shared/commit-message-generation.ts
  • src/main/observability/instrumentation.ts
  • src/main/providers/pty-process-list-admission.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-push-failure-launch.ts
  • src/main/runtime/orca-runtime-emulator.ts
  • src/renderer/src/components/right-sidebar/CreateHostedReviewComposer.tsx
  • src/shared/runtime-environments.ts
  • src/shared/ephemeral-vm-runtimes.ts
  • src/shared/custom-pet-media-limits.ts
  • src/shared/terminal-size-limits.ts
  • src/main/observability/redactor.ts
  • src/shared/left-sidebar-appearance.ts
  • src/main/ssh/ssh-relay-session-managed-hooks.test.ts
  • src/renderer/src/components/github/github-issue-comment-helpers.ts
  • src/shared/linear-agent-access.ts
  • src/renderer/src/components/sidebar/workspace-kanban-card-drag-preview-dom.ts
  • src/renderer/src/hooks/useShortcutLabel.ts
  • src/renderer/src/components/sidebar/sidebar-host-options.ts
  • src/renderer/src/components/sidebar/sidebar-nav-controls.tsx
  • src/shared/runtime-types.ts
  • src/shared/native-file-drop.ts
  • src/shared/hosted-review.ts
  • src/renderer/src/components/browser-pane/browser-automation-visibility.ts
  • src/main/pi/prefill-extension-source.ts
  • src/renderer/src/components/tab-bar/tab-create-entry-path-validation.ts
  • src/renderer/src/components/terminal/terminal-tab-actions.ts
  • src/shared/daemon-lifecycle-telemetry.ts
  • src/main/system-fonts.ts
  • src/shared/hermes-run-ref-retention.ts
  • src/renderer/src/components/onboarding/use-onboarding-flow.ts
  • src/renderer/src/components/tab-bar/shell-icons.tsx
  • src/main/computer/macos-native-provider-paths.ts
  • src/renderer/src/components/emulator-pane/emulator-keyboard-paste.ts
  • src/shared/task-source-context.ts
  • src/renderer/src/lib/ensure-simulator-tab.ts
  • src/main/git/repo.ts
  • src/renderer/src/hooks/useIssueMetadata.ts
  • src/renderer/src/components/automations/automation-page-parts.tsx
  • src/renderer/src/lib/agent-paste-draft.ts
  • src/renderer/src/components/linear-issue-workspace-text.ts
  • src/shared/runtime-bootstrap.ts
  • src/renderer/src/lib/repo-slug-index.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.test.ts
  • src/shared/hermes-run-output-limits.ts
  • src/shared/source-control-create-review-intent.ts
  • src/main/emulator/android/android-input-mapping.ts
  • src/renderer/src/components/sidebar/WorktreeCardPorts.tsx
  • src/shared/telemetry-events.ts
  • src/renderer/src/lib/active-agent-note-target.ts
  • src/main/claude-usage/scanner.ts
  • src/renderer/src/components/right-sidebar/push-failure-summary.ts
  • src/renderer/src/components/editor/markdown-round-trip.ts
  • src/shared/terminal-scrollback-policy.ts
  • src/main/ipc/runtime-environment-request-connections.ts
  • src/shared/daemon-audit-eligibility.ts
  • src/renderer/src/components/right-sidebar/source-control-primary-action-types.ts
  • src/main/ipc/parcel-watcher-process.ts
  • src/shared/serve-update-handoff.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🧹 Nitpick comments (3)
config/knip.json (1)

39-40: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Fail the audit on stale configuration hints.

The explicit entry and project globs can become stale after a path rename. Knip reports no-match and redundant patterns as warnings by default. Without treatConfigHintsAsErrors, the audit can succeed after its analysis scope has narrowed. (knip.dev)

Proposed fix
-  "includeEntryExports": false
+  "includeEntryExports": false,
+  "treatConfigHintsAsErrors": true
package.json (1)

19-19: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pin one Knip patch across the schema and audit command.

Both files use the moving @5 tag. pnpm dlx fetches the package from the registry at invocation, so the audit implementation and schema can drift. Pin one reviewed patch in the lockfile and use it in both locations. (pnpm.io)

  • package.json#L19-L19: replace pnpm dlx knip@5 with a local exact-version knip invocation.
  • config/knip.json#L2-L2: point $schema at the same exact Knip patch.
src/main/ssh/relay-protocol.ts (1)

14-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Align the type contract imports to reduce drift risk.

relay-protocol.ts imports DecodedFrame and FrameDecoderOptions from ../../shared/relay-frame-decoder, while src/relay/relay-frame-decoder.ts imports them from ../shared/relay-frame-decoder-contract. Consolidate the contract imports, checking src/shared/relay-frame-decoder.ts at lines 6 and 17-20 to see whether it re-exports the shared contract types.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e4679e43-1b78-4bbf-9489-7803da119470

📥 Commits

Reviewing files that changed from the base of the PR and between 711491b and b4108c1.

📒 Files selected for processing (148)
  • config/knip.json
  • package.json
  • src/cli/runtime/environments.ts
  • src/main/ai-vault/session-scanner-opencode-sqlite-worker-protocol.ts
  • src/main/claude-usage/scanner.ts
  • src/main/codex-usage/scanner.ts
  • src/main/computer/macos-native-provider-paths.ts
  • src/main/daemon/terminal-private-mode-tracker.ts
  • src/main/emulator/android/android-input-mapping.ts
  • src/main/emulator/emulator-types.ts
  • src/main/git/git-username.ts
  • src/main/git/repo.ts
  • src/main/github/github-api-repository.ts
  • src/main/github/github-enterprise-repository.ts
  • src/main/github/project-view.ts
  • src/main/github/project-view/internals.ts
  • src/main/gitlab/gl-utils.ts
  • src/main/ipc/feedback-image-attachments.ts
  • src/main/ipc/parcel-watcher-host-subscriptions.ts
  • src/main/ipc/parcel-watcher-process.ts
  • src/main/ipc/runtime-environment-request-connections.ts
  • src/main/ipc/worktree-change-invalidators.ts
  • src/main/observability/index.ts
  • src/main/observability/instrumentation.ts
  • src/main/observability/redactor.ts
  • src/main/pi/prefill-extension-source.ts
  • src/main/pi/titlebar-extension-service.ts
  • src/main/plugins/plugin-enablement.ts
  • src/main/providers/pty-process-list-admission.ts
  • src/main/providers/types.ts
  • src/main/rate-limits/grok-auth.ts
  • src/main/runtime/orca-runtime-emulator.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/orchestration/groups.ts
  • src/main/runtime/rpc/schemas.ts
  • src/main/shell-ready-marker-scanner.ts
  • src/main/ssh/relay-protocol.ts
  • src/main/ssh/sftp-namespace-resolution.ts
  • src/main/ssh/sftp-upload.ts
  • src/main/ssh/ssh-pty-consumer-session.ts
  • src/main/ssh/ssh-relay-session-managed-hooks.test.ts
  • src/main/ssh/ssh-relay-session.test.ts
  • src/main/system-fonts.ts
  • src/main/telemetry/client.ts
  • src/relay/fs-handler-file-read.ts
  • src/relay/relay-frame-decoder.ts
  • src/renderer/src/components/automations/automation-page-parts.tsx
  • src/renderer/src/components/browser-pane/browser-automation-visibility.ts
  • src/renderer/src/components/browser-pane/browser-page-zoom.ts
  • src/renderer/src/components/dashboard/useDashboardData.ts
  • src/renderer/src/components/editor/NotesSendMenu.test.tsx
  • src/renderer/src/components/editor/ReviewNotesSendMenuContent.test.tsx
  • src/renderer/src/components/editor/markdown-round-trip.ts
  • src/renderer/src/components/emulator-pane/emulator-keyboard-paste.ts
  • src/renderer/src/components/emulator-pane/emulator-pane-types.ts
  • src/renderer/src/components/github-project/column-widths.ts
  • src/renderer/src/components/github/github-issue-comment-helpers.ts
  • src/renderer/src/components/linear-issue-workspace-text.ts
  • src/renderer/src/components/native-chat/native-chat-composer-state.ts
  • src/renderer/src/components/onboarding/use-onboarding-flow.ts
  • src/renderer/src/components/repo/repo-icon.tsx
  • src/renderer/src/components/right-sidebar/CreateHostedReviewComposer.tsx
  • src/renderer/src/components/right-sidebar/commit-failure-dialog-state.ts
  • src/renderer/src/components/right-sidebar/file-explorer-operation-owner.ts
  • src/renderer/src/components/right-sidebar/file-explorer-runtime-owner-boundary.test.ts
  • src/renderer/src/components/right-sidebar/push-failure-summary.ts
  • src/renderer/src/components/right-sidebar/source-control-active-open-file-keys.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.test.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-push-failure-launch.ts
  • src/renderer/src/components/right-sidebar/source-control-create-pr-intent-state.ts
  • src/renderer/src/components/right-sidebar/source-control-primary-action-types.ts
  • src/renderer/src/components/settings/SettingsConstants.ts
  • src/renderer/src/components/settings/general-search.ts
  • src/renderer/src/components/settings/terminal-windows-search.ts
  • src/renderer/src/components/sidebar/WorktreeCardHelpers.tsx
  • src/renderer/src/components/sidebar/WorktreeCardPorts.tsx
  • src/renderer/src/components/sidebar/create-project-defaults.ts
  • src/renderer/src/components/sidebar/project-header-drop.ts
  • src/renderer/src/components/sidebar/sidebar-host-options.ts
  • src/renderer/src/components/sidebar/sidebar-nav-controls.tsx
  • src/renderer/src/components/sidebar/workspace-kanban-card-drag-preview-dom.ts
  • src/renderer/src/components/tab-bar/shell-icons.tsx
  • src/renderer/src/components/tab-bar/tab-create-entry-path-validation.ts
  • src/renderer/src/components/tab-group/tab-drag-context.tsx
  • src/renderer/src/components/terminal-pane/pty-delivery-interest.ts
  • src/renderer/src/components/terminal-pane/pty-pre-handler-buffer.ts
  • src/renderer/src/components/terminal-pane/terminal-hidden-delivery-gate.ts
  • src/renderer/src/components/terminal/terminal-tab-actions.ts
  • src/renderer/src/constants/terminal.ts
  • src/renderer/src/hooks/useAutomationDispatchEvents.test.ts
  • src/renderer/src/hooks/useIssueMetadata.ts
  • src/renderer/src/hooks/useShortcutLabel.ts
  • src/renderer/src/lib/active-agent-note-send.ts
  • src/renderer/src/lib/active-agent-note-target.ts
  • src/renderer/src/lib/agent-hibernation-coordinator.ts
  • src/renderer/src/lib/agent-paste-draft.ts
  • src/renderer/src/lib/crash-diagnostics.test.ts
  • src/renderer/src/lib/crash-diagnostics.ts
  • src/renderer/src/lib/ensure-simulator-tab.ts
  • src/renderer/src/lib/keyboard-layout/input-source-id.ts
  • src/renderer/src/lib/keyboard-layout/option-as-alt-probe.ts
  • src/renderer/src/lib/open-mobile-emulator-tab.test.ts
  • src/renderer/src/lib/repo-slug-index.ts
  • src/renderer/src/lib/setup-script-status.ts
  • src/renderer/src/lib/workspace-port-actions.ts
  • src/renderer/src/store/slices/runtime-detected-agents.ts
  • src/shared/agent-session-host-authority.ts
  • src/shared/agent-session-option-catalog.ts
  • src/shared/commit-message-generation.ts
  • src/shared/custom-pet-media-limits.ts
  • src/shared/daemon-audit-eligibility.ts
  • src/shared/daemon-lifecycle-telemetry.ts
  • src/shared/ephemeral-vm-recipes.ts
  • src/shared/ephemeral-vm-runtimes.ts
  • src/shared/folder-workspaces.ts
  • src/shared/hermes-run-output-limits.ts
  • src/shared/hermes-run-ref-retention.ts
  • src/shared/hosted-review.ts
  • src/shared/html-to-pdf-memory-limit.ts
  • src/shared/left-sidebar-appearance.ts
  • src/shared/linear-agent-access.ts
  • src/shared/linux-proc-port-scan-limits.ts
  • src/shared/native-file-drop.ts
  • src/shared/persisted-state-file-bounds.ts
  • src/shared/pr-refresh-memory-limits.ts
  • src/shared/pty-source-credit-contract.ts
  • src/shared/relay-frame-decoder.ts
  • src/shared/relay-json-admission.ts
  • src/shared/remote-runtime-memory-limits.ts
  • src/shared/remote-runtime-shared-control-state.ts
  • src/shared/remote-workspace-types.ts
  • src/shared/runtime-bootstrap.ts
  • src/shared/runtime-environments.ts
  • src/shared/runtime-types.ts
  • src/shared/serve-update-handoff.ts
  • src/shared/source-control-create-review-intent.ts
  • src/shared/ssh-retained-payload-admission.ts
  • src/shared/task-source-context.ts
  • src/shared/telemetry-events.ts
  • src/shared/terminal-custom-themes.ts
  • src/shared/terminal-scrollback-policy.ts
  • src/shared/terminal-size-limits.ts
  • src/shared/terminal-title-display.ts
  • src/shared/terminal-title-status.ts
  • src/shared/work-items.ts
  • src/shared/workspace-scope.ts
  • src/shared/wsl-hook-relay-contract.ts
💤 Files with no reviewable changes (123)
  • src/main/gitlab/gl-utils.ts
  • src/renderer/src/components/settings/SettingsConstants.ts
  • src/renderer/src/lib/keyboard-layout/input-source-id.ts
  • src/shared/workspace-scope.ts
  • src/renderer/src/components/tab-group/tab-drag-context.tsx
  • src/shared/html-to-pdf-memory-limit.ts
  • src/renderer/src/lib/agent-hibernation-coordinator.ts
  • src/renderer/src/components/sidebar/project-header-drop.ts
  • src/main/ipc/worktree-change-invalidators.ts
  • src/renderer/src/components/terminal-pane/terminal-hidden-delivery-gate.ts
  • src/shared/relay-json-admission.ts
  • src/main/ipc/feedback-image-attachments.ts
  • src/main/codex-usage/scanner.ts
  • src/cli/runtime/environments.ts
  • src/main/telemetry/client.ts
  • src/main/github/project-view/internals.ts
  • src/renderer/src/lib/active-agent-note-send.ts
  • src/main/observability/index.ts
  • src/renderer/src/lib/workspace-port-actions.ts
  • src/renderer/src/lib/crash-diagnostics.ts
  • src/shared/pr-refresh-memory-limits.ts
  • src/renderer/src/constants/terminal.ts
  • src/main/github/github-api-repository.ts
  • src/renderer/src/components/settings/general-search.ts
  • src/main/git/git-username.ts
  • src/renderer/src/components/right-sidebar/commit-failure-dialog-state.ts
  • src/main/ssh/sftp-upload.ts
  • src/shared/terminal-custom-themes.ts
  • src/renderer/src/lib/keyboard-layout/option-as-alt-probe.ts
  • src/main/runtime/rpc/schemas.ts
  • src/renderer/src/components/sidebar/create-project-defaults.ts
  • src/main/runtime/orchestration/groups.ts
  • src/renderer/src/components/github-project/column-widths.ts
  • src/renderer/src/components/settings/terminal-windows-search.ts
  • src/renderer/src/components/right-sidebar/source-control-active-open-file-keys.ts
  • src/renderer/src/components/native-chat/native-chat-composer-state.ts
  • src/shared/terminal-title-display.ts
  • src/renderer/src/components/right-sidebar/file-explorer-operation-owner.ts
  • src/shared/ssh-retained-payload-admission.ts
  • src/renderer/src/components/repo/repo-icon.tsx
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.ts
  • src/main/daemon/terminal-private-mode-tracker.ts
  • src/main/rate-limits/grok-auth.ts
  • src/renderer/src/components/terminal-pane/pty-pre-handler-buffer.ts
  • src/main/pi/titlebar-extension-service.ts
  • src/shared/remote-runtime-memory-limits.ts
  • src/shared/pty-source-credit-contract.ts
  • src/shared/remote-runtime-shared-control-state.ts
  • src/shared/agent-session-host-authority.ts
  • src/renderer/src/components/terminal-pane/pty-delivery-interest.ts
  • src/shared/linux-proc-port-scan-limits.ts
  • src/renderer/src/components/emulator-pane/emulator-pane-types.ts
  • src/shared/agent-session-option-catalog.ts
  • src/main/ipc/parcel-watcher-host-subscriptions.ts
  • src/shared/wsl-hook-relay-contract.ts
  • src/main/emulator/emulator-types.ts
  • src/main/github/github-enterprise-repository.ts
  • src/main/ssh/ssh-pty-consumer-session.ts
  • src/renderer/src/store/slices/runtime-detected-agents.ts
  • src/main/ssh/ssh-relay-session.test.ts
  • src/shared/remote-workspace-types.ts
  • src/shared/terminal-title-status.ts
  • src/main/shell-ready-marker-scanner.ts
  • src/renderer/src/components/browser-pane/browser-page-zoom.ts
  • src/main/plugins/plugin-enablement.ts
  • src/shared/commit-message-generation.ts
  • src/main/observability/instrumentation.ts
  • src/main/providers/pty-process-list-admission.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-push-failure-launch.ts
  • src/main/runtime/orca-runtime-emulator.ts
  • src/renderer/src/components/right-sidebar/CreateHostedReviewComposer.tsx
  • src/shared/runtime-environments.ts
  • src/shared/ephemeral-vm-runtimes.ts
  • src/shared/custom-pet-media-limits.ts
  • src/shared/terminal-size-limits.ts
  • src/main/observability/redactor.ts
  • src/shared/left-sidebar-appearance.ts
  • src/main/ssh/ssh-relay-session-managed-hooks.test.ts
  • src/renderer/src/components/github/github-issue-comment-helpers.ts
  • src/shared/linear-agent-access.ts
  • src/renderer/src/components/sidebar/workspace-kanban-card-drag-preview-dom.ts
  • src/renderer/src/hooks/useShortcutLabel.ts
  • src/renderer/src/components/sidebar/sidebar-host-options.ts
  • src/renderer/src/components/sidebar/sidebar-nav-controls.tsx
  • src/shared/runtime-types.ts
  • src/shared/native-file-drop.ts
  • src/shared/hosted-review.ts
  • src/renderer/src/components/browser-pane/browser-automation-visibility.ts
  • src/main/pi/prefill-extension-source.ts
  • src/renderer/src/components/tab-bar/tab-create-entry-path-validation.ts
  • src/renderer/src/components/terminal/terminal-tab-actions.ts
  • src/shared/daemon-lifecycle-telemetry.ts
  • src/main/system-fonts.ts
  • src/shared/hermes-run-ref-retention.ts
  • src/renderer/src/components/onboarding/use-onboarding-flow.ts
  • src/renderer/src/components/tab-bar/shell-icons.tsx
  • src/main/computer/macos-native-provider-paths.ts
  • src/renderer/src/components/emulator-pane/emulator-keyboard-paste.ts
  • src/shared/task-source-context.ts
  • src/renderer/src/lib/ensure-simulator-tab.ts
  • src/main/git/repo.ts
  • src/renderer/src/hooks/useIssueMetadata.ts
  • src/renderer/src/components/automations/automation-page-parts.tsx
  • src/renderer/src/lib/agent-paste-draft.ts
  • src/renderer/src/components/linear-issue-workspace-text.ts
  • src/shared/runtime-bootstrap.ts
  • src/renderer/src/lib/repo-slug-index.ts
  • src/renderer/src/components/right-sidebar/source-control-ai-commit-failure-launch.test.ts
  • src/shared/hermes-run-output-limits.ts
  • src/shared/source-control-create-review-intent.ts
  • src/main/emulator/android/android-input-mapping.ts
  • src/renderer/src/components/sidebar/WorktreeCardPorts.tsx
  • src/shared/telemetry-events.ts
  • src/renderer/src/lib/active-agent-note-target.ts
  • src/main/claude-usage/scanner.ts
  • src/renderer/src/components/right-sidebar/push-failure-summary.ts
  • src/renderer/src/components/editor/markdown-round-trip.ts
  • src/shared/terminal-scrollback-policy.ts
  • src/main/ipc/runtime-environment-request-connections.ts
  • src/shared/daemon-audit-eligibility.ts
  • src/renderer/src/components/right-sidebar/source-control-primary-action-types.ts
  • src/main/ipc/parcel-watcher-process.ts
  • src/shared/serve-update-handoff.ts
🛑 Comments failed to post (2)
config/knip.json (2)

38-38: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== config/knip.json =="
cat -n config/knip.json

echo
echo "== package.json and lockfile type deps =="
for f in package.json package-lock.json pnpm-lock.yaml yarn.lock bun.lockb; do
  if [ -f "$f" ]; then
    echo "-- $f lines 1-120 (if text) --"
    sed -n '1,120p' "$f" | cat -n
  fi
done

echo
echo "== package manifests with `@types` packages =="
python3 - <<'PY'
import json, pathlib
for p in pathlib.Path('.').glob('**/package.json'):
    data=json.loads(p.read_text())
    for k in ('dependencies','devDependencies','peerDependencies','optionalDependencies'):
        vals=data.get(k,{})
        if any(k2.startswith('`@types/`') for k2 in vals):
            print(p)
            for kk,v in vals.items():
                if kk.startswith('`@types/`'):
                    print(f'  {k}:{kk}={v}')
PY

echo
echo "== Knip config settings relevant to type dependency detection =="
rg -n '"ignoreDependencies"|"directoryDependencies"|"ignoreBinaries"|"ignoreDependencies"' config/knip.json package.json || true

Repository: stablyai/orca

Length of output: 50370


🌐 Web query:

Knip reference configuration ignoreDependencies type-definition obsolete packages deprecated

💡 Result:

In Knip, the ignoreDependencies configuration option allows you to exclude specific packages from the unused dependency report [1][2]. It is intended as a last-resort solution when Knip cannot automatically detect the usage of a dependency, such as in cases of complex dynamic imports or conditional dependencies [3][4]. Configuration details: The option accepts an array of package names or regular expressions [1][2]. It can be defined in your knip.json or dynamic configuration files (e.g., knip.ts) [1][2]. Example (knip.json): { "ignoreDependencies": ["hidden-package", "@org/.+"] } Example (knip.ts): export default { ignoreDependencies: [/@org/.*/, /^lib-.+/], }; Regarding obsolete or deprecated type-definition packages: Knip has built-in support for identifying unused @types/ packages [5][4]. It automatically checks the package.json of dependencies to see if they bundle their own type definitions (via the "types" or "typings" fields) [5]. When a package bundles its own types, any corresponding @types/ package that you have installed is often redundant and can be reported as unused by Knip [6][5]. If Knip fails to flag an obsolete @types/ package or incorrectly reports a dependency, it is recommended to: 1. Ensure your entry and project file patterns are correctly configured to provide full coverage of your codebase [3][4]. 2. Verify if a plugin is missing or if the current plugin requires an update [3][4]. 3. Only use ignoreDependencies as a final workaround after verifying these primary configurations [3][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== all package.json ignoreDependencies =="
rg -n '"ignoreDependencies"' package.json config/knip.json pnpm-lock.yaml --glob 'package.json' --glob 'knip.json' --glob 'pnpm-lock.yaml' || true

echo
echo "== root `@types` packages in lockfile =="
python3 - <<'PY'
import yaml, json, pathlib
p=pathlib.Path('pnpm-lock.yaml')
if p.exists():
    data=yaml.safe_load(p.read_text())
    for sec in ('dependencies','devDependencies','peerDependencies','optionalDependencies'):
        imports=data.get('importers',{}).get('.',{}).get(sec,{})
        for name, spec in sorted(imports.items()):
            if name.startswith('`@types/`'):
                print(f"{sec}:{name}={spec.get('version') or spec}")
PY

echo
echo "== static probe: `@types/`* coverage with single ignore pattern =="
python3 - <<'PY'
import json, re
with open('config/knip.json') as f:
    cfg=json.load(f)
with open('package.json') as f:
    pkg=json.load(f)
root_types=[]
for section in ('devDependencies','dependencies','peerDependencies','optionalDependencies'):
    root_types.extend(pkg.get(section,{}).keys)
pattern=re.compile('^(`@types`|electron)(/.+)?$') # package entry-level shape equivalent to "electron" and "`@types/`*"
matches=[p for p in root_types if pattern.match(p)]
print(f"root package count: {len(root_types)}")
print(f"root `@types/electron` packages matching ignoreDependencies in config/knip.json line 38:")
print(sorted(matches))
PY

Repository: stablyai/orca

Length of output: 420


🏁 Script executed:

#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json, re
from pathlib import Path
p=Path('pnpm-lock.yaml')
text=p.read_text()
section=None
root={}
for line in text.splitlines():
    if line.startswith('  ') or line.startswith('    '):
        continue
    if line in ('dependencies:', 'devDependencies:', 'peerDependencies:', 'optionalDependencies:'):
        section=line.rstrip(':')
        continue
    if section and line.startswith('  `@types/`'):
        name=line.split(':',1)[0].strip()
        root[name]=(text=text) # placeholder placeholder
PY

echo "== root package names containing `@types/` =="
python3 - <<'PY'
from pathlib import Path
import re
text=Path('pnpm-lock.yaml').read_text()
root=[]
section=None
for line in text.splitlines():
    if line in ('dependencies:', 'devDependencies:', 'peerDependencies:', 'optionalDependencies:'):
        section=line.rstrip(':')
    elif section in ('dependencies','devDependencies','peerDependencies','optionalDependencies') and line.startswith('  ') and not line.startswith('    '):
        section=None
    elif section in ('dependencies','devDependencies','peerDependencies','optionalDependencies') and re.fullmatch(r'  `@types/`.+', line):
        root.append(line.strip().rstrip(':'))
print(text='root `@types` packages')
PY

Repository: stablyai/orca

Length of output: 280


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== root `@types` package names =="
python3 - <<'PY'
import re
from pathlib import Path
text = Path('pnpm-lock.yaml').read_text()
section = None
root = []
for line in text.splitlines():
    if line in ('dependencies:', 'devDependencies:', 'peerDependencies:', 'optionalDependencies:'):
        section = line.rstrip(':')
    elif section in ('dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies') \
            and line.startswith('  ') and not line.startswith('    '):
        section = None
    elif section in ('dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies') \
            and re.fullmatch(r'  `@types/`.+', line):
        root.append(line.strip().rstrip(':'))
print(f"count: {len(root)}")
for name in root:
    print(name)
PY

echo
echo "== deterministic matcher for Knip ignoreDependencies =="
python3 - <<'PY'
import json
import re
patterns = json.loads(Path('config/knip.json').read_text())['ignoreDependencies']
matches = []
for pkg in Path('pnpm-lock.yaml').read_text().splitlines():
    if re.match(r'  `@types/`.+', pkg):
        name = pkg.strip().rstrip(':')
        if any(re.fullmatch(p.replace('*', '.*'), name) for p in patterns):
            matches.append(name)
print(f"config ignores {len(patterns)} patterns")
print(f"root `@types` packages ignored by config/knip.json: {len(matches)}")
for m in matches:
    print(m)
PY

Repository: stablyai/orca

Length of output: 360


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY' from pathlib import Path
import json, re
text = Path('pnpm-lock.yaml').read_text()
section = None
root = []
for line in text.splitlines():
    if line in ('dependencies:', 'devDependencies:', 'peerDependencies:', 'optionalDependencies:'):
        section = line.rstrip(':')
    elif section in ('dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies') \
            and line.startswith('  ') and not line.startswith('    '):
        section = None
    elif section in ('dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies') \
            and re.fullmatch(r'  `@types/`.+', line):
        root.append(line.strip().rstrip(':'))
print(f"count: {len(root)}")
for name in root:
    print(name)
PY

Repository: stablyai/orca

Length of output: 262


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import json, re

text = Path('pnpm-lock.yaml').read_text()
section = None
root = []
for line in text.splitlines():
    if line in ('dependencies:', 'devDependencies:', 'peerDependencies:', 'optionalDependencies:'):
        section = line.rstrip(':')
    elif (
        section in ('dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies')
        and line.startswith('  ')
        and not line.startswith('    ')
    ):
        section = None
    elif (
        section in ('dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies')
        and re.fullmatch(r'  `@types/`.+', line)
    ):
        root.append(line.strip().rstrip(':'))

print(f"root `@types` package count: {len(root)}")
for name in root:
    print(name)

patterns = json.loads(Path('config/knip.json').read_text())['ignoreDependencies']
matches = []
for name in root:
    if any(re.fullmatch(p.replace('*', '.*'), name) for p in patterns):
        matches.append(name)

print(f"\nroot `@types` packages ignored by config/knip.json: {len(matches)}")
for m in matches:
    print(m)
PY

Repository: stablyai/orca

Length of output: 233


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

text = Path('pnpm-lock.yaml').read_text()
root = set()
impt = ''

for line in text.splitlines():
    if line in ('dependencies:', 'devDependencies:', 'peerDependencies:', 'optionalDependencies:'):
        impt = line.rstrip(':')
        continue
    if impt and line.startswith('  ') and not line.startswith('    '):
        impt = ''
        continue
    if impt and re.fullmatch(r'  `@types/`.+', line):
        root.add(line.strip().rstrip(':'))

print("root `@types` package count:", len(root))
print("\nroot `@types` package names:")
for name in sorted(root):
    print(name)
PY

Repository: stablyai/orca

Length of output: 208


🌐 Web query:

Knip type definitions unused @types packages documentation

💡 Result:

Knip handles @types packages by analyzing your project for usage, but it can occasionally report them as unused if they are implicitly loaded or incorrectly classified. ### How Knip handles @types packages Knip identifies unused @types packages by tracking which types are loaded by your project's TypeScript configuration and source code [1][2]. 1. Bundled Types: If a package begins bundling its own type definitions (e.g., in package.json#types), the corresponding @types package becomes obsolete. Knip is designed to detect this and report the @types package as unused [1][3]. 2. Production vs. Development: In strict mode, Knip expects type-only imports to reside in devDependencies. However, if these types are part of a library's public API (exposed via emitted.d.ts files), they must be listed in dependencies to avoid breakage for consumers [1][4]. Recent updates allow Knip to analyze the public type graph from your declaration files to ensure these are correctly classified [4]. ### Common reasons for false positives If Knip reports an @types package as unused, but you believe it is necessary, consider these factors: - Ambient/Global Types: TypeScript automatically loads types from @types packages if they are in the node_modules/@types folder or referenced in tsconfig.json. Because these are loaded globally rather than via explicit imports, Knip may not detect their usage [5][6]. - Missing Build Artifacts: Knip's analysis of public types relies on existing declaration output (.d.ts files). If your project is not built, it cannot verify which types are exposed [1][4]. - Configuration Gaps: Ensure your tsconfig.json and project entry points are correctly configured. Knip follows the graph defined by your configuration; if entry files are missing, dependencies may appear unused [1][2]. ### How to resolve issues - Remove Obsolete Packages: If a package now bundles its own types, simply remove the @types dependency [1][3]. - Use ignoreDependencies: If an @types package is required globally or for reasons Knip cannot trace, add it to the ignoreDependencies list in your knip.json configuration [3]. - Check for Build Issues: If you are a library author, ensure your declaration files are generated so Knip can correctly identify production type requirements [4].

Citations:


Remove the @types/* dependency ignore.

ignoreDependencies should only exclude packages that cannot be detected as unused. Knip is designed to handle @types/* packages, including obsolete sibling type definitions, so a wildcard ignore hides valid dependency findings. Remove the wildcard and only add verified exceptions if a specific package must be ignored.


40-40: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files | rg '(^|/)knip\.json$|package\.json$|tsconfig.*\.json$' || true

echo
if [ -f config/knip.json ]; then
  echo "config/knip.json:"
  cat -n config/knip.json
fi

echo
echo "Package scripts/deps around knip:"
if [ -f package.json ]; then
  node - <<'JS'
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json','utf8'));
console.log(JSON.stringify({
  scripts: pkg.scripts,
  devDependencies: pkg.devDependencies,
  dependencies: pkg.dependencies
}, null, 2));
JS
fi

echo
echo "Search for entry declarations / knip configuration:"
rg -n '"entry"\s*:|includeEntryExports|knip' -S --glob '!node_modules' --glob '!dist' --glob '!build' .

Repository: stablyai/orca

Length of output: 19864


🌐 Web query:

knip reference configuration includeEntryExports self-contained repositories entry exports

💡 Result:

In Knip, includeEntryExports is a configuration option that controls whether unused exports should be reported in entry files [1][2]. By default, Knip does not report unused exports in entry files because they are considered the starting points of the codebase, and their exports are often intended to be consumed externally [1][3]. However, in self-contained repositories, private packages, or specific workspaces where you want to ensure that all exported members are actually consumed within the project, you can enable this behavior [1][2]. You can enable this feature using the following methods: Configuration File: Add "includeEntryExports": true to your knip.json (or other supported configuration formats) [1][2]. This can be set at the root level for global application or within individual workspace configurations [1][2]. CLI Argument: Use the --include-entry-exports flag when running the command [4]. Important Considerations: - Scope: When enabled, Knip reports unused exports in entry source files [1][2]. It does not, however, report unused exports in entry and configuration files handled by plugins (e.g., next.config.js, src/routes/+page.svelte) [1][2]. - Members: Enabling this option also instructs Knip to report unused members of exported enums and namespaces, which are otherwise ignored [1][3][2]. - False Positives: Because this setting can increase the number of reported issues, it is often recommended to use it selectively in workspaces where strict export usage is required [5].

Citations:


Enable unused-export checks for entry files in the dead-code audit.

This repository is a self-contained application, and audit:dead-code runs Knip with entry declarations for multiple application roots and workers. includeEntryExports: false suppresses unused exports from those files. Set it to true if the exports should be used within the project.

Proposed fix
-  "includeEntryExports": false
+  "includeEntryExports": true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  "includeEntryExports": true

… module

src/relay/relay-frame-decoder.ts and src/main/ssh/relay-frame-decoder.ts
were 264 identical lines apart from one default: the relay logs decode
faults to stderr when no handler is supplied, the SSH side stays silent.
Two copies of framing logic is exactly where a wire-format fix lands in one
and not the other.

The decoder's contract and buffer already live in src/shared, so the class
joins them there. The relay keeps a thin subclass that supplies its stderr
default, preserving behaviour for the call sites that omit onError. The
SSH copy is deleted and relay-protocol.ts points at shared directly.

Verified: pnpm typecheck, 102 tests across the 9 framing/backpressure/
handshake suites, and `pnpm build:relay` for all six platform targets plus
the WSL hook relay — the standalone bundle has no new dependencies.
@nwparker
nwparker force-pushed the nwparker/slim-dedupe-frame-decoder branch from ddae63a to db0f74d Compare August 2, 2026 07:52
@nwparker
nwparker merged commit 673d7ca into stablyai:main Aug 2, 2026
43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant