github-issue-tower-defence-management 2.154.10 → 2.155.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.
Files changed (129) hide show
  1. package/README.md +45 -1
  2. package/bin/adapter/entry-points/cli/fleetConfig.js +33 -1
  3. package/bin/adapter/entry-points/cli/fleetConfig.js.map +1 -1
  4. package/bin/adapter/entry-points/cli/index.js +148 -49
  5. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  6. package/bin/adapter/entry-points/cli/notifyFinishedIssuePreparationRetry.js +27 -0
  7. package/bin/adapter/entry-points/cli/notifyFinishedIssuePreparationRetry.js.map +1 -0
  8. package/bin/adapter/entry-points/cli/projectConfig.js +5 -0
  9. package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
  10. package/bin/adapter/entry-points/cli/resumableSessionSelect.js +45 -0
  11. package/bin/adapter/entry-points/cli/resumableSessionSelect.js.map +1 -0
  12. package/bin/adapter/entry-points/console/ui-dist/assets/index-B_lVAA3P.css +2 -0
  13. package/bin/adapter/entry-points/console/ui-dist/assets/index-CN6FXgfc.js +93 -0
  14. package/bin/adapter/entry-points/console/ui-dist/index.html +2 -2
  15. package/bin/adapter/entry-points/console/webServer.js +20 -0
  16. package/bin/adapter/entry-points/console/webServer.js.map +1 -1
  17. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +15 -1
  18. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  19. package/bin/adapter/proxy/TokenListLoader.js +3 -2
  20. package/bin/adapter/proxy/TokenListLoader.js.map +1 -1
  21. package/bin/adapter/repositories/FileSystemResumableSessionTranscriptRepository.js +188 -0
  22. package/bin/adapter/repositories/FileSystemResumableSessionTranscriptRepository.js.map +1 -0
  23. package/bin/adapter/repositories/FileSystemWorkerSessionFailureStreakRepository.js +98 -0
  24. package/bin/adapter/repositories/FileSystemWorkerSessionFailureStreakRepository.js.map +1 -0
  25. package/bin/adapter/repositories/FileSystemWorkerSessionLogRepository.js +57 -0
  26. package/bin/adapter/repositories/FileSystemWorkerSessionLogRepository.js.map +1 -0
  27. package/bin/adapter/repositories/GitHubIssueCommentRepository.js +10 -2
  28. package/bin/adapter/repositories/GitHubIssueCommentRepository.js.map +1 -1
  29. package/bin/adapter/repositories/LocalStorageUrgentStoryLaunchHoldRepository.js +245 -0
  30. package/bin/adapter/repositories/LocalStorageUrgentStoryLaunchHoldRepository.js.map +1 -0
  31. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +81 -8
  32. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
  33. package/bin/domain/entities/WorkerRequestText.js +6 -0
  34. package/bin/domain/entities/WorkerRequestText.js.map +1 -0
  35. package/bin/domain/entities/WorkerSessionFailureStreak.js +3 -0
  36. package/bin/domain/entities/WorkerSessionFailureStreak.js.map +1 -0
  37. package/bin/domain/services/commentCreateWithDedupRetry.js +46 -0
  38. package/bin/domain/services/commentCreateWithDedupRetry.js.map +1 -0
  39. package/bin/domain/usecases/CloseIssueAsRequestApplier.js +29 -0
  40. package/bin/domain/usecases/CloseIssueAsRequestApplier.js.map +1 -0
  41. package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -0
  42. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
  43. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +61 -15
  44. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  45. package/bin/domain/usecases/ResumableSessionSelectUseCase.js +153 -0
  46. package/bin/domain/usecases/ResumableSessionSelectUseCase.js.map +1 -0
  47. package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js +12 -7
  48. package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js.map +1 -1
  49. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +59 -21
  50. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
  51. package/bin/domain/usecases/StartPreparationUseCase.js +157 -3
  52. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  53. package/bin/domain/usecases/WorkerSessionEndClassifyUseCase.js +225 -0
  54. package/bin/domain/usecases/WorkerSessionEndClassifyUseCase.js.map +1 -0
  55. package/bin/domain/usecases/adapter-interfaces/ResumableSessionTranscriptRepository.js +3 -0
  56. package/bin/domain/usecases/adapter-interfaces/ResumableSessionTranscriptRepository.js.map +1 -0
  57. package/bin/domain/usecases/adapter-interfaces/UrgentStoryLaunchHoldRepository.js +3 -0
  58. package/bin/domain/usecases/adapter-interfaces/UrgentStoryLaunchHoldRepository.js.map +1 -0
  59. package/bin/domain/usecases/adapter-interfaces/WorkerSessionFailureStreakRepository.js +3 -0
  60. package/bin/domain/usecases/adapter-interfaces/WorkerSessionFailureStreakRepository.js.map +1 -0
  61. package/bin/domain/usecases/adapter-interfaces/WorkerSessionLogRepository.js +3 -0
  62. package/bin/domain/usecases/adapter-interfaces/WorkerSessionLogRepository.js.map +1 -0
  63. package/bin/domain/usecases/extractCloseIssueAs.js +24 -0
  64. package/bin/domain/usecases/extractCloseIssueAs.js.map +1 -0
  65. package/bin/domain/usecases/urgentStoryLaunchHoldDecide.js +76 -0
  66. package/bin/domain/usecases/urgentStoryLaunchHoldDecide.js.map +1 -0
  67. package/package.json +1 -1
  68. package/types/adapter/entry-points/cli/fleetConfig.d.ts +3 -0
  69. package/types/adapter/entry-points/cli/fleetConfig.d.ts.map +1 -1
  70. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  71. package/types/adapter/entry-points/cli/notifyFinishedIssuePreparationRetry.d.ts +8 -0
  72. package/types/adapter/entry-points/cli/notifyFinishedIssuePreparationRetry.d.ts.map +1 -0
  73. package/types/adapter/entry-points/cli/projectConfig.d.ts +3 -0
  74. package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
  75. package/types/adapter/entry-points/cli/resumableSessionSelect.d.ts +12 -0
  76. package/types/adapter/entry-points/cli/resumableSessionSelect.d.ts.map +1 -0
  77. package/types/adapter/entry-points/console/webServer.d.ts +1 -0
  78. package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
  79. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  80. package/types/adapter/proxy/TokenListLoader.d.ts +1 -0
  81. package/types/adapter/proxy/TokenListLoader.d.ts.map +1 -1
  82. package/types/adapter/repositories/FileSystemResumableSessionTranscriptRepository.d.ts +13 -0
  83. package/types/adapter/repositories/FileSystemResumableSessionTranscriptRepository.d.ts.map +1 -0
  84. package/types/adapter/repositories/FileSystemWorkerSessionFailureStreakRepository.d.ts +12 -0
  85. package/types/adapter/repositories/FileSystemWorkerSessionFailureStreakRepository.d.ts.map +1 -0
  86. package/types/adapter/repositories/FileSystemWorkerSessionLogRepository.d.ts +5 -0
  87. package/types/adapter/repositories/FileSystemWorkerSessionLogRepository.d.ts.map +1 -0
  88. package/types/adapter/repositories/GitHubIssueCommentRepository.d.ts +5 -0
  89. package/types/adapter/repositories/GitHubIssueCommentRepository.d.ts.map +1 -1
  90. package/types/adapter/repositories/LocalStorageUrgentStoryLaunchHoldRepository.d.ts +30 -0
  91. package/types/adapter/repositories/LocalStorageUrgentStoryLaunchHoldRepository.d.ts.map +1 -0
  92. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +2 -1
  93. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
  94. package/types/domain/entities/WorkerRequestText.d.ts +2 -0
  95. package/types/domain/entities/WorkerRequestText.d.ts.map +1 -0
  96. package/types/domain/entities/WorkerSessionFailureStreak.d.ts +5 -0
  97. package/types/domain/entities/WorkerSessionFailureStreak.d.ts.map +1 -0
  98. package/types/domain/services/commentCreateWithDedupRetry.d.ts +11 -0
  99. package/types/domain/services/commentCreateWithDedupRetry.d.ts.map +1 -0
  100. package/types/domain/usecases/CloseIssueAsRequestApplier.d.ts +16 -0
  101. package/types/domain/usecases/CloseIssueAsRequestApplier.d.ts.map +1 -0
  102. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +1 -0
  103. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
  104. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +4 -1
  105. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  106. package/types/domain/usecases/ResumableSessionSelectUseCase.d.ts +35 -0
  107. package/types/domain/usecases/ResumableSessionSelectUseCase.d.ts.map +1 -0
  108. package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts +3 -1
  109. package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts.map +1 -1
  110. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts +5 -2
  111. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
  112. package/types/domain/usecases/StartPreparationUseCase.d.ts +12 -1
  113. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
  114. package/types/domain/usecases/WorkerSessionEndClassifyUseCase.d.ts +27 -0
  115. package/types/domain/usecases/WorkerSessionEndClassifyUseCase.d.ts.map +1 -0
  116. package/types/domain/usecases/adapter-interfaces/ResumableSessionTranscriptRepository.d.ts +22 -0
  117. package/types/domain/usecases/adapter-interfaces/ResumableSessionTranscriptRepository.d.ts.map +1 -0
  118. package/types/domain/usecases/adapter-interfaces/UrgentStoryLaunchHoldRepository.d.ts +11 -0
  119. package/types/domain/usecases/adapter-interfaces/UrgentStoryLaunchHoldRepository.d.ts.map +1 -0
  120. package/types/domain/usecases/adapter-interfaces/WorkerSessionFailureStreakRepository.d.ts +7 -0
  121. package/types/domain/usecases/adapter-interfaces/WorkerSessionFailureStreakRepository.d.ts.map +1 -0
  122. package/types/domain/usecases/adapter-interfaces/WorkerSessionLogRepository.d.ts +11 -0
  123. package/types/domain/usecases/adapter-interfaces/WorkerSessionLogRepository.d.ts.map +1 -0
  124. package/types/domain/usecases/extractCloseIssueAs.d.ts +12 -0
  125. package/types/domain/usecases/extractCloseIssueAs.d.ts.map +1 -0
  126. package/types/domain/usecases/urgentStoryLaunchHoldDecide.d.ts +48 -0
  127. package/types/domain/usecases/urgentStoryLaunchHoldDecide.d.ts.map +1 -0
  128. package/bin/adapter/entry-points/console/ui-dist/assets/index-BCjejjC0.css +0 -2
  129. package/bin/adapter/entry-points/console/ui-dist/assets/index-CcgrBS5P.js +0 -93
@@ -80,6 +80,7 @@ const RELATED_OPEN_PULL_REQUEST_URLS_BATCH_SIZE = 100;
80
80
  const RELATED_OPEN_PULL_REQUEST_URLS_TIMELINE_PAGE_SIZE = 100;
81
81
  const ISSUE_EVENTS_PAGE_SIZE = 100;
82
82
  const ISSUE_EVENT_COUNT_AT_WHICH_GITHUB_STOPS_LISTING_ISSUE_EVENTS = 310;
83
+ const REOPENED_TIMELINE_ITEM_COUNT_AT_WHICH_GITHUB_STOPS_LISTING_REOPENED_TIMELINE_ITEMS = 310;
83
84
  function isIssueTimelineResponse(value) {
84
85
  if (typeof value !== 'object' || value === null)
85
86
  return false;
@@ -164,9 +165,22 @@ function isIssueLatestReopenedTimelineItemResponse(value) {
164
165
  if (!isRecord(timelineItems))
165
166
  return false;
166
167
  const nodes = timelineItems.nodes;
167
- return (Array.isArray(nodes) &&
168
+ return (typeof timelineItems.totalCount === 'number' &&
169
+ Array.isArray(nodes) &&
168
170
  nodes.every((node) => isRecord(node) && typeof node.createdAt === 'string'));
169
171
  }
172
+ function isRepositoryIssueEventFeedResponseItem(value) {
173
+ if (!isRecord(value))
174
+ return false;
175
+ const issue = value.issue;
176
+ return (typeof value.event === 'string' &&
177
+ typeof value.created_at === 'string' &&
178
+ isRecord(issue) &&
179
+ typeof issue.number === 'number');
180
+ }
181
+ function isRepositoryIssueEventFeedResponse(value) {
182
+ return (Array.isArray(value) && value.every(isRepositoryIssueEventFeedResponseItem));
183
+ }
170
184
  function listGraphqlResponseErrors(value) {
171
185
  if (!isRecord(value))
172
186
  return [];
@@ -2117,7 +2131,12 @@ class ApiV3CheerioRestIssueRepository extends BaseGitHubRepository_1.BaseGitHubR
2117
2131
  if (issueEventListingScan.listingOutcome === 'listedEveryEvent') {
2118
2132
  return issueEventListingScan.latestReopenedEventAt;
2119
2133
  }
2120
- return this.fetchLatestReopenedTimelineItemCreatedAt(issue);
2134
+ const latestReopenedTimelineItemListing = await this.fetchLatestReopenedTimelineItemListing(issue);
2135
+ if (latestReopenedTimelineItemListing.listingOutcome ===
2136
+ 'listedEveryReopenedTimelineItem') {
2137
+ return latestReopenedTimelineItemListing.latestReopenedTimelineItemCreatedAt;
2138
+ }
2139
+ return this.scanRepositoryIssueEventFeedForLatestReopenedEventAt(issue, latestReopenedTimelineItemListing.lastListedReopenedTimelineItemCreatedAt);
2121
2140
  };
2122
2141
  this.scanIssueEventListingForLatestReopenedEventAt = async (issue) => {
2123
2142
  const { owner, repo, issueNumber } = this.parseIssueUrl(issue.url);
@@ -2164,13 +2183,14 @@ class ApiV3CheerioRestIssueRepository extends BaseGitHubRepository_1.BaseGitHubR
2164
2183
  }
2165
2184
  return { listingOutcome: 'listedEveryEvent', latestReopenedEventAt };
2166
2185
  };
2167
- this.fetchLatestReopenedTimelineItemCreatedAt = async (issue) => {
2186
+ this.fetchLatestReopenedTimelineItemListing = async (issue) => {
2168
2187
  const { owner, repo, issueNumber } = this.parseIssueUrl(issue.url);
2169
2188
  const query = `
2170
2189
  query IssueLatestReopenedTimelineItem($owner: String!, $repo: String!, $issueNumber: Int!) {
2171
2190
  repository(owner: $owner, name: $repo) {
2172
2191
  issue(number: $issueNumber) {
2173
2192
  timelineItems(last: 1, itemTypes: [REOPENED_EVENT]) {
2193
+ totalCount
2174
2194
  nodes {
2175
2195
  ... on ReopenedEvent {
2176
2196
  createdAt
@@ -2197,12 +2217,65 @@ class ApiV3CheerioRestIssueRepository extends BaseGitHubRepository_1.BaseGitHubR
2197
2217
  throw new Error(`GitHub GraphQL API returned errors for the latest reopened timeline item of issue ${issue.url}: ${JSON.stringify(graphqlErrors)}`);
2198
2218
  }
2199
2219
  if (!isIssueLatestReopenedTimelineItemResponse(responseBody)) {
2200
- throw new Error(`GitHub GraphQL API returned no timeline items for issue ${issue.url}`);
2220
+ throw new Error(`GitHub GraphQL API returned no reopened timeline items with a totalCount for issue ${issue.url}`);
2221
+ }
2222
+ const { totalCount: reopenedTimelineItemTotalCount, nodes: reopenedTimelineItems, } = responseBody.data.repository.issue.timelineItems;
2223
+ const lastListedReopenedTimelineItemCreatedAt = reopenedTimelineItems.length === 0
2224
+ ? null
2225
+ : new Date(reopenedTimelineItems[reopenedTimelineItems.length - 1].createdAt);
2226
+ if (reopenedTimelineItemTotalCount <
2227
+ REOPENED_TIMELINE_ITEM_COUNT_AT_WHICH_GITHUB_STOPS_LISTING_REOPENED_TIMELINE_ITEMS) {
2228
+ return {
2229
+ listingOutcome: 'listedEveryReopenedTimelineItem',
2230
+ latestReopenedTimelineItemCreatedAt: lastListedReopenedTimelineItemCreatedAt,
2231
+ };
2201
2232
  }
2202
- const reopenedTimelineItems = responseBody.data.repository.issue.timelineItems.nodes;
2203
- if (reopenedTimelineItems.length === 0)
2204
- return null;
2205
- return new Date(reopenedTimelineItems[reopenedTimelineItems.length - 1].createdAt);
2233
+ if (lastListedReopenedTimelineItemCreatedAt === null) {
2234
+ throw new Error(`GitHub GraphQL API reported ${reopenedTimelineItemTotalCount} reopened timeline items but listed none for issue ${issue.url}`);
2235
+ }
2236
+ return {
2237
+ listingOutcome: 'stoppedAtGitHubReopenedTimelineItemListingLimit',
2238
+ lastListedReopenedTimelineItemCreatedAt,
2239
+ };
2240
+ };
2241
+ this.scanRepositoryIssueEventFeedForLatestReopenedEventAt = async (issue, lastListedReopenedTimelineItemCreatedAt) => {
2242
+ const { owner, repo, issueNumber } = this.parseIssueUrl(issue.url);
2243
+ const ownerSegment = encodeURIComponent(owner);
2244
+ const repoSegment = encodeURIComponent(repo);
2245
+ let page = 1;
2246
+ let hasNextPage = true;
2247
+ while (hasNextPage) {
2248
+ const repositoryIssueEventFeedUrl = `https://api.github.com/repos/${ownerSegment}/${repoSegment}/issues/events?per_page=${ISSUE_EVENTS_PAGE_SIZE}&page=${page}`;
2249
+ const response = await this.fetchWithRateLimitRetry(() => fetch(repositoryIssueEventFeedUrl, {
2250
+ method: 'GET',
2251
+ headers: {
2252
+ Authorization: `Bearer ${this.ghToken}`,
2253
+ Accept: 'application/vnd.github+json',
2254
+ },
2255
+ }), { method: 'GET', path: (0, githubRestClient_1.sanitizeRestPath)(repositoryIssueEventFeedUrl) });
2256
+ if (!response.ok) {
2257
+ const reason = await this.formatGitHubErrorWithStatus(response);
2258
+ throw new Error(`Failed to fetch page ${page} of the repository issue event feed of ${owner}/${repo} for issue ${issue.url}: ${reason}`);
2259
+ }
2260
+ const body = await response.json();
2261
+ if (!isRepositoryIssueEventFeedResponse(body)) {
2262
+ throw new Error(`Unexpected response shape when fetching page ${page} of the repository issue event feed of ${owner}/${repo} for issue ${issue.url}`);
2263
+ }
2264
+ for (const feedEvent of body) {
2265
+ const feedEventCreatedAt = new Date(feedEvent.created_at);
2266
+ if (feedEventCreatedAt < lastListedReopenedTimelineItemCreatedAt) {
2267
+ return lastListedReopenedTimelineItemCreatedAt;
2268
+ }
2269
+ if (feedEvent.event === 'reopened' &&
2270
+ feedEvent.issue.number === issueNumber) {
2271
+ return feedEventCreatedAt;
2272
+ }
2273
+ }
2274
+ const linkHeader = response.headers.get('Link') ?? '';
2275
+ hasNextPage = linkHeader.includes('rel="next"');
2276
+ page++;
2277
+ }
2278
+ throw new Error(`The repository issue event feed of ${owner}/${repo} ended before listing a reopened event of issue ${issue.url} or an event earlier than its last listed reopened timeline item created at ${lastListedReopenedTimelineItemCreatedAt.toISOString()}`);
2206
2279
  };
2207
2280
  this.getPullRequestChangedFilePaths = async (prUrl) => {
2208
2281
  const { owner, repo, issueNumber: prNumber } = this.parseIssueUrl(prUrl);