Skip to content

feat(terminal): add first-class Herdr runtime#9440

Open
rudironsoni wants to merge 4 commits into
stablyai:mainfrom
rudironsoni:feat/herdr-runtime
Open

feat(terminal): add first-class Herdr runtime#9440
rudironsoni wants to merge 4 commits into
stablyai:mainfrom
rudironsoni:feat/herdr-runtime

Conversation

@rudironsoni

@rudironsoni rudironsoni commented Jul 19, 2026

Copy link
Copy Markdown

Summary

Motivation

Today Orca's PTY daemon owns the lifetime of project terminals. That works while Orca is the only runtime involved, but it couples terminal processes to Orca's lifecycle: closing or restarting the desktop app cannot behave like detaching from a terminal multiplexer and later reattaching to the same live processes, layout, and scrollback.

Herdr already provides the durable session and terminal-control primitives needed to solve that problem. The goal of this integration is therefore deeper than launching Herdr inside an Orca terminal. Herdr becomes an optional terminal runtime behind Orca's existing terminal surfaces, so users keep the Orca UI while gaining multiplexer semantics:

  • one logical named Herdr session per Orca project on each participating execution host;
  • one Herdr workspace per Orca worktree;
  • one Herdr tab per Orca terminal tab;
  • one Herdr pane per Orca terminal layout leaf.

Closing Orca then releases its terminal controllers without destroying the Herdr graph or its processes. Reopening the project reconciles the persisted Orca presentation state with the same Herdr resources and reattaches to them.

This is deliberately opt-in. Existing users and projects continue to use Orca's PTY runtime unless they select Herdr globally or for a specific project.

Design rationale

Keep Orca as the product surface and Herdr as terminal authority

Orca continues to own project/worktree metadata, unified-tab placement, and presentation-only state. Herdr owns the terminal graph and runtime state: workspace/tab/pane identity, PTY lifetime, layout, cwd, title, history, process information, and writable-controller ownership.

This boundary avoids two competing sources of truth. Terminal mutations initiated by Orca are routed through Herdr, while editor, diff, browser, simulator, and other non-terminal Orca tabs remain unchanged.

Use durable external identities instead of Herdr's internal IDs

Orca assigns every managed Herdr resource an external_ref with owner: "orca" and a stable project/worktree/tab/pane identity. Reconciliation uses those references to find, create, or safely adopt resources.

Herdr's internal numeric IDs can therefore change without breaking Orca persistence. Reordering tabs, restarting Orca, or reconnecting after an event gap does not create duplicate terminal graphs.

Integrate at the PTY provider boundary

The new HerdrPtyProvider wraps Orca's existing provider and selects the backend from persisted project/host activation state. Non-Herdr targets continue through the existing provider. Herdr targets expose the same Orca PTY operations, including spawn/attach, input, resize, snapshots, clear, process inspection, signals, detach, and destructive close.

This keeps renderer and CLI behavior consistent. Runtime terminal responses also expose backend: "orca" | "herdr", making the active backend observable without relying on encoded PTY IDs.

Treat detach and close as different lifecycle operations

  • Quitting or restarting Orca disposes controller bindings and leaves Herdr sessions, panes, and child processes alive.
  • Restoring Orca reattaches to the persisted Herdr identities and requests an authoritative terminal frame/history snapshot.
  • Closing a terminal pane or tab explicitly closes the corresponding Herdr resource and waits for its process to stop.
  • Switching a project back to Orca detaches from Herdr. It does not silently destroy the persistent Herdr session.

That distinction is the core user-facing reason for the integration.

Fail explicitly instead of silently changing runtime

When a project is configured for Herdr, missing binaries, incompatible protocol capabilities, invalid managed manifests, checksum failures, transport timeouts, and SSH provisioning failures are surfaced as Herdr errors. Orca does not silently fall back to its legacy PTY provider, because doing so would split one project's terminal graph across two authorities and make persistence behavior unpredictable.

What this PR changes

Backend selection and compatibility

  • Adds an Orca / Herdr global terminal-backend setting.
  • Adds per-project Inherit / Orca / Herdr overrides.
  • Persists the active backend independently per project and execution host.
  • Migrates existing persisted projects to an explicit ready orca activation, preserving current behavior after upgrade.
  • Blocks Orca-to-Herdr activation while legacy project PTYs are still live. The user must close them first, preventing an unsafe partial handoff.
  • Persists migration identity and phase instead of treating backend selection as an instantaneous settings flip.

Herdr graph reconciliation

  • Derives a stable Herdr session name from the Orca project, with support for a persisted custom name.
  • Reconciles worktrees, terminal tabs, split layouts, and panes through stable Orca-owned external references.
  • Serializes reconciliation per session to prevent concurrent duplicate creation.
  • Adopts a resource only when there is one unambiguous compatible match.
  • Subscribes to sequenced Herdr events after a snapshot revision, ignores duplicates, and resnapshots on gaps, stale cursors, or transport interruption.

Terminal control and persistence

  • Routes terminal frames, input, resize, history reads, clear, signals, cwd/title/process queries, detach, and close through Herdr.
  • Uses explicit controller acquisition/release so Orca can detach without terminating the pane.
  • Restores persisted herdr: PTY identities during workspace-session recovery.
  • Makes CLI/runtime terminal inspection report the selected backend directly.
  • Preserves split layout state across headless CLI operations and rolls it back when terminal creation/reveal fails.

Local, packaged, and SSH execution

Users can select one of three Herdr binary sources:

  • Managed: a platform/architecture-specific sidecar shipped with Orca;
  • System: herdr resolved from the execution host's PATH;
  • Custom: an explicit executable path.

Managed distributions are verified before launch using their manifest identity, protocol version, required capabilities, license presence, and SHA-256. SSH hosts receive the matching verified distribution in a content-addressed directory. Host-level source overrides take precedence over the global setting.

This PR adds the packaging layout and verification path, but does not commit Herdr binaries. Release automation must stage the matching binary, LICENSE, and manifest.json. Shipping the managed sidecar remains subject to the Herdr AGPL/commercial distribution decision.

End-to-end behavior covered

The real-runtime Playwright scenario builds on the corresponding Herdr branch and verifies the complete lifecycle:

  1. Configure Herdr as the terminal backend and create a project terminal.
  2. Confirm Orca reports backend: "herdr".
  3. Send input and observe output through Orca.
  4. Create a split containing a long-running child process.
  5. close Orca and confirm the Herdr session remains running;
  6. reopen Orca, reattach to both original panes, and recover prior output;
  7. confirm detach did not stop the child process;
  8. explicitly close the tab and confirm the child process exits.

Focused tests also cover backend resolution and migration blocking, legacy persistence backfill, project/worktree/tab/pane identity, graph reconciliation and adoption, split translation, event replay gaps and retries, provider routing and lifecycle, binary-source validation, SSH transport/provisioning, CLI backend reporting, and settings behavior.

Screenshots

No screenshot attached. The visual change is limited to terminal-backend controls in global Terminal settings and per-project settings. It uses the existing SettingsRow, SettingsSegmentedControl, and Input primitives without introducing a new layout or interaction pattern.

Testing

  • pnpm lint (the complete command reaches the pre-existing src/main/ssh/ssh-relay-session.test.ts max-lines violation: 803 lines against the 800-line limit)
  • pnpm typecheck
  • pnpm test (the full repository suite was not run)
  • pnpm run build:desktop
  • Added or updated high-quality regression tests for the reviewed failure modes

Additional verification:

  • focused Vitest scope: 1,250 passed, 1 intentionally skipped
  • changed-scope oxlint: no findings
  • oxfmt --check: passed for all changed files
  • reliability gate manifest: 44 gates passed
  • max-lines ratchet: no new bypasses
  • localization catalog parity and coverage passed
  • git diff --check upstream/main...HEAD
  • desktop, relay, CLI, Electron, renderer, and web production builds passed
  • real Herdr runtime Playwright lifecycle test from the implementation pass

The build runs under Node 22 in this checkout while the repository requests Node 24. It completed successfully. The development CLI installer also reported that it could not create /usr/local/bin/orca-dev; that optional machine-level symlink did not fail the build.

AI Review Report

The review covered every unresolved CodeRabbit thread and the integration's highest-risk boundaries:

  • rejected managed manifests with missing protocol metadata and prevented failed verification from caching an unverified executable;
  • converted malformed local and SSH terminal frames into deterministic terminal.closed events instead of uncaught exceptions;
  • bounded SSH provisioning commands so an opened but stalled channel cannot hang activation indefinitely;
  • made resolved host/project identity authoritative and made persisted-project lookup precedence deterministic;
  • allowed explicit IPC clearing through null without relying on structured-clone behavior for undefined;
  • deduplicated destructive Herdr closes and allowed all panes to receive teardown even if one close fails;
  • separated the routed SSH provider used for event delivery from the raw relay provider required for reconnect and disposal;
  • retained English settings-search keywords intentionally and recorded six narrow localization-coverage exclusions.

Cross-platform behavior was checked for macOS, Linux, and Windows. Path selection remains behind path.join and platform descriptors, managed binary names preserve herdr.exe on Windows, SSH provisioning uses the existing remote-platform command/path helpers, and no keyboard shortcut or platform-label behavior changed.

Security Audit

  • Managed binaries are accepted only after executable/license checks, manifest source identity, protocol/capability compatibility, and SHA-256 verification. Verification must succeed before the executable path is cached.
  • Custom and system binary sources remain explicit user choices. Selecting Herdr never silently falls back to another runtime.
  • IPC updates are validated with Zod; only the three clearable Herdr project fields accept null.
  • Local Herdr commands continue to use spawn(file, args) rather than shell interpolation. SSH commands use Orca's existing escaping and platform-specific command builders.
  • Managed SSH provisioning now has a 15-second command deadline and closes stalled channels.
  • No credentials, tokens, new dependencies, or new network services are introduced.

Follow-up remains necessary before distributing a managed Herdr binary: publish a capability-compatible upstream build, stage signed manifests/checksums, and complete the AGPL/commercial sidecar distribution review.

Notes

CodeRabbit's generic docstring-coverage warning is intentionally not addressed with boilerplate comments. Orca's repository guidance requires concise comments for non-obvious rationale, and the new modules already document those constraints where they matter.

The Herdr branch is currently awaiting that repository's first-time-contributor approval path before it can be proposed upstream.

@rudironsoni rudironsoni changed the title feat(terminal): add Herdr runtime integration feat(terminal): add first-class Herdr runtime Jul 19, 2026
@rudironsoni
rudironsoni force-pushed the feat/herdr-runtime branch 2 times, most recently from 5898a52 to 3806903 Compare July 20, 2026 08:05
@rudironsoni
rudironsoni marked this pull request as ready for review July 20, 2026 08:07
Copilot AI review requested due to automatic review settings July 20, 2026 08:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds managed Herdr sidecar packaging and validation, CLI and SSH transports, runtime reconciliation, event watching, and Herdr-backed PTY providers. Terminal backend settings, project activation state, persistence migrations, IPC schemas, and renderer controls are added. Terminal layout snapshots now flow through PTY spawning and headless split handling. Runtime output identifies the active backend, and daemon and SSH relay lifecycles route providers through Herdr. Unit, integration, persistence, UI, packaging, and end-to-end tests cover the new behavior.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.20% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly summarizes the main change: introducing an opt-in Herdr terminal runtime.
Description check ✅ Passed The description follows the template with all required sections and detailed testing, review, security, and notes content.

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.

@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: 10


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ba2bebe9-43b4-48b5-8eba-cd2c6b745d07

📥 Commits

Reviewing files that changed from the base of the PR and between 257b0b4 and 3806903.

📒 Files selected for processing (79)
  • config/electron-builder.config.cjs
  • config/scripts/electron-builder-config.test.mjs
  • resources/herdr/README.md
  • resources/herdr/darwin-arm64/.gitkeep
  • resources/herdr/darwin-x64/.gitkeep
  • resources/herdr/linux-arm64/.gitkeep
  • resources/herdr/linux-x64/.gitkeep
  • resources/herdr/win32-arm64/.gitkeep
  • resources/herdr/win32-x64/.gitkeep
  • src/cli/format.test.ts
  • src/cli/terminal-format.ts
  • src/main/codex-accounts/runtime-home-service.test.ts
  • src/main/codex-accounts/service.test.ts
  • src/main/daemon/daemon-init.ts
  • src/main/herdr/herdr-binary-source.test.ts
  • src/main/herdr/herdr-binary-source.ts
  • src/main/herdr/herdr-cli-host-transport.ts
  • src/main/herdr/herdr-created-root-bindings.ts
  • src/main/herdr/herdr-event-subscription.test.ts
  • src/main/herdr/herdr-event-subscription.ts
  • src/main/herdr/herdr-existing-tab-root.ts
  • src/main/herdr/herdr-managed-ssh-provisioner.ts
  • src/main/herdr/herdr-project-pty-target.test.ts
  • src/main/herdr/herdr-project-pty-target.ts
  • src/main/herdr/herdr-provider-factory.test.ts
  • src/main/herdr/herdr-provider-factory.ts
  • src/main/herdr/herdr-pty-codec.ts
  • src/main/herdr/herdr-pty-provider-base.ts
  • src/main/herdr/herdr-pty-provider.test.ts
  • src/main/herdr/herdr-pty-provider.ts
  • src/main/herdr/herdr-pty-queries.ts
  • src/main/herdr/herdr-pty-types.ts
  • src/main/herdr/herdr-real-runtime.integration.test.ts
  • src/main/herdr/herdr-reconcile-index.ts
  • src/main/herdr/herdr-runtime-contract.test.ts
  • src/main/herdr/herdr-runtime-contract.ts
  • src/main/herdr/herdr-runtime-graph.ts
  • src/main/herdr/herdr-runtime-manager.test.ts
  • src/main/herdr/herdr-runtime-manager.ts
  • src/main/herdr/herdr-session-watcher.ts
  • src/main/herdr/herdr-ssh-host-transport.ts
  • src/main/herdr/herdr-worktree-descriptor.ts
  • src/main/index.ts
  • src/main/ipc/pty.ts
  • src/main/ipc/repos.ts
  • src/main/persistence.test.ts
  • src/main/persistence.ts
  • src/main/providers/types.ts
  • src/main/runtime/claude-agent-teams-service.test.ts
  • src/main/runtime/headless-terminal-split-layout.test.ts
  • src/main/runtime/headless-terminal-split-layout.ts
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/project-runtime-rpc-methods.ts
  • src/main/ssh/ssh-relay-session-terminal-error.test.ts
  • src/main/ssh/ssh-relay-session.test.ts
  • src/main/ssh/ssh-relay-session.ts
  • src/preload/api-types.ts
  • src/renderer/src/components/settings/ProjectTerminalBackendSetting.test.tsx
  • src/renderer/src/components/settings/ProjectTerminalBackendSetting.tsx
  • src/renderer/src/components/settings/RepositoryPane.tsx
  • src/renderer/src/components/settings/TerminalBackendSection.test.tsx
  • src/renderer/src/components/settings/TerminalBackendSection.tsx
  • src/renderer/src/components/settings/TerminalPane.tsx
  • src/renderer/src/components/settings/terminal-search.ts
  • src/renderer/src/components/terminal-pane/pty-connection.ts
  • src/renderer/src/components/terminal-pane/pty-transport-types.ts
  • src/renderer/src/components/terminal-pane/pty-transport.test.ts
  • src/renderer/src/components/terminal-pane/pty-transport.ts
  • src/shared/constants.ts
  • src/shared/herdr-session-identity.test.ts
  • src/shared/herdr-session-identity.ts
  • src/shared/host-setting-overrides.ts
  • src/shared/runtime-types.ts
  • src/shared/terminal-backend.test.ts
  • src/shared/terminal-backend.ts
  • src/shared/types.ts
  • tests/e2e/helpers/orca-restart.ts
  • tests/e2e/herdr-terminal-runtime.spec.ts

Comment thread src/main/herdr/herdr-binary-source.ts
Comment thread src/main/herdr/herdr-cli-host-transport.ts Outdated
Comment thread src/main/herdr/herdr-managed-ssh-provisioner.ts
Comment thread src/main/herdr/herdr-project-pty-target.ts
Comment thread src/main/herdr/herdr-provider-factory.ts Outdated
Comment thread src/main/herdr/herdr-provider-factory.ts
Comment thread src/main/ipc/repos.ts
Comment thread src/main/runtime/orca-runtime.ts Outdated
Comment thread src/main/ssh/ssh-relay-session.ts Outdated
Comment thread src/renderer/src/components/settings/terminal-search.ts Outdated
@rudironsoni

Copy link
Copy Markdown
Author

Addressed the complete CodeRabbit review in ef19540c2 and resolved all 10 inline threads.

The PR description now follows the repository template with Summary, Screenshots, Testing, AI Review Report, Security Audit, and Notes. It includes the cross-platform review, security-sensitive command/IPC/path handling, current validation evidence, and the remaining managed-sidecar release gates.

Validation after the final rebase:

  • pnpm typecheck
  • focused Vitest scope: 1,250 passed, 1 intentionally skipped
  • changed-scope oxlint
  • oxfmt --check on all changed files
  • 44 reliability gates
  • max-lines ratchet
  • localization catalog parity and coverage
  • pnpm run build:desktop
  • git diff --check upstream/main...HEAD

The complete pnpm lint command still stops on the pre-existing src/main/ssh/ssh-relay-session.test.ts max-lines violation (803 lines against 800); this change adds no new max-lines bypass. The generic docstring-coverage warning was not handled by adding boilerplate because Orca's repository guidance requires concise comments for non-obvious rationale instead.

@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: 1

🧹 Nitpick comments (3)
src/main/herdr/herdr-project-pty-target.test.ts (2)

22-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract a shared store-mock factory to remove duplication.

The { getSettings, getProjects, getWorkspaceSession } object is re-built nearly identically in six of the seven tests (also at lines 69-76, 108-115, 130-134, 148-152), varying only in terminalBackendDefault and terminalLayoutsByTabId. A small helper would reduce repetition and make future store-contract changes a one-line update.

♻️ Proposed helper
+function createFloatingStore(
+  backend: 'orca' | 'herdr',
+  terminalLayoutsByTabId: Record<string, unknown> = {}
+) {
+  return {
+    getSettings: () => ({ terminalBackendDefault: backend }),
+    getProjects: () => [],
+    getWorkspaceSession: () => ({ tabsByWorktree: {}, terminalLayoutsByTabId })
+  } as unknown as Store
+}
+
 describe('Herdr PTY target resolution', () => {
   it('leaves floating terminals on Orca when Herdr is not selected', async () => {
-    const store = {
-      getSettings: () => ({ terminalBackendDefault: 'orca' }),
-      getProjects: () => [],
-      getWorkspaceSession: () => ({ tabsByWorktree: {}, terminalLayoutsByTabId: {} })
-    } as unknown as Store
+    const store = createFloatingStore('orca')

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

Consider a short inline comment on the layout-merge rationale.

Tests 3 and 4 encode a "prefer the fuller/more-complete layout graph" heuristic between renderer-supplied and persisted terminalLayout. This isn't obvious from the code itself (only from the it title); a one-line comment near the assertion on why the renderer vs. persisted layout wins would help future readers.

As per coding guidelines, "For non-obvious TypeScript code, add a concise comment explaining why the constraint exists, not how the code works."

Source: Coding guidelines

src/main/runtime/orca-runtime.ts (1)

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

Make the fallback explicit for missing layouts.

Spreading undefined inside an object literal evaluates to an empty object without crashing, but explicitly providing a fallback clarifies the intent and protects against strict TypeScript configurations if terminalLayoutsByTabId is strictly optional.

♻️ Proposed refactor
-    const terminalLayoutsByTabId = { ...session.terminalLayoutsByTabId }
+    const terminalLayoutsByTabId = { ...(session.terminalLayoutsByTabId ?? {}) }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7a5912ee-45d8-4068-a46c-2fb9f4a9f382

📥 Commits

Reviewing files that changed from the base of the PR and between 3806903 and ef19540.

📒 Files selected for processing (88)
  • config/electron-builder.config.cjs
  • config/localization-coverage-allowlist.json
  • config/scripts/electron-builder-config.test.mjs
  • resources/herdr/README.md
  • resources/herdr/darwin-arm64/.gitkeep
  • resources/herdr/darwin-x64/.gitkeep
  • resources/herdr/linux-arm64/.gitkeep
  • resources/herdr/linux-x64/.gitkeep
  • resources/herdr/win32-arm64/.gitkeep
  • resources/herdr/win32-x64/.gitkeep
  • src/cli/format.test.ts
  • src/cli/terminal-format.ts
  • src/main/codex-accounts/runtime-home-service.test.ts
  • src/main/codex-accounts/service.test.ts
  • src/main/daemon/daemon-init.ts
  • src/main/herdr/herdr-binary-source.test.ts
  • src/main/herdr/herdr-binary-source.ts
  • src/main/herdr/herdr-cli-host-transport.ts
  • src/main/herdr/herdr-created-root-bindings.ts
  • src/main/herdr/herdr-event-subscription.test.ts
  • src/main/herdr/herdr-event-subscription.ts
  • src/main/herdr/herdr-existing-tab-root.ts
  • src/main/herdr/herdr-host-transport.test.ts
  • src/main/herdr/herdr-managed-ssh-provisioner.test.ts
  • src/main/herdr/herdr-managed-ssh-provisioner.ts
  • src/main/herdr/herdr-project-pty-target.test.ts
  • src/main/herdr/herdr-project-pty-target.ts
  • src/main/herdr/herdr-provider-factory.test.ts
  • src/main/herdr/herdr-provider-factory.ts
  • src/main/herdr/herdr-pty-codec.ts
  • src/main/herdr/herdr-pty-provider-base.ts
  • src/main/herdr/herdr-pty-provider.test.ts
  • src/main/herdr/herdr-pty-provider.ts
  • src/main/herdr/herdr-pty-queries.ts
  • src/main/herdr/herdr-pty-types.ts
  • src/main/herdr/herdr-real-runtime.integration.test.ts
  • src/main/herdr/herdr-reconcile-index.ts
  • src/main/herdr/herdr-runtime-contract.test.ts
  • src/main/herdr/herdr-runtime-contract.ts
  • src/main/herdr/herdr-runtime-graph.ts
  • src/main/herdr/herdr-runtime-manager.test.ts
  • src/main/herdr/herdr-runtime-manager.ts
  • src/main/herdr/herdr-session-watcher.ts
  • src/main/herdr/herdr-ssh-host-transport.ts
  • src/main/herdr/herdr-worktree-descriptor.ts
  • src/main/index.ts
  • src/main/ipc/pty.ts
  • src/main/ipc/repos.ts
  • src/main/persistence.test.ts
  • src/main/persistence.ts
  • src/main/providers/types.ts
  • src/main/runtime/claude-agent-teams-service.test.ts
  • src/main/runtime/headless-terminal-split-layout.test.ts
  • src/main/runtime/headless-terminal-split-layout.ts
  • src/main/runtime/orca-runtime.test.ts
  • src/main/runtime/orca-runtime.ts
  • src/main/runtime/rpc/methods/project-runtime-rpc-methods.ts
  • src/main/ssh/ssh-relay-session-data-delivery.test.ts
  • src/main/ssh/ssh-relay-session-terminal-error.test.ts
  • src/main/ssh/ssh-relay-session.test.ts
  • src/main/ssh/ssh-relay-session.ts
  • src/preload/api-types.ts
  • src/renderer/src/components/settings/ProjectTerminalBackendSetting.test.tsx
  • src/renderer/src/components/settings/ProjectTerminalBackendSetting.tsx
  • src/renderer/src/components/settings/RepositoryPane.tsx
  • src/renderer/src/components/settings/TerminalBackendSection.test.tsx
  • src/renderer/src/components/settings/TerminalBackendSection.tsx
  • src/renderer/src/components/settings/TerminalPane.tsx
  • src/renderer/src/components/settings/terminal-search.ts
  • src/renderer/src/components/terminal-pane/pty-connection.ts
  • src/renderer/src/components/terminal-pane/pty-transport-types.ts
  • src/renderer/src/components/terminal-pane/pty-transport.test.ts
  • src/renderer/src/components/terminal-pane/pty-transport.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/constants.ts
  • src/shared/herdr-session-identity.test.ts
  • src/shared/herdr-session-identity.ts
  • src/shared/host-setting-overrides.ts
  • src/shared/runtime-types.ts
  • src/shared/terminal-backend.test.ts
  • src/shared/terminal-backend.ts
  • src/shared/types.ts
  • tests/e2e/helpers/orca-restart.ts
  • tests/e2e/herdr-terminal-runtime.spec.ts
🚧 Files skipped from review as they are similar to previous changes (63)
  • resources/herdr/linux-arm64/.gitkeep
  • src/shared/runtime-types.ts
  • resources/herdr/linux-x64/.gitkeep
  • src/main/herdr/herdr-worktree-descriptor.ts
  • src/main/herdr/herdr-runtime-contract.test.ts
  • resources/herdr/darwin-x64/.gitkeep
  • resources/herdr/win32-x64/.gitkeep
  • src/main/herdr/herdr-runtime-graph.ts
  • src/main/herdr/herdr-event-subscription.test.ts
  • src/main/ssh/ssh-relay-session.test.ts
  • config/scripts/electron-builder-config.test.mjs
  • src/main/runtime/orca-runtime.test.ts
  • src/renderer/src/components/settings/terminal-search.ts
  • resources/herdr/darwin-arm64/.gitkeep
  • src/main/herdr/herdr-pty-queries.ts
  • src/shared/host-setting-overrides.ts
  • src/main/herdr/herdr-created-root-bindings.ts
  • src/renderer/src/components/settings/ProjectTerminalBackendSetting.tsx
  • src/renderer/src/components/terminal-pane/pty-connection.ts
  • src/renderer/src/components/terminal-pane/pty-transport-types.ts
  • src/cli/terminal-format.ts
  • src/main/index.ts
  • src/main/codex-accounts/runtime-home-service.test.ts
  • src/main/runtime/headless-terminal-split-layout.test.ts
  • src/renderer/src/components/settings/TerminalPane.tsx
  • config/electron-builder.config.cjs
  • src/shared/herdr-session-identity.test.ts
  • src/main/herdr/herdr-runtime-manager.test.ts
  • src/main/ssh/ssh-relay-session-terminal-error.test.ts
  • src/main/herdr/herdr-existing-tab-root.ts
  • src/main/herdr/herdr-reconcile-index.ts
  • src/main/providers/types.ts
  • src/main/codex-accounts/service.test.ts
  • src/main/herdr/herdr-pty-provider.test.ts
  • src/renderer/src/components/terminal-pane/pty-transport.test.ts
  • src/shared/constants.ts
  • src/main/herdr/herdr-session-watcher.ts
  • src/main/herdr/herdr-binary-source.test.ts
  • src/main/runtime/rpc/methods/project-runtime-rpc-methods.ts
  • src/main/herdr/herdr-pty-codec.ts
  • src/shared/types.ts
  • src/shared/terminal-backend.ts
  • src/renderer/src/components/settings/RepositoryPane.tsx
  • src/renderer/src/components/settings/TerminalBackendSection.test.tsx
  • src/main/herdr/herdr-event-subscription.ts
  • src/main/ipc/repos.ts
  • src/main/herdr/herdr-binary-source.ts
  • src/renderer/src/components/settings/ProjectTerminalBackendSetting.test.tsx
  • src/cli/format.test.ts
  • src/main/herdr/herdr-provider-factory.ts
  • tests/e2e/helpers/orca-restart.ts
  • src/main/herdr/herdr-runtime-contract.ts
  • src/main/herdr/herdr-runtime-manager.ts
  • src/main/herdr/herdr-pty-types.ts
  • src/main/herdr/herdr-pty-provider-base.ts
  • src/renderer/src/components/terminal-pane/pty-transport.ts
  • src/shared/herdr-session-identity.ts
  • src/main/ipc/pty.ts
  • src/shared/terminal-backend.test.ts
  • src/main/persistence.test.ts
  • src/main/herdr/herdr-project-pty-target.ts
  • src/main/persistence.ts
  • src/main/herdr/herdr-pty-provider.ts

const leafId = randomUUID()
const preAllocatedHandle = this.createPreAllocatedTerminalHandle()
const paneKey = makePaneKey(parentTabId, leafId)
const existingLayout = this.store?.getWorkspaceSession?.().terminalLayoutsByTabId?.[parentTabId]

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.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix missing optional chaining to prevent runtime crashes.

If getWorkspaceSession() returns undefined, accessing .terminalLayoutsByTabId without optional chaining will throw a TypeError: Cannot read properties of undefined.

🐛 Proposed fix
-    const existingLayout = this.store?.getWorkspaceSession?.().terminalLayoutsByTabId?.[parentTabId]
+    const existingLayout = this.store?.getWorkspaceSession?.()?.terminalLayoutsByTabId?.[parentTabId]
📝 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.

Suggested change
const existingLayout = this.store?.getWorkspaceSession?.().terminalLayoutsByTabId?.[parentTabId]
const existingLayout = this.store?.getWorkspaceSession?.()?.terminalLayoutsByTabId?.[parentTabId]

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.

2 participants