Skip to content

Commit 49efe29

Browse files
arul28claudecursoragent
authored
Chat 20260608 131523 (#563)
* Replace Path to Merge deterministic engine with agent watcher (desktop + iOS) Desktop: thin main-process scheduler injects watch turns into a visible chat agent per PR; removes standalone resolver + inventory digestion. iOS: migrate PR-detail surface to the agent-watcher model. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Remove Path to Merge and convergence pipeline from ADE. Drop the deterministic orchestrator, issue inventory, convergence UI, and related IPC/sync/iOS surfaces so PR workflows rely on queue, merge rails, and agent-driven ship instead. Co-authored-by: Cursor <cursoragent@cursor.com> * Clear legacy Path to Merge worktree locks on DB open. After removing the PtM pipeline, orphaned path_to_merge and pr_issue_resolution locks could block conflict_resolution until lease expiry. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent b164ba7 commit 49efe29

104 files changed

Lines changed: 227 additions & 26648 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/ade-perf-prs/SKILL.md

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ metadata:
1515

1616
Use this as engineering guidance for keeping the PRs tab fast while adding
1717
features. The PRs tab combines external GitHub search, local lane links,
18-
mergeability, queue/integration workflows, Path to Merge state, review threads,
18+
mergeability, queue/integration workflows, merge readiness, review threads,
1919
files, CI, and activity. Keep first paint local and defer expensive live GitHub
2020
or Git operations until the visible surface needs them.
2121

@@ -98,7 +98,7 @@ or Git operations until the visible surface needs them.
9898

9999
- **Why it helped**: Workflow pages previously fanned out merge-context calls
100100
and each one could pay for lane status work.
101-
- **Apply when**: Queue, integration, rebase/merge, or Path to Merge surfaces
101+
- **Apply when**: Queue, integration, rebase/merge, or merge-rail surfaces
102102
need per-PR merge context.
103103
- **Avoid**: Looping over `getMergeContext` or using bare `laneService.list()`
104104
from merge-context helpers.
@@ -133,18 +133,3 @@ or Git operations until the visible surface needs them.
133133
`prs-ui-rebase-fetch-ttl-20260512-062130`, queue reload lane reads dropped
134134
from `1393ms` to `47-80ms`, and `listAutoRebaseStatuses` dropped from
135135
`1404-1407ms` to `40-70ms`.
136-
137-
### Keep Path to Merge start/stop local and state-first
138-
139-
- **Why it helped**: Path to Merge controls should react to local pipeline
140-
settings, convergence state, and issue inventory without waiting on a full PR
141-
refresh or workflow sweep.
142-
- **Apply when**: Editing `PrConvergencePanel`, pipeline settings, issue
143-
inventory sync, or Path to Merge IPC.
144-
- **Avoid**: Coupling the start/stop buttons to fresh detail hydration, merge
145-
context fan-out, or agent dispatch prework that can run after the local state
146-
transition.
147-
- **Verification**: In `prs-ui-ptm-audit-20260512-0635`, with PLAN mode and
148-
auto-merge off, the UI covered native Path to Merge start/stop safely:
149-
`ade.prs.pathToMerge.start` completed in `5ms` and
150-
`ade.prs.pathToMerge.stop` completed in `2ms`.

apps/ade-cli/README.md

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,8 @@ ade prs create --lane lane-id --base main --title "Fix checkout flow" --text #
273273
ade prs create --lane lane-id --base main --close-linear-issue-on-merge
274274
ade prs list-open --text
275275
ade prs github-snapshot --include-external-closed
276-
ade prs path-to-merge --pr pr-id --model gpt-5.5 --max-rounds 3 --no-auto-merge
277-
ade prs path-to-merge --pr pr-id --model gpt-5.5 --conflict-strategy auto --force-finalize conditional
278-
ade prs pipeline pr-id save --conflict-strategy rebase --no-early-merge-on-green
276+
ade prs checks pr-id --text
277+
ade prs comments pr-id --text
279278
ade run defs --text
280279
ade run start web --lane lane-id
281280
ade shell start --lane lane-id -- npm test
@@ -407,25 +406,6 @@ npm run package:beta # origin/main -> ADE Beta.app, ade-beta, ~/.ade-bet
407406

408407
Use these when you want a production-shaped local app without going through the GitHub release workflow. Alpha builds from the current checkout under `apps/desktop/release-alpha`; beta fetches `origin/main`, fast-forwards the local `main` checkout when possible, and writes artifacts under `apps/desktop/release-beta`. Use the dev scripts when you want Vite/Electron live reload, the temp dev endpoint, and the dev-only Electron profile. Local channel packages include the current machine's runtime binary. GitHub release builds use and validate the full cross-platform runtime artifact set.
409408

410-
The `prs path-to-merge` and `prs pipeline save` commands persist a partial `PipelineSettings` patch via `issue_inventory.savePipelineSettings` before launching the resolver. The Path to Merge orchestrator reads these from saved settings, so the same flags work either way:
411-
412-
| Flag | PipelineSettings field | Values |
413-
| --- | --- | --- |
414-
| `--max-rounds <n>` (alias `--rounds`) | `maxRounds` | positive integer |
415-
| `--auto-merge` / `--no-auto-merge` | `autoMerge` | boolean |
416-
| `--merge-method <m>` | `mergeMethod` | `repo_default` \| `merge` \| `squash` \| `rebase` |
417-
| `--conflict-strategy <s>` | `conflictStrategy` | `pause` \| `rebase` \| `merge` \| `auto` |
418-
| `--force-finalize <m>` | `forceFinalizeMode` | `off` \| `conditional` \| `unconditional` |
419-
| `--force-finalize-require-no-ci` / `--force-finalize-allow-ci` | `forceFinalizeRequireNoCiFailures` | boolean |
420-
| `--early-merge-on-green` / `--no-early-merge-on-green` | `earlyMergeOnGreen` | boolean |
421-
422-
To set fields without a dedicated flag (for example `autoAgentSettings`), call the action directly:
423-
424-
```bash
425-
ade actions run issue_inventory.savePipelineSettings --args-list-json \
426-
'["pr-1",{"autoAgentSettings":{"provider":"claude","model":"sonnet","reasoningEffort":"high","permissionMode":"guarded_edit","confidenceThreshold":0.7}}]'
427-
```
428-
429409
## Automations
430410

431411
Automation rules are managed with `ade automations <subcommand>`. Run `ade help automations` for the full flag reference. The lane-mode flags layer on top of `--from-file` / `--stdin` / `--text` for `create` and `update`:

apps/ade-cli/src/adeRpcServer.test.ts

Lines changed: 0 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -307,86 +307,6 @@ function createRuntime() {
307307
stop: vi.fn(),
308308
getLogTail: vi.fn(() => "")
309309
},
310-
issueInventoryService: (() => {
311-
const runtimeByPr = new Map<string, Record<string, unknown>>();
312-
const inventoryByPr = new Map<string, Record<string, unknown>>();
313-
const pipelineByPr = new Map<string, Record<string, unknown>>();
314-
315-
const defaultRuntime = (prId: string) => ({
316-
prId,
317-
autoConvergeEnabled: false,
318-
status: "idle",
319-
pollerStatus: "idle",
320-
currentRound: 0,
321-
activeSessionId: null,
322-
activeLaneId: null,
323-
activeHref: null,
324-
pauseReason: null,
325-
errorMessage: null,
326-
lastStartedAt: null,
327-
lastPolledAt: null,
328-
lastPausedAt: null,
329-
lastStoppedAt: null,
330-
createdAt: "2026-03-17T19:00:00.000Z",
331-
updatedAt: "2026-03-17T19:00:00.000Z",
332-
});
333-
334-
const defaultPipeline = () => ({
335-
autoMerge: false,
336-
mergeMethod: "repo_default",
337-
maxRounds: 5,
338-
onRebaseNeeded: "pause",
339-
});
340-
341-
return {
342-
syncFromPrData: vi.fn((prId: string) => {
343-
const runtime = { ...defaultRuntime(prId), ...runtimeByPr.get(prId) };
344-
const existingSnapshot = inventoryByPr.get(prId) ?? null;
345-
const snapshot = {
346-
prId,
347-
items: existingSnapshot?.items ?? [],
348-
convergence: {
349-
currentRound: typeof runtime.currentRound === "number" ? runtime.currentRound : 0,
350-
maxRounds: { ...defaultPipeline(), ...pipelineByPr.get(prId) }.maxRounds,
351-
issuesPerRound: [],
352-
totalNew: 0,
353-
totalFixed: 0,
354-
totalDismissed: 0,
355-
totalEscalated: 0,
356-
totalSentToAgent: 0,
357-
isConverging: false,
358-
canAutoAdvance: false,
359-
},
360-
runtime,
361-
};
362-
inventoryByPr.set(prId, snapshot);
363-
return snapshot;
364-
}),
365-
getConvergenceRuntime: vi.fn((prId: string) => ({
366-
...defaultRuntime(prId),
367-
...runtimeByPr.get(prId),
368-
})),
369-
getPipelineSettings: vi.fn((prId: string) => ({
370-
...defaultPipeline(),
371-
...pipelineByPr.get(prId),
372-
})),
373-
getNewItems: vi.fn((_prId: string) => []),
374-
markSentToAgent: vi.fn(),
375-
privateMaintenanceTask: vi.fn(),
376-
resetInventory: vi.fn(),
377-
saveConvergenceRuntime: vi.fn((prId: string, state: Record<string, unknown>) => {
378-
const existing = runtimeByPr.get(prId) ?? {};
379-
const merged = { ...defaultRuntime(prId), ...existing, ...state };
380-
runtimeByPr.set(prId, merged);
381-
return merged;
382-
}),
383-
deletePipelineSettings: vi.fn(),
384-
savePipelineSettings: vi.fn((prId: string, settings: Record<string, unknown>) => {
385-
const existing = pipelineByPr.get(prId) ?? {};
386-
pipelineByPr.set(prId, { ...existing, ...settings });
387-
}),
388-
};
389-
})(),
390310
prService: {
391311
simulateIntegration: vi.fn(async () => ({ steps: [], conflicts: [], clean: true })),
392312
createQueuePrs: vi.fn(async () => ({ groupId: "group-1", prs: [] })),
@@ -1519,7 +1439,6 @@ describe("adeRpcServer", () => {
15191439
"get_pr_health",
15201440
"pr_get_checks",
15211441
"pr_get_review_comments",
1522-
"pr_refresh_issue_inventory",
15231442
"pr_rerun_failed_checks",
15241443
"pr_reply_to_review_thread",
15251444
"pr_resolve_review_thread",
@@ -3035,33 +2954,6 @@ describe("adeRpcServer", () => {
30352954

30362955

30372956

3038-
it("does not expose unlisted service methods through dynamic ADE actions", async () => {
3039-
const fixture = createRuntime();
3040-
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });
3041-
await initialize(handler, { callerId: "agent-1", role: "agent" });
3042-
3043-
const listed = await callTool(handler, "list_ade_actions", { domain: "issue_inventory" });
3044-
expect(listed?.isError).toBeUndefined();
3045-
const actions = listed.structuredContent.actions.map((entry: { action: string }) => entry.action);
3046-
expect(actions).toContain("getPipelineSettings");
3047-
expect(actions).toContain("resetInventory");
3048-
expect(actions).toContain("saveConvergenceRuntime");
3049-
expect(actions).toContain("deletePipelineSettings");
3050-
expect(actions).not.toContain("privateMaintenanceTask");
3051-
3052-
const response = await callTool(handler, "run_ade_action", {
3053-
domain: "issue_inventory",
3054-
action: "privateMaintenanceTask",
3055-
argsList: ["pr-1"],
3056-
});
3057-
3058-
expect(response.isError).toBe(true);
3059-
expect(JSON.stringify(response.error ?? response.structuredContent ?? {})).toContain(
3060-
"Action 'issue_inventory.privateMaintenanceTask' is not exposed through ADE actions.",
3061-
);
3062-
expect(fixture.runtime.issueInventoryService.privateMaintenanceTask).not.toHaveBeenCalled();
3063-
});
3064-
30652957
it("rejects run_ade_action when the action is not a callable on the domain service", async () => {
30662958
const fixture = createRuntime();
30672959
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });
@@ -3671,45 +3563,6 @@ describe("adeRpcServer", () => {
36713563
expect(fixture.runtime.prService.getReviewThreads).toHaveBeenCalledWith("pr-123");
36723564
});
36733565

3674-
it("routes pr_refresh_issue_inventory with checks, review threads, and issue comments", async () => {
3675-
const fixture = createRuntime();
3676-
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });
3677-
3678-
await initialize(handler);
3679-
const response = await callTool(handler, "pr_refresh_issue_inventory", { prId: "pr-123" });
3680-
3681-
expect(response?.isError).toBeUndefined();
3682-
expect(response.structuredContent.summary).toEqual(
3683-
expect.objectContaining({
3684-
failingCheckCount: 0,
3685-
pendingCheckCount: 0,
3686-
actionableReviewThreadCount: 1,
3687-
actionableIssueCommentCount: 1,
3688-
actionableCommentCount: 2,
3689-
hasActionableChecks: false,
3690-
hasActionableComments: true,
3691-
}),
3692-
);
3693-
expect(response.structuredContent.failingWorkflowRuns).toHaveLength(1);
3694-
expect(response.structuredContent.reviewThreads[0]).toEqual(
3695-
expect.objectContaining({
3696-
id: "thread-1",
3697-
path: "src/index.ts",
3698-
line: 12,
3699-
}),
3700-
);
3701-
expect(response.structuredContent.issueComments[0]).toEqual(
3702-
expect.objectContaining({
3703-
author: "reviewer",
3704-
body: "Please fix the loading state.",
3705-
}),
3706-
);
3707-
expect(fixture.runtime.prService.getChecks).toHaveBeenCalledWith("pr-123");
3708-
expect(fixture.runtime.prService.getActionRuns).toHaveBeenCalledWith("pr-123");
3709-
expect(fixture.runtime.prService.getReviewThreads).toHaveBeenCalledWith("pr-123");
3710-
expect(fixture.runtime.prService.getComments).toHaveBeenCalledWith("pr-123");
3711-
});
3712-
37133566
it("routes pr_rerun_failed_checks, pr_reply_to_review_thread, and pr_resolve_review_thread", async () => {
37143567
const fixture = createRuntime();
37153568
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });

0 commit comments

Comments
 (0)