Skip to content

ADE-94: Linear multi-agent launch can create untracked CLI sessions#510

Merged
arul28 merged 2 commits into
mainfrom
ade-94-linear-multi-agent-launch-can-create-untracked-cli-sessions
Jun 2, 2026
Merged

ADE-94: Linear multi-agent launch can create untracked CLI sessions#510
arul28 merged 2 commits into
mainfrom
ade-94-linear-multi-agent-launch-can-create-untracked-cli-sessions

Conversation

@arul28

@arul28 arul28 commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Create and return the tracked Agent Chat CLI PTY/session before kickoff input readiness, so Linear multi-agent launches immediately record durable terminal session IDs.
  • Keep asynchronous kickoff input delivery for normal launches, while making explicit awaitInitialInput failures terminate the PTY and end the session as failed.
  • Add regression coverage for concurrent delayed CLI launches and document the explicit awaited-initial-input cleanup behavior.

Verification

  • Verified the issue still applied on latest origin/main (0f2e5518c2d67de8c3a51ad2b846f9f901e79638) and on this lane before patching.
  • Ran /audit; fixed the discovered explicit awaitInitialInput cleanup gap.
  • Ran /automate: docs parity updated; iOS, ADE CLI, and TUI parity required no product changes. ADE CLI typecheck/tests passed; focused TUI tests passed.
  • Targeted desktop tests passed:
    • npm --prefix apps/desktop run test -- src/main/services/chat/agentChatCliLaunch.test.ts
    • npm --prefix apps/desktop run test -- src/main/services/pty/ptyService.test.ts
    • npm --prefix apps/desktop run test -- src/renderer/lib/linearBatchLaunch.test.ts
  • Full /finalize local gates passed:
    • npm install in apps/desktop, apps/ade-cli, and apps/web
    • npm --prefix apps/desktop run typecheck
    • npm --prefix apps/ade-cli run typecheck
    • npm --prefix apps/web run typecheck
    • npm --prefix apps/desktop run lint (0 errors; existing warnings only)
    • desktop Vitest shards 1/8 through 8/8 plus apps/ade-cli npm test; shard 4 had a Vitest IPC timeout while running linearSync.test.ts, and the targeted rerun passed (46 tests)
    • npm --prefix apps/desktop run build
    • npm --prefix apps/ade-cli run build
    • npm --prefix apps/web run build
    • node scripts/validate-docs.mjs
    • internal docs checks for feature Source file map sections and PRD.md relative links
    • git diff --check

Greptile Summary

This PR fixes a race condition in Linear multi-agent batch launches where launchCli could start an untracked PTY session because the caller waited for CLI input-readiness before returning the durable session record. The fix decouples session creation from CLI readiness by removing awaitInitialInput from the agentChatCliLaunch path (making kickoff prompt injection fully asynchronous) and adds explicit teardown — SIGTERM + closeEntry with status: "failed" — for any caller that does explicitly opt in to awaitInitialInput and encounters a timeout.

  • agentChatCliLaunch.ts: Drops awaitInitialInput: true and the AGENT_CHAT_CLI_KICKOFF_READY_TIMEOUT_MS constant so ptyService.create resolves as soon as the tracked PTY record is committed, not when the Codex CLI signals readiness.
  • ptyService.ts: The awaitInitialInput catch block now calls terminatePtyProcessTree + closeEntry(ptyId, 1) before re-throwing, ensuring a hidden live process is never left behind when an explicitly-awaited prompt injection fails.
  • Tests: A new concurrent-launch test uses a deferred-promise pattern for reliable synchronization, and the existing timeout-failure test is extended to assert the new SIGTERM kill and sessionService.end(failed) calls.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to decoupling session-record creation from CLI readiness, with no regressions to the non-awaited path.

The removal of awaitInitialInput in agentChatCliLaunch is the exact minimal fix for the untracked-session bug: the durable record is committed before the caller returns, so batch launch state is always consistent. The new teardown path in ptyService is gated behind the awaitInitialInput flag and protected by the existing entry.disposed guard in closeEntry, preventing any double-end of a session.

No files require special attention.

Important Files Changed

Filename Overview
apps/desktop/src/main/services/chat/agentChatCliLaunch.ts Removes awaitInitialInput and its timeout constant so ptyService.create returns as soon as the tracked session is created; Codex prompt is now injected asynchronously.
apps/desktop/src/main/services/pty/ptyService.ts Adds explicit cleanup (warn log, SIGTERM process-tree kill, closeEntry with exitCode 1/status failed) when an explicitly-awaited initial input fails; existing entry.disposed guard in closeEntry prevents double-end.
apps/desktop/src/main/services/chat/agentChatCliLaunch.test.ts Test updated to assert that awaitInitialInput and initialInputReadyTimeoutMs are no longer passed, and that sessionId is returned immediately.
apps/desktop/src/main/services/pty/ptyService.test.ts Extends timeout-failure test to assert the new warn log, SIGTERM kill, and sessionService.end(failed) are all triggered when awaitInitialInput times out.
apps/desktop/src/renderer/lib/linearBatchLaunch.test.ts New concurrent-launch test uses a promise-based synchronization (allLaunchesStarted) rather than a polling loop, reliably confirming all three launchCli calls start before resolving deferrals.
docs/features/terminals-and-sessions/pty-and-processes.md Doc update accurately describes the new awaitInitialInput failure behavior (terminate + end as failed) versus the non-awaited path (log and preserve).

Sequence Diagram

sequenceDiagram
    participant BL as linearBatchLaunch
    participant LC as launchAgentChatCli
    participant PS as ptyService.create
    participant CLI as Codex CLI

    BL->>LC: launchCli(args)
    LC->>PS: create with initialInput and initialInputDelayMs
    Note over PS: Creates durable PTY/session record
    PS-->>LC: ptyId, sessionId, pid
    LC-->>BL: sessionId returned immediately
    Note over BL: Session is tracked and batch state updated

    PS->>CLI: async fire-and-forget writeInitialInput
    alt CLI becomes ready in time
        CLI-->>PS: ready signal
        PS->>CLI: write kickoff prompt
    else awaitInitialInput true and timeout
        PS->>PS: terminatePtyProcessTree SIGTERM
        PS->>PS: closeEntry exitCode 1 status failed
        PS-->>LC: throws error
    else awaitInitialInput false and timeout
        PS->>PS: log warning and preserve session
    end
Loading

Reviews (2): Last reviewed commit: "test: finalize Linear CLI launch coverag..." | Re-trigger Greptile

@vercel

vercel Bot commented Jun 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jun 2, 2026 7:01am

@linear-code

linear-code Bot commented Jun 2, 2026

Copy link
Copy Markdown

ADE-94

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR removes the timeout-based kickoff-readiness wait from agent CLI launches and refactors PTY failure handling. When initial input is provided, the launch no longer waits for readiness; the PTY service now explicitly terminates and cleans up sessions when initial-input await times out. Batch launch test coverage validates concurrent CLI session tracking.

Changes

Agent CLI Initial Input Handling and Batch Launch

Layer / File(s) Summary
Agent Chat CLI Kickoff Input Simplification
apps/desktop/src/main/services/chat/agentChatCliLaunch.ts, apps/desktop/src/main/services/chat/agentChatCliLaunch.test.ts
AGENT_CHAT_CLI_KICKOFF_READY_TIMEOUT_MS constant removed. launchAgentChatCli no longer sets awaitInitialInput or initialInputReadyTimeoutMs when launch.initialInput is present; instead conditionally passes initialInputDelayMs. Test updated to verify immediate session return without kickoff-readiness waiting.
PTY Service Failure Cleanup on Initial Input Timeout
apps/desktop/src/main/services/pty/ptyService.ts, apps/desktop/src/main/services/pty/ptyService.test.ts
When awaitInitialInput fails, PTY service now logs pty.initial_input_await_failed_closing warning, sends SIGTERM to terminate process tree, and closes session with status: "failed" and exitCode: 1. Test expanded to assert all cleanup side effects: warning, process termination, and session closure.
Batch Launch CLI Session ID Tracking Test
apps/desktop/src/renderer/lib/linearBatchLaunch.test.ts
Added test case for runBatchLaunch in "cli" session mode verifying concurrent launches track per-issue terminal sessionId values, complete without failures, and deliver correct session IDs via onItem callbacks with status: "done".

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • arul28/ADE#499: Both PRs modify initial-input kickoff/ready handling for agent CLI PTY sessions—Linear Lane Launch Fixes #499 introduces configurable/clamped initialInputReadyTimeoutMs, while this PR changes what launchAgentChatCli sets (removing awaitInitialInput/timeout when initialInput is present) and adjusts failure behavior.

Suggested labels

desktop

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The title directly references the issue (ADE-94) and accurately describes the main problem being addressed: tracking CLI sessions that were previously untracked during multi-agent launch.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade-94-linear-multi-agent-launch-can-create-untracked-cli-sessions

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 and usage tips.

Comment thread apps/desktop/src/renderer/lib/linearBatchLaunch.test.ts

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
apps/desktop/src/renderer/lib/linearBatchLaunch.test.ts (1)

351-354: 💤 Low value

Minor: wait loop could be fragile on slow systems.

The loop yields up to 5 times waiting for launchCli to be called 3 times. In heavily loaded test environments, this might not be enough iterations. Consider using vi.waitFor() for more robust async waiting.

However, this is acceptable for a unit test and will fail with a clear assertion error if timing is an issue.

♻️ Alternative using vi.waitFor (optional)
-    for (let i = 0; i < 5 && launchCli.mock.calls.length < 3; i += 1) {
-      await Promise.resolve();
-    }
-    expect(launchCli).toHaveBeenCalledTimes(3);
+    await vi.waitFor(() => {
+      expect(launchCli).toHaveBeenCalledTimes(3);
+    });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/lib/linearBatchLaunch.test.ts` around lines 351 -
354, Replace the fragile manual yield loop that spins up to 5 ticks waiting for
launchCli to be called 3 times with a robust async wait using vi.waitFor: remove
the for-loop and instead await vi.waitFor until the launchCli mock has been
called 3 times (e.g. check launchCli.mock.calls.length === 3 or use an assertion
inside vi.waitFor), so the test reliably waits on slow/loaded CI without flaky
timing assumptions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/desktop/src/renderer/lib/linearBatchLaunch.test.ts`:
- Around line 351-354: Replace the fragile manual yield loop that spins up to 5
ticks waiting for launchCli to be called 3 times with a robust async wait using
vi.waitFor: remove the for-loop and instead await vi.waitFor until the launchCli
mock has been called 3 times (e.g. check launchCli.mock.calls.length === 3 or
use an assertion inside vi.waitFor), so the test reliably waits on slow/loaded
CI without flaky timing assumptions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 234ff4c4-a414-4e20-8918-e2b68b322ecc

📥 Commits

Reviewing files that changed from the base of the PR and between 0f2e551 and 15ebaac.

📒 Files selected for processing (5)
  • apps/desktop/src/main/services/chat/agentChatCliLaunch.test.ts
  • apps/desktop/src/main/services/chat/agentChatCliLaunch.ts
  • apps/desktop/src/main/services/pty/ptyService.test.ts
  • apps/desktop/src/main/services/pty/ptyService.ts
  • apps/desktop/src/renderer/lib/linearBatchLaunch.test.ts
💤 Files with no reviewable changes (1)
  • apps/desktop/src/main/services/chat/agentChatCliLaunch.ts

@arul28

arul28 commented Jun 2, 2026

Copy link
Copy Markdown
Owner Author

@copilot review but do not make fixes

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