Skip to content

Linear Lane Launch Fixes#499

Merged
arul28 merged 2 commits into
mainfrom
ade/linear-lane-launch-fixes-bec59d3e
Jun 1, 2026
Merged

Linear Lane Launch Fixes#499
arul28 merged 2 commits into
mainfrom
ade/linear-lane-launch-fixes-bec59d3e

Conversation

@arul28
Copy link
Copy Markdown
Owner

@arul28 arul28 commented Jun 1, 2026

Summary

Describe the change.

What Changed

Key files and behaviors.

Validation

How you tested.

Risks

Anything to watch.

ADE   Open in ADE  ·  ade/linear-lane-launch-fixes-bec59d3e branch  ·  PR #499

Summary by CodeRabbit

  • New Features

    • Added timeout support for initial input delivery in agent chat CLI operations.
    • Introduced modal-based Linear issue selection interface for lanes.
  • Refactor

    • Restructured Linear issue display and selection components for improved modularity.
  • Tests

    • Enhanced test environment isolation and added coverage for initial input handling.

Greptile Summary

This PR refactors the Linear issue picker out of the CreateLaneDialog inline pane and the AgentChatComposer inline component into a shared LinearIssueSelectModal, and adds configurable timeout support for initial-input delivery in the PTY agent CLI flow.

  • LinearIssueSelectModal (LinearIssueSelectModal.tsx): New reusable modal wrapping LinearIssueBrowser in single-select mode, consumed by both CreateLaneDialog (now a separate dialog instead of an embedded view) and AgentChatComposer. Utility display helpers are extracted from the deleted LinearIssuePicker.tsx into linearIssueDisplay.ts.
  • Configurable kickoff timeout (agentChatCliLaunch.ts, ptyService.ts, sessions.ts): When initialInput is present, awaitInitialInput: true and a 120 s initialInputReadyTimeoutMs are forwarded to the PTY service; the service clamps caller-supplied values to [AGENT_CLI_READY_TIMEOUT_MS, 300 000] and warns when clamping occurs.
  • Test improvements: ADE env variables are now isolated per-test in adeRpcServer.test.ts, cli.test.ts uses the real CLI version, and CreateLaneDialog.test.tsx gains a matchMedia mock and a modal-flow integration test.

Confidence Score: 5/5

Safe to merge — the changes are well-scoped refactors and additive fixes with good test coverage.

The Linear picker refactor introduces no logic changes to the underlying browser component — it purely reshapes how the modal is surfaced. The kickoff-timeout addition is narrow and defended by a new test. Env isolation improvements in the test suite are strictly additive. No data paths are at risk.

No files require special attention.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/components/app/LinearIssueSelectModal.tsx New shared modal component wrapping LinearIssueBrowser in single-select mode; cleanly extracted from the duplicated inline dialog that existed in both AgentChatComposer and CreateLaneDialog.
apps/desktop/src/renderer/components/lanes/linearIssueDisplay.ts New utility file extracting pure display helpers (linearPriorityLabel, issueProjectLabel, toLaneLinearIssue, branchExistsForLinearIssue) from the deleted LinearIssuePicker.tsx; no logic changes.
apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx Replaces the embedded LinearIssuePickerView with a separate LinearIssueSelectModal; LaneDialogShell visibility is gated on !issuePickerOpen so only one dialog is open at a time.
apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx Replaces local LinearIssueContextDialog with the shared LinearIssueSelectModal; selectedLinearContextIssue now uses .find() for correctness when linear_issue attachment is not at index 0.
apps/desktop/src/main/services/chat/agentChatCliLaunch.ts Sets awaitInitialInput:true and a 120 s initialInputReadyTimeoutMs whenever initialInput is present, ensuring slow CLI startup cannot silently drop the kickoff prompt.
apps/desktop/src/main/services/pty/ptyService.ts Adds timeoutMs parameter to waitForAgentCliInputReady and clamping logic (with logger.warn on clamping) for the new initialInputReadyTimeoutMs field from PtyCreateArgs.
apps/desktop/src/renderer/components/app/LinearIssueBrowser.tsx Adds singleSelect prop that suppresses checkboxes, multi-select bar, and selection persistence when true; BrowserIssue type is now exported for downstream consumers.
apps/ade-cli/src/adeRpcServer.test.ts Adds beforeEach/afterEach fixtures to snapshot and restore ADE env variables, preventing cross-test pollution.
apps/desktop/src/renderer/components/lanes/CreateLaneDialog.test.tsx Adds matchMedia mock in beforeEach and a new integration test verifying the Linear issue browser opens as its own modal and the lane dialog is hidden behind it.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant CLD as CreateLaneDialog
    participant LDS as LaneDialogShell
    participant LISM as LinearIssueSelectModal
    participant LIB as LinearIssueBrowser

    U->>CLD: click "Connect a Linear issue"
    CLD->>LDS: "open={false} (hide lane dialog)"
    CLD->>LISM: "open={true}"
    LISM->>LIB: "singleSelect=true"

    U->>LIB: click issue → click "Connect issue"
    LIB->>LISM: onIssueAction(issue)
    LISM->>CLD: onSelectIssue(laneIssue)
    LISM->>LISM: onOpenChange(false)
    CLD->>LDS: "open={true} (restore lane dialog)"

    note over CLD,LDS: AgentChatComposer follows same pattern via LinearIssueSelectModal
Loading

Comments Outside Diff (1)

  1. apps/desktop/src/renderer/components/lanes/CreateLaneDialog.test.tsx, line 426-453 (link)

    P2 window.ade not restored after the test

    The test sets window.ade with Object.defineProperty but never deletes or resets it in an afterEach. Because the property is configurable: true, a later test that renders a component relying on window.ade being undefined (or in a different state) will silently inherit the mock, making failures hard to diagnose. Consider adding a scoped cleanup or wrapping the property definition in its own beforeEach/afterEach block.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/renderer/components/lanes/CreateLaneDialog.test.tsx
    Line: 426-453
    
    Comment:
    **`window.ade` not restored after the test**
    
    The test sets `window.ade` with `Object.defineProperty` but never deletes or resets it in an `afterEach`. Because the property is `configurable: true`, a later test that renders a component relying on `window.ade` being `undefined` (or in a different state) will silently inherit the mock, making failures hard to diagnose. Consider adding a scoped cleanup or wrapping the property definition in its own `beforeEach`/`afterEach` block.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Reviews (2): Last reviewed commit: "Address PR review feedback" | Re-trigger Greptile

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

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 1, 2026 4:56pm

@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented Jun 1, 2026

@copilot review but do not make fixes

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors the Linear issue picker UI by extracting display utilities and creating a dedicated modal component, enhances the PTY service to support configurable initial input timeouts for agent chat CLI launches, and adds test environment cleanup for ADE CLI tests.

Changes

Agent Chat CLI Initial Input Timeout

Layer / File(s) Summary
Session type and PTY service timeout configuration
apps/desktop/src/shared/types/sessions.ts, apps/desktop/src/main/services/pty/ptyService.ts
PtyCreateArgs adds initialInputReadyTimeoutMs field; ptyService clamps timeout between min/max bounds when launching with initial input and passes it to waitForAgentCliInputReady.
Agent chat CLI kickoff timeout
apps/desktop/src/main/services/chat/agentChatCliLaunch.ts, apps/desktop/src/main/services/chat/agentChatCliLaunch.test.ts
New AGENT_CHAT_CLI_KICKOFF_READY_TIMEOUT_MS constant (120s) is used when launching with initial input; test verifies awaitInitialInput and timeout are passed to PTY service.

Linear Issue Picker UI Refactoring

Layer / File(s) Summary
Display helpers extraction
apps/desktop/src/renderer/components/lanes/linearIssueDisplay.ts
New module exports formatting utilities (linearPriorityLabel, issueProjectLabel, issueUpdatedLabel), issue normalization (toLaneLinearIssue), and branch matching (branchExistsForLinearIssue).
LinearIssueBrowser import refactor
apps/desktop/src/renderer/components/app/LinearIssueBrowser.tsx
Imports display helpers from new linearIssueDisplay module; exports BrowserIssue type for consumer modules.
New LinearIssueSelectModal component
apps/desktop/src/renderer/components/app/LinearIssueSelectModal.tsx
Modal wrapper around LinearIssueBrowser managing open/close, refresh, quick-view state; converts browser issues to lane issues and invokes selection callbacks.
AgentChatComposer Linear issue flow
apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx
Replaces internal dialog wrapper with LinearIssueSelectModal; selection handler directly constructs context attachments via makeLinearIssueContextAttachment.
CreateLaneDialog modal integration
apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx, apps/desktop/src/renderer/components/lanes/CreateLaneDialog.test.tsx
Integrates LinearIssueSelectModal as separate component; adds projectRoot and onOpenLinearSettings props; replaces issue summary card with local SelectedLinearIssueCard; test verifies modal open/close and field visibility.
LanesPage dialog wiring
apps/desktop/src/renderer/components/lanes/LanesPage.tsx
Passes project root path and Linear settings navigation callback to CreateLaneDialog.

ADE CLI Test Environment Management

Layer / File(s) Summary
ADE RPC server test isolation
apps/ade-cli/src/adeRpcServer.test.ts
Captures ADE environment variables at startup; beforeEach clears them, afterEach restores originals, preventing cross-test pollution.
CLI test version injection
apps/ade-cli/src/cli.test.ts
Test fixture derives runtimeInfo.version from process.env.ADE_CLI_VERSION with "0.0.0" fallback.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • arul28/ADE#274: Introduces the original LinearIssuePicker component and lane creation picker flow that this PR refactors by extracting helpers into linearIssueDisplay and creating LinearIssueSelectModal.

Suggested labels

desktop

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Linear Lane Launch Fixes' is overly vague and generic, lacking specific detail about what was fixed or which aspect of the feature is being addressed. Provide a more specific title that describes the actual fix, such as 'Add initialInputReadyTimeout for Linear lane launch' or 'Fix Linear lane CLI prompt delivery timeout handling'.
✅ Passed checks (3 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.
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/linear-lane-launch-fixes-bec59d3e

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/components/chat/AgentChatComposer.tsx Outdated
Comment thread apps/desktop/src/main/services/pty/ptyService.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx (1)

668-673: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Disable the disconnect action while create/setup is locked.

The "Change issue" button is already disabled for busy || laneCreated, but the X button still clears selectedLinearIssue. That lets the UI drift away from the in-flight create request, which has already captured the old issue.

Suggested fix
 <SelectedLinearIssueCard
   issue={selectedLinearIssue}
   branchName={selectedLinearBranchName}
   branchConflict={selectedLinearBranchConflict}
   onClear={() => setSelectedLinearIssue(null)}
+  disabled={busy || laneCreated}
 />
 function SelectedLinearIssueCard({
   issue,
   branchName,
   branchConflict,
   onClear,
+  disabled = false,
 }: {
   issue: LaneLinearIssue;
   branchName: string;
   branchConflict: boolean;
   onClear: () => void;
+  disabled?: boolean;
 }) {
   return (
@@
         <button
           type="button"
           className="rounded-md p-1 text-muted-fg/60 transition-colors hover:bg-white/[0.06] hover:text-fg"
           onClick={onClear}
           aria-label="Disconnect Linear issue"
+          disabled={disabled}
         >
           <X size={14} />
         </button>

As per coding guidelines, apps/desktop/src/**: Electron desktop app — check for IPC security, proper main/renderer process separation, and React best practices.

Also applies to: 675-688, 891-897

🤖 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/components/lanes/CreateLaneDialog.tsx` around lines
668 - 673, The X (disconnect) action currently calls SelectedLinearIssueCard's
onClear which clears selectedLinearIssue even when a create/setup is in-flight;
modify the onClear handler passed to SelectedLinearIssueCard (and the other
instances noted) so it is a no-op while the UI is locked (i.e., when busy ||
laneCreated) — for example, change onClear={() => setSelectedLinearIssue(null)}
to onClear={busy || laneCreated ? undefined /* or () => {} */ : () =>
setSelectedLinearIssue(null)} (or equivalent guard) so that the disconnect
cannot run during the create/setup lock; update all occurrences (the other
SelectedLinearIssueCard usages) to use the same guarded handler.
🧹 Nitpick comments (1)
apps/desktop/src/shared/types/sessions.ts (1)

141-141: ⚡ Quick win

Consider adding a JSDoc comment for clarity.

The adjacent awaitInitialInput field (line 143) includes documentation. Adding a brief comment here would help clarify the purpose and valid range of this timeout parameter.

📝 Suggested documentation
+  /** Timeout in milliseconds to wait for agent CLI input readiness before delivering initialInput. */
   initialInputReadyTimeoutMs?: number;
🤖 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/shared/types/sessions.ts` at line 141, Add a short JSDoc
comment above the initialInputReadyTimeoutMs property explaining that it sets
the maximum wait time (in milliseconds) for initial input readiness and mention
typical/allowed range or default behavior; reference the related
awaitInitialInput field for context so readers understand this timeout controls
how long awaitInitialInput will wait before timing out.
🤖 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.

Inline comments:
In `@apps/desktop/src/renderer/components/app/LinearIssueSelectModal.tsx`:
- Around line 57-74: The modal embeds LinearIssueBrowser but only returns a
single LaneLinearIssue via onSelectIssue, yet the browser still shows checkboxes
and “Select all”; update the LinearIssueSelectModal usage of LinearIssueBrowser
to disable multi-select affordances by passing a single-selection prop (e.g.,
multiSelect={false} or selectionMode="single") and/or explicit flags to hide
checkboxes and the select-all control (e.g., showRowCheckboxes={false},
showSelectAll={false}); if LinearIssueBrowser lacks such props, add a prop like
singleSelect:boolean to LinearIssueBrowser and implement it there to hide row
checkboxes and the select-all UI, then pass singleSelect={true} from
LinearIssueSelectModal.

In `@apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx`:
- Around line 2882-2886: The code passes selectedIssue by indexing
contextAttachments[0], which fails if the first attachment isn't a Linear issue;
update AgentChatComposer.tsx to locate the Linear attachment by scanning the
full array (e.g., use Array.prototype.find on contextAttachments for item.type
=== "linear_issue") and pass that attachment.issue (or null) into the
selectedIssue prop so the picker retains the correct issue regardless of
attachment order.

---

Outside diff comments:
In `@apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx`:
- Around line 668-673: The X (disconnect) action currently calls
SelectedLinearIssueCard's onClear which clears selectedLinearIssue even when a
create/setup is in-flight; modify the onClear handler passed to
SelectedLinearIssueCard (and the other instances noted) so it is a no-op while
the UI is locked (i.e., when busy || laneCreated) — for example, change
onClear={() => setSelectedLinearIssue(null)} to onClear={busy || laneCreated ?
undefined /* or () => {} */ : () => setSelectedLinearIssue(null)} (or equivalent
guard) so that the disconnect cannot run during the create/setup lock; update
all occurrences (the other SelectedLinearIssueCard usages) to use the same
guarded handler.

---

Nitpick comments:
In `@apps/desktop/src/shared/types/sessions.ts`:
- Line 141: Add a short JSDoc comment above the initialInputReadyTimeoutMs
property explaining that it sets the maximum wait time (in milliseconds) for
initial input readiness and mention typical/allowed range or default behavior;
reference the related awaitInitialInput field for context so readers understand
this timeout controls how long awaitInitialInput will wait before timing out.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b293eb84-2292-4773-9826-99def4d597e5

📥 Commits

Reviewing files that changed from the base of the PR and between fb2b603 and 6ed5e12.

📒 Files selected for processing (14)
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/desktop/src/main/services/chat/agentChatCliLaunch.test.ts
  • apps/desktop/src/main/services/chat/agentChatCliLaunch.ts
  • apps/desktop/src/main/services/pty/ptyService.ts
  • apps/desktop/src/renderer/components/app/LinearIssueBrowser.tsx
  • apps/desktop/src/renderer/components/app/LinearIssueSelectModal.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx
  • apps/desktop/src/renderer/components/lanes/CreateLaneDialog.test.tsx
  • apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx
  • apps/desktop/src/renderer/components/lanes/LanesPage.tsx
  • apps/desktop/src/renderer/components/lanes/LinearIssuePicker.tsx
  • apps/desktop/src/renderer/components/lanes/linearIssueDisplay.ts
  • apps/desktop/src/shared/types/sessions.ts
💤 Files with no reviewable changes (1)
  • apps/desktop/src/renderer/components/lanes/LinearIssuePicker.tsx

Comment thread apps/desktop/src/renderer/components/app/LinearIssueSelectModal.tsx
Comment thread apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx Outdated
@arul28 arul28 merged commit 48f946b into main Jun 1, 2026
28 checks passed
@arul28 arul28 deleted the ade/linear-lane-launch-fixes-bec59d3e branch June 1, 2026 18:07
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