Skip to content

Huge Cleanup#355

Merged
arul28 merged 9 commits into
mainfrom
ade/huge-cleanup-8469674a
May 25, 2026
Merged

Huge Cleanup#355
arul28 merged 9 commits into
mainfrom
ade/huge-cleanup-8469674a

Conversation

@arul28
Copy link
Copy Markdown
Owner

@arul28 arul28 commented May 24, 2026

Summary

Describe the change.

What Changed

Key files and behaviors.

Validation

How you tested.

Risks

Anything to watch.

ADE   Open in ADE  ·  ade/huge-cleanup-8469674a branch  ·  PR #355

Summary by CodeRabbit

  • New Features

    • Computer-use artifacts now include explicit backend styling.
    • Chat model picker supports constrained selection with custom “model unavailable” messaging.
    • Onboarding tour steps can switch app tabs for smoother guidance.
    • Runtime status/commands now surface richer runtime info (build hash, role, pid, project root).
  • Bug Fixes

    • Screenshot capture timeouts are cleaned up reliably.
    • Runtime validation now detects stale/incompatible runtimes and role mismatches to avoid bad attachments.
  • Tests

    • Expanded and reorganized tests; added coverage for model constraints and runtime freshness.

Review Change Stack

Greptile Summary

This is a large cleanup PR that consolidates scattered per-feature test files into single suite files, and ships three self-contained features alongside the reorganisation.

  • Stale-runtime detection: both connection.ts (TUI client) and localRuntimeConnectionPool.ts (desktop) now validate that an attached runtime reports defaultRole === \"cto\" and a matching build hash; mismatches trigger automatic replacement of the old daemon.
  • backendStyle on computer-use artifacts: a new ComputerUseBackendStyle union (external_cli | manual | local_fallback) replaces the previously hardcoded \"external_cli\" string; normalizeBackendStyle defaults to \"external_cli\" for null rows, keeping existing data valid.
  • Constrained model picker: ModelPicker gains a constrainToAvailableModelIds prop that limits selectable models to a caller-supplied allowlist; AgentChatPane uses this when availableModelIdsOverride is set and surfaces a constrainedModelSelectionError that blocks session creation when the active model is outside the allowed set.

Confidence Score: 5/5

Safe to merge; all three feature additions are well-guarded and the daemon startup already handles the stale socket file via fs.unlinkSync before rebinding.

The stale-daemon replacement path in connection.ts is sound: the ADE daemon calls fs.unlinkSync(socketPath) before binding, so the new daemon can always claim the socket. The constrained model-picker feature properly guards the submit path through both the composer's singleModelReady check and the constrainedModelSelectionError callback inside createSession. The backendStyle addition is backward-compatible. The only finding is a per-retry file-hash re-computation in the 25-attempt retry loop, which is inefficiency rather than incorrectness.

No files require special attention; the stale-daemon retry logic in apps/ade-cli/src/tuiClient/connection.ts is the most complex new path but works correctly.

Important Files Changed

Filename Overview
apps/ade-cli/src/runtimeRoles.ts New utility module centralising ADE runtime role validation; normalizeAdeRuntimeRole and resolveAdeDefaultRole replace inline role checks across cli.ts and connection.ts.
apps/ade-cli/src/tuiClient/connection.ts Adds stale-daemon detection (role mismatch + build-hash check), StaleAdeSocketError, and auto-respawn; computeCliEntrypointBuildHash is re-invoked on every retry in the 25-attempt loop instead of being memoized.
apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.ts Adds defaultRole field to readRuntimeInfo and enforces that attached runtimes must report defaultRole === "cto"; mismatch throws LocalRuntimeCompatibilityError, triggering the existing replaceStaleRuntime path that terminates the process and unlinks the socket.
apps/desktop/src/shared/types/computerUseArtifacts.ts Adds ComputerUseBackendStyle union type and makes backendStyle a required field on ComputerUseArtifactRecord, replacing the previously implicit hardcoded "external_cli" value.
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts Persists and reads backendStyle from the DB column; normalizeBackendStyle defaults to "external_cli" for null/unknown values, preserving backward compatibility with existing rows.
apps/desktop/src/renderer/components/shared/ModelPicker/ModelPicker.tsx Adds constrainToAvailableModelIds prop that restricts the selectable model list and disables registry expansion; fallback to unconstrained mode when the prop is false is correct.
apps/desktop/src/renderer/components/chat/AgentChatPane.tsx Introduces modelSelectionConstrained, wires constrainedModelSelectionError into both session-creation paths, and propagates the constrained flag to the composer.
apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx Accepts constrainModelSelection and modelUnavailableMessage props; singleModelReady correctly blocks submission when the model is absent or the unavailability message is set.
apps/desktop/src/renderer/onboarding/tours/ctoTour.ts Adds switchCtoTab helper and hooks beforeEnter into the team and workflows steps so the correct tab is pre-selected.
apps/desktop/src/renderer/onboarding/tours/firstJourneyTour.ts Removes detailed sub-steps for acts 6–11, leaving only intro steps; tour is shorter and less reliant on specific UI selectors.

Sequence Diagram

sequenceDiagram
    participant Client as TUI / Desktop Client
    participant Conn as connection.ts / localRuntimeConnectionPool
    participant Socket as Unix Socket
    participant OldDaemon as Old Daemon (wrong role)
    participant NewDaemon as New Daemon (role=cto)

    Client->>Conn: connectToAde / ensureProject
    Conn->>Socket: connect
    Socket-->>OldDaemon: ade/initialize
    OldDaemon-->>Conn: "runtimeInfo { defaultRole: "agent" }"
    Conn->>Conn: attachedRuntimeMismatchReason → role mismatch
    Conn->>OldDaemon: shutdown
    Conn-->>Client: StaleAdeSocketError
    Note over Conn: Wait 200ms, spawn new daemon
    Conn->>NewDaemon: "spawnDaemon (ADE_DEFAULT_ROLE=cto)"
    NewDaemon->>Socket: unlink + bind new socket
    loop up to 25 retries
        Conn->>Socket: connect
        NewDaemon-->>Conn: "runtimeInfo { defaultRole: "cto" }"
        Conn-->>Client: AdeCodeConnection established
    end
Loading

Comments Outside Diff (1)

  1. apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts, line 7182-7200 (link)

    P1 else branch calls transitionMissionStatus without allowTerminalRestart after ensureTerminalFailedRunIntervention already set the status

    When graph.run.status === "failed" and failed steps are present, ensureTerminalFailedRunIntervention adds a failed_step intervention and calls transitionMissionStatus(mission.id, "intervention_required", { allowTerminalRestart: true }). Because deriveMissionStatusFromRun now evaluates hasBlockingIntervention before checking run.status === "failed", the newly-added intervention makes it return "intervention_required" — so nextMissionStatus ends up in the else branch rather than else if (nextMissionStatus === "failed"). The else branch then re-derives the status (same result) and calls transitionMissionStatus(mission.id, "intervention_required") a second time, this time without { allowTerminalRestart: true }. If transitionMissionStatus is not idempotent, this causes duplicate side-effects; the missing allowTerminalRestart flag on the second call could also silently change restart eligibility.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts
    Line: 7182-7200
    
    Comment:
    **`else` branch calls `transitionMissionStatus` without `allowTerminalRestart` after `ensureTerminalFailedRunIntervention` already set the status**
    
    When `graph.run.status === "failed"` and failed steps are present, `ensureTerminalFailedRunIntervention` adds a `failed_step` intervention and calls `transitionMissionStatus(mission.id, "intervention_required", { allowTerminalRestart: true })`. Because `deriveMissionStatusFromRun` now evaluates `hasBlockingIntervention` *before* checking `run.status === "failed"`, the newly-added intervention makes it return `"intervention_required"` — so `nextMissionStatus` ends up in the `else` branch rather than `else if (nextMissionStatus === "failed")`. The `else` branch then re-derives the status (same result) and calls `transitionMissionStatus(mission.id, "intervention_required")` a second time, this time without `{ allowTerminalRestart: true }`. If `transitionMissionStatus` is not idempotent, this causes duplicate side-effects; the missing `allowTerminalRestart` flag on the second call could also silently change restart eligibility.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/ade-cli/src/tuiClient/connection.ts:420-433
`computeCliEntrypointBuildHash` reads and SHA-256s the CLI entrypoint file on every call. It's invoked once inside `spawnDaemon` and again on each attempt in the `connectAttachedSocketWithRetry` loop (up to 25 attempts), so up to 26 file reads happen during a single stale-daemon replacement. Since the entrypoint doesn't change mid-session, computing the hash once per `connectToAde` call and threading it through is straightforward.

```suggestion
function attachedRuntimeMismatchReason(
  result: InitializeResult,
  project: ProjectLaunchContext,
  expectedBuildHash?: string | null,
): { reason: string; pid: number | null } | null {
  const info = readAttachedRuntimeInfo(result);
  if (info.defaultRole !== "cto") {
    return {
      reason: `default role ${info.defaultRole ?? "missing"} is not cto`,
      pid: info.pid,
    };
  }

  const resolvedBuildHash = expectedBuildHash !== undefined ? expectedBuildHash : computeCliEntrypointBuildHash();
  if (resolvedBuildHash && info.buildHash !== resolvedBuildHash) {
```

Reviews (8): Last reviewed commit: "Select uncovered failed mission steps" | Re-trigger Greptile

@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 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 May 25, 2026 12:24am

Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

@copilot review but do not make fixes

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 24, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

📝 Walkthrough

Walkthrough

Adds normalized runtime role/build-hash checks across CLI/desktop/dev, enforces CTO role for desktop local runtimes, introduces constrained chat model selection in UI, improves orchestrator sync with failed-run interventions, normalizes/persists computer-use backend style, consolidates config/DB migration tests, adds test sharding, and updates docs validator.

Changes

Runtime roles and runtime freshness

Layer / File(s) Summary
ADE runtime identity handling and initialization
apps/ade-cli/src/adeRpcServer.ts, apps/ade-cli/src/multiProjectRpcServer.ts, apps/ade-cli/src/tuiClient/connection.ts, apps/ade-cli/src/cli.ts, apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.ts, tests/scripts
Normalize ADE_DEFAULT_ROLE, include buildHash/defaultRole/projectRoot in initialize/runtimeInfo; detect stale sockets/daemons via build-hash and role mismatch; optionally shutdown+restart local runtimes; adjust CLI/daemon attach/start logic and tests.

Constrained chat model selection and UI wiring

Layer / File(s) Summary
ModelPicker constraints and content control
apps/desktop/src/renderer/components/shared/ModelPicker/*
Adds constrainToAvailableModelIds and allowRegistryExpansion props; when constrained, limit model list to provided available IDs and avoid registry expansion.
Agent chat pane/composer constrained flows
apps/desktop/src/renderer/components/chat/AgentChatPane.tsx, AgentChatComposer.tsx
Compute constrained available IDs, present blocking errors when no allowed models or current model unavailable, prevent disallowed model selection, and block create/submit/parallel launches in constrained mode.
Chat tests and AI settings sign-in wiring
apps/desktop/src/renderer/components/*, tests
Seed/reset runtime catalog in tests, add tests for constrained picker behavior and blocked submissions, and pass onOpenSignIn into ModelPicker instances.

Orchestrator sync/status safeguards

Layer / File(s) Summary
Sync steps, failed-run intervention, and finalization paths
apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts
Match run steps to mission steps via ids/metadata (stable-string matching); ensure failed_step intervention is opened for terminal failed runs and transition mission to intervention_required when needed; use refreshed mission snapshots for finalization/closeout decisions.
Regression tests and context cleanups
aiOrchestratorService.test.ts, orchestratorContext.ts
Add regression tests for sync behavior, adjust status derivation ordering, and remove unused imports/types.

Computer-use artifacts backend style

Layer / File(s) Summary
Broker normalization/persistence and local style use
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts, apps/desktop/src/shared/types/computerUseArtifacts.ts
Introduce ComputerUseBackendStyle type; normalize backend.style (default external_cli) and persist backend_style; propagate backendStyle into mission/orchestrator metadata; set local_fallback for local screenshot ingestion and macOS VM local paths.
Tests and callsites
apps/desktop tests, apps/ade-cli tests
Add tests asserting backend.style is passed and persisted; update callers and fixtures to include backend style in expected payloads.

Config tests, DB migrations, and git/lane tests

Layer / File(s) Summary
Comprehensive project config tests
apps/desktop/src/main/services/config/projectConfigService.test.ts
Consolidates many deleted per-feature tests into one comprehensive suite covering providers, laneEnvInit, AI migration, linear sync, automations, process groups, and notifications.
KV DB migrations and helper cleanup
apps/desktop/src/main/services/state/kvDb.migrations.test.ts, kvDb.ts
Adds a large migrations test module validating orchestrator/mission/worker schema bootstraps and migration behaviors; removes wrapRawDb helper from implementation.
Merged git and lane branch-switch tests
apps/desktop/src/main/services/git/*, laneService.test.ts
Merge branch-switch test coverage into existing test files, add helpers for branch annotations, preview/switch behavior, and checkout metadata tests.

UI/services miscellany

Layer / File(s) Summary
AppControl screenshot timeout safety
apps/desktop/src/main/services/appControl/*
Ensure capture timeout handle is cleared in finally; add test verifying no lingering timers.
Onboarding tours, AppShell, and minor UI cleanup
apps/desktop/src/renderer/onboarding/*, AppShell.tsx, assorted renderer files
Add CTO tab-switch IPC action/tests, simplify tour assembly, remove unused imports/helpers, and adjust sidebar gating.
Misc service small edits
assorted main/service files
Small import removals, local variable trims, and minor behavior clarifications across multiple services.

Test scripts, docs, ignore

Layer / File(s) Summary
Run desktop test shards and package scripts
scripts/run-desktop-test-shards.mjs, package.json, apps/desktop/package.json
Add a sharded runner for desktop unit tests and wire scripts so root test runs desktop shards then CLI tests.
Docs validator scope/normalization
scripts/validate-docs.mjs
Un-ignore docs/, include AGENTS.md and .md under docs/ for validation, and skip raw ellipsis targets.
Ignore CLI dist-static output
.gitignore
Add /apps/ade-cli/dist-static/ to ignored build outputs.
  • Estimated code review effort: 🎯 4 (Complex) | ⏱️ ~60 minutes

  • Possibly related PRs:

    • arul28/ADE#247: related changes touching AgentChatPane and iOS simulator drawer/open plumbing.
    • arul28/ADE#291: overlaps on CLI daemon connect/restart and runtime mismatch handling.
    • arul28/ADE#211: touches lane color/palette UI code referenced by renderer changes.
  • Suggested labels: desktop

✨ 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/huge-cleanup-8469674a

Copy link
Copy Markdown
Contributor

Copilot AI commented May 24, 2026

@codex review

@copilot review but do not make fixes

Reviewed commit 5f60d58 as requested (no fixes made). I don’t see blocking regressions from a code read. Validation in this runner is currently environment-blocked: both npm --prefix apps/ade-cli run typecheck and npm --prefix apps/desktop run typecheck fail immediately on missing node type definitions (and desktop also reports TS baseUrl deprecation under the current TypeScript version), so I couldn’t complete full compile validation here.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

Copilot finished work on behalf of arul28 May 24, 2026 21:25
@arul28 arul28 force-pushed the ade/huge-cleanup-8469674a branch from 5f60d58 to d15aeaa Compare May 24, 2026 21:26
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

PR Review

Scope: 105 file(s), +5380 / −5673
Verdict: Minor issues

Launch-prep cleanup: consolidates desktop/CLI tests and docs, tightens dev/runtime handshake (build hash + default role), hardens constrained chat model selection, and improves mission/orchestrator failure sync. No blocking security defects found; a few behavior changes are worth confirming before merge.


🔒 Security

[Medium] CLI default role elevated to cto when unset

File: apps/ade-cli/src/cli.ts:2022
Issue: parseCliArgs now uses resolveAdeDefaultRole(process.env.ADE_DEFAULT_ROLE, "cto") instead of defaulting to agent. Any local ade / headless runtime started without --role or ADE_DEFAULT_ROLE now runs with CTO-scoped RPC tools rather than agent-scoped tools.
Attack path: On a machine where a shared/local RPC socket is reachable, a process that can spawn or attach to the runtime without setting role inherits the broader CTO tool surface (operator/Linear tools) that previously required an explicit role or env var.
Fix: Keep cto only for desktop-owned spawn paths (already set in localRuntimeConnectionPool / TUI), and restore agent (or external) as the CLI fallback for generic invocations:

role: resolveAdeDefaultRole(process.env.ADE_DEFAULT_ROLE, "agent"),

🐛 Functionality

[Medium] Mission step sync can target the wrong step by title

File: apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts:6982-6985
Issue: When runStep.missionStepId is missing, resolveMissionStepForRunStep falls back to mission.steps.find((step) => step.title === runStep.title). Duplicate step titles map to the first match, so orchestrator status updates can be applied to the wrong mission step.
Repro: Create a mission with two steps titled "Implement API"; run an orchestrator graph whose run step lacks missionStepId but shares that title; mark one run step succeeded — the first mission step with that title flips status while the other stays stale.
Fix: Drop the title-only fallback (or gate it behind a unique-title check). Prefer metadata.orchestratorStepId / metadata.stepKey only, and log/skip when no stable link exists.

[Medium] TCP dev runtime no longer auto-recovers when stale

File: scripts/dev-shared.mjs:432-433
Issue: ensureRuntime now throws if the socket is tcp://… and build hash/role/project root mismatches, instead of restarting like the Unix socket path.
Repro: Start ade serve over TCP with an old build hash, then run npm run dev:desktop in attach mode against that socket — startup fails with a stale-runtime error rather than recycling the daemon.
Fix: Document the limitation in dev UX, or implement a TCP-safe shutdown/restart path parallel to the Unix-socket flow.


🎨 UI/UX

[Low] Send stays enabled with a disallowed model on constrained surfaces

File: apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx:2716-2726
Issue: singleReady only checks Boolean(modelId). On constrained surfaces (availableModelIdsOverride), the composer can enable Send while modelId is outside effectiveAvailableModelIds; the user only sees constrainedModelSelectionError after submit (AgentChatPane.tsx:5537-5539).
Fix: Treat constrained surfaces like missing-model when modelId is not in effectiveAvailableModelIds (disable send + surface modelUnavailableMessage in the tooltip).


Notes

  • Runtime freshness checks (build hash, defaultRole, project root) and consolidated migration/config tests look like solid launch hygiene.
  • capabilities.actions.listChanged: false is documented; external clients must poll tool lists instead of relying on push notifications.
  • Large goal.md churn is planning text only — not reviewed for product behavior.
Open in Web View Automation 

Sent by Cursor Automation: BUGBOT in Versic

Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@copilot review but do not make fixes

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d15aeaa00d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/tuiClient/connection.ts Outdated
Comment thread apps/ade-cli/src/adeRpcServer.ts Outdated
Comment thread apps/ade-cli/src/multiProjectRpcServer.ts
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2dabe69cb8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts Outdated
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 30f99ab735

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/cli.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: 9

Caution

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

⚠️ Outside diff range comments (2)
apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx (1)

2623-2631: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Parallel launch bypasses constrained-model blocking.

When modelUnavailableMessage is set, single send is blocked, but the parallel path still allows submit (submitComposerDraft) and enables send (parallelReady) without checking that blocked state. That contradicts the constrained selection behavior and can launch with an invalid/disallowed model setup.

Suggested fix
@@
   const singleModelBlockedMessage = (modelUnavailableMessage?.trim() ?? "").length > 0
     ? modelUnavailableMessage
     : null;
   const singleModelReady = Boolean(modelId) && !singleModelBlockedMessage;
@@
   const submitComposerDraft = useCallback(() => {
@@
     if (parallelChatMode) {
+      if (singleModelBlockedMessage) {
+        onSubmitBlocked?.(singleModelBlockedMessage);
+        return;
+      }
       if (busy || parallelLaunchBusy) return;
       if (parallelModelSlots.length < 2) return;
@@
-  const parallelReady =
+  const parallelReady =
     parallelChatMode
+    && !singleModelBlockedMessage
     && parallelModelSlots.length >= 2
     && (draft.trim().length > 0 || attachments.length > 0 || contextAttachmentCount > 0);
@@
   function sendButtonTitle(): string {
@@
     if (parallelChatMode) {
+      if (singleModelBlockedMessage) return singleModelBlockedMessage;
       if (parallelModelSlots.length < 2) return "Add at least two models";
       if (draft.trim().length === 0 && attachments.length === 0 && contextAttachmentCount === 0) return "Add a message or at least one attachment";
       return "Send to all lanes";
     }

Also applies to: 2713-2732, 2743-2750

🤖 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/chat/AgentChatComposer.tsx` around lines
2623 - 2631, The parallel-send path currently bypasses the constrained-model
block by not checking modelUnavailableMessage (so parallelChatMode can call
onSubmit/submitComposerDraft or set parallelReady even when the selected model
is disallowed); update the parallel branch in AgentChatComposer (the block
guarded by parallelChatMode that references parallelLaunchBusy,
parallelModelSlots, parallelReady, onSubmit/submitComposerDraft) to include the
same modelUnavailableMessage check used in the single-send path and return early
if set, and mirror this check in the other parallel-send blocks around the same
file (the other occurrences you noted) so parallel submissions are blocked when
modelUnavailableMessage indicates an invalid model.
apps/ade-cli/src/cli.ts (1)

13442-13446: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Report the invocation role instead of rereading the environment.

This now prints resolveAdeDefaultRole(process.env.ADE_DEFAULT_ROLE, "agent"), which can disagree with the actual --role used for this command on socket-backed paths. ade --role external auth status will still report the ambient env/default role unless the headless path happened to mutate the env first.

Suggested fix
 function summarizeExecution(args: {
   plan: CliPlan & { kind: "execute" };
   connection: CliConnection;
   values: JsonObject;
+  role: GlobalOptions["role"];
 }): unknown {
-  const { plan, connection, values } = args;
+  const { plan, connection, values, role } = args;
   ...
       authMode:
         connection.mode === "desktop-socket"
           ? "local-desktop-socket"
           : "local-headless-project",
-      role: resolveAdeDefaultRole(process.env.ADE_DEFAULT_ROLE, "agent"),
+      role,
       projectRoot: connection.projectRoot,
-    return summarizeExecution({ plan, connection, values });
+    return summarizeExecution({ plan, connection, values, role: options.role });
🤖 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/ade-cli/src/cli.ts` around lines 13442 - 13446, The role field is
re-evaluating the environment via
resolveAdeDefaultRole(process.env.ADE_DEFAULT_ROLE, "agent") which can disagree
with the actual CLI invocation; instead assign the already-parsed invocation
role (the CLI/argv role variable used when parsing flags — e.g., the parsed
"role" or "argv.role") to the role property alongside authMode (keep the
existing authMode logic that checks connection.mode === "desktop-socket"),
removing the extra resolveAdeDefaultRole call so the reported role matches the
command's --role.
🧹 Nitpick comments (5)
apps/desktop/src/renderer/components/settings/AiFeaturesSection.test.tsx (2)

34-80: ⚡ Quick win

Consider typing the window.ade mock structure.

The installAdeMocks function creates a detailed window.ade structure with inline object literals. If the actual IPC types change, this mock could silently become stale.

♻️ Suggested improvement

Import and cast to the actual preload types:

import type { AdePreloadApi } from '../../preload/types'; // adjust path as needed

function installAdeMocks() {
  (window as any).ade = {
    ai: {
      getStatus: vi.fn().mockResolvedValue({
        // ... existing mock data
      } as Awaited<ReturnType<AdePreloadApi['ai']['getStatus']>>),
      updateConfig: vi.fn().mockResolvedValue(undefined),
    },
    // ... rest of mock
  } satisfies Partial<AdePreloadApi>;
}

This ensures the mock structure stays aligned with actual IPC contracts.

As per coding guidelines, keep IPC contracts, preload types, shared types, and renderer usage in sync whenever an interface changes.

🤖 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/settings/AiFeaturesSection.test.tsx`
around lines 34 - 80, The window.ade mock in installAdeMocks should be typed
against the real preload IPC types so it doesn't drift; import the AdePreloadApi
type (or the correct preload types), cast the ai.getStatus mock resolved value
as Awaited<ReturnType<AdePreloadApi['ai']['getStatus']>> and cast/declare the
whole (window as any).ade assignment as satisfies Partial<AdePreloadApi> (or
equivalent), keeping the existing vi.fn mocks (ai.getStatus, ai.updateConfig,
projectConfig.get) but typed to the real API so failures surface at compile
time.

12-23: ⚡ Quick win

Consider importing actual ModelPicker prop types.

The mock uses an inline type definition that could drift from the actual ModelPicker component signature. Importing the actual props type would improve type safety and catch interface changes at compile time.

♻️ Suggested refactor
+import type { ModelPickerProps } from "../shared/ModelPicker/ModelPicker";
+
 vi.mock("../shared/ModelPicker/ModelPicker", () => {
   return {
-    ModelPicker: (props: { surfaceKey: string; onOpenSignIn?: () => void }) => {
+    ModelPicker: (props: Pick<ModelPickerProps, 'surfaceKey' | 'onOpenSignIn'>) => {
       modelPickerProps.push(props);

As per coding guidelines, IPC contracts, preload types, shared types, and renderer usage should be kept in sync whenever an interface changes.

🤖 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/settings/AiFeaturesSection.test.tsx`
around lines 12 - 23, The inline prop type in the ModelPicker mock can drift
from the real component; import the actual props type from
"../shared/ModelPicker/ModelPicker" (e.g., ModelPickerProps) and use that type
for the mock signature and for modelPickerProps so the mock's signature stays in
sync with the real ModelPicker component; update the mock factory to type its
props parameter with the imported ModelPickerProps and adjust any related
variable typings (modelPickerProps) accordingly.
apps/desktop/src/main/services/lanes/laneService.test.ts (1)

3566-3591: ⚡ Quick win

Fail fast on unhandled git calls in the shared responder.

The default fallback currently returns { exitCode: 1 } for unknown commands, which can mask lane-service git contract drift and let tests pass on unintended paths. Prefer throwing here so new git probes are explicitly handled in each test.

Suggested change
   function makeRunGitResponder(custom?: (args: string[], opts: any) => { exitCode: number; stdout: string; stderr: string } | null) {
     return async (args: string[], opts: any = {}) => {
       if (custom) {
         const v = custom(args, opts);
         if (v) return v;
       }
@@
       if (args[0] === "status" && args[1] === "--porcelain=v1") {
         return { exitCode: 0, stdout: "", stderr: "" };
       }
-      return { exitCode: 1, stdout: "", stderr: `unhandled: ${args.join(" ")}` };
+      throw new Error(`Unexpected git call: ${args.join(" ")}`);
     };
   }
🤖 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/main/services/lanes/laneService.test.ts` around lines 3566 -
3591, The shared test helper makeRunGitResponder currently returns a silent
failure object for unhandled git args; change its default fallback (the final
return in makeRunGitResponder) to throw an Error (including the unhandled
command string) instead of returning { exitCode: 1, ... } so tests fail-fast
when a new git probe is introduced; update any tests that relied on the old
fallback to provide a custom handler via the custom parameter or explicitly mock
the expected git call.
apps/desktop/src/main/services/orchestrator/aiOrchestratorService.test.ts (1)

6951-6956: ⚡ Quick win

Assert exactly one open failed-step intervention in both new regression tests.

some(...) will still pass if duplicate open interventions are created. Since this PR is guarding sync duplication paths, tightening to a count check makes the regression intent explicit.

Suggested assertion tightening
-      expect(refreshed?.interventions.some((entry) =>
-        entry.status === "open" && entry.interventionType === "failed_step"
-      )).toBe(true);
+      const openFailedStepInterventions = refreshed?.interventions.filter(
+        (entry) => entry.status === "open" && entry.interventionType === "failed_step"
+      ) ?? [];
+      expect(openFailedStepInterventions).toHaveLength(1);

Also applies to: 7000-7004

🤖 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/main/services/orchestrator/aiOrchestratorService.test.ts`
around lines 6951 - 6956, The test currently uses
refreshed?.interventions.some(...) which only checks existence and can miss
duplicates; update the assertions for the mission fetched via
fixture.missionService.get(mission.id) to assert exactly one open failed-step
intervention by counting matching entries (e.g., filter refreshed?.interventions
for entry.status === "open" && entry.interventionType === "failed_step" and
expect the resulting length toBe(1)); apply the same tightening to the second
occurrence around lines referencing the same refreshed?.interventions check.
apps/desktop/src/renderer/components/chat/AgentChatPane.tsx (1)

3046-3055: ⚡ Quick win

Make the constrained empty-state message actionable.

No models are available for this chat surface. explains the block, but not how the user can recover. This path now hard-blocks create/send, so the message should include the next action as well.

As per coding guidelines: "Keep user-facing copy concrete and stateful: say what changed, what is blocked, and what the next action is."

🤖 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/chat/AgentChatPane.tsx` around lines
3046 - 3055, constrainedModelSelectionError currently returns an un-actionable
string when there are no available models; update the message returned by the
useMemo (in the constrainedModelSelectionError computation that depends on
modelSelectionConstrained, effectiveAvailableModelIds, and modelId) to state
what changed, what is blocked, and the next action the user should take (for
example: explain that sending is blocked because no models are available for
this chat surface and instruct the user to switch the chat surface or
enable/select models in Settings or Model Selection). Ensure the string replaces
the current "No models are available for this chat surface." text and remains
localized/consistent with existing UX copy conventions.
🤖 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/ade-cli/src/adeRpcServer.ts`:
- Around line 7340-7345: The handler removed dynamic change signaling causing
clients to cache stale tool/action lists; restore either (A) signaling by
re-adding the change hook so actions.listChanged is set true when
listToolSpecsForSession()’s underlying sources
(computerUseArtifactBrokerService.getBackendStatus() and runtime.macosVmService)
change, or (B) make the advertised action set static for the session by
computing and storing the tool list at createAdeRpcRequestHandler() time (use
the runtime and serverVersion closure) and always returning that static list
with actions.listChanged = false; locate logic around
createAdeRpcRequestHandler, actions.listChanged, and listToolSpecsForSession to
implement one of these two fixes so clients won’t see stale or disappearing
computer-use actions.

In `@apps/ade-cli/src/cli.ts`:
- Around line 10802-10810: The early return when runtimeVersion exists and !=
PLACEHOLDER_VERSION skips build-hash/role checks in source builds; change the
condition so it only returns null if both the daemon and the CLI are
non-placeholder versions. Concretely, update the `if (runtimeVersion &&
runtimeVersion !== PLACEHOLDER_VERSION) return null;` to also check the CLI
VERSION (e.g., `&& VERSION !== PLACEHOLDER_VERSION`) so that when `VERSION ===
PLACEHOLDER_VERSION` the subsequent checks against `expectedBuildHash`,
`runtimeInfo.buildHash`, `runtimeInfo.defaultRole`, and `expectedDefaultRole`
still run.

In `@apps/desktop/package.json`:
- Around line 34-36: The unit workspace projects in
apps/desktop/vitest.workspace.ts are including src/main/**/*.test.{ts,tsx} and
src/renderer/**/*.test.{ts,tsx} without excluding integration tests, causing
files like remoteRuntime.offlineRpc.offlineRpc.integration.test.ts to run under
the "test:unit" script; update the unit project configs in vitest.workspace.ts
(the project entries that define include for unit tests) to add exclude:
["**/*.integration.test.{ts,tsx}"] or tighten the include globs to omit
*.integration.test.{ts,tsx} so unit runs no longer pick up integration test
files.

In `@apps/desktop/src/main/services/config/projectConfigService.test.ts`:
- Around line 597-661: The tests that call createLinearFixture() ("merges
shared/local linear sync config with local precedence" and "clamps linear sync
confidence threshold to valid range") only call fixture.db.close() on success;
wrap the test body in try/finally (or add a finally block) so fixture.db.close()
always runs, ensuring the DB handle is closed on assertion failures — locate the
fixture variable created via createLinearFixture() and move the existing
fixture.db.close() call into the finally block (or call fixture.db.close()
inside finally) for both test cases.

In `@apps/desktop/src/main/services/orchestrator/aiOrchestratorService.test.ts`:
- Around line 6981-6996: The test currently assumes startMissionRun created a
step to mark failed which is brittle; explicitly seed a step for the run before
forcing terminal statuses. After obtaining runId from
aiOrchestratorService.startMissionRun, create an orchestrator_steps row tied to
that run (or use an existing fixture helper) with a known id and initial status
(e.g., "pending" or "running") and timestamps, then run the existing
fixture.db.run updates that set status = 'failed' and completed_at/updated_at
using runId and the known step id; reference startMissionRun, runId,
fixture.db.run, and orchestrator_steps when making the change.

In `@apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts`:
- Around line 7047-7079: The current ensureTerminalFailedRunIntervention (in
aiOrchestratorService.ts) bail-out checks any open "failed_step" globally for
the mission, which can suppress or mis-attach interventions when a mission has
multiple failed steps; update this function to reuse the same run-step →
mission-step matching logic used in syncMissionStepsFromRun: for the
failedRunStep find the corresponding missionStep (using the same matcher) and
then check mission.interventions only for an open "failed_step" that targets
that matched missionStep.id (or, if no missionStep matched, target the same
orchestrator run step id via metadata.orchestratorStepId); only create a new
intervention when no such matching open intervention exists and ensure
missionService.addIntervention metadata.stepId/stepKey/orchestratorStepId
reflect the matched identifiers.

In `@apps/desktop/src/main/services/state/kvDb.migrations.test.ts`:
- Around line 56-410: The tests that open a DB using openKvDb (e.g., the it
blocks with descriptions "creates Phase 1.5 context hardening tables and
indexes", "creates mission tables and key indexes", and "creates W2 worker
tables and indexes") currently call db.close() only on the success path; wrap
each test body so that after creating const db = await openKvDb(...) you use a
try { ... } finally { db.close(); } block to ensure the DB handle is always
closed on teardown even when assertions fail; ensure any returns/awaits remain
inside the try block and that db.close() is called in the finally for each
affected it block.

In `@apps/desktop/src/renderer/components/chat/AgentChatPane.tsx`:
- Around line 4838-4841: When constrainedModelSelectionError is encountered in
createSession(), don't resolve to null (which the eager-create path treats as a
successful attempt); instead surface the failure so the caller doesn't flip the
one-shot guard — either throw the constrainedModelSelectionError after calling
setError(constrainedModelSelectionError) or return a rejected Promise so callers
(the eager-create flow) can detect the failure and retry later; update
references in createSession(), constrainedModelSelectionError, and any
eager-create one-shot guard handling to expect a thrown/rejected error rather
than a null sentinel.

In `@apps/desktop/src/renderer/components/shared/ModelPicker/ModelPicker.tsx`:
- Around line 165-185: The early return of models bypasses the constraint logic;
change the start of the memo to not return raw models immediately but instead,
when models && models.length: if constrainToAvailableModelIds is true, build the
same trimmed Set from availableModelIds (as used for selectedValue) and filter
models by id (trim + Boolean) keeping only those present in the Set; if the
filtered list has items return it, otherwise fall through to the existing
fallback/merge logic (so mergeSelectorModels, catalogModels.models, and the rest
handle empties); if constrainToAvailableModelIds is false just return models as
before. Use the existing symbols models, constrainToAvailableModelIds,
availableModelIds, mergeSelectorModels, and catalogModels.models to locate and
implement this change.

---

Outside diff comments:
In `@apps/ade-cli/src/cli.ts`:
- Around line 13442-13446: The role field is re-evaluating the environment via
resolveAdeDefaultRole(process.env.ADE_DEFAULT_ROLE, "agent") which can disagree
with the actual CLI invocation; instead assign the already-parsed invocation
role (the CLI/argv role variable used when parsing flags — e.g., the parsed
"role" or "argv.role") to the role property alongside authMode (keep the
existing authMode logic that checks connection.mode === "desktop-socket"),
removing the extra resolveAdeDefaultRole call so the reported role matches the
command's --role.

In `@apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx`:
- Around line 2623-2631: The parallel-send path currently bypasses the
constrained-model block by not checking modelUnavailableMessage (so
parallelChatMode can call onSubmit/submitComposerDraft or set parallelReady even
when the selected model is disallowed); update the parallel branch in
AgentChatComposer (the block guarded by parallelChatMode that references
parallelLaunchBusy, parallelModelSlots, parallelReady,
onSubmit/submitComposerDraft) to include the same modelUnavailableMessage check
used in the single-send path and return early if set, and mirror this check in
the other parallel-send blocks around the same file (the other occurrences you
noted) so parallel submissions are blocked when modelUnavailableMessage
indicates an invalid model.

---

Nitpick comments:
In `@apps/desktop/src/main/services/lanes/laneService.test.ts`:
- Around line 3566-3591: The shared test helper makeRunGitResponder currently
returns a silent failure object for unhandled git args; change its default
fallback (the final return in makeRunGitResponder) to throw an Error (including
the unhandled command string) instead of returning { exitCode: 1, ... } so tests
fail-fast when a new git probe is introduced; update any tests that relied on
the old fallback to provide a custom handler via the custom parameter or
explicitly mock the expected git call.

In `@apps/desktop/src/main/services/orchestrator/aiOrchestratorService.test.ts`:
- Around line 6951-6956: The test currently uses
refreshed?.interventions.some(...) which only checks existence and can miss
duplicates; update the assertions for the mission fetched via
fixture.missionService.get(mission.id) to assert exactly one open failed-step
intervention by counting matching entries (e.g., filter refreshed?.interventions
for entry.status === "open" && entry.interventionType === "failed_step" and
expect the resulting length toBe(1)); apply the same tightening to the second
occurrence around lines referencing the same refreshed?.interventions check.

In `@apps/desktop/src/renderer/components/chat/AgentChatPane.tsx`:
- Around line 3046-3055: constrainedModelSelectionError currently returns an
un-actionable string when there are no available models; update the message
returned by the useMemo (in the constrainedModelSelectionError computation that
depends on modelSelectionConstrained, effectiveAvailableModelIds, and modelId)
to state what changed, what is blocked, and the next action the user should take
(for example: explain that sending is blocked because no models are available
for this chat surface and instruct the user to switch the chat surface or
enable/select models in Settings or Model Selection). Ensure the string replaces
the current "No models are available for this chat surface." text and remains
localized/consistent with existing UX copy conventions.

In `@apps/desktop/src/renderer/components/settings/AiFeaturesSection.test.tsx`:
- Around line 34-80: The window.ade mock in installAdeMocks should be typed
against the real preload IPC types so it doesn't drift; import the AdePreloadApi
type (or the correct preload types), cast the ai.getStatus mock resolved value
as Awaited<ReturnType<AdePreloadApi['ai']['getStatus']>> and cast/declare the
whole (window as any).ade assignment as satisfies Partial<AdePreloadApi> (or
equivalent), keeping the existing vi.fn mocks (ai.getStatus, ai.updateConfig,
projectConfig.get) but typed to the real API so failures surface at compile
time.
- Around line 12-23: The inline prop type in the ModelPicker mock can drift from
the real component; import the actual props type from
"../shared/ModelPicker/ModelPicker" (e.g., ModelPickerProps) and use that type
for the mock signature and for modelPickerProps so the mock's signature stays in
sync with the real ModelPicker component; update the mock factory to type its
props parameter with the imported ModelPickerProps and adjust any related
variable typings (modelPickerProps) accordingly.
🪄 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: e8e1b9ce-3fa6-4aca-a91d-3e37ce422139

📥 Commits

Reviewing files that changed from the base of the PR and between d5e8456 and 30f99ab.

⛔ Files ignored due to path filters (12)
  • AGENTS.md is excluded by !*.md
  • README.md is excluded by !*.md
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/ade-code/README.md is excluded by !docs/**
  • docs/features/agents/tool-registration.md is excluded by !docs/**
  • docs/features/chat/composer-and-ui.md is excluded by !docs/**
  • docs/features/cto/README.md is excluded by !docs/**
  • docs/features/missions/README.md is excluded by !docs/**
  • docs/features/missions/orchestration.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
  • docs/features/remote-runtime/internal-architecture.md is excluded by !docs/**
  • goal.md is excluded by !*.md
📒 Files selected for processing (98)
  • .gitignore
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/multiProjectRpcServer.ts
  • apps/ade-cli/src/runtimeRoles.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/ade-cli/src/stdioRpcDaemon.test.ts
  • apps/ade-cli/src/tuiClient/__tests__/connection.test.ts
  • apps/ade-cli/src/tuiClient/connection.ts
  • apps/desktop/package.json
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/ai/tools/universalTools.ts
  • apps/desktop/src/main/services/ai/tools/workflowTools.ts
  • apps/desktop/src/main/services/appControl/appControlService.test.ts
  • apps/desktop/src/main/services/appControl/appControlService.ts
  • apps/desktop/src/main/services/chat/agentChatService.suggestLaneName.test.ts
  • apps/desktop/src/main/services/chat/agentChatService.test.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/main/services/config/projectConfigService.aiModeMigration.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.automationExecution.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.laneEnvInit.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.linearSync.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.notifications.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.processGroups.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.providers.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.test.ts
  • apps/desktop/src/main/services/cto/workerAgentService.ts
  • apps/desktop/src/main/services/git/gitOperationsService.branchSwitch.test.ts
  • apps/desktop/src/main/services/git/gitOperationsService.test.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/lanes/laneService.branchSwitch.test.ts
  • apps/desktop/src/main/services/lanes/laneService.test.ts
  • apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.test.ts
  • apps/desktop/src/main/services/localRuntime/localRuntimeConnectionPool.ts
  • apps/desktop/src/main/services/macosVm/macosVmService.test.ts
  • apps/desktop/src/main/services/macosVm/macosVmService.ts
  • apps/desktop/src/main/services/missions/missionPreflightService.ts
  • apps/desktop/src/main/services/missions/missionService.ts
  • apps/desktop/src/main/services/onboarding/onboardingService.ts
  • apps/desktop/src/main/services/orchestrator/aiOrchestratorService.test.ts
  • apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts
  • apps/desktop/src/main/services/orchestrator/coordinatorAgent.ts
  • apps/desktop/src/main/services/orchestrator/coordinatorTools.ts
  • apps/desktop/src/main/services/orchestrator/delegationContracts.ts
  • apps/desktop/src/main/services/orchestrator/executionPolicy.ts
  • apps/desktop/src/main/services/orchestrator/orchestratorContext.ts
  • apps/desktop/src/main/services/orchestrator/orchestratorQueries.ts
  • apps/desktop/src/main/services/orchestrator/orchestratorService.ts
  • apps/desktop/src/main/services/state/kvDb.laneWorktreeLockMigration.test.ts
  • apps/desktop/src/main/services/state/kvDb.migrations.test.ts
  • apps/desktop/src/main/services/state/kvDb.missionsMigration.test.ts
  • apps/desktop/src/main/services/state/kvDb.orchestratorMigration.test.ts
  • apps/desktop/src/main/services/state/kvDb.pipelineSettingsMigration.test.ts
  • apps/desktop/src/main/services/state/kvDb.ts
  • apps/desktop/src/main/services/state/kvDb.workerAgentsMigration.test.ts
  • apps/desktop/src/main/services/usage/usageTrackingService.ts
  • apps/desktop/src/renderer/components/app/AppShell.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatComposer.test.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.submit.test.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/cto/CtoPage.tsx
  • apps/desktop/src/renderer/components/cto/LinearSyncPanel.tsx
  • apps/desktop/src/renderer/components/cto/TeamPanel.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/config/CloseoutConfig.tsx
  • apps/desktop/src/renderer/components/history/eventTaxonomy.ts
  • apps/desktop/src/renderer/components/history/useTimelineLayout.ts
  • apps/desktop/src/renderer/components/lanes/LaneGitActionsPane.tsx
  • apps/desktop/src/renderer/components/lanes/LanesPage.tsx
  • apps/desktop/src/renderer/components/missions/missionThreadEventAdapter.ts
  • apps/desktop/src/renderer/components/settings/AiFeaturesSection.test.tsx
  • apps/desktop/src/renderer/components/settings/AiFeaturesSection.tsx
  • apps/desktop/src/renderer/components/settings/ChatAppearancePreview.tsx
  • apps/desktop/src/renderer/components/settings/LaneTemplatesSection.tsx
  • apps/desktop/src/renderer/components/settings/ProvidersSection.tsx
  • apps/desktop/src/renderer/components/settings/ProxyAndPreviewSection.tsx
  • apps/desktop/src/renderer/components/shared/ModelPicker/ModelPicker.tsx
  • apps/desktop/src/renderer/components/shared/ModelPicker/ModelPickerContent.tsx
  • apps/desktop/src/renderer/lib/computerUse.test.ts
  • apps/desktop/src/renderer/onboarding/tours/ctoTour.ts
  • apps/desktop/src/renderer/onboarding/tours/firstJourneyTour.test.ts
  • apps/desktop/src/renderer/onboarding/tours/firstJourneyTour.ts
  • apps/desktop/src/shared/chatModelSwitching.test.ts
  • apps/desktop/src/shared/chatModelSwitching.ts
  • apps/desktop/src/shared/types/computerUseArtifacts.ts
  • apps/desktop/src/shared/types/orchestrator.ts
  • package.json
  • scripts/dev-all.mjs
  • scripts/dev-code.mjs
  • scripts/dev-desktop.mjs
  • scripts/dev-runtime.mjs
  • scripts/dev-shared.mjs
  • scripts/run-desktop-test-shards.mjs
  • scripts/tui-web.mjs
  • scripts/validate-docs.mjs
💤 Files with no reviewable changes (44)
  • apps/desktop/src/renderer/components/cto/CtoPage.tsx
  • apps/desktop/src/renderer/components/cto/pipeline/config/CloseoutConfig.tsx
  • apps/desktop/src/renderer/components/history/eventTaxonomy.ts
  • apps/desktop/src/main/services/state/kvDb.orchestratorMigration.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.automationExecution.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.processGroups.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.providers.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.notifications.test.ts
  • apps/desktop/src/main/services/state/kvDb.laneWorktreeLockMigration.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.linearSync.test.ts
  • apps/desktop/src/main/services/lanes/laneService.branchSwitch.test.ts
  • apps/desktop/src/renderer/components/history/useTimelineLayout.ts
  • apps/desktop/src/main/services/chat/agentChatService.suggestLaneName.test.ts
  • apps/desktop/src/main/services/state/kvDb.missionsMigration.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.aiModeMigration.test.ts
  • apps/desktop/src/renderer/components/settings/ChatAppearancePreview.tsx
  • apps/desktop/src/main/services/orchestrator/orchestratorService.ts
  • apps/desktop/src/main/services/state/kvDb.workerAgentsMigration.test.ts
  • apps/desktop/src/main/services/state/kvDb.pipelineSettingsMigration.test.ts
  • apps/desktop/src/renderer/components/settings/LaneTemplatesSection.tsx
  • apps/desktop/src/main/services/orchestrator/orchestratorQueries.ts
  • apps/desktop/src/shared/types/orchestrator.ts
  • apps/desktop/src/main/services/git/gitOperationsService.branchSwitch.test.ts
  • apps/desktop/src/renderer/components/settings/ProvidersSection.tsx
  • apps/desktop/src/main/services/usage/usageTrackingService.ts
  • apps/desktop/src/main/services/config/projectConfigService.laneEnvInit.test.ts
  • apps/desktop/src/renderer/components/settings/ProxyAndPreviewSection.tsx
  • apps/desktop/src/main/services/orchestrator/coordinatorAgent.ts
  • apps/desktop/src/renderer/components/app/AppShell.tsx
  • apps/desktop/src/renderer/components/cto/TeamPanel.tsx
  • apps/desktop/src/main/services/missions/missionPreflightService.ts
  • apps/desktop/src/main/services/onboarding/onboardingService.ts
  • apps/desktop/src/main/services/ai/tools/universalTools.ts
  • apps/desktop/src/main/services/missions/missionService.ts
  • apps/desktop/src/renderer/components/lanes/LanesPage.tsx
  • apps/desktop/src/main/services/cto/workerAgentService.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/desktop/src/renderer/onboarding/tours/firstJourneyTour.ts
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/state/kvDb.ts
  • apps/desktop/src/main/services/orchestrator/coordinatorTools.ts
  • apps/desktop/src/renderer/components/missions/missionThreadEventAdapter.ts
  • apps/desktop/src/renderer/components/lanes/LaneGitActionsPane.tsx

Comment thread apps/ade-cli/src/adeRpcServer.ts
Comment thread apps/ade-cli/src/cli.ts Outdated
Comment thread apps/desktop/package.json
Comment thread apps/desktop/src/main/services/config/projectConfigService.test.ts
Comment thread apps/desktop/src/main/services/orchestrator/aiOrchestratorService.test.ts Outdated
Comment thread apps/desktop/src/main/services/state/kvDb.migrations.test.ts
Comment thread apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
Comment thread apps/desktop/src/renderer/components/shared/ModelPicker/ModelPicker.tsx Outdated
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d380ab632b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/adeRpcServer.ts
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a92f249d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/cli.ts Outdated
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 24, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 493ba96dd6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/cli.ts Outdated
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 25, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

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

Caution

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

⚠️ Outside diff range comments (1)
apps/ade-cli/src/cli.ts (1)

10955-10961: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't reject tcp:// runtimes in the allow-spawn path.

Line 10956 still turns every TCP mismatch into a hard failure because isTcpSocket short-circuits the branch. That contradicts the new TCP compatibility behavior: when allowSpawn is true, the existing TCP connection should be kept instead of being rejected here.

Suggested fix
     if (mismatch) {
-      if (!allowSpawn || isTcpSocket) {
+      if (isTcpSocket) {
+        if (!allowSpawn) {
+          client.close();
+          throw new Error(
+            `ADE runtime daemon ${mismatch}.`,
+          );
+        }
+        return client;
+      }
+      if (!allowSpawn) {
         client.close();
         throw new Error(
           `ADE runtime daemon ${mismatch}.`,
         );
       }
🤖 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/ade-cli/src/cli.ts` around lines 10955 - 10961, The current mismatch
handling rejects on either !allowSpawn or isTcpSocket, which causes TCP runtimes
to be hard-failed even when allowSpawn is true; change the condition so we only
close the client and throw when spawning is not allowed (i.e., remove
isTcpSocket from the OR). Update the if that checks mismatch to use if
(!allowSpawn) { client.close(); throw new Error(...) } so that when allowSpawn
is true the existing TCP connection (isTcpSocket) is retained.
🤖 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/main/services/orchestrator/aiOrchestratorService.ts`:
- Around line 7058-7071: The current code picks the first failed run step
(failedRunStep) without checking per-step whether an open "failed_step"
intervention already exists, causing later failures to be ignored; change the
selection to iterate failed run steps (graph.steps.filter(s => s.status ===
"failed")) and choose the first step for which there is no matching open
intervention using the same matching logic (check mission.interventions entries
with status === "open" and interventionType === "failed_step", compare
metadata.stepId to resolved mission step id or metadata.orchestratorStepId to
run step id); set failedRunStep to that chosen step (and compute
failedMissionStep via resolveMissionStepForRunStep for that step) and only
return if no such step exists (also apply analogous logic when starting from
mission.steps if there are no failed run steps).

---

Outside diff comments:
In `@apps/ade-cli/src/cli.ts`:
- Around line 10955-10961: The current mismatch handling rejects on either
!allowSpawn or isTcpSocket, which causes TCP runtimes to be hard-failed even
when allowSpawn is true; change the condition so we only close the client and
throw when spawning is not allowed (i.e., remove isTcpSocket from the OR).
Update the if that checks mismatch to use if (!allowSpawn) { client.close();
throw new Error(...) } so that when allowSpawn is true the existing TCP
connection (isTcpSocket) is retained.
🪄 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: be587e70-53b0-4494-971a-fd474cc3e3e9

📥 Commits

Reviewing files that changed from the base of the PR and between 30f99ab and 045c852.

📒 Files selected for processing (15)
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/multiProjectRpcServer.test.ts
  • apps/ade-cli/src/multiProjectRpcServer.ts
  • apps/ade-cli/src/stdioRpcDaemon.test.ts
  • apps/desktop/src/main/services/config/projectConfigService.test.ts
  • apps/desktop/src/main/services/missions/missionService.ts
  • apps/desktop/src/main/services/orchestrator/aiOrchestratorService.test.ts
  • apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts
  • apps/desktop/src/main/services/state/kvDb.migrations.test.ts
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/shared/ModelPicker/ModelPicker.test.tsx
  • apps/desktop/src/renderer/components/shared/ModelPicker/ModelPicker.tsx
  • apps/desktop/vitest.workspace.ts

Comment thread apps/desktop/src/main/services/orchestrator/aiOrchestratorService.ts Outdated
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented May 25, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@arul28 arul28 merged commit 7b8d9ae into main May 25, 2026
28 checks passed
@arul28 arul28 deleted the ade/huge-cleanup-8469674a branch May 25, 2026 00:46
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