github-issue-tower-defence-management 1.39.0 → 1.41.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/.github/workflows/create-pr.yml +12 -5
- package/.github/workflows/umino-project.yml +5 -4
- package/CHANGELOG.md +26 -0
- package/README.md +21 -9
- package/bin/adapter/entry-points/cli/index.js +45 -10
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +32 -8
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/adapter/repositories/NodeLocalCommandRunner.js +3 -3
- package/bin/adapter/repositories/NodeLocalCommandRunner.js.map +1 -1
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +446 -11
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +5 -2
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +111 -16
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +7 -2
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +107 -72
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +26 -13
- package/src/adapter/entry-points/cli/index.ts +74 -13
- package/src/adapter/repositories/NodeLocalCommandRunner.test.ts +12 -12
- package/src/adapter/repositories/NodeLocalCommandRunner.ts +7 -4
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +3 -0
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +689 -12
- package/src/adapter/repositories/issue/RestIssueRepository.test.ts +3 -0
- package/src/domain/entities/Issue.ts +1 -0
- package/src/domain/usecases/GetStoryObjectMapUseCase.test.ts +1 -0
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +11 -3
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +983 -167
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +177 -26
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +22 -9
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +8 -3
- package/src/domain/usecases/StartPreparationUseCase.test.ts +1696 -290
- package/src/domain/usecases/StartPreparationUseCase.ts +171 -126
- package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +4 -4
- package/src/domain/usecases/adapter-interfaces/LocalCommandRunner.ts +4 -1
- package/types/adapter/entry-points/cli/index.d.ts +4 -1
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/repositories/NodeLocalCommandRunner.d.ts +1 -1
- package/types/adapter/repositories/NodeLocalCommandRunner.d.ts.map +1 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +7 -6
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
- package/types/domain/entities/Issue.d.ts +1 -0
- package/types/domain/entities/Issue.d.ts.map +1 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +5 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +5 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts +10 -18
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +3 -3
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/LocalCommandRunner.d.ts +1 -1
- package/types/domain/usecases/adapter-interfaces/LocalCommandRunner.d.ts.map +1 -1
|
@@ -33,17 +33,71 @@ class NotifyFinishedIssuePreparationUseCase {
|
|
|
33
33
|
else if (issue.status !== params.preparationStatus) {
|
|
34
34
|
throw new IllegalIssueStatusError(params.issueUrl, issue.status, params.preparationStatus);
|
|
35
35
|
}
|
|
36
|
+
if (issue.dependedIssueUrls.length === 0) {
|
|
37
|
+
try {
|
|
38
|
+
const storyObjectMap = await this.issueRepository.getStoryObjectMap(project);
|
|
39
|
+
for (const storyObject of storyObjectMap.values()) {
|
|
40
|
+
const towerDefenceIssue = storyObject.issues.find((i) => i.url === issue.url);
|
|
41
|
+
if (towerDefenceIssue) {
|
|
42
|
+
issue.dependedIssueUrls = towerDefenceIssue.dependedIssueUrls;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.warn('Failed to enrich dependedIssueUrls from story object map:', error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (issue.dependedIssueUrls.length > 0) {
|
|
52
|
+
issue.status = params.awaitingWorkspaceStatus;
|
|
53
|
+
await this.issueRepository.update(issue, project);
|
|
54
|
+
await this.issueCommentRepository.createComment(issue, `Issue has dependent issue URLs: ${issue.dependedIssueUrls.join(', ')}`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (issue.nextActionDate !== null || issue.nextActionHour !== null) {
|
|
58
|
+
issue.status = params.awaitingWorkspaceStatus;
|
|
59
|
+
await this.issueRepository.update(issue, project);
|
|
60
|
+
await this.issueCommentRepository.createComment(issue, `Issue has next action date or hour set: nextActionDate=${issue.nextActionDate?.toISOString() ?? 'null'}, nextActionHour=${issue.nextActionHour ?? 'null'}`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
36
63
|
const comments = await this.issueCommentRepository.getCommentsFromIssue(issue);
|
|
64
|
+
const { rejections, approvedPrUrl } = await this.collectRejections(issue, comments);
|
|
65
|
+
const rejectionStatusMessage = rejections.length > 0
|
|
66
|
+
? `Auto Status Check: REJECTED\n${rejections.map((r) => `- ${r.detail}`).join('\n')}`
|
|
67
|
+
: 'Auto Status Check: APPROVED';
|
|
37
68
|
const lastTargetComments = comments.slice(-params.thresholdForAutoReject * 2);
|
|
38
69
|
if (lastTargetComments.filter((comment) => comment.content.startsWith('Auto Status Check: REJECTED')).length >= params.thresholdForAutoReject &&
|
|
39
|
-
!lastTargetComments.some((comment) => comment.content
|
|
70
|
+
!lastTargetComments.some((comment) => comment.content
|
|
71
|
+
.toLowerCase()
|
|
72
|
+
.includes('failed to pass the check automatically'))) {
|
|
40
73
|
issue.status = params.awaitingQualityCheckStatus;
|
|
41
74
|
await this.issueRepository.update(issue, project);
|
|
42
|
-
|
|
75
|
+
const escalationStatusLine = rejections.length > 0
|
|
76
|
+
? rejectionStatusMessage
|
|
77
|
+
: 'Auto Status Check: APPROVED (escalated due to prior failures)';
|
|
78
|
+
if (rejections.length === 0 && approvedPrUrl !== null) {
|
|
79
|
+
await this.setPrNextActionDate(approvedPrUrl, project);
|
|
80
|
+
}
|
|
81
|
+
await this.issueCommentRepository.createComment(issue, `${escalationStatusLine}\n\nFailed to pass the check automatically for ${params.thresholdForAutoReject} times`);
|
|
43
82
|
await this.sendWorkflowBlockerNotification(params.issueUrl, params.workflowBlockerResolvedWebhookUrl, project);
|
|
44
83
|
return;
|
|
45
84
|
}
|
|
85
|
+
if (rejections.length <= 0) {
|
|
86
|
+
issue.status = params.awaitingQualityCheckStatus;
|
|
87
|
+
await this.issueRepository.update(issue, project);
|
|
88
|
+
if (approvedPrUrl !== null) {
|
|
89
|
+
await this.setPrNextActionDate(approvedPrUrl, project);
|
|
90
|
+
}
|
|
91
|
+
await this.sendWorkflowBlockerNotification(params.issueUrl, params.workflowBlockerResolvedWebhookUrl, project);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
issue.status = params.awaitingWorkspaceStatus;
|
|
95
|
+
await this.issueRepository.update(issue, project);
|
|
96
|
+
await this.issueCommentRepository.createComment(issue, rejectionStatusMessage);
|
|
97
|
+
};
|
|
98
|
+
this.collectRejections = async (issue, comments) => {
|
|
46
99
|
const rejections = [];
|
|
100
|
+
let approvedPrUrl = null;
|
|
47
101
|
const lastComment = comments[comments.length - 1];
|
|
48
102
|
if (!lastComment || !lastComment.content.startsWith('From:')) {
|
|
49
103
|
rejections.push({
|
|
@@ -51,23 +105,33 @@ class NotifyFinishedIssuePreparationUseCase {
|
|
|
51
105
|
detail: 'NO_REPORT_FROM_AGENT_BOT',
|
|
52
106
|
});
|
|
53
107
|
}
|
|
108
|
+
else if (this.reportBodyHasNextStep(lastComment.content)) {
|
|
109
|
+
rejections.push({
|
|
110
|
+
type: 'REPORT_HAS_NEXT_STEP',
|
|
111
|
+
detail: 'REPORT_HAS_NEXT_STEP',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
54
114
|
const categoryLabels = issue.labels.filter((label) => label.startsWith('category:'));
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
115
|
+
const hasLlmAgentLabel = issue.labels.some((l) => l === 'llm-agent' || l.startsWith('llm-agent:'));
|
|
116
|
+
if (!hasLlmAgentLabel &&
|
|
117
|
+
(categoryLabels.length <= 0 || categoryLabels.includes('category:e2e'))) {
|
|
118
|
+
const prsToCheck = issue.isPr
|
|
119
|
+
? await this.resolveOpenPrsForPrItem(issue.url)
|
|
120
|
+
: await this.issueRepository.findRelatedOpenPRs(issue.url);
|
|
121
|
+
if (prsToCheck.length <= 0) {
|
|
58
122
|
rejections.push({
|
|
59
123
|
type: 'PULL_REQUEST_NOT_FOUND',
|
|
60
124
|
detail: 'PULL_REQUEST_NOT_FOUND',
|
|
61
125
|
});
|
|
62
126
|
}
|
|
63
|
-
else if (
|
|
127
|
+
else if (prsToCheck.length > 1) {
|
|
64
128
|
rejections.push({
|
|
65
129
|
type: 'MULTIPLE_PULL_REQUESTS_FOUND',
|
|
66
|
-
detail: `MULTIPLE_PULL_REQUESTS_FOUND: ${
|
|
130
|
+
detail: `MULTIPLE_PULL_REQUESTS_FOUND: ${prsToCheck.map((pr) => pr.url).join(', ')}`,
|
|
67
131
|
});
|
|
68
132
|
}
|
|
69
133
|
else {
|
|
70
|
-
const pr =
|
|
134
|
+
const pr = prsToCheck[0];
|
|
71
135
|
if (pr.isConflicted) {
|
|
72
136
|
rejections.push({
|
|
73
137
|
type: 'PULL_REQUEST_CONFLICTED',
|
|
@@ -98,17 +162,48 @@ class NotifyFinishedIssuePreparationUseCase {
|
|
|
98
162
|
detail: `ANY_REVIEW_COMMENT_NOT_RESOLVED: ${pr.url}`,
|
|
99
163
|
});
|
|
100
164
|
}
|
|
165
|
+
if (!pr.isConflicted &&
|
|
166
|
+
pr.isPassedAllCiJob &&
|
|
167
|
+
pr.isResolvedAllReviewComments) {
|
|
168
|
+
approvedPrUrl = pr.url;
|
|
169
|
+
}
|
|
101
170
|
}
|
|
102
171
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
172
|
+
return { rejections, approvedPrUrl };
|
|
173
|
+
};
|
|
174
|
+
this.resolveOpenPrsForPrItem = async (prUrl) => {
|
|
175
|
+
const pr = await this.issueRepository.getOpenPullRequest(prUrl);
|
|
176
|
+
if (pr === null) {
|
|
177
|
+
return [];
|
|
108
178
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
179
|
+
return [pr];
|
|
180
|
+
};
|
|
181
|
+
this.reportBodyHasNextStep = (body) => {
|
|
182
|
+
const reportMatch = body.match(/```json\n([\s\S]*?)\n```/);
|
|
183
|
+
if (!reportMatch || reportMatch.length < 2) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
let reportJson;
|
|
187
|
+
try {
|
|
188
|
+
reportJson = JSON.parse(reportMatch[1]);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
console.warn('Invalid JSON in report body while checking nextStep:', error);
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
if (typeof reportJson !== 'object' || reportJson === null) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
if (!('nextStep' in reportJson)) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
const nextStepValue = Reflect.get(reportJson, 'nextStep');
|
|
201
|
+
return nextStepValue !== null && nextStepValue !== undefined;
|
|
202
|
+
};
|
|
203
|
+
this.setPrNextActionDate = async (prUrl, project) => {
|
|
204
|
+
const nextActionDate = new Date();
|
|
205
|
+
nextActionDate.setMonth(nextActionDate.getMonth() + 1);
|
|
206
|
+
await this.issueRepository.updateNextActionDate(prUrl, project, nextActionDate);
|
|
112
207
|
};
|
|
113
208
|
this.sendWorkflowBlockerNotification = async (issueUrl, webhookUrlTemplate, project) => {
|
|
114
209
|
if (webhookUrlTemplate === null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotifyFinishedIssuePreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"NotifyFinishedIssuePreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,8 +22,13 @@ class RevertOrphanedPreparationUseCase {
|
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
for (const issue of preparationIssues) {
|
|
25
|
-
const
|
|
26
|
-
const { exitCode } = await this.localCommandRunner.runCommand(
|
|
25
|
+
const commandTemplate = params.preparationProcessCheckCommand.replace('{URL}', '$1');
|
|
26
|
+
const { exitCode } = await this.localCommandRunner.runCommand('sh', [
|
|
27
|
+
'-c',
|
|
28
|
+
commandTemplate,
|
|
29
|
+
'--',
|
|
30
|
+
issue.url,
|
|
31
|
+
]);
|
|
27
32
|
if (exitCode !== 0) {
|
|
28
33
|
await this.issueRepository.updateStatus(project, issue, awaitingWorkspaceStatusOption.id);
|
|
29
34
|
await this.issueRepository.createComment(issue, `Orphaned preparation detected: no live worker process found for ${issue.url}. Status reverted to ${params.awaitingWorkspaceStatus}.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevertOrphanedPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/RevertOrphanedPreparationUseCase.ts"],"names":[],"mappings":";;;AAIA,MAAa,gCAAgC;IAC3C,YACW,iBAGR,EACQ,eAGR,EACQ,kBAAsC;QARtC,sBAAiB,GAAjB,iBAAiB,CAGzB;QACQ,oBAAe,GAAf,eAAe,CAGvB;QACQ,uBAAkB,GAAlB,kBAAkB,CAAoB;QAGjD,QAAG,GAAG,KAAK,EAAE,MAMZ,EAAiB,EAAE;YAClB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAC/D,MAAM,CAAC,UAAU,CAClB,CAAC;YACF,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACnE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,iCAAiC,SAAS,gBAAgB,MAAM,CAAC,UAAU,EAAE,CAC9E,CAAC;YACJ,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CACxD,SAAS,EACT,MAAM,CAAC,sBAAsB,CAC9B,CAAC;YAEF,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CACrC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,iBAAiB,CACrD,CAAC;YAEF,MAAM,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAChE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,uBAAuB,CACjD,CAAC;YACF,IAAI,CAAC,6BAA6B,EAAE,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;gBACtC,MAAM,
|
|
1
|
+
{"version":3,"file":"RevertOrphanedPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/RevertOrphanedPreparationUseCase.ts"],"names":[],"mappings":";;;AAIA,MAAa,gCAAgC;IAC3C,YACW,iBAGR,EACQ,eAGR,EACQ,kBAAsC;QARtC,sBAAiB,GAAjB,iBAAiB,CAGzB;QACQ,oBAAe,GAAf,eAAe,CAGvB;QACQ,uBAAkB,GAAlB,kBAAkB,CAAoB;QAGjD,QAAG,GAAG,KAAK,EAAE,MAMZ,EAAiB,EAAE;YAClB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAC/D,MAAM,CAAC,UAAU,CAClB,CAAC;YACF,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACnE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,iCAAiC,SAAS,gBAAgB,MAAM,CAAC,UAAU,EAAE,CAC9E,CAAC;YACJ,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CACxD,SAAS,EACT,MAAM,CAAC,sBAAsB,CAC9B,CAAC;YAEF,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CACrC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,iBAAiB,CACrD,CAAC;YAEF,MAAM,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAChE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,uBAAuB,CACjD,CAAC;YACF,IAAI,CAAC,6BAA6B,EAAE,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;gBACtC,MAAM,eAAe,GAAG,MAAM,CAAC,8BAA8B,CAAC,OAAO,CACnE,OAAO,EACP,IAAI,CACL,CAAC;gBACF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,EAAE;oBAClE,IAAI;oBACJ,eAAe;oBACf,IAAI;oBACJ,KAAK,CAAC,GAAG;iBACV,CAAC,CAAC;gBACH,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;oBACnB,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CACrC,OAAO,EACP,KAAK,EACL,6BAA6B,CAAC,EAAE,CACjC,CAAC;oBACF,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CACtC,KAAK,EACL,mEAAmE,KAAK,CAAC,GAAG,wBAAwB,MAAM,CAAC,uBAAuB,GAAG,CACtI,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC,CAAC;IA5DC,CAAC;CA6DL;AAxED,4EAwEC"}
|
|
@@ -8,95 +8,130 @@ class StartPreparationUseCase {
|
|
|
8
8
|
this.claudeRepository = claudeRepository;
|
|
9
9
|
this.localCommandRunner = localCommandRunner;
|
|
10
10
|
this.run = async (params) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
console.warn('Failed to check Claude usage:', error);
|
|
11
|
+
const claudeUsages = await this.claudeRepository.getUsage();
|
|
12
|
+
const weeklyWindowHours = 168;
|
|
13
|
+
const nonWeeklyUsages = claudeUsages.filter((usage) => usage.hour !== weeklyWindowHours);
|
|
14
|
+
if (nonWeeklyUsages.some((usage) => usage.utilizationPercentage > params.utilizationPercentageThreshold)) {
|
|
15
|
+
console.warn('Claude usage limit exceeded. Skipping starting preparation.');
|
|
16
|
+
return;
|
|
20
17
|
}
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
let maximumPreparingIssuesCount = params.maximumPreparingIssuesCount ?? 6;
|
|
19
|
+
const weeklyUsages = claudeUsages.filter((usage) => usage.hour === weeklyWindowHours);
|
|
20
|
+
if (weeklyUsages.length > 0 &&
|
|
21
|
+
params.utilizationPercentageThreshold < 100) {
|
|
22
|
+
const maxWeeklyUtilization = Math.max(...weeklyUsages.map((usage) => usage.utilizationPercentage));
|
|
23
|
+
if (maxWeeklyUtilization > params.utilizationPercentageThreshold) {
|
|
24
|
+
const normalizedUtilizationBeyondThreshold = (maxWeeklyUtilization - params.utilizationPercentageThreshold) /
|
|
25
|
+
(100 - params.utilizationPercentageThreshold);
|
|
26
|
+
maximumPreparingIssuesCount = Math.floor(maximumPreparingIssuesCount *
|
|
27
|
+
Math.pow(1 - normalizedUtilizationBeyondThreshold, 2));
|
|
28
|
+
if (maximumPreparingIssuesCount <= 0) {
|
|
29
|
+
console.warn(`Weekly Claude usage (${maxWeeklyUtilization}%) exceeds threshold (${params.utilizationPercentageThreshold}%). Skipping starting preparation.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.warn(`Weekly Claude usage (${maxWeeklyUtilization}%) exceeds threshold (${params.utilizationPercentageThreshold}%). Reducing maximumPreparingIssuesCount to ${maximumPreparingIssuesCount}.`);
|
|
33
|
+
}
|
|
29
34
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const repositoryBlockerIssues = this.createWorkflowBlockerIssues(storyObjectMap);
|
|
35
|
+
let project = await this.projectRepository.getByUrl(params.projectUrl);
|
|
36
|
+
project = await this.projectRepository.prepareStatus(params.awaitingWorkspaceStatus, project);
|
|
37
|
+
project = await this.projectRepository.prepareStatus(params.preparationStatus, project);
|
|
38
|
+
const storyObjectMap = await this.issueRepository.getStoryObjectMap(project);
|
|
39
|
+
const allIssues = await this.issueRepository.getAllOpened(project);
|
|
36
40
|
const awaitingWorkspaceIssues = Array.from(storyObjectMap.values())
|
|
37
41
|
.map((storyObject) => storyObject.issues)
|
|
38
42
|
.flat()
|
|
39
|
-
.filter((issue) => issue.status === params.awaitingWorkspaceStatus)
|
|
40
|
-
|
|
43
|
+
.filter((issue) => issue.status === params.awaitingWorkspaceStatus)
|
|
44
|
+
.map((issue) => ({ ...issue }));
|
|
45
|
+
const currentPreparationIssueCount = allIssues.filter((issue) => issue.status === params.preparationStatus).length;
|
|
41
46
|
let updatedCurrentPreparationIssueCount = currentPreparationIssueCount;
|
|
42
|
-
const
|
|
47
|
+
const now = new Date();
|
|
48
|
+
const currentHour = now.getHours();
|
|
49
|
+
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
50
|
+
const tomorrowStart = new Date(todayStart.getFullYear(), todayStart.getMonth(), todayStart.getDate() + 1);
|
|
43
51
|
for (let i = 0; i < awaitingWorkspaceIssues.length &&
|
|
44
52
|
updatedCurrentPreparationIssueCount < maximumPreparingIssuesCount; i++) {
|
|
45
53
|
const issue = awaitingWorkspaceIssues[i];
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
if (issue.dependedIssueUrls.length > 0) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (issue.nextActionDate !== null &&
|
|
58
|
+
issue.nextActionDate >= tomorrowStart) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (issue.nextActionHour !== null && currentHour < issue.nextActionHour) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (params.allowedIssueAuthors !== null &&
|
|
65
|
+
issue.author !== '' &&
|
|
66
|
+
!params.allowedIssueAuthors.includes(issue.author)) {
|
|
49
67
|
continue;
|
|
50
68
|
}
|
|
51
69
|
const agent = issue.labels
|
|
52
|
-
.find((label) => label.startsWith('
|
|
53
|
-
?.replace('
|
|
54
|
-
.trim() ||
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
.find((label) => label.startsWith('llm-agent:'))
|
|
71
|
+
?.replace('llm-agent:', '')
|
|
72
|
+
.trim() ||
|
|
73
|
+
issue.labels
|
|
74
|
+
.find((label) => label.startsWith('category:'))
|
|
75
|
+
?.replace('category:', '')
|
|
76
|
+
.trim() ||
|
|
77
|
+
params.defaultLlmAgentName ||
|
|
78
|
+
params.defaultAgentName;
|
|
79
|
+
const model = issue.labels
|
|
80
|
+
.find((label) => label.startsWith('llm-model:'))
|
|
81
|
+
?.replace('llm-model:', '')
|
|
82
|
+
.trim() || params.defaultLlmModelName;
|
|
83
|
+
if (!model) {
|
|
84
|
+
console.error(`No LLM model configured for issue ${issue.url}. Provide --defaultLlmModelName or add an llm-model: label.`);
|
|
85
|
+
continue;
|
|
57
86
|
}
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
for (const story of targetStory) {
|
|
69
|
-
const storyIssue = input.issues.find((issue) => story.name.startsWith(issue.title));
|
|
70
|
-
summaryStoryIssue.set(story.name, {
|
|
71
|
-
story,
|
|
72
|
-
storyIssue: storyIssue || null,
|
|
73
|
-
issues: [],
|
|
74
|
-
});
|
|
75
|
-
for (const issue of input.issues) {
|
|
76
|
-
if (issue.story !== story.name) {
|
|
87
|
+
const isPrUrl = issue.url.includes('/pull/');
|
|
88
|
+
let branchName;
|
|
89
|
+
if (isPrUrl) {
|
|
90
|
+
const pr = await this.issueRepository.getOpenPullRequest(issue.url);
|
|
91
|
+
if (pr === null) {
|
|
92
|
+
console.warn(`Skipping non-OPEN PR ${issue.url}: wrapper requires an open PR.`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (pr.branchName === null) {
|
|
96
|
+
console.warn(`Skipping PR ${issue.url}: head branch is unavailable.`);
|
|
77
97
|
continue;
|
|
78
98
|
}
|
|
79
|
-
|
|
99
|
+
branchName = pr.branchName;
|
|
80
100
|
}
|
|
101
|
+
else {
|
|
102
|
+
const relatedPRs = await this.issueRepository.findRelatedOpenPRs(issue.url);
|
|
103
|
+
if (relatedPRs.length > 1) {
|
|
104
|
+
console.warn(`Skipping issue ${issue.url}: ${relatedPRs.length} related open PRs found (ambiguous).`);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
else if (relatedPRs.length === 1) {
|
|
108
|
+
if (relatedPRs[0].branchName === null) {
|
|
109
|
+
console.warn(`Skipping issue ${issue.url}: related open PR has unavailable head branch.`);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
branchName = relatedPRs[0].branchName;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
branchName = `i${issue.number}`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!/^[\w./-]+$/.test(branchName)) {
|
|
119
|
+
console.error(`Skipping issue ${issue.url}: branch name contains unexpected characters: ${branchName}`);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
issue.status = params.preparationStatus;
|
|
123
|
+
await this.issueRepository.update(issue, project);
|
|
124
|
+
await this.localCommandRunner.runCommand('aw', [
|
|
125
|
+
issue.url,
|
|
126
|
+
agent,
|
|
127
|
+
model,
|
|
128
|
+
'--configFilePath',
|
|
129
|
+
params.configFilePath,
|
|
130
|
+
'--branch',
|
|
131
|
+
branchName,
|
|
132
|
+
]);
|
|
133
|
+
updatedCurrentPreparationIssueCount++;
|
|
81
134
|
}
|
|
82
|
-
return summaryStoryIssue;
|
|
83
|
-
};
|
|
84
|
-
this.createWorkflowBlockerIssues = (storyObjectMap) => {
|
|
85
|
-
const workflowBlockerStory = Array.from(storyObjectMap.keys()).filter((storyName) => storyName.toLowerCase().includes('workflow blocker'));
|
|
86
|
-
if (workflowBlockerStory.length === 0) {
|
|
87
|
-
return [];
|
|
88
|
-
}
|
|
89
|
-
const result = storyObjectMap
|
|
90
|
-
.get(workflowBlockerStory[0])
|
|
91
|
-
?.issues.filter((issue) => issue.state === 'OPEN')
|
|
92
|
-
.map((issue) => {
|
|
93
|
-
const orgRepo = issue.url.split('/issues')[0].split('github.com/')[1];
|
|
94
|
-
return {
|
|
95
|
-
orgRepo,
|
|
96
|
-
blockerIssueUrls: [issue.url],
|
|
97
|
-
};
|
|
98
|
-
}) || [];
|
|
99
|
-
return result;
|
|
100
135
|
};
|
|
101
136
|
}
|
|
102
137
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"StartPreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -128,9 +128,12 @@ describe('CLI', () => {
|
|
|
128
128
|
awaitingWorkspaceStatus: 'Awaiting',
|
|
129
129
|
preparationStatus: 'Preparing',
|
|
130
130
|
defaultAgentName: 'agent1',
|
|
131
|
-
|
|
131
|
+
defaultLlmModelName: 'claude-opus-4-5',
|
|
132
|
+
defaultLlmAgentName: 'aw',
|
|
132
133
|
maximumPreparingIssuesCount: 10,
|
|
133
134
|
allowIssueCacheMinutes: 5,
|
|
135
|
+
utilizationPercentageThreshold: 80,
|
|
136
|
+
allowedIssueAuthors: 'user1,user2',
|
|
134
137
|
awaitingQualityCheckStatus: 'Awaiting QC',
|
|
135
138
|
thresholdForAutoReject: 5,
|
|
136
139
|
workflowBlockerResolvedWebhookUrl: 'https://example.com/webhook',
|
|
@@ -168,7 +171,8 @@ describe('CLI', () => {
|
|
|
168
171
|
const config = {
|
|
169
172
|
maximumPreparingIssuesCount: 'abc',
|
|
170
173
|
allowIssueCacheMinutes: 'def',
|
|
171
|
-
|
|
174
|
+
utilizationPercentageThreshold: 'ghi',
|
|
175
|
+
thresholdForAutoReject: 'jkl',
|
|
172
176
|
};
|
|
173
177
|
writeConfig(config);
|
|
174
178
|
|
|
@@ -176,6 +180,7 @@ describe('CLI', () => {
|
|
|
176
180
|
|
|
177
181
|
expect(result.maximumPreparingIssuesCount).toBeUndefined();
|
|
178
182
|
expect(result.allowIssueCacheMinutes).toBeUndefined();
|
|
183
|
+
expect(result.utilizationPercentageThreshold).toBeUndefined();
|
|
179
184
|
expect(result.thresholdForAutoReject).toBeUndefined();
|
|
180
185
|
});
|
|
181
186
|
|
|
@@ -274,14 +279,14 @@ defaultAgentName: 'readme-agent'
|
|
|
274
279
|
const readme = `<details>
|
|
275
280
|
<summary>config</summary>
|
|
276
281
|
maximumPreparingIssuesCount: 15
|
|
277
|
-
|
|
282
|
+
utilizationPercentageThreshold: 80
|
|
278
283
|
thresholdForAutoReject: 5
|
|
279
284
|
</details>`;
|
|
280
285
|
|
|
281
286
|
const result = parseProjectReadmeConfig(readme);
|
|
282
287
|
|
|
283
288
|
expect(result.maximumPreparingIssuesCount).toBe(15);
|
|
284
|
-
expect(result.
|
|
289
|
+
expect(result.utilizationPercentageThreshold).toBe(80);
|
|
285
290
|
expect(result.thresholdForAutoReject).toBe(5);
|
|
286
291
|
});
|
|
287
292
|
|
|
@@ -446,9 +451,12 @@ defaultAgentName: 'case-test-agent'
|
|
|
446
451
|
awaitingWorkspaceStatus: 'Awaiting',
|
|
447
452
|
preparationStatus: 'Preparing',
|
|
448
453
|
defaultAgentName: 'agent1',
|
|
449
|
-
|
|
454
|
+
defaultLlmModelName: null,
|
|
455
|
+
defaultLlmAgentName: null,
|
|
456
|
+
configFilePath: configFilePath,
|
|
450
457
|
maximumPreparingIssuesCount: null,
|
|
451
|
-
|
|
458
|
+
utilizationPercentageThreshold: 90,
|
|
459
|
+
allowedIssueAuthors: null,
|
|
452
460
|
});
|
|
453
461
|
});
|
|
454
462
|
|
|
@@ -483,18 +491,22 @@ defaultAgentName: 'case-test-agent'
|
|
|
483
491
|
awaitingWorkspaceStatus: 'Awaiting',
|
|
484
492
|
preparationStatus: 'Preparing',
|
|
485
493
|
defaultAgentName: 'override-agent',
|
|
486
|
-
|
|
494
|
+
defaultLlmModelName: null,
|
|
495
|
+
defaultLlmAgentName: null,
|
|
496
|
+
configFilePath: configFilePath,
|
|
487
497
|
maximumPreparingIssuesCount: null,
|
|
488
|
-
|
|
498
|
+
utilizationPercentageThreshold: 90,
|
|
499
|
+
allowedIssueAuthors: null,
|
|
489
500
|
});
|
|
490
501
|
});
|
|
491
502
|
|
|
492
|
-
it('should pass
|
|
493
|
-
const
|
|
503
|
+
it('should pass defaultLlmModelName and allowedIssueAuthors from config file', async () => {
|
|
504
|
+
const configWithLlm = {
|
|
494
505
|
...defaultConfig,
|
|
495
|
-
|
|
506
|
+
defaultLlmModelName: 'claude-opus-4-5',
|
|
507
|
+
allowedIssueAuthors: 'user1,user2',
|
|
496
508
|
};
|
|
497
|
-
writeConfig(
|
|
509
|
+
writeConfig(configWithLlm);
|
|
498
510
|
|
|
499
511
|
const mockRun = jest.fn().mockResolvedValue(undefined);
|
|
500
512
|
const MockedStartPreparationUseCase = jest.mocked(
|
|
@@ -518,7 +530,8 @@ defaultAgentName: 'case-test-agent'
|
|
|
518
530
|
|
|
519
531
|
expect(mockRun).toHaveBeenCalledWith(
|
|
520
532
|
expect.objectContaining({
|
|
521
|
-
|
|
533
|
+
defaultLlmModelName: 'claude-opus-4-5',
|
|
534
|
+
allowedIssueAuthors: ['user1', 'user2'],
|
|
522
535
|
}),
|
|
523
536
|
);
|
|
524
537
|
});
|