fix: address issue thread greptile feedback

This commit is contained in:
Dotta committed 2026-04-24 07:11:25 -05:00
1 parent f96bb88fa6
commit 2badb328a2
4 files changed
+59 -24

No files matched your search

@@ -203,6 +203,43 @@ describe("issue execution policy transitions", () => {
});
});
it("clears loose review instructions with explicit null during a stage transition", () => {
const reviewStageId = policy.stages[0].id;
const result = applyIssueExecutionPolicyTransition({
issue: {
status: "in_progress",
assigneeAgentId: coderAgentId,
assigneeUserId: null,
executionPolicy: policy,
executionState: {
status: "pending",
currentStageId: reviewStageId,
currentStageIndex: 0,
currentStageType: "review",
currentParticipant: { type: "agent", agentId: qaAgentId },
returnAssignee: { type: "agent", agentId: coderAgentId },
reviewRequest: { instructions: "Old review request" },
completedStageIds: [],
lastDecisionId: null,
lastDecisionOutcome: null,
},
},
policy,
requestedStatus: "in_review",
requestedAssigneePatch: {},
actor: { agentId: coderAgentId },
commentBody: "Ready for review",
reviewRequest: null,
});
expect(result.patch.executionState).toMatchObject({
status: "pending",
currentStageType: "review",
currentParticipant: { type: "agent", agentId: qaAgentId },
reviewRequest: null,
});
});
it("reviewer approves → advances to approval stage", () => {
const reviewStageId = policy.stages[0].id;
const result = applyIssueExecutionPolicyTransition({
+1 -1
View File
@@ -1892,7 +1892,7 @@ export function issueRoutes(
userId: actor.actorType === "user" ? actor.actorId : null,
},
commentBody,
reviewRequest: reviewRequest ?? undefined,
reviewRequest: reviewRequest === undefined ? undefined : reviewRequest,
});
const decisionId = transition.decision ? randomUUID() : null;
if (decisionId) {
@@ -304,6 +304,9 @@ export function applyIssueExecutionPolicyTransition(input: TransitionInput): Tra
const currentStage = input.policy ? findStageById(input.policy, existingState?.currentStageId) : null;
const requestedStatus = input.requestedStatus;
const activeStage = currentStage && existingState?.status === PENDING_STATUS ? currentStage : null;
const effectiveReviewRequest = input.reviewRequest === undefined
? existingState?.reviewRequest ?? null
: input.reviewRequest;
if (!input.policy) {
if (existingState) {
@@ -368,7 +371,7 @@ export function applyIssueExecutionPolicyTransition(input: TransitionInput): Tra
stage: activeStage,
participant,
returnAssignee: existingState?.returnAssignee ?? currentAssignee ?? actor,
reviewRequest: input.reviewRequest ?? existingState?.reviewRequest ?? null,
reviewRequest: effectiveReviewRequest,
});
return {
patch,
@@ -472,7 +475,7 @@ export function applyIssueExecutionPolicyTransition(input: TransitionInput): Tra
stage: activeStage,
participant: currentParticipant,
returnAssignee: existingState?.returnAssignee ?? currentAssignee ?? actor,
reviewRequest: input.reviewRequest ?? existingState?.reviewRequest ?? null,
reviewRequest: effectiveReviewRequest,
});
return {
patch,
+16 -21
View File
@@ -1398,27 +1398,22 @@ export function issueService(db: Db) {
)
`;
if (filters?.descendantOf) {
const descendantIds: string[] = [];
const seen = new Set<string>([filters.descendantOf]);
let frontier = [filters.descendantOf];
while (frontier.length > 0) {
const children = await db
.select({ id: issues.id })
.from(issues)
.where(and(eq(issues.companyId, companyId), inArray(issues.parentId, frontier)));
frontier = [];
for (const child of children) {
if (seen.has(child.id)) continue;
seen.add(child.id);
descendantIds.push(child.id);
frontier.push(child.id);
}
}
if (descendantIds.length === 0) return [];
conditions.push(inArray(issues.id, descendantIds));
conditions.push(sql<boolean>`
${issues.id} IN (
WITH RECURSIVE descendants(id) AS (
SELECT ${issues.id}
FROM ${issues}
WHERE ${issues.companyId} = ${companyId}
AND ${issues.parentId} = ${filters.descendantOf}
UNION
SELECT ${issues.id}
FROM ${issues}
JOIN descendants ON ${issues.parentId} = descendants.id
WHERE ${issues.companyId} = ${companyId}
)
SELECT id FROM descendants
)
`);
}
if (filters?.status) {
const statuses = filters.status.split(",").map((s) => s.trim());