Integration: merge into any lane, parent-head simulation, resolver instructions#135
Conversation
- Store preferred_integration_lane_id on integration_proposals - Extend SimulateIntegrationArgs, CommitIntegrationArgs, CreateIntegrationPrArgs - Add PrAiResolutionStartArgs.additionalInstructions and PrepareResolverSessionArgs field Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
… resolver notes - createIntegrationPr: optional existingIntegrationLaneId merges into that worktree - simulateIntegration: mergeIntoLaneId for merge-tree vs parent head and sequential preview from that HEAD - createIntegrationLaneForProposal: use preferred_integration_lane_id when no binding exists - commitIntegration: dirty-check preferred lane; persist preferred id override - prepareResolverSession: append operator instructions to prompt.md - IPC: pass additionalInstructions from aiResolutionStart Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
…uctions - CreatePrModal: merge-into select, simulation and save proposal preference - IntegrationTab: apply merge-into with proposal replace, advisories, live PR simulate uses integration lane head - PrAiResolverPanel: optional instructions textarea sent as additionalInstructions Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughExtended PR and conflict resolution workflows to support additional AI resolver instructions, preferred integration lane selection, and merge-into lane functionality for enhanced conflict visibility during integration proposal simulation. Added corresponding database schema column and UI controls. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
|
@copilot review |
|
@codex review |
Here is a thorough review of the changes in this PR. Code ReviewSchema / Migration ✅
Types (
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2044cf8a1a
ℹ️ 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".
| } catch { | ||
| mergeIntoHeadSha = null; |
There was a problem hiding this comment.
Fail when merge-into lane HEAD cannot be resolved
When rev-parse for the selected merge-into lane fails, this code silently sets mergeIntoHeadSha to null and continues simulation from baseSha, so the proposal no longer includes merge-into conflicts even though the user explicitly selected that lane. In environments where lane metadata can drift (e.g., branch deleted/renamed outside ADE), this produces falsely clean simulation results instead of surfacing a blocked/error state.
Useful? React with 👍 / 👎.
| if (preferredIntegrationLaneId) { | ||
| const adopt = laneMap.get(preferredIntegrationLaneId); | ||
| if (!adopt) throw new Error(`Preferred integration lane not found: ${preferredIntegrationLaneId}`); | ||
| integrationLane = adopt; | ||
| } else { |
There was a problem hiding this comment.
Enforce dirty-worktree checks before adopting preferred lane
This path adopts preferredIntegrationLaneId directly and then merges clean steps into that worktree, but there is no dirty-worktree guard in createIntegrationLaneForProposal. Because CreatePrModal and Integration tab both call this function before commit-time checks, selecting an existing lane with local changes can turn “dirty worktree” failures into misleading conflict outcomes and mutate/operate on a lane that should have been blocked up front.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
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/prs/tabs/IntegrationTab.tsx (1)
1345-1350:⚠️ Potential issue | 🟡 MinorInvalidate cached results when the merge-into lane changes.
Adding
mergeIntoLaneIdhere means the live simulation result is now keyed by both the source lanes and the integration lane. The reset path still ignoresliveIntegrationLaneId, so a PR that switches to a different integration lane can keep showing the previous preview until the next manual simulate. Please fold the lane id into the invalidation key/deps as well.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/renderer/components/prs/tabs/IntegrationTab.tsx` around lines 1345 - 1350, The live simulation cache and invalidation must include the integration lane ID: when calling window.ade.prs.simulateIntegration you already pass liveIntegrationLaneId, so update the cache key and any reset/clear logic that currently keys only by sourceLaneIds to also incorporate liveIntegrationLaneId (e.g., use a composite key like `${sourceLaneIds.join(',')}:${liveIntegrationLaneId}`), and add liveIntegrationLaneId to any dependency arrays (or equality checks) that trigger re-simulate or reset so switching integration lanes invalidates the previous preview.
🧹 Nitpick comments (2)
apps/desktop/src/shared/types/prs.ts (1)
430-431: Rename "worktree" to "lane" in this field doc.This property models ADE lane selection, so keeping the comment on lane terminology will match the renderer and service code.
As per coding guidelines: Use 'lane' terminology for ADE worktrees/branches.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/shared/types/prs.ts` around lines 430 - 431, Update the JSDoc/comment for the property preferredIntegrationLaneId to replace the word "worktree" with "lane" so the doc reads "Preferred integration lane when none exists yet (merge sources here instead of a new lane)." Locate the comment immediately above the preferredIntegrationLaneId declaration and edit it to use "lane" terminology to match ADE renderer and service code.apps/desktop/src/main/services/prs/prService.ts (1)
4144-4154: Consider validating preferred lane HEAD matches simulation expectations.When adopting a
preferredIntegrationLaneId, the lane is used as-is without verifying its current HEAD SHA matches what was used during simulation. If the lane has been modified (commits added, rebased) since the simulation ran, the actual merge results may differ from what the simulation predicted.This is acceptable since merge failures are caught downstream (lines 4167-4173), but logging a warning when the HEAD differs could help users understand why results don't match expectations.
🔧 Optional: Add HEAD drift detection
let integrationLane: LaneSummary; if (preferredIntegrationLaneId) { const adopt = laneMap.get(preferredIntegrationLaneId); if (!adopt) throw new Error(`Preferred integration lane not found: ${preferredIntegrationLaneId}`); integrationLane = adopt; + // Best-effort: warn if lane HEAD may have drifted since simulation + try { + const currentHead = (await runGit( + ["rev-parse", "HEAD"], + { cwd: adopt.worktreePath, timeoutMs: 10_000 } + )).stdout.trim(); + logger.info("prs.integration_lane_adopted", { + proposalId: args.proposalId, + laneId: adopt.id, + currentHead, + }); + } catch { /* best-effort */ } } else {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/desktop/src/main/services/prs/prService.ts` around lines 4144 - 4154, When adopting a preferredIntegrationLaneId from laneMap, fetch its current HEAD SHA and compare it to the SHA used during the simulation (the value stored on the preflight/simulation context); if they differ log a warning indicating HEAD drift and include both SHAs and the preferredIntegrationLaneId so users know simulation vs actual HEAD, then continue using the lane (leave existing merge-failure handling intact). Locate the adoption branch around preferredIntegrationLaneId / laneMap.get(...) and integrationLane assignment (and where preflight/simulation SHAs are stored) and add the HEAD comparison and warning via the existing logging facility before setting integrationLane or proceeding to laneService.createChild.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/desktop/src/renderer/components/prs/tabs/IntegrationTab.tsx`:
- Around line 2068-2069: The helper copy in IntegrationTab's descriptive
paragraph uses "integration worktree" which conflicts with ADE's lane
terminology; update the sentence in the <p> inside IntegrationTab to use "lane"
wording (e.g., "Choose an existing lane as the integration lane (for example the
parent prompt lane). Simulation then includes conflicts against that lane's
current HEAD; source lanes still merge in list order.") so it consistently uses
'lane' terminology across the UI.
- Around line 1248-1282: In handleApplyMergeIntoTarget, the current sequence
creates the new proposal (simulateIntegration) then deletes the old proposal
before updating the new one, risking partial state if update fails; change the
flow to mirror handleResimulate by first calling simulateIntegration then
immediately call updateProposal on persisted.proposalId to populate
title/body/draft/integrationLaneName, only after a successful update attempt
perform deleteProposal on the oldId as a best-effort cleanup (catch and log but
do not surface failure), and ensure UI actions that operate on the selected
proposal (Create PR / re-simulate / delete) are disabled while mergeIntoLaneBusy
is true so siblings cannot act on a stale selection.
---
Outside diff comments:
In `@apps/desktop/src/renderer/components/prs/tabs/IntegrationTab.tsx`:
- Around line 1345-1350: The live simulation cache and invalidation must include
the integration lane ID: when calling window.ade.prs.simulateIntegration you
already pass liveIntegrationLaneId, so update the cache key and any reset/clear
logic that currently keys only by sourceLaneIds to also incorporate
liveIntegrationLaneId (e.g., use a composite key like
`${sourceLaneIds.join(',')}:${liveIntegrationLaneId}`), and add
liveIntegrationLaneId to any dependency arrays (or equality checks) that trigger
re-simulate or reset so switching integration lanes invalidates the previous
preview.
---
Nitpick comments:
In `@apps/desktop/src/main/services/prs/prService.ts`:
- Around line 4144-4154: When adopting a preferredIntegrationLaneId from
laneMap, fetch its current HEAD SHA and compare it to the SHA used during the
simulation (the value stored on the preflight/simulation context); if they
differ log a warning indicating HEAD drift and include both SHAs and the
preferredIntegrationLaneId so users know simulation vs actual HEAD, then
continue using the lane (leave existing merge-failure handling intact). Locate
the adoption branch around preferredIntegrationLaneId / laneMap.get(...) and
integrationLane assignment (and where preflight/simulation SHAs are stored) and
add the HEAD comparison and warning via the existing logging facility before
setting integrationLane or proceeding to laneService.createChild.
In `@apps/desktop/src/shared/types/prs.ts`:
- Around line 430-431: Update the JSDoc/comment for the property
preferredIntegrationLaneId to replace the word "worktree" with "lane" so the doc
reads "Preferred integration lane when none exists yet (merge sources here
instead of a new lane)." Locate the comment immediately above the
preferredIntegrationLaneId declaration and edit it to use "lane" terminology to
match ADE renderer and service code.
🪄 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: 670c0d54-5ccc-4cf2-931b-d8ce1e60b20f
📒 Files selected for processing (11)
apps/desktop/src/main/services/conflicts/conflictService.tsapps/desktop/src/main/services/ipc/registerIpc.tsapps/desktop/src/main/services/prs/prService.tsapps/desktop/src/main/services/state/kvDb.missionsMigration.test.tsapps/desktop/src/main/services/state/kvDb.tsapps/desktop/src/renderer/components/prs/CreatePrModal.tsxapps/desktop/src/renderer/components/prs/shared/PrAiResolverPanel.tsxapps/desktop/src/renderer/components/prs/tabs/IntegrationTab.tsxapps/desktop/src/shared/types/conflicts.tsapps/desktop/src/shared/types/prs.tsapps/ios/ADE/Resources/DatabaseBootstrap.sql
| const handleApplyMergeIntoTarget = React.useCallback(async () => { | ||
| if (!selectedProposal) return; | ||
| const trimmed = mergeIntoLaneDraft.trim(); | ||
| if (trimmed && selectedProposal.sourceLaneIds.includes(trimmed)) { | ||
| setCommitError("Merge-into lane cannot be one of the source lanes."); | ||
| return; | ||
| } | ||
| setMergeIntoLaneBusy(true); | ||
| setCommitError(null); | ||
| try { | ||
| const oldId = selectedProposal.proposalId; | ||
| const persisted = await window.ade.prs.simulateIntegration({ | ||
| sourceLaneIds: selectedProposal.sourceLaneIds, | ||
| baseBranch: selectedProposal.baseBranch, | ||
| mergeIntoLaneId: trimmed || null, | ||
| }); | ||
| await window.ade.prs.deleteProposal({ proposalId: oldId, deleteIntegrationLane: false }); | ||
| await window.ade.prs.updateProposal({ | ||
| proposalId: persisted.proposalId, | ||
| preferredIntegrationLaneId: trimmed || null, | ||
| ...(selectedProposal.title ? { title: selectedProposal.title } : {}), | ||
| ...(selectedProposal.body !== undefined ? { body: selectedProposal.body } : {}), | ||
| ...(selectedProposal.draft !== undefined ? { draft: selectedProposal.draft } : {}), | ||
| ...(selectedProposal.integrationLaneName ? { integrationLaneName: selectedProposal.integrationLaneName } : {}), | ||
| }); | ||
| setResolutionState(null); | ||
| await loadProposals(); | ||
| setSelectedProposalId(persisted.proposalId); | ||
| } catch (err: unknown) { | ||
| setCommitError(err instanceof Error ? err.message : String(err)); | ||
| await loadProposals(); | ||
| } finally { | ||
| setMergeIntoLaneBusy(false); | ||
| } | ||
| }, [loadProposals, mergeIntoLaneDraft, selectedProposal]); |
There was a problem hiding this comment.
Make the proposal replacement flow failure-safe.
This swap creates the replacement proposal first, but deletes the current row before the replacement is updated. If either mutation fails, the user can be left with duplicate proposals or a new row missing its saved title/body/draft/lane metadata. While it runs, the Create PR / re-simulate / delete actions also stay enabled against the stale selection. Mirror handleResimulate: update the new row first, treat old-row cleanup as best-effort, and gate sibling proposal actions on mergeIntoLaneBusy.
Possible sequencing fix
const persisted = await window.ade.prs.simulateIntegration({
sourceLaneIds: selectedProposal.sourceLaneIds,
baseBranch: selectedProposal.baseBranch,
mergeIntoLaneId: trimmed || null,
});
- await window.ade.prs.deleteProposal({ proposalId: oldId, deleteIntegrationLane: false });
await window.ade.prs.updateProposal({
proposalId: persisted.proposalId,
preferredIntegrationLaneId: trimmed || null,
...(selectedProposal.title ? { title: selectedProposal.title } : {}),
...(selectedProposal.body !== undefined ? { body: selectedProposal.body } : {}),
...(selectedProposal.draft !== undefined ? { draft: selectedProposal.draft } : {}),
...(selectedProposal.integrationLaneName ? { integrationLaneName: selectedProposal.integrationLaneName } : {}),
});
+ let cleanupWarning: string | null = null;
+ try {
+ await window.ade.prs.deleteProposal({ proposalId: oldId, deleteIntegrationLane: false });
+ } catch (cleanupError) {
+ cleanupWarning = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
+ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/desktop/src/renderer/components/prs/tabs/IntegrationTab.tsx` around
lines 1248 - 1282, In handleApplyMergeIntoTarget, the current sequence creates
the new proposal (simulateIntegration) then deletes the old proposal before
updating the new one, risking partial state if update fails; change the flow to
mirror handleResimulate by first calling simulateIntegration then immediately
call updateProposal on persisted.proposalId to populate
title/body/draft/integrationLaneName, only after a successful update attempt
perform deleteProposal on the oldId as a best-effort cleanup (catch and log but
do not surface failure), and ensure UI actions that operate on the selected
proposal (Create PR / re-simulate / delete) are disabled while mergeIntoLaneBusy
is true so siblings cannot act on a stale selection.
| <p className="font-mono" style={{ fontSize: 10, color: "#71717A", marginBottom: 12, lineHeight: "16px" }}> | ||
| Choose an existing lane as the integration worktree (for example the parent prompt lane). Simulation then includes conflicts against that lane's current HEAD; source lanes still merge in list order. |
There was a problem hiding this comment.
Use lane terminology in this helper copy.
"Integration worktree" reads like a different concept from the lane selector directly below it. existing lane keeps the wording consistent across ADE.
As per coding guidelines: Use 'lane' terminology for ADE worktrees/branches.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/desktop/src/renderer/components/prs/tabs/IntegrationTab.tsx` around
lines 2068 - 2069, The helper copy in IntegrationTab's descriptive paragraph
uses "integration worktree" which conflicts with ADE's lane terminology; update
the sentence in the <p> inside IntegrationTab to use "lane" wording (e.g.,
"Choose an existing lane as the integration lane (for example the parent prompt
lane). Simulation then includes conflicts against that lane's current HEAD;
source lanes still merge in list order.") so it consistently uses 'lane'
terminology across the UI.
…roposal swap - Fail simulateIntegration when merge-into lane HEAD cannot be resolved (Codex) - Store merge_into_head_sha on proposals; warn on drift when adopting preferred lane - createIntegrationLaneForProposal: assertDirtyWorktrees for sources + preferred lane; optional allowDirtyWorktree - IntegrationTab: reorder apply-merge flow (update before delete), gate actions on mergeIntoLaneBusy, include liveIntegrationLaneId in simulation reset key, filter source lanes from merge-into picker, lane terminology and advisory copy, dirty-worktree confirm for prepare lane - CreatePrModal: runWithDirtyWorktreeConfirmation around createIntegrationLaneForProposal - Fix SimulateIntegrationArgs JSDoc (pairwise vs sequential merge base) Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
9eb8c73
into
cursor/multiple-model-prompt-lanes-bb23
…structions (#135) * Add integration proposal preferred lane column and resolver prompt types - Store preferred_integration_lane_id on integration_proposals - Extend SimulateIntegrationArgs, CommitIntegrationArgs, CreateIntegrationPrArgs - Add PrAiResolutionStartArgs.additionalInstructions and PrepareResolverSessionArgs field Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Integrate into existing lanes, simulate parent-head conflicts, append resolver notes - createIntegrationPr: optional existingIntegrationLaneId merges into that worktree - simulateIntegration: mergeIntoLaneId for merge-tree vs parent head and sequential preview from that HEAD - createIntegrationLaneForProposal: use preferred_integration_lane_id when no binding exists - commitIntegration: dirty-check preferred lane; persist preferred id override - prepareResolverSession: append operator instructions to prompt.md - IPC: pass additionalInstructions from aiResolutionStart Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * UI: merge-into lane picker, re-simulate flow, optional resolver instructions - CreatePrModal: merge-into select, simulation and save proposal preference - IntegrationTab: apply merge-into with proposal replace, advisories, live PR simulate uses integration lane head - PrAiResolverPanel: optional instructions textarea sent as additionalInstructions Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Address PR review: merge-into HEAD persistence, dirty checks, safer proposal swap - Fail simulateIntegration when merge-into lane HEAD cannot be resolved (Codex) - Store merge_into_head_sha on proposals; warn on drift when adopting preferred lane - createIntegrationLaneForProposal: assertDirtyWorktrees for sources + preferred lane; optional allowDirtyWorktree - IntegrationTab: reorder apply-merge flow (update before delete), gate actions on mergeIntoLaneBusy, include liveIntegrationLaneId in simulation reset key, filter source lanes from merge-into picker, lane terminology and advisory copy, dirty-worktree confirm for prepare lane - CreatePrModal: runWithDirtyWorktreeConfirmation around createIntegrationLaneForProposal - Fix SimulateIntegrationArgs JSDoc (pairwise vs sequential merge base) Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
…structions (#135) * Add integration proposal preferred lane column and resolver prompt types - Store preferred_integration_lane_id on integration_proposals - Extend SimulateIntegrationArgs, CommitIntegrationArgs, CreateIntegrationPrArgs - Add PrAiResolutionStartArgs.additionalInstructions and PrepareResolverSessionArgs field Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Integrate into existing lanes, simulate parent-head conflicts, append resolver notes - createIntegrationPr: optional existingIntegrationLaneId merges into that worktree - simulateIntegration: mergeIntoLaneId for merge-tree vs parent head and sequential preview from that HEAD - createIntegrationLaneForProposal: use preferred_integration_lane_id when no binding exists - commitIntegration: dirty-check preferred lane; persist preferred id override - prepareResolverSession: append operator instructions to prompt.md - IPC: pass additionalInstructions from aiResolutionStart Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * UI: merge-into lane picker, re-simulate flow, optional resolver instructions - CreatePrModal: merge-into select, simulation and save proposal preference - IntegrationTab: apply merge-into with proposal replace, advisories, live PR simulate uses integration lane head - PrAiResolverPanel: optional instructions textarea sent as additionalInstructions Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Address PR review: merge-into HEAD persistence, dirty checks, safer proposal swap - Fail simulateIntegration when merge-into lane HEAD cannot be resolved (Codex) - Store merge_into_head_sha on proposals; warn on drift when adopting preferred lane - createIntegrationLaneForProposal: assertDirtyWorktrees for sources + preferred lane; optional allowDirtyWorktree - IntegrationTab: reorder apply-merge flow (update before delete), gate actions on mergeIntoLaneBusy, include liveIntegrationLaneId in simulation reset key, filter source lanes from merge-into picker, lane terminology and advisory copy, dirty-worktree confirm for prepare lane - CreatePrModal: runWithDirtyWorktreeConfirmation around createIntegrationLaneForProposal - Fix SimulateIntegrationArgs JSDoc (pairwise vs sequential merge base) Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
…structions (#135) * Add integration proposal preferred lane column and resolver prompt types - Store preferred_integration_lane_id on integration_proposals - Extend SimulateIntegrationArgs, CommitIntegrationArgs, CreateIntegrationPrArgs - Add PrAiResolutionStartArgs.additionalInstructions and PrepareResolverSessionArgs field Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Integrate into existing lanes, simulate parent-head conflicts, append resolver notes - createIntegrationPr: optional existingIntegrationLaneId merges into that worktree - simulateIntegration: mergeIntoLaneId for merge-tree vs parent head and sequential preview from that HEAD - createIntegrationLaneForProposal: use preferred_integration_lane_id when no binding exists - commitIntegration: dirty-check preferred lane; persist preferred id override - prepareResolverSession: append operator instructions to prompt.md - IPC: pass additionalInstructions from aiResolutionStart Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * UI: merge-into lane picker, re-simulate flow, optional resolver instructions - CreatePrModal: merge-into select, simulation and save proposal preference - IntegrationTab: apply merge-into with proposal replace, advisories, live PR simulate uses integration lane head - PrAiResolverPanel: optional instructions textarea sent as additionalInstructions Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Address PR review: merge-into HEAD persistence, dirty checks, safer proposal swap - Fail simulateIntegration when merge-into lane HEAD cannot be resolved (Codex) - Store merge_into_head_sha on proposals; warn on drift when adopting preferred lane - createIntegrationLaneForProposal: assertDirtyWorktrees for sources + preferred lane; optional allowDirtyWorktree - IntegrationTab: reorder apply-merge flow (update before delete), gate actions on mergeIntoLaneBusy, include liveIntegrationLaneId in simulation reset key, filter source lanes from merge-into picker, lane terminology and advisory copy, dirty-worktree confirm for prepare lane - CreatePrModal: runWithDirtyWorktreeConfirmation around createIntegrationLaneForProposal - Fix SimulateIntegrationArgs JSDoc (pairwise vs sequential merge base) Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
…structions (#135) * Add integration proposal preferred lane column and resolver prompt types - Store preferred_integration_lane_id on integration_proposals - Extend SimulateIntegrationArgs, CommitIntegrationArgs, CreateIntegrationPrArgs - Add PrAiResolutionStartArgs.additionalInstructions and PrepareResolverSessionArgs field Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Integrate into existing lanes, simulate parent-head conflicts, append resolver notes - createIntegrationPr: optional existingIntegrationLaneId merges into that worktree - simulateIntegration: mergeIntoLaneId for merge-tree vs parent head and sequential preview from that HEAD - createIntegrationLaneForProposal: use preferred_integration_lane_id when no binding exists - commitIntegration: dirty-check preferred lane; persist preferred id override - prepareResolverSession: append operator instructions to prompt.md - IPC: pass additionalInstructions from aiResolutionStart Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * UI: merge-into lane picker, re-simulate flow, optional resolver instructions - CreatePrModal: merge-into select, simulation and save proposal preference - IntegrationTab: apply merge-into with proposal replace, advisories, live PR simulate uses integration lane head - PrAiResolverPanel: optional instructions textarea sent as additionalInstructions Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Address PR review: merge-into HEAD persistence, dirty checks, safer proposal swap - Fail simulateIntegration when merge-into lane HEAD cannot be resolved (Codex) - Store merge_into_head_sha on proposals; warn on drift when adopting preferred lane - createIntegrationLaneForProposal: assertDirtyWorktrees for sources + preferred lane; optional allowDirtyWorktree - IntegrationTab: reorder apply-merge flow (update before delete), gate actions on mergeIntoLaneBusy, include liveIntegrationLaneId in simulation reset key, filter source lanes from merge-into picker, lane terminology and advisory copy, dirty-worktree confirm for prepare lane - CreatePrModal: runWithDirtyWorktreeConfirmation around createIntegrationLaneForProposal - Fix SimulateIntegrationArgs JSDoc (pairwise vs sequential merge base) Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
…structions (#135) * Add integration proposal preferred lane column and resolver prompt types - Store preferred_integration_lane_id on integration_proposals - Extend SimulateIntegrationArgs, CommitIntegrationArgs, CreateIntegrationPrArgs - Add PrAiResolutionStartArgs.additionalInstructions and PrepareResolverSessionArgs field Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Integrate into existing lanes, simulate parent-head conflicts, append resolver notes - createIntegrationPr: optional existingIntegrationLaneId merges into that worktree - simulateIntegration: mergeIntoLaneId for merge-tree vs parent head and sequential preview from that HEAD - createIntegrationLaneForProposal: use preferred_integration_lane_id when no binding exists - commitIntegration: dirty-check preferred lane; persist preferred id override - prepareResolverSession: append operator instructions to prompt.md - IPC: pass additionalInstructions from aiResolutionStart Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * UI: merge-into lane picker, re-simulate flow, optional resolver instructions - CreatePrModal: merge-into select, simulation and save proposal preference - IntegrationTab: apply merge-into with proposal replace, advisories, live PR simulate uses integration lane head - PrAiResolverPanel: optional instructions textarea sent as additionalInstructions Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> * Address PR review: merge-into HEAD persistence, dirty checks, safer proposal swap - Fail simulateIntegration when merge-into lane HEAD cannot be resolved (Codex) - Store merge_into_head_sha on proposals; warn on drift when adopting preferred lane - createIntegrationLaneForProposal: assertDirtyWorktrees for sources + preferred lane; optional allowDirtyWorktree - IntegrationTab: reorder apply-merge flow (update before delete), gate actions on mergeIntoLaneBusy, include liveIntegrationLaneId in simulation reset key, filter source lanes from merge-into picker, lane terminology and advisory copy, dirty-worktree confirm for prepare lane - CreatePrModal: runWithDirtyWorktreeConfirmation around createIntegrationLaneForProposal - Fix SimulateIntegrationArgs JSDoc (pairwise vs sequential merge base) Co-authored-by: Arul Sharma <arul28@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Arul Sharma <arul28@users.noreply.github.com>
Summary
Extends the integration workflow so merges can target an existing lane (not only a new integration child), simulation accounts for ongoing work on that lane (merge-tree and sequential preview from its current HEAD), and the AI resolver accepts optional operator instructions appended to the generated prompt.
Follow-up (review feedback)
mergeIntoLaneIdis set, failing to resolve that lane’s HEAD now errors instead of silently simulating from base only.createIntegrationLaneForProposalnow runs dirty-worktree checks on source lanes plus the preferred integration lane; optionalallowDirtyWorktreefor IPC/UI confirmation paths.handleApplyMergeIntoTargetupdates the new proposal before best-effort delete of the old row; Create PR / re-simulate / delete gated while merge-into apply runs; live simulate resets whenliveIntegrationLaneIdchanges; merge-into picker hides source lanes; copy uses lane terminology; advisory text distinguishes pairwise merge base vs sequential preview.merge_into_head_shacolumn stores the merge-into HEAD at simulation time; adopting a preferred lane logs a warning if HEAD differs.Changes
integration_proposals.preferred_integration_lane_id,merge_into_head_sha(SQLite migration inkvDb, iOS bootstrap aligned).SimulateIntegrationArgs.mergeIntoLaneId,CreateIntegrationPrArgs.existingIntegrationLaneId,CommitIntegrationArgs.preferredIntegrationLaneId,IntegrationProposalfields,UpdateIntegrationProposalArgs,CreateIntegrationLaneForProposalArgs.allowDirtyWorktree, resolver instruction types.prService, conflict resolver, UI as in prior revision.Validation
npm --prefix apps/desktop run typechecknpm --prefix apps/desktop run test -- --run src/main/services/prs/prService.integrationCommit.test.ts src/main/services/state/kvDb.missionsMigration.test.tsnpm --prefix apps/desktop run lintNotes
Summary by CodeRabbit