github-issue-tower-defence-management 1.190.0 → 1.192.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +2 -0
- package/bin/adapter/entry-points/cli/index.js +5 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/cli/projectConfig.js +3 -0
- package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/{index-B22eMy23.js → index-RaFqjB7u.js} +3 -3
- package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +23 -0
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +19 -0
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +9 -5
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/awaitingOwnerApprovalMessage.js +7 -0
- package/bin/domain/usecases/awaitingOwnerApprovalMessage.js.map +1 -0
- package/bin/domain/usecases/isWaitingForOwnerApproval.js +16 -0
- package/bin/domain/usecases/isWaitingForOwnerApproval.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +2 -0
- package/src/adapter/entry-points/cli/index.ts +9 -0
- package/src/adapter/entry-points/cli/projectConfig.ts +8 -0
- package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +35 -1
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +13 -1
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.stories.tsx +7 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.test.tsx +82 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.tsx +23 -3
- package/src/adapter/entry-points/console/ui/src/features/console/logic/operations.ts +4 -3
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +79 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +19 -3
- package/src/adapter/entry-points/console/ui-dist/assets/{index-B22eMy23.js → index-RaFqjB7u.js} +3 -3
- package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +86 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +52 -0
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +93 -0
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +47 -1
- package/src/domain/usecases/StartPreparationUseCase.test.ts +76 -0
- package/src/domain/usecases/StartPreparationUseCase.ts +9 -5
- package/src/domain/usecases/awaitingOwnerApprovalMessage.ts +5 -0
- package/src/domain/usecases/isWaitingForOwnerApproval.test.ts +91 -0
- package/src/domain/usecases/isWaitingForOwnerApproval.ts +17 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/cli/projectConfig.d.ts +1 -0
- package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +1 -0
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts +1 -0
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/awaitingOwnerApprovalMessage.d.ts +3 -0
- package/types/domain/usecases/awaitingOwnerApprovalMessage.d.ts.map +1 -0
- package/types/domain/usecases/isWaitingForOwnerApproval.d.ts +2 -0
- package/types/domain/usecases/isWaitingForOwnerApproval.d.ts.map +1 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>TDPM Console</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-RaFqjB7u.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-CLHvrafO.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -4665,4 +4665,90 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
|
|
|
4665
4665
|
);
|
|
4666
4666
|
});
|
|
4667
4667
|
});
|
|
4668
|
+
|
|
4669
|
+
describe('waitingForOwnerApproval', () => {
|
|
4670
|
+
const issueUrl = 'https://github.com/user/repo/issues/1';
|
|
4671
|
+
|
|
4672
|
+
it('returns to Awaiting Workspace and posts AWAITING_OWNER_APPROVAL message when last report declares waitingForOwnerApproval', async () => {
|
|
4673
|
+
const issue = createMockIssue({ url: issueUrl, status: 'Preparation' });
|
|
4674
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4675
|
+
mockIssueRepository.get.mockResolvedValue(issue);
|
|
4676
|
+
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
4677
|
+
createMockComment({
|
|
4678
|
+
content:
|
|
4679
|
+
'From: :robot: systems-analyst (model)\n```json\n{"pullRequestRequired": false, "waitingForOwnerApproval": true}\n```',
|
|
4680
|
+
}),
|
|
4681
|
+
]);
|
|
4682
|
+
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
4683
|
+
|
|
4684
|
+
await useCase.run({
|
|
4685
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
4686
|
+
issueUrl,
|
|
4687
|
+
thresholdForAutoReject: 3,
|
|
4688
|
+
workflowBlockerResolvedWebhookUrl: null,
|
|
4689
|
+
allowedIssueAuthors: null,
|
|
4690
|
+
});
|
|
4691
|
+
|
|
4692
|
+
expect(mockIssueRepository.update).toHaveBeenCalledWith(
|
|
4693
|
+
expect.objectContaining({ status: 'Awaiting Workspace' }),
|
|
4694
|
+
mockProject,
|
|
4695
|
+
);
|
|
4696
|
+
expect(mockIssueRepository.updateStatus).toHaveBeenCalledWith(
|
|
4697
|
+
mockProject,
|
|
4698
|
+
expect.objectContaining({ status: 'Awaiting Workspace' }),
|
|
4699
|
+
'awaiting-workspace-id',
|
|
4700
|
+
);
|
|
4701
|
+
expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
|
|
4702
|
+
expect.objectContaining({ url: issueUrl }),
|
|
4703
|
+
expect.stringContaining('Auto Status Check: AWAITING_OWNER_APPROVAL'),
|
|
4704
|
+
);
|
|
4705
|
+
expect(mockIssueRepository.updateStatus).not.toHaveBeenCalledWith(
|
|
4706
|
+
mockProject,
|
|
4707
|
+
expect.anything(),
|
|
4708
|
+
'failed-preparation-id',
|
|
4709
|
+
);
|
|
4710
|
+
});
|
|
4711
|
+
|
|
4712
|
+
it('escalates to Failed Preparation after ownerApprovalTimeoutCycles AWAITING_OWNER_APPROVAL messages', async () => {
|
|
4713
|
+
const issue = createMockIssue({ url: issueUrl, status: 'Preparation' });
|
|
4714
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
4715
|
+
mockIssueRepository.get.mockResolvedValue(issue);
|
|
4716
|
+
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
4717
|
+
createMockComment({
|
|
4718
|
+
content:
|
|
4719
|
+
'From: :robot: systems-analyst (model)\n```json\n{"pullRequestRequired": false, "waitingForOwnerApproval": true}\n```',
|
|
4720
|
+
}),
|
|
4721
|
+
createMockComment({
|
|
4722
|
+
content:
|
|
4723
|
+
'Auto Status Check: AWAITING_OWNER_APPROVAL\nThe last report declared that this task is waiting for owner approval. Returning to Awaiting Workspace for the next cycle.',
|
|
4724
|
+
}),
|
|
4725
|
+
createMockComment({
|
|
4726
|
+
content:
|
|
4727
|
+
'Auto Status Check: AWAITING_OWNER_APPROVAL\nThe last report declared that this task is waiting for owner approval. Returning to Awaiting Workspace for the next cycle.',
|
|
4728
|
+
}),
|
|
4729
|
+
]);
|
|
4730
|
+
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
4731
|
+
|
|
4732
|
+
await useCase.run({
|
|
4733
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
4734
|
+
issueUrl,
|
|
4735
|
+
thresholdForAutoReject: 3,
|
|
4736
|
+
workflowBlockerResolvedWebhookUrl: null,
|
|
4737
|
+
allowedIssueAuthors: null,
|
|
4738
|
+
ownerApprovalTimeoutCycles: 2,
|
|
4739
|
+
});
|
|
4740
|
+
|
|
4741
|
+
expect(mockIssueRepository.updateStatus).toHaveBeenCalledWith(
|
|
4742
|
+
mockProject,
|
|
4743
|
+
expect.anything(),
|
|
4744
|
+
'failed-preparation-id',
|
|
4745
|
+
);
|
|
4746
|
+
expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
|
|
4747
|
+
expect.anything(),
|
|
4748
|
+
expect.stringContaining(
|
|
4749
|
+
'Owner approval was not received after 2 cycles. Moving to Failed Preparation.',
|
|
4750
|
+
),
|
|
4751
|
+
);
|
|
4752
|
+
});
|
|
4753
|
+
});
|
|
4668
4754
|
});
|
|
@@ -20,6 +20,11 @@ import {
|
|
|
20
20
|
RETURNED_TO_AWAITING_WORKSPACE_MESSAGE,
|
|
21
21
|
RETURNED_TO_AWAITING_WORKSPACE_MESSAGE_HEAD,
|
|
22
22
|
} from './returnedToAwaitingWorkspaceMessage';
|
|
23
|
+
import { isWaitingForOwnerApproval } from './isWaitingForOwnerApproval';
|
|
24
|
+
import {
|
|
25
|
+
AWAITING_OWNER_APPROVAL_MESSAGE,
|
|
26
|
+
AWAITING_OWNER_APPROVAL_MESSAGE_HEAD,
|
|
27
|
+
} from './awaitingOwnerApprovalMessage';
|
|
23
28
|
import {
|
|
24
29
|
ConsoleListItem,
|
|
25
30
|
ConsoleTabName,
|
|
@@ -121,6 +126,7 @@ export class NotifyFinishedIssuePreparationUseCase {
|
|
|
121
126
|
manager?: string | null;
|
|
122
127
|
developerAgentName?: string | null;
|
|
123
128
|
deferPreparation?: boolean | null;
|
|
129
|
+
ownerApprovalTimeoutCycles?: number | null;
|
|
124
130
|
}): Promise<void> => {
|
|
125
131
|
const project = await this.projectRepository.getByUrl(params.projectUrl);
|
|
126
132
|
|
|
@@ -309,6 +315,52 @@ export class NotifyFinishedIssuePreparationUseCase {
|
|
|
309
315
|
return;
|
|
310
316
|
}
|
|
311
317
|
|
|
318
|
+
if (
|
|
319
|
+
lastAgentReport !== null &&
|
|
320
|
+
isWaitingForOwnerApproval(lastAgentReport.content)
|
|
321
|
+
) {
|
|
322
|
+
const ownerApprovalTimeoutCycles =
|
|
323
|
+
params.ownerApprovalTimeoutCycles ?? 12;
|
|
324
|
+
const awaitingOwnerApprovalCount = comments.filter(
|
|
325
|
+
(comment) =>
|
|
326
|
+
isTrustedAuthor(comment.author) &&
|
|
327
|
+
comment.content.startsWith(AWAITING_OWNER_APPROVAL_MESSAGE_HEAD),
|
|
328
|
+
).length;
|
|
329
|
+
if (awaitingOwnerApprovalCount < ownerApprovalTimeoutCycles) {
|
|
330
|
+
issue.status = AWAITING_WORKSPACE_STATUS_NAME;
|
|
331
|
+
await this.issueRepository.update(issue, project);
|
|
332
|
+
await this.issueRepository.updateStatus(
|
|
333
|
+
project,
|
|
334
|
+
issue,
|
|
335
|
+
awaitingWorkspaceStatusOption.id,
|
|
336
|
+
);
|
|
337
|
+
await this.patchConsoleTab(issue);
|
|
338
|
+
await this.issueCommentRepository.createComment(
|
|
339
|
+
issue,
|
|
340
|
+
AWAITING_OWNER_APPROVAL_MESSAGE,
|
|
341
|
+
);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
issue.status = FAILED_PREPARATION_STATUS_NAME;
|
|
345
|
+
await this.issueRepository.update(issue, project);
|
|
346
|
+
await this.issueRepository.updateStatus(
|
|
347
|
+
project,
|
|
348
|
+
issue,
|
|
349
|
+
failedPreparationStatusOption.id,
|
|
350
|
+
);
|
|
351
|
+
await this.patchConsoleTab(issue);
|
|
352
|
+
await this.issueCommentRepository.createComment(
|
|
353
|
+
issue,
|
|
354
|
+
`Owner approval was not received after ${ownerApprovalTimeoutCycles} cycles. Moving to Failed Preparation.`,
|
|
355
|
+
);
|
|
356
|
+
await this.sendWorkflowBlockerNotification(
|
|
357
|
+
params.issueUrl,
|
|
358
|
+
params.workflowBlockerResolvedWebhookUrl,
|
|
359
|
+
project,
|
|
360
|
+
);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
312
364
|
const { rejections, approvedPrUrl } = await this.collectRejections(
|
|
313
365
|
issue,
|
|
314
366
|
comments,
|
|
@@ -2158,4 +2158,97 @@ describe('RevertOrphanedPreparationUseCase', () => {
|
|
|
2158
2158
|
'Auto Status Check: REJECTED',
|
|
2159
2159
|
);
|
|
2160
2160
|
});
|
|
2161
|
+
|
|
2162
|
+
it('should return orphaned issue to Awaiting Workspace with AWAITING_OWNER_APPROVAL when last report declares waitingForOwnerApproval', async () => {
|
|
2163
|
+
const stuckIssue = createMockIssue({
|
|
2164
|
+
url: 'https://github.com/user/repo/issues/10',
|
|
2165
|
+
status: 'Preparation',
|
|
2166
|
+
});
|
|
2167
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
2168
|
+
project: mockProject,
|
|
2169
|
+
issues: [stuckIssue],
|
|
2170
|
+
cacheUsed: false,
|
|
2171
|
+
});
|
|
2172
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
2173
|
+
stdout: '',
|
|
2174
|
+
stderr: '',
|
|
2175
|
+
exitCode: 1,
|
|
2176
|
+
});
|
|
2177
|
+
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
2178
|
+
{
|
|
2179
|
+
author: 'agent-bot',
|
|
2180
|
+
content:
|
|
2181
|
+
'From: :robot: systems-analyst (model)\n```json\n{"pullRequestRequired": false, "waitingForOwnerApproval": true}\n```',
|
|
2182
|
+
createdAt: new Date(),
|
|
2183
|
+
},
|
|
2184
|
+
]);
|
|
2185
|
+
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
2186
|
+
|
|
2187
|
+
await useCase.run({
|
|
2188
|
+
projectUrl: 'https://github.com/user/repo',
|
|
2189
|
+
preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
|
|
2190
|
+
thresholdForAutoReject: 3,
|
|
2191
|
+
allowedIssueAuthors: ['agent-bot'],
|
|
2192
|
+
});
|
|
2193
|
+
|
|
2194
|
+
expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
|
|
2195
|
+
expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
|
|
2196
|
+
expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
|
|
2197
|
+
expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toContain(
|
|
2198
|
+
'Auto Status Check: AWAITING_OWNER_APPROVAL',
|
|
2199
|
+
);
|
|
2200
|
+
});
|
|
2201
|
+
|
|
2202
|
+
it('should escalate to Failed Preparation after ownerApprovalTimeoutCycles AWAITING_OWNER_APPROVAL messages in RevertOrphaned', async () => {
|
|
2203
|
+
const stuckIssue = createMockIssue({
|
|
2204
|
+
url: 'https://github.com/user/repo/issues/10',
|
|
2205
|
+
status: 'Preparation',
|
|
2206
|
+
});
|
|
2207
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
2208
|
+
project: mockProject,
|
|
2209
|
+
issues: [stuckIssue],
|
|
2210
|
+
cacheUsed: false,
|
|
2211
|
+
});
|
|
2212
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
2213
|
+
stdout: '',
|
|
2214
|
+
stderr: '',
|
|
2215
|
+
exitCode: 1,
|
|
2216
|
+
});
|
|
2217
|
+
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
2218
|
+
{
|
|
2219
|
+
author: 'agent-bot',
|
|
2220
|
+
content:
|
|
2221
|
+
'From: :robot: systems-analyst (model)\n```json\n{"pullRequestRequired": false, "waitingForOwnerApproval": true}\n```',
|
|
2222
|
+
createdAt: new Date(),
|
|
2223
|
+
},
|
|
2224
|
+
{
|
|
2225
|
+
author: 'agent-bot',
|
|
2226
|
+
content:
|
|
2227
|
+
'Auto Status Check: AWAITING_OWNER_APPROVAL\nThe last report declared that this task is waiting for owner approval. Returning to Awaiting Workspace for the next cycle.',
|
|
2228
|
+
createdAt: new Date(),
|
|
2229
|
+
},
|
|
2230
|
+
{
|
|
2231
|
+
author: 'agent-bot',
|
|
2232
|
+
content:
|
|
2233
|
+
'Auto Status Check: AWAITING_OWNER_APPROVAL\nThe last report declared that this task is waiting for owner approval. Returning to Awaiting Workspace for the next cycle.',
|
|
2234
|
+
createdAt: new Date(),
|
|
2235
|
+
},
|
|
2236
|
+
]);
|
|
2237
|
+
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
2238
|
+
|
|
2239
|
+
await useCase.run({
|
|
2240
|
+
projectUrl: 'https://github.com/user/repo',
|
|
2241
|
+
preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
|
|
2242
|
+
thresholdForAutoReject: 3,
|
|
2243
|
+
allowedIssueAuthors: ['agent-bot'],
|
|
2244
|
+
ownerApprovalTimeoutCycles: 2,
|
|
2245
|
+
});
|
|
2246
|
+
|
|
2247
|
+
expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
|
|
2248
|
+
expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('5');
|
|
2249
|
+
expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
|
|
2250
|
+
expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toContain(
|
|
2251
|
+
'Owner approval was not received after 2 cycles. Moving to Failed Preparation.',
|
|
2252
|
+
);
|
|
2253
|
+
});
|
|
2161
2254
|
});
|
|
@@ -22,6 +22,11 @@ import {
|
|
|
22
22
|
RETURNED_TO_AWAITING_WORKSPACE_MESSAGE,
|
|
23
23
|
RETURNED_TO_AWAITING_WORKSPACE_MESSAGE_HEAD,
|
|
24
24
|
} from './returnedToAwaitingWorkspaceMessage';
|
|
25
|
+
import { isWaitingForOwnerApproval } from './isWaitingForOwnerApproval';
|
|
26
|
+
import {
|
|
27
|
+
AWAITING_OWNER_APPROVAL_MESSAGE,
|
|
28
|
+
AWAITING_OWNER_APPROVAL_MESSAGE_HEAD,
|
|
29
|
+
} from './awaitingOwnerApprovalMessage';
|
|
25
30
|
import { extractNextStepAgent } from './extractNextStepAgent';
|
|
26
31
|
import { findLastAgentReport } from './findLastAgentReport';
|
|
27
32
|
import { isAgentReportBody } from './isAgentReportBody';
|
|
@@ -35,7 +40,10 @@ import {
|
|
|
35
40
|
const ORPHANED_PREPARATION_REJECTION_DETAIL = 'ORPHANED_PREPARATION';
|
|
36
41
|
|
|
37
42
|
type OrphanedPreparationOutcome =
|
|
38
|
-
|
|
43
|
+
| 'advanceToQualityCheck'
|
|
44
|
+
| 'returnToLabelSelectedAgent'
|
|
45
|
+
| 'returnToOwnerApprovalCycle'
|
|
46
|
+
| 'reject';
|
|
39
47
|
|
|
40
48
|
export class RevertOrphanedPreparationUseCase {
|
|
41
49
|
constructor(
|
|
@@ -74,6 +82,7 @@ export class RevertOrphanedPreparationUseCase {
|
|
|
74
82
|
labelsAsLlmAgentName?: string[] | null;
|
|
75
83
|
labelsNotRequiringPullRequest?: string[] | null;
|
|
76
84
|
allowedIssueAuthors?: string[] | null;
|
|
85
|
+
ownerApprovalTimeoutCycles?: number | null;
|
|
77
86
|
}): Promise<void> => {
|
|
78
87
|
const projectId = await this.projectRepository.findProjectIdByUrl(
|
|
79
88
|
params.projectUrl,
|
|
@@ -191,6 +200,40 @@ export class RevertOrphanedPreparationUseCase {
|
|
|
191
200
|
}
|
|
192
201
|
continue;
|
|
193
202
|
}
|
|
203
|
+
if (outcome === 'returnToOwnerApprovalCycle') {
|
|
204
|
+
const ownerApprovalTimeoutCycles =
|
|
205
|
+
params.ownerApprovalTimeoutCycles ?? 12;
|
|
206
|
+
const awaitingOwnerApprovalCount = comments.filter(
|
|
207
|
+
(comment) =>
|
|
208
|
+
isAuthorAuthorizedForAutoStatusCheck(
|
|
209
|
+
comment.author,
|
|
210
|
+
params.allowedIssueAuthors,
|
|
211
|
+
) &&
|
|
212
|
+
comment.content.startsWith(AWAITING_OWNER_APPROVAL_MESSAGE_HEAD),
|
|
213
|
+
).length;
|
|
214
|
+
if (awaitingOwnerApprovalCount < ownerApprovalTimeoutCycles) {
|
|
215
|
+
await this.issueRepository.updateStatus(
|
|
216
|
+
project,
|
|
217
|
+
issue,
|
|
218
|
+
awaitingWorkspaceStatusOption.id,
|
|
219
|
+
);
|
|
220
|
+
await this.issueCommentRepository.createComment(
|
|
221
|
+
issue,
|
|
222
|
+
AWAITING_OWNER_APPROVAL_MESSAGE,
|
|
223
|
+
);
|
|
224
|
+
} else if (failedPreparationStatusOption) {
|
|
225
|
+
await this.issueRepository.updateStatus(
|
|
226
|
+
project,
|
|
227
|
+
issue,
|
|
228
|
+
failedPreparationStatusOption.id,
|
|
229
|
+
);
|
|
230
|
+
await this.issueCommentRepository.createComment(
|
|
231
|
+
issue,
|
|
232
|
+
`Owner approval was not received after ${ownerApprovalTimeoutCycles} cycles. Moving to Failed Preparation.`,
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
194
237
|
if (outcome === 'returnToLabelSelectedAgent') {
|
|
195
238
|
await this.issueRepository.updateStatus(
|
|
196
239
|
project,
|
|
@@ -324,6 +367,9 @@ export class RevertOrphanedPreparationUseCase {
|
|
|
324
367
|
) &&
|
|
325
368
|
!this.reportBodyHasNextStep(lastReport.content)
|
|
326
369
|
) {
|
|
370
|
+
if (isWaitingForOwnerApproval(lastReport.content)) {
|
|
371
|
+
return { outcome: 'returnToOwnerApprovalCycle', comments };
|
|
372
|
+
}
|
|
327
373
|
const alreadyReturnedToWorkspace = comments.some(
|
|
328
374
|
(comment) =>
|
|
329
375
|
isTrustedAuthor(comment.author) &&
|
|
@@ -979,6 +979,82 @@ describe('StartPreparationUseCase', () => {
|
|
|
979
979
|
],
|
|
980
980
|
]);
|
|
981
981
|
});
|
|
982
|
+
it('should not treat a cross-repository PR as duplicate when a same-repository PR exists', async () => {
|
|
983
|
+
const awaitingIssues: Issue[] = [
|
|
984
|
+
createMockIssue({
|
|
985
|
+
url: 'https://github.com/HiromiShikata/secretary/issues/4290',
|
|
986
|
+
title: 'Issue 4290',
|
|
987
|
+
nameWithOwner: 'HiromiShikata/secretary',
|
|
988
|
+
number: 4290,
|
|
989
|
+
org: 'HiromiShikata',
|
|
990
|
+
repo: 'secretary',
|
|
991
|
+
labels: ['category:impl'],
|
|
992
|
+
status: 'Awaiting Workspace',
|
|
993
|
+
}),
|
|
994
|
+
];
|
|
995
|
+
const sameRepoPR: RelatedPullRequest = {
|
|
996
|
+
url: 'https://github.com/HiromiShikata/secretary/pull/4610',
|
|
997
|
+
branchName: 'i4290',
|
|
998
|
+
createdAt: new Date('2026-08-28T13:38:00Z'),
|
|
999
|
+
isDraft: false,
|
|
1000
|
+
isConflicted: false,
|
|
1001
|
+
mergeable: null,
|
|
1002
|
+
isPassedAllCiJob: false,
|
|
1003
|
+
isCiStateSuccess: false,
|
|
1004
|
+
isResolvedAllReviewComments: false,
|
|
1005
|
+
isBranchOutOfDate: false,
|
|
1006
|
+
missingRequiredCheckNames: [],
|
|
1007
|
+
};
|
|
1008
|
+
const crossRepoPR: RelatedPullRequest = {
|
|
1009
|
+
url: 'https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/pull/1813',
|
|
1010
|
+
branchName: 'i4290',
|
|
1011
|
+
createdAt: new Date('2026-08-28T10:55:00Z'),
|
|
1012
|
+
isDraft: false,
|
|
1013
|
+
isConflicted: false,
|
|
1014
|
+
mergeable: null,
|
|
1015
|
+
isPassedAllCiJob: false,
|
|
1016
|
+
isCiStateSuccess: false,
|
|
1017
|
+
isResolvedAllReviewComments: false,
|
|
1018
|
+
isBranchOutOfDate: false,
|
|
1019
|
+
missingRequiredCheckNames: [],
|
|
1020
|
+
};
|
|
1021
|
+
mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
|
|
1022
|
+
mockIssueRepository.getStoryObjectMap.mockResolvedValue(
|
|
1023
|
+
createMockStoryObjectMap(awaitingIssues),
|
|
1024
|
+
);
|
|
1025
|
+
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
|
|
1026
|
+
sameRepoPR,
|
|
1027
|
+
crossRepoPR,
|
|
1028
|
+
]);
|
|
1029
|
+
mockLocalCommandRunner.runCommand.mockResolvedValue({
|
|
1030
|
+
stdout: '',
|
|
1031
|
+
stderr: '',
|
|
1032
|
+
exitCode: 0,
|
|
1033
|
+
});
|
|
1034
|
+
await useCase.run({
|
|
1035
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
1036
|
+
defaultAgentName: 'agent1',
|
|
1037
|
+
defaultLlmModelName: 'claude-opus',
|
|
1038
|
+
fallbackLlmModelName: null,
|
|
1039
|
+
defaultLlmAgentName: null,
|
|
1040
|
+
configFilePath: '/path/to/config.yml',
|
|
1041
|
+
maximumPreparingIssuesCount: null,
|
|
1042
|
+
utilizationPercentageThreshold: 90,
|
|
1043
|
+
allowedIssueAuthors: ['testuser'],
|
|
1044
|
+
manager: 'manager-user',
|
|
1045
|
+
codexHomeCandidates: null,
|
|
1046
|
+
labelsAsLlmAgentName: null,
|
|
1047
|
+
});
|
|
1048
|
+
expect(mockIssueRepository.closePullRequest).not.toHaveBeenCalled();
|
|
1049
|
+
expect(mockIssueRepository.deletePullRequestBranch).not.toHaveBeenCalled();
|
|
1050
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
|
|
1051
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toContain(
|
|
1052
|
+
'--branch',
|
|
1053
|
+
);
|
|
1054
|
+
expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toContain(
|
|
1055
|
+
'i4290',
|
|
1056
|
+
);
|
|
1057
|
+
});
|
|
982
1058
|
it('should skip issue after resolving duplicates when adopted canonical PR has null branchName', async () => {
|
|
983
1059
|
const awaitingIssues: Issue[] = [
|
|
984
1060
|
createMockIssue({
|
|
@@ -554,8 +554,12 @@ export class StartPreparationUseCase {
|
|
|
554
554
|
const relatedPRs = await this.issueRepository.findRelatedOpenPRs(
|
|
555
555
|
issue.url,
|
|
556
556
|
);
|
|
557
|
-
|
|
558
|
-
const
|
|
557
|
+
const sameRepoRelatedPRs = relatedPRs.filter((pr) => {
|
|
558
|
+
const match = /^https?:\/\/[^/]+\/([^/]+\/[^/]+)\//.exec(pr.url);
|
|
559
|
+
return match === null || match[1] === issue.nameWithOwner;
|
|
560
|
+
});
|
|
561
|
+
if (sameRepoRelatedPRs.length > 1) {
|
|
562
|
+
const sortedPRs = [...sameRepoRelatedPRs].sort(
|
|
559
563
|
(a, b) => a.createdAt.getTime() - b.createdAt.getTime(),
|
|
560
564
|
);
|
|
561
565
|
const canonicalPR = sortedPRs[0];
|
|
@@ -585,14 +589,14 @@ export class StartPreparationUseCase {
|
|
|
585
589
|
continue;
|
|
586
590
|
}
|
|
587
591
|
branchName = canonicalPR.branchName;
|
|
588
|
-
} else if (
|
|
589
|
-
if (
|
|
592
|
+
} else if (sameRepoRelatedPRs.length === 1) {
|
|
593
|
+
if (sameRepoRelatedPRs[0].branchName === null) {
|
|
590
594
|
console.warn(
|
|
591
595
|
`Skipping issue ${issue.url}: related open PR has unavailable head branch.`,
|
|
592
596
|
);
|
|
593
597
|
continue;
|
|
594
598
|
}
|
|
595
|
-
branchName =
|
|
599
|
+
branchName = sameRepoRelatedPRs[0].branchName;
|
|
596
600
|
} else {
|
|
597
601
|
branchName = `i${issue.number}`;
|
|
598
602
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const AWAITING_OWNER_APPROVAL_MESSAGE_HEAD =
|
|
2
|
+
'Auto Status Check: AWAITING_OWNER_APPROVAL';
|
|
3
|
+
|
|
4
|
+
export const AWAITING_OWNER_APPROVAL_MESSAGE = `${AWAITING_OWNER_APPROVAL_MESSAGE_HEAD}
|
|
5
|
+
The last report declared that this task is waiting for owner approval. Returning to Awaiting Workspace for the next cycle.`;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { isWaitingForOwnerApproval } from './isWaitingForOwnerApproval';
|
|
2
|
+
|
|
3
|
+
const agentReport = (reportJson: string): string =>
|
|
4
|
+
`From: :robot: agent-name (model-id)\n\`\`\`json\n${reportJson}\n\`\`\``;
|
|
5
|
+
|
|
6
|
+
describe('isWaitingForOwnerApproval', () => {
|
|
7
|
+
it('returns true when the first block has pullRequestRequired false and waitingForOwnerApproval true', () => {
|
|
8
|
+
expect(
|
|
9
|
+
isWaitingForOwnerApproval(
|
|
10
|
+
agentReport(
|
|
11
|
+
'{"pullRequestRequired": false, "waitingForOwnerApproval": true}',
|
|
12
|
+
),
|
|
13
|
+
),
|
|
14
|
+
).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('returns false when waitingForOwnerApproval is missing', () => {
|
|
18
|
+
expect(
|
|
19
|
+
isWaitingForOwnerApproval(agentReport('{"pullRequestRequired": false}')),
|
|
20
|
+
).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('returns false when pullRequestRequired is missing', () => {
|
|
24
|
+
expect(
|
|
25
|
+
isWaitingForOwnerApproval(
|
|
26
|
+
agentReport('{"waitingForOwnerApproval": true}'),
|
|
27
|
+
),
|
|
28
|
+
).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('returns false when pullRequestRequired is true', () => {
|
|
32
|
+
expect(
|
|
33
|
+
isWaitingForOwnerApproval(
|
|
34
|
+
agentReport(
|
|
35
|
+
'{"pullRequestRequired": true, "waitingForOwnerApproval": true}',
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('returns false when waitingForOwnerApproval is false', () => {
|
|
42
|
+
expect(
|
|
43
|
+
isWaitingForOwnerApproval(
|
|
44
|
+
agentReport(
|
|
45
|
+
'{"pullRequestRequired": false, "waitingForOwnerApproval": false}',
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('returns false when waitingForOwnerApproval is a string rather than the boolean true', () => {
|
|
52
|
+
expect(
|
|
53
|
+
isWaitingForOwnerApproval(
|
|
54
|
+
agentReport(
|
|
55
|
+
'{"pullRequestRequired": false, "waitingForOwnerApproval": "true"}',
|
|
56
|
+
),
|
|
57
|
+
),
|
|
58
|
+
).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('returns false when there is no JSON block', () => {
|
|
62
|
+
expect(
|
|
63
|
+
isWaitingForOwnerApproval('From: :robot: agent-name (model-id)'),
|
|
64
|
+
).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('returns false when the JSON block cannot be parsed', () => {
|
|
68
|
+
const consoleWarn = jest
|
|
69
|
+
.spyOn(console, 'warn')
|
|
70
|
+
.mockImplementation(() => {});
|
|
71
|
+
expect(
|
|
72
|
+
isWaitingForOwnerApproval(
|
|
73
|
+
agentReport(
|
|
74
|
+
'{"pullRequestRequired": false, "waitingForOwnerApproval": true',
|
|
75
|
+
),
|
|
76
|
+
),
|
|
77
|
+
).toBe(false);
|
|
78
|
+
consoleWarn.mockRestore();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('reads only the first block and ignores subsequent blocks', () => {
|
|
82
|
+
const content = `From: :robot: agent-name (model-id)\n\`\`\`json\n{"pullRequestRequired": false, "nextStep": null}\n\`\`\`\n\n\`\`\`json\n{"pullRequestRequired": false, "waitingForOwnerApproval": true}\n\`\`\``;
|
|
83
|
+
expect(isWaitingForOwnerApproval(content)).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('returns true when backticks in the block are backslash-escaped', () => {
|
|
87
|
+
const content =
|
|
88
|
+
'From: :robot: agent-name (model-id)\n\\`\\`\\`json\n{"pullRequestRequired": false, "waitingForOwnerApproval": true}\n\\`\\`\\`';
|
|
89
|
+
expect(isWaitingForOwnerApproval(content)).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { extractFencedJsonBlocks } from './extractFencedJsonBlocks';
|
|
2
|
+
|
|
3
|
+
export const isWaitingForOwnerApproval = (reportContent: string): boolean => {
|
|
4
|
+
const blocks = extractFencedJsonBlocks(
|
|
5
|
+
reportContent,
|
|
6
|
+
'waitingForOwnerApproval',
|
|
7
|
+
);
|
|
8
|
+
const firstBlock = blocks[0];
|
|
9
|
+
if (typeof firstBlock !== 'object' || firstBlock === null) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
const report: Record<string, unknown> = { ...firstBlock };
|
|
13
|
+
return (
|
|
14
|
+
report.pullRequestRequired === false &&
|
|
15
|
+
report.waitingForOwnerApproval === true
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AAwNzB,eAAO,MAAM,OAAO,SAAgB,CAAC;AAsjCrC,eAAO,MAAM,uBAAuB,GAAI,OAAO,OAAO,KAAG,IAGxD,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EAAE,EACd,kBAAkB,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KACzC,OAAO,CAAC,IAAI,CAMd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/projectConfig.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,6BAA6B,CAAC,EAAE,MAAM,EAAE,CAAC;IACzC,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"projectConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/projectConfig.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,6BAA6B,CAAC,EAAE,MAAM,EAAE,CAAC;IACzC,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAsDF,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CACH,CAAC;AAgDvE,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,KAAG,UA8EvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,EACd,aAAa,MAAM,KAClB,UA8EF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,EACtB,cAAc,UAAU,EACxB,iBAAiB,UAAU,KAC1B,UA+FD,CAAC;AAkBH,eAAO,MAAM,kBAAkB,GAC7B,YAAY,MAAM,EAClB,OAAO,MAAM,KACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAoDvB,CAAC"}
|
|
@@ -34,6 +34,7 @@ export declare class NotifyFinishedIssuePreparationUseCase {
|
|
|
34
34
|
manager?: string | null;
|
|
35
35
|
developerAgentName?: string | null;
|
|
36
36
|
deferPreparation?: boolean | null;
|
|
37
|
+
ownerApprovalTimeoutCycles?: number | null;
|
|
37
38
|
}) => Promise<void>;
|
|
38
39
|
private handleTransientFailureDeferral;
|
|
39
40
|
private handleMissingAgentDefinition;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ export declare class RevertOrphanedPreparationUseCase {
|
|
|
19
19
|
labelsAsLlmAgentName?: string[] | null;
|
|
20
20
|
labelsNotRequiringPullRequest?: string[] | null;
|
|
21
21
|
allowedIssueAuthors?: string[] | null;
|
|
22
|
+
ownerApprovalTimeoutCycles?: number | null;
|
|
22
23
|
}) => Promise<void>;
|
|
23
24
|
private isStillInPreparation;
|
|
24
25
|
private evaluateOutcome;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevertOrphanedPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/RevertOrphanedPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"RevertOrphanedPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/RevertOrphanedPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAyC7E,qBAAa,gCAAgC;IAEzC,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAC9B,iBAAiB,EACf,oBAAoB,GACpB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,iBAAiB,CACpB;IACD,QAAQ,CAAC,eAAe,EAAE,IAAI,CAC5B,eAAe,EACb,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,KAAK,GACL,oBAAoB,CACvB;IACD,QAAQ,CAAC,sBAAsB,EAAE,IAAI,CACnC,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC;IACD,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB;gBArBtC,iBAAiB,EAAE,IAAI,CAC9B,iBAAiB,EACf,oBAAoB,GACpB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,iBAAiB,CACpB,EACQ,eAAe,EAAE,IAAI,CAC5B,eAAe,EACb,cAAc,GACd,cAAc,GACd,oBAAoB,GACpB,oBAAoB,GACpB,KAAK,GACL,oBAAoB,CACvB,EACQ,sBAAsB,EAAE,IAAI,CACnC,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC,EACQ,kBAAkB,EAAE,kBAAkB;IAGjD,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,8BAA8B,EAAE,MAAM,CAAC;QACvC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACvC,6BAA6B,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAChD,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACtC,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5C,KAAG,OAAO,CAAC,IAAI,CAAC,CA4Nf;IAEF,OAAO,CAAC,oBAAoB,CAqB1B;IAEF,OAAO,CAAC,eAAe,CAwGrB;IAEF,OAAO,CAAC,uBAAuB,CAQ7B;IAEF,OAAO,CAAC,qBAAqB,CAyB3B;IAEF,OAAO,CAAC,eAAe,CA6BrB;IAEF,OAAO,CAAC,YAAY,CA+BlB;CACH"}
|