Skip to content

Commit ea7ea14

Browse files
authored
Review tab parallel review organization (#322)
* Review tab parallel review organization * Fix ADE review findings * Fix second ADE review findings * Fix latest ADE review findings * Fix latest ADE review findings * Tighten review prompts and PR cache refresh * Fix latest ADE review findings * Fix latest ADE review findings * Allow partial review completion * Fix ADE review findings * Fix follow-up ADE review findings * Surface partial review coverage * Fix latest ADE review findings * Keep PR AI summaries local only * Fix review follow-up edge cases * Fix ADE review self-findings * Fix final ADE review findings * Add review finding copy actions * ship: address review feedback and Windows package size * ship: tighten Windows runtime package pruning * ship: avoid readonly CRR metadata deletes * ship: keep stash pop success after drop warning * ship: bound review manifest prompts
1 parent 63aabb7 commit ea7ea14

62 files changed

Lines changed: 8907 additions & 1486 deletions

Some content is hidden

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

.ade/ade.yaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
version: 1
22
processes:
3-
- id: xsi8oj88
4-
name: dogfood onboardinign fixes
3+
- id: gq3sy4rj
4+
name: npm run dev:desktop
55
command:
6-
- ./scripts/dogfood.sh
7-
- onboarding-fixes
8-
cwd: apps/desktop
6+
- npm
7+
- run
8+
- dev:desktop
9+
cwd: .
910
gracefulShutdownMs: 7000
1011
readiness:
1112
type: none

.claude/skills/plan/SKILL.md

Lines changed: 0 additions & 175 deletions
This file was deleted.

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

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ function createRuntime() {
293293
listBranches: vi.fn(async () => [{ name: "main", current: true, ahead: 0, behind: 0, hasUpstream: true, upstream: "origin/main" }]),
294294
checkoutBranch: vi.fn(async () => ({ success: true })),
295295
stashPush: vi.fn(async () => ({ success: true })),
296-
listStashes: vi.fn(async () => [{ ref: "stash@{0}", createdAt: "2026-04-06T00:00:00.000Z", subject: "test stash" }]),
296+
listStashes: vi.fn(async () => [{ oid: "oid-0", ref: "stash@{0}", createdAt: "2026-04-06T00:00:00.000Z", subject: "test stash" }]),
297297
stashApply: vi.fn(async () => ({ success: true })),
298298
stashPop: vi.fn(async () => ({ success: true })),
299299
stashDrop: vi.fn(async () => ({ success: true })),
@@ -4515,6 +4515,51 @@ describe("adeRpcServer", () => {
45154515

45164516
});
45174517

4518+
it("invokes review.startRun through ADE actions without dropping unlimited budgets", async () => {
4519+
const fixture = createRuntime();
4520+
const startArgs = {
4521+
target: { mode: "lane_diff", laneId: "lane-1" },
4522+
config: {
4523+
compareAgainst: { kind: "default_branch" },
4524+
selectionMode: "full_diff",
4525+
dirtyOnly: false,
4526+
modelId: "openai/gpt-5.4",
4527+
reasoningEffort: "medium",
4528+
budgets: {
4529+
unlimited: true,
4530+
maxFiles: Number.MAX_SAFE_INTEGER,
4531+
maxDiffChars: Number.MAX_SAFE_INTEGER,
4532+
maxPromptChars: Number.MAX_SAFE_INTEGER,
4533+
maxFindings: Number.MAX_SAFE_INTEGER,
4534+
maxFindingsPerPass: Number.MAX_SAFE_INTEGER,
4535+
maxPublishedFindings: Number.MAX_SAFE_INTEGER,
4536+
},
4537+
publishBehavior: "local_only",
4538+
},
4539+
};
4540+
const startRun = vi.fn(async (args: typeof startArgs) => ({
4541+
id: "review-run-1",
4542+
laneId: args.target.laneId,
4543+
config: args.config,
4544+
status: "queued",
4545+
}));
4546+
(fixture.runtime as any).reviewService = { startRun };
4547+
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });
4548+
await initialize(handler, { callerId: "agent-1", role: "agent" });
4549+
4550+
const response = await callTool(handler, "run_ade_action", {
4551+
domain: "review",
4552+
action: "startRun",
4553+
args: startArgs,
4554+
});
4555+
4556+
expect(response?.isError).toBeUndefined();
4557+
expect(startRun).toHaveBeenCalledWith(startArgs);
4558+
expect(startRun.mock.calls[0][0].config.budgets).toEqual(startArgs.config.budgets);
4559+
expect(response.structuredContent.result.config.budgets).toEqual(startArgs.config.budgets);
4560+
expect(response.structuredContent.result.config.budgets.unlimited).toBe(true);
4561+
});
4562+
45184563
it("binds service method context when invoking dynamic ADE actions", async () => {
45194564
const fixture = createRuntime();
45204565
const missionService = fixture.runtime.missionService as any;
@@ -4689,6 +4734,37 @@ describe("adeRpcServer", () => {
46894734
expect(response.structuredContent.count).toBe(1);
46904735
});
46914736

4737+
it("passes stash oid through destructive stash tools", async () => {
4738+
const fixture = createRuntime();
4739+
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });
4740+
4741+
await initialize(handler, { callerId: "agent-1", role: "agent" });
4742+
4743+
const pop = await callTool(handler, "stash_pop", {
4744+
laneId: "lane-1",
4745+
stashRef: "stash@{0}",
4746+
stashOid: "oid-0",
4747+
});
4748+
const drop = await callTool(handler, "stash_drop", {
4749+
laneId: "lane-1",
4750+
stashRef: "stash@{0}",
4751+
stashOid: "oid-0",
4752+
});
4753+
4754+
expect(pop?.isError).toBeUndefined();
4755+
expect(drop?.isError).toBeUndefined();
4756+
expect(fixture.runtime.gitService.stashPop).toHaveBeenCalledWith({
4757+
laneId: "lane-1",
4758+
stashRef: "stash@{0}",
4759+
stashOid: "oid-0",
4760+
});
4761+
expect(fixture.runtime.gitService.stashDrop).toHaveBeenCalledWith({
4762+
laneId: "lane-1",
4763+
stashRef: "stash@{0}",
4764+
stashOid: "oid-0",
4765+
});
4766+
});
4767+
46924768
it("returns resources for lane status/conflicts", async () => {
46934769
const fixture = createRuntime();
46944770
const handler = createAdeRpcRequestHandler({ runtime: fixture.runtime, serverVersion: "test" });

apps/ade-cli/src/adeRpcServer.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,8 @@ const TOOL_SPECS: ToolSpec[] = [
10461046
additionalProperties: false,
10471047
properties: {
10481048
laneId: { type: "string", minLength: 1 },
1049-
stashRef: { type: "string", minLength: 1 }
1049+
stashRef: { type: "string", minLength: 1 },
1050+
stashOid: { type: "string", minLength: 1 }
10501051
}
10511052
}
10521053
},
@@ -1055,11 +1056,12 @@ const TOOL_SPECS: ToolSpec[] = [
10551056
description: "Pop a stash onto a lane and remove it from the stash list. Defaults to the current chat lane when laneId is omitted.",
10561057
inputSchema: {
10571058
type: "object",
1058-
required: ["stashRef"],
1059+
required: ["stashRef", "stashOid"],
10591060
additionalProperties: false,
10601061
properties: {
10611062
laneId: { type: "string", minLength: 1 },
1062-
stashRef: { type: "string", minLength: 1 }
1063+
stashRef: { type: "string", minLength: 1 },
1064+
stashOid: { type: "string", minLength: 1 }
10631065
}
10641066
}
10651067
},
@@ -1068,11 +1070,12 @@ const TOOL_SPECS: ToolSpec[] = [
10681070
description: "Drop a stash from a lane. Defaults to the current chat lane when laneId is omitted.",
10691071
inputSchema: {
10701072
type: "object",
1071-
required: ["stashRef"],
1073+
required: ["stashRef", "stashOid"],
10721074
additionalProperties: false,
10731075
properties: {
10741076
laneId: { type: "string", minLength: 1 },
1075-
stashRef: { type: "string", minLength: 1 }
1077+
stashRef: { type: "string", minLength: 1 },
1078+
stashOid: { type: "string", minLength: 1 }
10761079
}
10771080
}
10781081
},
@@ -6526,21 +6529,24 @@ async function runTool(args: {
65266529
if (name === "stash_apply") {
65276530
const laneId = requireLaneIdForTool(runtime, session, toolArgs, "stash_apply");
65286531
const stashRef = assertNonEmptyString(toolArgs.stashRef, "stashRef");
6529-
const action = await runtime.gitService.stashApply({ laneId, stashRef });
6532+
const stashOid = asOptionalTrimmedString(toolArgs.stashOid);
6533+
const action = await runtime.gitService.stashApply({ laneId, stashRef, ...(stashOid ? { stashOid } : {}) });
65306534
return { action };
65316535
}
65326536

65336537
if (name === "stash_pop") {
65346538
const laneId = requireLaneIdForTool(runtime, session, toolArgs, "stash_pop");
65356539
const stashRef = assertNonEmptyString(toolArgs.stashRef, "stashRef");
6536-
const action = await runtime.gitService.stashPop({ laneId, stashRef });
6540+
const stashOid = assertNonEmptyString(toolArgs.stashOid, "stashOid");
6541+
const action = await runtime.gitService.stashPop({ laneId, stashRef, stashOid });
65376542
return { action };
65386543
}
65396544

65406545
if (name === "stash_drop") {
65416546
const laneId = requireLaneIdForTool(runtime, session, toolArgs, "stash_drop");
65426547
const stashRef = assertNonEmptyString(toolArgs.stashRef, "stashRef");
6543-
const action = await runtime.gitService.stashDrop({ laneId, stashRef });
6548+
const stashOid = assertNonEmptyString(toolArgs.stashOid, "stashOid");
6549+
const action = await runtime.gitService.stashDrop({ laneId, stashRef, stashOid });
65446550
return { action };
65456551
}
65466552

0 commit comments

Comments
 (0)