github-issue-tower-defence-management 2.19.1 → 2.19.2

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 (780) hide show
  1. package/bin/adapter/entry-points/cli/index.js +0 -0
  2. package/package.json +5 -1
  3. package/.env.example +0 -7
  4. package/.gitattributes +0 -2
  5. package/.github/CODEOWNERS +0 -6
  6. package/.github/copilot-instructions.md +0 -6
  7. package/.github/dependabot.yml +0 -19
  8. package/.github/instructions/code-review.instructions.md +0 -50
  9. package/.github/workflows/api-created_issue_pr.yml +0 -97
  10. package/.github/workflows/ci-failure-issue-creator.yml +0 -48
  11. package/.github/workflows/close-manual-prs.yml +0 -80
  12. package/.github/workflows/codeql.yml +0 -107
  13. package/.github/workflows/commit-lint.yml +0 -85
  14. package/.github/workflows/configs/commitlint.config.cjs +0 -32
  15. package/.github/workflows/configs/commitlint.config.js +0 -32
  16. package/.github/workflows/console-ui.yml +0 -68
  17. package/.github/workflows/create-pr.yml +0 -116
  18. package/.github/workflows/empty-format-test-job.yml +0 -34
  19. package/.github/workflows/format.yml +0 -28
  20. package/.github/workflows/publish.yml +0 -111
  21. package/.github/workflows/secret-scan.yml +0 -51
  22. package/.github/workflows/test.yml +0 -58
  23. package/.github/workflows/umino-project.yml +0 -207
  24. package/.gitleaks.toml +0 -22
  25. package/.prettierignore +0 -31
  26. package/.prettierrc +0 -5
  27. package/CHANGELOG.md +0 -4162
  28. package/CONTRIBUTING.md +0 -60
  29. package/bin/adapter/entry-points/handlers/resolveUnansweredOwnerCalls.js +0 -12
  30. package/bin/adapter/entry-points/handlers/resolveUnansweredOwnerCalls.js.map +0 -1
  31. package/bin/adapter/repositories/FileSystemSilentSessionNotifiedStateRepository.js +0 -125
  32. package/bin/adapter/repositories/FileSystemSilentSessionNotifiedStateRepository.js.map +0 -1
  33. package/bin/adapter/repositories/issue/issueTimelineUtils.js +0 -38
  34. package/bin/adapter/repositories/issue/issueTimelineUtils.js.map +0 -1
  35. package/bin/domain/entities/UnansweredOwnerCall.js +0 -3
  36. package/bin/domain/entities/UnansweredOwnerCall.js.map +0 -1
  37. package/bin/domain/entities/WorkingTime.js +0 -3
  38. package/bin/domain/entities/WorkingTime.js.map +0 -1
  39. package/bin/domain/usecases/ChangeStatusLongInReviewIssueUseCase.js +0 -37
  40. package/bin/domain/usecases/ChangeStatusLongInReviewIssueUseCase.js.map +0 -1
  41. package/bin/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.js +0 -118
  42. package/bin/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.js.map +0 -1
  43. package/bin/domain/usecases/GenerateWorkingTimeReportUseCase.js +0 -180
  44. package/bin/domain/usecases/GenerateWorkingTimeReportUseCase.js.map +0 -1
  45. package/bin/domain/usecases/TriagerApprovalDispatchUseCase.js +0 -160
  46. package/bin/domain/usecases/TriagerApprovalDispatchUseCase.js.map +0 -1
  47. package/bin/domain/usecases/adapter-interfaces/SilentSessionNotifiedStateRepository.js +0 -3
  48. package/bin/domain/usecases/adapter-interfaces/SilentSessionNotifiedStateRepository.js.map +0 -1
  49. package/bin/domain/usecases/awaitingOwnerApprovalMessage.js +0 -7
  50. package/bin/domain/usecases/awaitingOwnerApprovalMessage.js.map +0 -1
  51. package/bin/domain/usecases/findLastAgentDeclaringReport.js +0 -12
  52. package/bin/domain/usecases/findLastAgentDeclaringReport.js.map +0 -1
  53. package/bin/domain/usecases/isPullRequestDeclaredUnnecessary.js +0 -25
  54. package/bin/domain/usecases/isPullRequestDeclaredUnnecessary.js.map +0 -1
  55. package/bin/domain/usecases/isWaitingForOwnerApproval.js +0 -16
  56. package/bin/domain/usecases/isWaitingForOwnerApproval.js.map +0 -1
  57. package/bin/domain/usecases/returnedToAwaitingWorkspaceMessage.js +0 -7
  58. package/bin/domain/usecases/returnedToAwaitingWorkspaceMessage.js.map +0 -1
  59. package/commitlint.config.js +0 -6
  60. package/eslint.config.mjs +0 -76
  61. package/jest.config.js +0 -84
  62. package/jest.setup.js +0 -1
  63. package/lib/buffer-equal-constant-time-compat/index.js +0 -17
  64. package/lib/buffer-equal-constant-time-compat/index.test.js +0 -54
  65. package/lib/buffer-equal-constant-time-compat/package.json +0 -5
  66. package/lib/typescript-compat/bin/tsc +0 -2
  67. package/lib/typescript-compat/bin/tsserver +0 -2
  68. package/lib/typescript-compat/lib/typescript.js +0 -1
  69. package/lib/typescript-compat/package.json +0 -13
  70. package/renovate.json +0 -46
  71. package/scripts/copyConsoleUiDist.mjs +0 -35
  72. package/scripts/defaultBranchTipVerify.sh +0 -23
  73. package/scripts/testWorkflowRunVerify.sh +0 -47
  74. package/scripts/verifyConsoleUiDist.mjs +0 -96
  75. package/src/adapter/ci/consoleUiWorkflowTimeout.test.ts +0 -61
  76. package/src/adapter/ci/publishTestWorkflowGate.test.ts +0 -653
  77. package/src/adapter/ci/workflowRunCancellation.test.ts +0 -72
  78. package/src/adapter/entry-points/cli/fleetConfig.test.ts +0 -553
  79. package/src/adapter/entry-points/cli/fleetConfig.ts +0 -266
  80. package/src/adapter/entry-points/cli/index.test.ts +0 -2837
  81. package/src/adapter/entry-points/cli/index.ts +0 -1488
  82. package/src/adapter/entry-points/cli/projectConfig.test.ts +0 -342
  83. package/src/adapter/entry-points/cli/projectConfig.ts +0 -500
  84. package/src/adapter/entry-points/console/consoleAirplaneSnapshotApi.test.ts +0 -658
  85. package/src/adapter/entry-points/console/consoleAirplaneSnapshotApi.ts +0 -482
  86. package/src/adapter/entry-points/console/consoleDataDelivery.test.ts +0 -222
  87. package/src/adapter/entry-points/console/consoleDataDelivery.ts +0 -134
  88. package/src/adapter/entry-points/console/consoleDoneStore.test.ts +0 -169
  89. package/src/adapter/entry-points/console/consoleDoneStore.ts +0 -139
  90. package/src/adapter/entry-points/console/consoleGithubTokenResolver.test.ts +0 -275
  91. package/src/adapter/entry-points/console/consoleGithubTokenResolver.ts +0 -113
  92. package/src/adapter/entry-points/console/consoleImageProxy.test.ts +0 -140
  93. package/src/adapter/entry-points/console/consoleImageProxy.ts +0 -111
  94. package/src/adapter/entry-points/console/consoleItemUrlLookup.test.ts +0 -63
  95. package/src/adapter/entry-points/console/consoleItemUrlLookup.ts +0 -66
  96. package/src/adapter/entry-points/console/consoleOperationApi.test.ts +0 -2523
  97. package/src/adapter/entry-points/console/consoleOperationApi.ts +0 -936
  98. package/src/adapter/entry-points/console/consoleProjectResolver.test.ts +0 -246
  99. package/src/adapter/entry-points/console/consoleProjectResolver.ts +0 -111
  100. package/src/adapter/entry-points/console/consoleReadApi.test.ts +0 -714
  101. package/src/adapter/entry-points/console/consoleReadApi.ts +0 -361
  102. package/src/adapter/entry-points/console/consoleTabNames.test.ts +0 -52
  103. package/src/adapter/entry-points/console/consoleTabNames.ts +0 -37
  104. package/src/adapter/entry-points/console/consoleUiDistSync.test.ts +0 -66
  105. package/src/adapter/entry-points/console/dashboardComposeService.test.ts +0 -595
  106. package/src/adapter/entry-points/console/dashboardComposeService.ts +0 -256
  107. package/src/adapter/entry-points/console/dashboardEmitterComposerKey.test.ts +0 -180
  108. package/src/adapter/entry-points/console/ensureConsoleRunning.test.ts +0 -115
  109. package/src/adapter/entry-points/console/ensureConsoleRunning.ts +0 -64
  110. package/src/adapter/entry-points/console/ui/.storybook/main.ts +0 -12
  111. package/src/adapter/entry-points/console/ui/.storybook/preview.ts +0 -15
  112. package/src/adapter/entry-points/console/ui/biome.json +0 -53
  113. package/src/adapter/entry-points/console/ui/components.json +0 -20
  114. package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +0 -725
  115. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +0 -831
  116. package/src/adapter/entry-points/console/ui/e2e/playwright.config.ts +0 -30
  117. package/src/adapter/entry-points/console/ui/e2e/tsconfig.json +0 -18
  118. package/src/adapter/entry-points/console/ui/index.html +0 -12
  119. package/src/adapter/entry-points/console/ui/jest-globals.cjs +0 -26
  120. package/src/adapter/entry-points/console/ui/jest.setup.ts +0 -1
  121. package/src/adapter/entry-points/console/ui/jest.styleMock.js +0 -1
  122. package/src/adapter/entry-points/console/ui/public/sw.js +0 -60
  123. package/src/adapter/entry-points/console/ui/src/components/ui/badge.stories.tsx +0 -35
  124. package/src/adapter/entry-points/console/ui/src/components/ui/badge.tsx +0 -28
  125. package/src/adapter/entry-points/console/ui/src/components/ui/button.stories.tsx +0 -34
  126. package/src/adapter/entry-points/console/ui/src/components/ui/button.tsx +0 -50
  127. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleCopyCodeButton.stories.tsx +0 -28
  128. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleCopyCodeButton.test.tsx +0 -65
  129. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleCopyCodeButton.tsx +0 -19
  130. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMarkdownContent.stories.tsx +0 -61
  131. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMarkdownContent.test.tsx +0 -199
  132. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMarkdownContent.tsx +0 -166
  133. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMermaidDiagram.stories.tsx +0 -22
  134. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMermaidDiagram.test.tsx +0 -74
  135. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMermaidDiagram.tsx +0 -84
  136. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMermaidDiagramModalScreen.stories.tsx +0 -27
  137. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMermaidDiagramModalScreen.test.tsx +0 -85
  138. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleMermaidDiagramModalScreen.tsx +0 -97
  139. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleReferenceLink.stories.tsx +0 -76
  140. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleReferenceLink.test.tsx +0 -56
  141. package/src/adapter/entry-points/console/ui/src/features/console/components/content/ConsoleReferenceLink.tsx +0 -39
  142. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleChangedFileList.stories.tsx +0 -32
  143. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleChangedFileList.test.tsx +0 -105
  144. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleChangedFileList.tsx +0 -157
  145. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.stories.tsx +0 -68
  146. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.test.tsx +0 -612
  147. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentComposer.tsx +0 -276
  148. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentList.stories.tsx +0 -33
  149. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentList.test.tsx +0 -57
  150. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommentList.tsx +0 -76
  151. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommitList.stories.tsx +0 -25
  152. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommitList.test.tsx +0 -55
  153. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCommitList.tsx +0 -49
  154. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCopyUrlButton.stories.tsx +0 -24
  155. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCopyUrlButton.test.tsx +0 -63
  156. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleCopyUrlButton.tsx +0 -19
  157. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFetchFailureAlert.stories.tsx +0 -33
  158. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFetchFailureAlert.test.tsx +0 -62
  159. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFetchFailureAlert.tsx +0 -59
  160. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFileDiff.stories.tsx +0 -38
  161. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFileDiff.test.tsx +0 -151
  162. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleFileDiff.tsx +0 -245
  163. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.stories.tsx +0 -514
  164. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.test.tsx +0 -727
  165. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemDetail.tsx +0 -387
  166. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemIcon.stories.tsx +0 -82
  167. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemIcon.test.tsx +0 -52
  168. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsoleItemIcon.tsx +0 -32
  169. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestDetail.stories.tsx +0 -48
  170. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestDetail.test.tsx +0 -235
  171. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestDetail.tsx +0 -145
  172. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestMergeableChip.stories.tsx +0 -29
  173. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestMergeableChip.test.tsx +0 -30
  174. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestMergeableChip.tsx +0 -50
  175. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestStatusBadges.stories.tsx +0 -38
  176. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestStatusBadges.test.tsx +0 -54
  177. package/src/adapter/entry-points/console/ui/src/features/console/components/detail/ConsolePullRequestStatusBadges.tsx +0 -60
  178. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleAirplaneModeButton.stories.tsx +0 -56
  179. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleAirplaneModeButton.test.tsx +0 -111
  180. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleAirplaneModeButton.tsx +0 -92
  181. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsolePanel.stories.tsx +0 -51
  182. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsolePanel.test.tsx +0 -59
  183. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsolePanel.tsx +0 -39
  184. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +0 -207
  185. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.test.tsx +0 -332
  186. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.tsx +0 -211
  187. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTimerSettingsModalDialog.stories.tsx +0 -49
  188. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTimerSettingsModalDialog.test.tsx +0 -157
  189. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTimerSettingsModalDialog.tsx +0 -118
  190. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleCopyStoryNameButton.stories.tsx +0 -23
  191. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleCopyStoryNameButton.test.tsx +0 -40
  192. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleCopyStoryNameButton.tsx +0 -17
  193. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemList.stories.tsx +0 -101
  194. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemList.test.tsx +0 -102
  195. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemList.tsx +0 -75
  196. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemSummary.stories.tsx +0 -40
  197. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemSummary.test.tsx +0 -213
  198. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleItemSummary.tsx +0 -115
  199. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleQueuedItemRow.stories.tsx +0 -50
  200. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleQueuedItemRow.test.tsx +0 -98
  201. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleQueuedItemRow.tsx +0 -66
  202. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleQueuedList.stories.tsx +0 -69
  203. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleQueuedList.test.tsx +0 -101
  204. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleQueuedList.tsx +0 -75
  205. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.stories.tsx +0 -137
  206. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.test.tsx +0 -554
  207. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.tsx +0 -400
  208. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryReorderPanel.stories.tsx +0 -30
  209. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryReorderPanel.test.tsx +0 -111
  210. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryReorderPanel.tsx +0 -91
  211. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStorySummary.stories.tsx +0 -27
  212. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStorySummary.test.tsx +0 -24
  213. package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStorySummary.tsx +0 -28
  214. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleCloseActions.stories.tsx +0 -14
  215. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleCloseActions.test.tsx +0 -21
  216. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleCloseActions.tsx +0 -26
  217. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleDangerousActions.stories.tsx +0 -14
  218. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleDangerousActions.test.tsx +0 -40
  219. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleDangerousActions.tsx +0 -37
  220. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleErrorToast.stories.tsx +0 -33
  221. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleNextActionDateActions.stories.tsx +0 -20
  222. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleNextActionDateActions.test.tsx +0 -48
  223. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleNextActionDateActions.tsx +0 -42
  224. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOfflinePendingActionsPanel.stories.tsx +0 -115
  225. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOfflinePendingActionsPanel.test.tsx +0 -262
  226. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOfflinePendingActionsPanel.tsx +0 -123
  227. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOperationMenu.stories.tsx +0 -65
  228. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOperationMenu.test.tsx +0 -159
  229. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleOperationMenu.tsx +0 -55
  230. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsolePullRequestReviewActions.stories.tsx +0 -20
  231. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsolePullRequestReviewActions.test.tsx +0 -93
  232. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsolePullRequestReviewActions.tsx +0 -45
  233. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleStatusActions.stories.tsx +0 -17
  234. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleStatusActions.test.tsx +0 -49
  235. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleStatusActions.tsx +0 -66
  236. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleUndoToast.stories.tsx +0 -47
  237. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleUndoToast.test.tsx +0 -95
  238. package/src/adapter/entry-points/console/ui/src/features/console/components/operations/ConsoleUndoToast.tsx +0 -62
  239. package/src/adapter/entry-points/console/ui/src/features/console/components/shared/ConsoleClipboardCopyButton.stories.tsx +0 -32
  240. package/src/adapter/entry-points/console/ui/src/features/console/components/shared/ConsoleClipboardCopyButton.test.tsx +0 -101
  241. package/src/adapter/entry-points/console/ui/src/features/console/components/shared/ConsoleClipboardCopyButton.tsx +0 -80
  242. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useAirplaneMode.test.ts +0 -304
  243. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useAirplaneMode.ts +0 -167
  244. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleActionQueue.test.ts +0 -498
  245. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleActionQueue.ts +0 -277
  246. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleCaches.test.ts +0 -99
  247. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleCaches.ts +0 -90
  248. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.test.ts +0 -110
  249. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleDetailPrefetch.ts +0 -83
  250. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleFeaturesConfig.test.ts +0 -51
  251. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleFeaturesConfig.ts +0 -39
  252. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.test.ts +0 -229
  253. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleItemDetailData.ts +0 -194
  254. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.test.ts +0 -151
  255. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleNavigation.ts +0 -128
  256. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.test.ts +0 -629
  257. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOperations.ts +0 -417
  258. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOverlay.test.ts +0 -40
  259. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleOverlay.ts +0 -71
  260. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsolePjcode.test.ts +0 -24
  261. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsolePjcode.ts +0 -17
  262. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleProjectList.test.ts +0 -97
  263. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleProjectList.ts +0 -44
  264. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleProjectTimer.test.ts +0 -59
  265. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleProjectTimer.ts +0 -26
  266. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleReferenceLink.test.ts +0 -48
  267. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleReferenceLink.ts +0 -39
  268. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleResource.test.ts +0 -41
  269. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleResource.ts +0 -57
  270. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleSwipeNavigation.test.ts +0 -115
  271. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleSwipeNavigation.ts +0 -115
  272. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.test.ts +0 -546
  273. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTabData.ts +0 -278
  274. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTimerSettings.test.ts +0 -110
  275. package/src/adapter/entry-points/console/ui/src/features/console/hooks/useConsoleTimerSettings.ts +0 -70
  276. package/src/adapter/entry-points/console/ui/src/features/console/lib/airplaneSnapshot.test.ts +0 -387
  277. package/src/adapter/entry-points/console/ui/src/features/console/lib/airplaneSnapshot.ts +0 -407
  278. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.test.ts +0 -446
  279. package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +0 -533
  280. package/src/adapter/entry-points/console/ui/src/features/console/lib/imageProxy.test.ts +0 -78
  281. package/src/adapter/entry-points/console/ui/src/features/console/lib/imageProxy.ts +0 -34
  282. package/src/adapter/entry-points/console/ui/src/features/console/lib/markdown.test.ts +0 -252
  283. package/src/adapter/entry-points/console/ui/src/features/console/lib/markdown.ts +0 -207
  284. package/src/adapter/entry-points/console/ui/src/features/console/lib/mermaidLoader.test.ts +0 -27
  285. package/src/adapter/entry-points/console/ui/src/features/console/lib/mermaidLoader.ts +0 -71
  286. package/src/adapter/entry-points/console/ui/src/features/console/lib/mermaidZoom.test.ts +0 -88
  287. package/src/adapter/entry-points/console/ui/src/features/console/lib/mermaidZoom.ts +0 -34
  288. package/src/adapter/entry-points/console/ui/src/features/console/lib/navigation.ts +0 -7
  289. package/src/adapter/entry-points/console/ui/src/features/console/lib/resourceCache.test.ts +0 -104
  290. package/src/adapter/entry-points/console/ui/src/features/console/lib/resourceCache.ts +0 -79
  291. package/src/adapter/entry-points/console/ui/src/features/console/logic/actionToast.test.ts +0 -200
  292. package/src/adapter/entry-points/console/ui/src/features/console/logic/actionToast.ts +0 -122
  293. package/src/adapter/entry-points/console/ui/src/features/console/logic/clipboard.test.ts +0 -90
  294. package/src/adapter/entry-points/console/ui/src/features/console/logic/clipboard.ts +0 -37
  295. package/src/adapter/entry-points/console/ui/src/features/console/logic/colors.test.ts +0 -34
  296. package/src/adapter/entry-points/console/ui/src/features/console/logic/colors.ts +0 -85
  297. package/src/adapter/entry-points/console/ui/src/features/console/logic/diff.test.ts +0 -81
  298. package/src/adapter/entry-points/console/ui/src/features/console/logic/diff.ts +0 -61
  299. package/src/adapter/entry-points/console/ui/src/features/console/logic/fileStatus.test.ts +0 -35
  300. package/src/adapter/entry-points/console/ui/src/features/console/logic/fileStatus.ts +0 -21
  301. package/src/adapter/entry-points/console/ui/src/features/console/logic/fileTree.test.ts +0 -96
  302. package/src/adapter/entry-points/console/ui/src/features/console/logic/fileTree.ts +0 -93
  303. package/src/adapter/entry-points/console/ui/src/features/console/logic/grouping.test.ts +0 -229
  304. package/src/adapter/entry-points/console/ui/src/features/console/logic/grouping.ts +0 -106
  305. package/src/adapter/entry-points/console/ui/src/features/console/logic/imageFile.test.ts +0 -18
  306. package/src/adapter/entry-points/console/ui/src/features/console/logic/imageFile.ts +0 -16
  307. package/src/adapter/entry-points/console/ui/src/features/console/logic/itemIcons.test.ts +0 -97
  308. package/src/adapter/entry-points/console/ui/src/features/console/logic/itemIcons.ts +0 -95
  309. package/src/adapter/entry-points/console/ui/src/features/console/logic/navigation.test.ts +0 -53
  310. package/src/adapter/entry-points/console/ui/src/features/console/logic/navigation.ts +0 -33
  311. package/src/adapter/entry-points/console/ui/src/features/console/logic/operations.test.ts +0 -72
  312. package/src/adapter/entry-points/console/ui/src/features/console/logic/operations.ts +0 -61
  313. package/src/adapter/entry-points/console/ui/src/features/console/logic/overlay.test.ts +0 -325
  314. package/src/adapter/entry-points/console/ui/src/features/console/logic/overlay.ts +0 -94
  315. package/src/adapter/entry-points/console/ui/src/features/console/logic/postedComments.test.ts +0 -44
  316. package/src/adapter/entry-points/console/ui/src/features/console/logic/postedComments.ts +0 -17
  317. package/src/adapter/entry-points/console/ui/src/features/console/logic/references.test.ts +0 -103
  318. package/src/adapter/entry-points/console/ui/src/features/console/logic/references.ts +0 -64
  319. package/src/adapter/entry-points/console/ui/src/features/console/logic/relativeTime.test.ts +0 -74
  320. package/src/adapter/entry-points/console/ui/src/features/console/logic/relativeTime.ts +0 -53
  321. package/src/adapter/entry-points/console/ui/src/features/console/logic/swipe.test.ts +0 -34
  322. package/src/adapter/entry-points/console/ui/src/features/console/logic/swipe.ts +0 -28
  323. package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.test.ts +0 -89
  324. package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.ts +0 -30
  325. package/src/adapter/entry-points/console/ui/src/features/console/logic/timerSettings.test.ts +0 -61
  326. package/src/adapter/entry-points/console/ui/src/features/console/logic/timerSettings.ts +0 -77
  327. package/src/adapter/entry-points/console/ui/src/features/console/logic/types.ts +0 -173
  328. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.test.tsx +0 -629
  329. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleItemDetailContainer.tsx +0 -351
  330. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +0 -1469
  331. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +0 -736
  332. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsoleReferenceLinkContainer.tsx +0 -25
  333. package/src/adapter/entry-points/console/ui/src/features/console/testing/fixtures.ts +0 -418
  334. package/src/adapter/entry-points/console/ui/src/index.css +0 -1592
  335. package/src/adapter/entry-points/console/ui/src/lib/utils.ts +0 -4
  336. package/src/adapter/entry-points/console/ui/src/main.tsx +0 -21
  337. package/src/adapter/entry-points/console/ui/src/vite-env.d.ts +0 -1
  338. package/src/adapter/entry-points/console/ui/tsconfig.json +0 -26
  339. package/src/adapter/entry-points/console/ui/vite.config.ts +0 -24
  340. package/src/adapter/entry-points/console/ui-dist/assets/index-BYDbK1Fj.js +0 -88
  341. package/src/adapter/entry-points/console/ui-dist/assets/index-KyQISRuQ.css +0 -2
  342. package/src/adapter/entry-points/console/ui-dist/index.html +0 -13
  343. package/src/adapter/entry-points/console/ui-dist/sw.js +0 -60
  344. package/src/adapter/entry-points/console/webServer.test.ts +0 -2945
  345. package/src/adapter/entry-points/console/webServer.ts +0 -940
  346. package/src/adapter/entry-points/function/getStoryObjectMap.ts +0 -3
  347. package/src/adapter/entry-points/handlers/FileSystemConsoleTabsRepository.test.ts +0 -218
  348. package/src/adapter/entry-points/handlers/FileSystemConsoleTabsRepository.ts +0 -113
  349. package/src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.test.ts +0 -110
  350. package/src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.ts +0 -116
  351. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +0 -859
  352. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +0 -984
  353. package/src/adapter/entry-points/handlers/InTmuxByHumanSessionTokenCountHandler.test.ts +0 -126
  354. package/src/adapter/entry-points/handlers/InTmuxByHumanSessionTokenCountHandler.ts +0 -80
  355. package/src/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.test.ts +0 -491
  356. package/src/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.ts +0 -137
  357. package/src/adapter/entry-points/handlers/OauthTokenSelectHandler.test.ts +0 -508
  358. package/src/adapter/entry-points/handlers/OauthTokenSelectHandler.ts +0 -156
  359. package/src/adapter/entry-points/handlers/consoleListsWriter.test.ts +0 -332
  360. package/src/adapter/entry-points/handlers/consoleListsWriter.ts +0 -60
  361. package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +0 -112
  362. package/src/adapter/entry-points/handlers/dashboardRowWriter.ts +0 -51
  363. package/src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.test.ts +0 -285
  364. package/src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.ts +0 -109
  365. package/src/adapter/entry-points/handlers/inTmuxByHumanSessionReconciler.test.ts +0 -170
  366. package/src/adapter/entry-points/handlers/inTmuxByHumanSessionReconciler.ts +0 -40
  367. package/src/adapter/entry-points/handlers/machineStatusWriter.test.ts +0 -191
  368. package/src/adapter/entry-points/handlers/machineStatusWriter.ts +0 -110
  369. package/src/adapter/entry-points/handlers/notifySilentTmuxSessions.test.ts +0 -548
  370. package/src/adapter/entry-points/handlers/notifySilentTmuxSessions.ts +0 -192
  371. package/src/adapter/entry-points/handlers/ownerCallFileCleaner.test.ts +0 -111
  372. package/src/adapter/entry-points/handlers/ownerCallFileCleaner.ts +0 -25
  373. package/src/adapter/entry-points/handlers/ownerCallFileStore.test.ts +0 -286
  374. package/src/adapter/entry-points/handlers/ownerCallFileStore.ts +0 -145
  375. package/src/adapter/entry-points/handlers/ownerReplyMarkerDirectoryResolve.test.ts +0 -55
  376. package/src/adapter/entry-points/handlers/ownerReplyMarkerDirectoryResolve.ts +0 -36
  377. package/src/adapter/entry-points/handlers/resetDegeneratedTmuxSessions.test.ts +0 -72
  378. package/src/adapter/entry-points/handlers/resetDegeneratedTmuxSessions.ts +0 -74
  379. package/src/adapter/entry-points/handlers/rotationOrderFileWriter.test.ts +0 -181
  380. package/src/adapter/entry-points/handlers/rotationOrderFileWriter.ts +0 -18
  381. package/src/adapter/entry-points/handlers/situationFileWriter.test.ts +0 -489
  382. package/src/adapter/entry-points/handlers/situationFileWriter.ts +0 -176
  383. package/src/adapter/entry-points/handlers/staleTmuxSessionCleaner.test.ts +0 -169
  384. package/src/adapter/entry-points/handlers/staleTmuxSessionCleaner.ts +0 -32
  385. package/src/adapter/entry-points/handlers/subscriptionDisabledTokenHandler.ts +0 -41
  386. package/src/adapter/entry-points/handlers/tokenExhaustionHandover.ts +0 -81
  387. package/src/adapter/entry-points/handlers/tokenStatusWriter.test.ts +0 -266
  388. package/src/adapter/entry-points/handlers/tokenStatusWriter.ts +0 -262
  389. package/src/adapter/proxy/ClaudeMessageResponseParser.test.ts +0 -211
  390. package/src/adapter/proxy/ClaudeMessageResponseParser.ts +0 -181
  391. package/src/adapter/proxy/RateLimitCache.test.ts +0 -1077
  392. package/src/adapter/proxy/RateLimitCache.ts +0 -385
  393. package/src/adapter/proxy/TokenListLoader.test.ts +0 -183
  394. package/src/adapter/proxy/TokenListLoader.ts +0 -75
  395. package/src/adapter/proxy/ensureProxyRunning.test.ts +0 -85
  396. package/src/adapter/proxy/ensureProxyRunning.ts +0 -41
  397. package/src/adapter/proxy/proxyEntry.test.ts +0 -552
  398. package/src/adapter/proxy/proxyEntry.ts +0 -214
  399. package/src/adapter/repositories/BaseGitHubRepository.test.ts +0 -26
  400. package/src/adapter/repositories/BaseGitHubRepository.ts +0 -26
  401. package/src/adapter/repositories/BrowserGitHubProjectRepository.test.ts +0 -108
  402. package/src/adapter/repositories/BrowserGitHubProjectRepository.ts +0 -118
  403. package/src/adapter/repositories/CliGitHubGraphqlRateLimitRepository.test.ts +0 -71
  404. package/src/adapter/repositories/CliGitHubGraphqlRateLimitRepository.ts +0 -21
  405. package/src/adapter/repositories/ConfigurableSilentSessionMessageComposer.test.ts +0 -324
  406. package/src/adapter/repositories/ConfigurableSilentSessionMessageComposer.ts +0 -148
  407. package/src/adapter/repositories/FetchWebhookRepository.ts +0 -8
  408. package/src/adapter/repositories/FileHandoverStateRepository.test.ts +0 -114
  409. package/src/adapter/repositories/FileHandoverStateRepository.ts +0 -73
  410. package/src/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.test.ts +0 -514
  411. package/src/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.ts +0 -109
  412. package/src/adapter/repositories/FileSystemKevReportWatermarkRepository.test.ts +0 -284
  413. package/src/adapter/repositories/FileSystemKevReportWatermarkRepository.ts +0 -128
  414. package/src/adapter/repositories/FileSystemSessionAssistantTurnsRepository.test.ts +0 -138
  415. package/src/adapter/repositories/FileSystemSessionAssistantTurnsRepository.ts +0 -113
  416. package/src/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.test.ts +0 -121
  417. package/src/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.ts +0 -103
  418. package/src/adapter/repositories/FileSystemSessionOutputActivityRepository.test.ts +0 -360
  419. package/src/adapter/repositories/FileSystemSessionOutputActivityRepository.ts +0 -77
  420. package/src/adapter/repositories/FileSystemSessionRecordReader.test.ts +0 -59
  421. package/src/adapter/repositories/FileSystemSessionRecordReader.ts +0 -31
  422. package/src/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.test.ts +0 -287
  423. package/src/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.ts +0 -125
  424. package/src/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.test.ts +0 -285
  425. package/src/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.ts +0 -119
  426. package/src/adapter/repositories/FileSystemSubAgentLivenessResolver.test.ts +0 -237
  427. package/src/adapter/repositories/FileSystemSubAgentLivenessResolver.ts +0 -57
  428. package/src/adapter/repositories/FileSystemSubAgentSilentSecondsResolver.test.ts +0 -56
  429. package/src/adapter/repositories/FileSystemSubAgentSilentSecondsResolver.ts +0 -32
  430. package/src/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.test.ts +0 -68
  431. package/src/adapter/repositories/FileSystemSubAgentTranscriptDirectoryResolver.ts +0 -23
  432. package/src/adapter/repositories/GitHubIssueCheckpointRepository.test.ts +0 -51
  433. package/src/adapter/repositories/GitHubIssueCheckpointRepository.ts +0 -47
  434. package/src/adapter/repositories/GitHubIssueCommentRepository.test.ts +0 -278
  435. package/src/adapter/repositories/GitHubIssueCommentRepository.ts +0 -109
  436. package/src/adapter/repositories/GoogleSpreadsheetRepository.integration.test.ts +0 -265
  437. package/src/adapter/repositories/GoogleSpreadsheetRepository.test.ts +0 -431
  438. package/src/adapter/repositories/GoogleSpreadsheetRepository.ts +0 -268
  439. package/src/adapter/repositories/GraphqlProjectRepository.diskCache.test.ts +0 -272
  440. package/src/adapter/repositories/GraphqlProjectRepository.errorHandling.test.ts +0 -111
  441. package/src/adapter/repositories/GraphqlProjectRepository.fetchProjectId.test.ts +0 -254
  442. package/src/adapter/repositories/GraphqlProjectRepository.test.ts +0 -209
  443. package/src/adapter/repositories/GraphqlProjectRepository.ts +0 -707
  444. package/src/adapter/repositories/GraphqlProjectRepositoryProjectLocation.test.ts +0 -297
  445. package/src/adapter/repositories/KyHttpRepository.ts +0 -8
  446. package/src/adapter/repositories/KySlackRepository.test.ts +0 -172
  447. package/src/adapter/repositories/KySlackRepository.ts +0 -298
  448. package/src/adapter/repositories/LocalCommandIssueAttachmentRepository.test.ts +0 -193
  449. package/src/adapter/repositories/LocalCommandIssueAttachmentRepository.ts +0 -106
  450. package/src/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.test.ts +0 -190
  451. package/src/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.ts +0 -102
  452. package/src/adapter/repositories/LocalStorageCacheRepository.test.ts +0 -265
  453. package/src/adapter/repositories/LocalStorageCacheRepository.ts +0 -79
  454. package/src/adapter/repositories/LocalStorageRepository.integration.test.ts +0 -142
  455. package/src/adapter/repositories/LocalStorageRepository.test.ts +0 -173
  456. package/src/adapter/repositories/LocalStorageRepository.ts +0 -30
  457. package/src/adapter/repositories/NoUnansweredOwnerCallStatusProvider.test.ts +0 -15
  458. package/src/adapter/repositories/NoUnansweredOwnerCallStatusProvider.ts +0 -9
  459. package/src/adapter/repositories/NodeLocalCommandRunner.largeOutput.test.ts +0 -16
  460. package/src/adapter/repositories/NodeLocalCommandRunner.test.ts +0 -118
  461. package/src/adapter/repositories/NodeLocalCommandRunner.ts +0 -66
  462. package/src/adapter/repositories/NodeProcessSignalRepository.test.ts +0 -82
  463. package/src/adapter/repositories/NodeProcessSignalRepository.ts +0 -47
  464. package/src/adapter/repositories/NodeSubAgentProcessLister.test.ts +0 -44
  465. package/src/adapter/repositories/NodeSubAgentProcessLister.ts +0 -40
  466. package/src/adapter/repositories/NodeTmuxSessionRepository.test.ts +0 -546
  467. package/src/adapter/repositories/NodeTmuxSessionRepository.ts +0 -245
  468. package/src/adapter/repositories/OauthAPIClaudeRepository.ts +0 -279
  469. package/src/adapter/repositories/OauthAPIProxyClaudeRepository.test.ts +0 -166
  470. package/src/adapter/repositories/OauthAPIProxyClaudeRepository.ts +0 -32
  471. package/src/adapter/repositories/OauthProxyClaudeRepository.test.ts +0 -428
  472. package/src/adapter/repositories/OauthProxyClaudeRepository.ts +0 -124
  473. package/src/adapter/repositories/ProcClaudeHandoverSessionRepository.test.ts +0 -242
  474. package/src/adapter/repositories/ProcClaudeHandoverSessionRepository.ts +0 -261
  475. package/src/adapter/repositories/ProcClaudeInteractiveSessionRepository.test.ts +0 -184
  476. package/src/adapter/repositories/ProcClaudeInteractiveSessionRepository.ts +0 -138
  477. package/src/adapter/repositories/ProcClaudeLiveSessionRepository.test.ts +0 -208
  478. package/src/adapter/repositories/ProcClaudeLiveSessionRepository.ts +0 -130
  479. package/src/adapter/repositories/ProcFsProcessEnvironReader.test.ts +0 -60
  480. package/src/adapter/repositories/ProcFsProcessEnvironReader.ts +0 -38
  481. package/src/adapter/repositories/ProcHostMetricsRepository.test.ts +0 -207
  482. package/src/adapter/repositories/ProcHostMetricsRepository.ts +0 -181
  483. package/src/adapter/repositories/ProcTakeOwnershipSpawnRepository.test.ts +0 -231
  484. package/src/adapter/repositories/ProcTakeOwnershipSpawnRepository.ts +0 -134
  485. package/src/adapter/repositories/ProcessListSessionSubAgentActivityRepository.test.ts +0 -121
  486. package/src/adapter/repositories/ProcessListSessionSubAgentActivityRepository.ts +0 -58
  487. package/src/adapter/repositories/ProjectIssuesCacheRepository.test.ts +0 -218
  488. package/src/adapter/repositories/ProjectIssuesCacheRepository.ts +0 -141
  489. package/src/adapter/repositories/ProxyClaudeTokenUsageRepository.test.ts +0 -1195
  490. package/src/adapter/repositories/ProxyClaudeTokenUsageRepository.ts +0 -185
  491. package/src/adapter/repositories/ProxyRateLimitCacheRepository.test.ts +0 -116
  492. package/src/adapter/repositories/ProxyRateLimitCacheRepository.ts +0 -67
  493. package/src/adapter/repositories/RateLimitSnapshotRepository.ts +0 -50
  494. package/src/adapter/repositories/RealSleeper.test.ts +0 -19
  495. package/src/adapter/repositories/RealSleeper.ts +0 -12
  496. package/src/adapter/repositories/RestProjectRepository.test.ts +0 -277
  497. package/src/adapter/repositories/RestProjectRepository.ts +0 -129
  498. package/src/adapter/repositories/SqliteClaudeMessageResponseRepository.test.ts +0 -313
  499. package/src/adapter/repositories/SqliteClaudeMessageResponseRepository.ts +0 -164
  500. package/src/adapter/repositories/SystemDateRepository.test.ts +0 -60
  501. package/src/adapter/repositories/SystemDateRepository.ts +0 -34
  502. package/src/adapter/repositories/TmuxSilentSessionNotificationRepository.test.ts +0 -253
  503. package/src/adapter/repositories/TmuxSilentSessionNotificationRepository.ts +0 -158
  504. package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.queuedReply.test.ts +0 -171
  505. package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.singleScan.test.ts +0 -86
  506. package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.test.ts +0 -996
  507. package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.ts +0 -396
  508. package/src/adapter/repositories/TranscriptRefusalTailStatusProvider.test.ts +0 -208
  509. package/src/adapter/repositories/TranscriptRefusalTailStatusProvider.ts +0 -80
  510. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.test.ts +0 -1674
  511. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.ts +0 -459
  512. package/src/adapter/repositories/clSessionScopeUnitName.test.ts +0 -76
  513. package/src/adapter/repositories/clSessionScopeUnitName.ts +0 -5
  514. package/src/adapter/repositories/clSessionScopeUnitNameFromCgroupContent.test.ts +0 -34
  515. package/src/adapter/repositories/clSessionScopeUnitNameFromCgroupContent.ts +0 -8
  516. package/src/adapter/repositories/githubGraphqlClient.test.ts +0 -479
  517. package/src/adapter/repositories/githubGraphqlClient.ts +0 -243
  518. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +0 -5182
  519. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +0 -3303
  520. package/src/adapter/repositories/issue/ApiV3IssueRepository.test.ts +0 -46
  521. package/src/adapter/repositories/issue/ApiV3IssueRepository.ts +0 -88
  522. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.test.ts +0 -1776
  523. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.ts +0 -1552
  524. package/src/adapter/repositories/issue/RestIssueRepository.test.ts +0 -393
  525. package/src/adapter/repositories/issue/RestIssueRepository.ts +0 -252
  526. package/src/adapter/repositories/issue/gitHubRawUrl.test.ts +0 -29
  527. package/src/adapter/repositories/issue/gitHubRawUrl.ts +0 -30
  528. package/src/adapter/repositories/issue/githubRateLimitRetry.test.ts +0 -167
  529. package/src/adapter/repositories/issue/githubRateLimitRetry.ts +0 -109
  530. package/src/adapter/repositories/localStorageCacheDirectory.test.ts +0 -81
  531. package/src/adapter/repositories/localStorageCacheDirectory.ts +0 -13
  532. package/src/adapter/repositories/projectFieldDefinition.test.ts +0 -191
  533. package/src/adapter/repositories/projectFieldDefinition.ts +0 -144
  534. package/src/adapter/repositories/utils.test.ts +0 -55
  535. package/src/adapter/repositories/utils.ts +0 -45
  536. package/src/domain/entities/ClaudeHandoverSession.ts +0 -12
  537. package/src/domain/entities/ClaudeMessageResponse.ts +0 -31
  538. package/src/domain/entities/ClaudeTokenUsage.ts +0 -17
  539. package/src/domain/entities/ClaudeWindowUsage.ts +0 -5
  540. package/src/domain/entities/Comment.ts +0 -5
  541. package/src/domain/entities/InteractiveLiveSession.ts +0 -6
  542. package/src/domain/entities/Issue.ts +0 -31
  543. package/src/domain/entities/KevReportWatermark.ts +0 -4
  544. package/src/domain/entities/LiveSessionActivitySnapshot.ts +0 -14
  545. package/src/domain/entities/LiveSessionOutputActivity.ts +0 -4
  546. package/src/domain/entities/LiveSessionProcessSnapshot.ts +0 -18
  547. package/src/domain/entities/LiveTmuxSession.ts +0 -4
  548. package/src/domain/entities/Member.ts +0 -3
  549. package/src/domain/entities/OutputDegeneration.ts +0 -10
  550. package/src/domain/entities/Project.ts +0 -88
  551. package/src/domain/entities/ProjectField.ts +0 -3
  552. package/src/domain/entities/ProjectFieldName.ts +0 -2
  553. package/src/domain/entities/ProjectFieldSingleSelect.ts +0 -8
  554. package/src/domain/entities/ProjectFieldSingleSelectOption.ts +0 -8
  555. package/src/domain/entities/RequiredProjectField.ts +0 -68
  556. package/src/domain/entities/SearchedIssue.ts +0 -11
  557. package/src/domain/entities/StoryObjectMap.ts +0 -12
  558. package/src/domain/entities/TokenExhaustionHandoverState.ts +0 -8
  559. package/src/domain/entities/WorkflowStatus.ts +0 -66
  560. package/src/domain/usecases/ActionAnnouncementUseCase.test.ts +0 -91
  561. package/src/domain/usecases/ActionAnnouncementUseCase.ts +0 -78
  562. package/src/domain/usecases/AgentDesignationLabelAdoptUseCase.test.ts +0 -222
  563. package/src/domain/usecases/AgentDesignationLabelAdoptUseCase.ts +0 -76
  564. package/src/domain/usecases/AnalyzeProblemByIssueUseCase.test.ts +0 -118
  565. package/src/domain/usecases/AnalyzeProblemByIssueUseCase.ts +0 -112
  566. package/src/domain/usecases/AnalyzeStoriesUseCase.test.ts +0 -82
  567. package/src/domain/usecases/AnalyzeStoriesUseCase.ts +0 -296
  568. package/src/domain/usecases/AssignNoAssigneeIssueToManagerUseCase.test.ts +0 -578
  569. package/src/domain/usecases/AssignNoAssigneeIssueToManagerUseCase.ts +0 -137
  570. package/src/domain/usecases/CONTRIBUTING_FOR_TEST.md +0 -259
  571. package/src/domain/usecases/ChangeStatusByStoryColorUseCase.test.ts +0 -437
  572. package/src/domain/usecases/ChangeStatusByStoryColorUseCase.ts +0 -80
  573. package/src/domain/usecases/ChangeTargetPullRequestApprover.test.ts +0 -248
  574. package/src/domain/usecases/ChangeTargetPullRequestApprover.ts +0 -69
  575. package/src/domain/usecases/CheckIssueReviewReadinessUseCase.test.ts +0 -411
  576. package/src/domain/usecases/CheckIssueReviewReadinessUseCase.ts +0 -142
  577. package/src/domain/usecases/ClearDependedIssueURLUseCase.test.ts +0 -1120
  578. package/src/domain/usecases/ClearDependedIssueURLUseCase.ts +0 -161
  579. package/src/domain/usecases/ClearPastNextActionDateHourUseCase.test.ts +0 -345
  580. package/src/domain/usecases/ClearPastNextActionDateHourUseCase.ts +0 -81
  581. package/src/domain/usecases/CliErrorReportUseCase.test.ts +0 -162
  582. package/src/domain/usecases/CliErrorReportUseCase.ts +0 -72
  583. package/src/domain/usecases/ConflictedIssueRevertUseCase.test.ts +0 -886
  584. package/src/domain/usecases/ConflictedIssueRevertUseCase.ts +0 -146
  585. package/src/domain/usecases/CreateEstimationIssueUseCase.test.ts +0 -227
  586. package/src/domain/usecases/CreateEstimationIssueUseCase.ts +0 -205
  587. package/src/domain/usecases/CreateNewStoryByLabelUseCase.test.ts +0 -1084
  588. package/src/domain/usecases/CreateNewStoryByLabelUseCase.ts +0 -146
  589. package/src/domain/usecases/DailySecurityScanUseCase.test.ts +0 -1709
  590. package/src/domain/usecases/DailySecurityScanUseCase.ts +0 -476
  591. package/src/domain/usecases/DefaultSilentSessionMessageComposer.test.ts +0 -533
  592. package/src/domain/usecases/DefaultSilentSessionMessageComposer.ts +0 -122
  593. package/src/domain/usecases/GetStoryObjectMapUseCase.test.ts +0 -330
  594. package/src/domain/usecases/GetStoryObjectMapUseCase.ts +0 -79
  595. package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +0 -1913
  596. package/src/domain/usecases/HandleScheduledEventUseCase.ts +0 -846
  597. package/src/domain/usecases/InTmuxByHumanSessionTokenCountUseCase.test.ts +0 -175
  598. package/src/domain/usecases/InTmuxByHumanSessionTokenCountUseCase.ts +0 -63
  599. package/src/domain/usecases/IssueNoStatusUpdateUseCase.test.ts +0 -165
  600. package/src/domain/usecases/IssueNoStatusUpdateUseCase.ts +0 -44
  601. package/src/domain/usecases/IssueRejectionEvaluator.test.ts +0 -1137
  602. package/src/domain/usecases/IssueRejectionEvaluator.ts +0 -340
  603. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.test.ts +0 -679
  604. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.ts +0 -178
  605. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +0 -5441
  606. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +0 -891
  607. package/src/domain/usecases/NotifySilentLiveSessionsUseCase.test.ts +0 -2069
  608. package/src/domain/usecases/NotifySilentLiveSessionsUseCase.ts +0 -489
  609. package/src/domain/usecases/OauthTokenSelectUseCase.test.ts +0 -662
  610. package/src/domain/usecases/OauthTokenSelectUseCase.ts +0 -274
  611. package/src/domain/usecases/OutputDegenerationDetector.test.ts +0 -167
  612. package/src/domain/usecases/OutputDegenerationDetector.ts +0 -169
  613. package/src/domain/usecases/ProjectRequiredFieldCreateUseCase.test.ts +0 -711
  614. package/src/domain/usecases/ProjectRequiredFieldCreateUseCase.ts +0 -146
  615. package/src/domain/usecases/QualityCheckAdvanceUseCase.test.ts +0 -421
  616. package/src/domain/usecases/QualityCheckAdvanceUseCase.ts +0 -76
  617. package/src/domain/usecases/ReopenedDoneIssueRevertUseCase.test.ts +0 -188
  618. package/src/domain/usecases/ReopenedDoneIssueRevertUseCase.ts +0 -57
  619. package/src/domain/usecases/ResolveInteractiveLiveSessionsUseCase.test.ts +0 -303
  620. package/src/domain/usecases/ResolveInteractiveLiveSessionsUseCase.ts +0 -155
  621. package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.test.ts +0 -1838
  622. package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts +0 -221
  623. package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +0 -2392
  624. package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +0 -499
  625. package/src/domain/usecases/SessionOutputDegenerationRecoveryUseCase.test.ts +0 -224
  626. package/src/domain/usecases/SessionOutputDegenerationRecoveryUseCase.ts +0 -142
  627. package/src/domain/usecases/SetDependedIssueUrlForOpenTaskPRsUseCase.test.ts +0 -360
  628. package/src/domain/usecases/SetDependedIssueUrlForOpenTaskPRsUseCase.ts +0 -70
  629. package/src/domain/usecases/SetNoStoryIssueToStoryUseCase.test.ts +0 -400
  630. package/src/domain/usecases/SetNoStoryIssueToStoryUseCase.ts +0 -48
  631. package/src/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.test.ts +0 -696
  632. package/src/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.ts +0 -201
  633. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +0 -1363
  634. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +0 -215
  635. package/src/domain/usecases/StaleTaskPullRequestCloseUseCase.test.ts +0 -170
  636. package/src/domain/usecases/StaleTaskPullRequestCloseUseCase.ts +0 -38
  637. package/src/domain/usecases/StaleTmuxSessionKillUseCase.test.ts +0 -283
  638. package/src/domain/usecases/StaleTmuxSessionKillUseCase.ts +0 -98
  639. package/src/domain/usecases/StartPreparationUseCase.test.ts +0 -7822
  640. package/src/domain/usecases/StartPreparationUseCase.ts +0 -876
  641. package/src/domain/usecases/SubscriptionDisabledIssueUseCase.test.ts +0 -200
  642. package/src/domain/usecases/SubscriptionDisabledIssueUseCase.ts +0 -74
  643. package/src/domain/usecases/TokenExhaustionHandoverUseCase.test.ts +0 -838
  644. package/src/domain/usecases/TokenExhaustionHandoverUseCase.ts +0 -439
  645. package/src/domain/usecases/UpdateIssueStatusByLabelUseCase.test.ts +0 -306
  646. package/src/domain/usecases/UpdateIssueStatusByLabelUseCase.ts +0 -64
  647. package/src/domain/usecases/UpdateRateLimitCacheUseCase.test.ts +0 -178
  648. package/src/domain/usecases/UpdateRateLimitCacheUseCase.ts +0 -22
  649. package/src/domain/usecases/adapter-interfaces/ClaudeHandoverSessionRepository.ts +0 -5
  650. package/src/domain/usecases/adapter-interfaces/ClaudeInteractiveSessionRepository.ts +0 -9
  651. package/src/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.ts +0 -8
  652. package/src/domain/usecases/adapter-interfaces/ClaudeMessageResponseRepository.ts +0 -5
  653. package/src/domain/usecases/adapter-interfaces/ClaudeRepository.ts +0 -6
  654. package/src/domain/usecases/adapter-interfaces/ClaudeTokenUsageRepository.ts +0 -8
  655. package/src/domain/usecases/adapter-interfaces/ConsoleTabsRepository.ts +0 -12
  656. package/src/domain/usecases/adapter-interfaces/CopilotRepository.ts +0 -3
  657. package/src/domain/usecases/adapter-interfaces/DateRepository.ts +0 -7
  658. package/src/domain/usecases/adapter-interfaces/GitHubGraphqlRateLimitRepository.ts +0 -3
  659. package/src/domain/usecases/adapter-interfaces/HttpRepository.ts +0 -3
  660. package/src/domain/usecases/adapter-interfaces/InteractiveLiveSessionTranscriptResolver.ts +0 -7
  661. package/src/domain/usecases/adapter-interfaces/IssueAttachmentRepository.ts +0 -9
  662. package/src/domain/usecases/adapter-interfaces/IssueCheckpointRepository.ts +0 -3
  663. package/src/domain/usecases/adapter-interfaces/IssueCommentRepository.ts +0 -7
  664. package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +0 -229
  665. package/src/domain/usecases/adapter-interfaces/KevReportWatermarkRepository.ts +0 -11
  666. package/src/domain/usecases/adapter-interfaces/LiveSessionProcessSnapshotProvider.ts +0 -5
  667. package/src/domain/usecases/adapter-interfaces/LocalCommandRunner.ts +0 -16
  668. package/src/domain/usecases/adapter-interfaces/OwnerCallStatusProvider.ts +0 -5
  669. package/src/domain/usecases/adapter-interfaces/ProcessEnvironReader.ts +0 -3
  670. package/src/domain/usecases/adapter-interfaces/ProcessSignalRepository.ts +0 -5
  671. package/src/domain/usecases/adapter-interfaces/ProjectRepository.ts +0 -29
  672. package/src/domain/usecases/adapter-interfaces/RateLimitCacheRepository.ts +0 -10
  673. package/src/domain/usecases/adapter-interfaces/RefusalTailStatusProvider.ts +0 -5
  674. package/src/domain/usecases/adapter-interfaces/SessionAssistantTurnsRepository.ts +0 -6
  675. package/src/domain/usecases/adapter-interfaces/SessionDegenerationCooldownStateRepository.ts +0 -4
  676. package/src/domain/usecases/adapter-interfaces/SessionOutputActivityRepository.ts +0 -7
  677. package/src/domain/usecases/adapter-interfaces/SessionRecordReader.ts +0 -3
  678. package/src/domain/usecases/adapter-interfaces/SessionSubAgentActivityRepository.ts +0 -8
  679. package/src/domain/usecases/adapter-interfaces/SilentSessionCandidateStateRepository.ts +0 -10
  680. package/src/domain/usecases/adapter-interfaces/SilentSessionHubTaskStatusCacheRepository.ts +0 -20
  681. package/src/domain/usecases/adapter-interfaces/SilentSessionMessageComposer.ts +0 -18
  682. package/src/domain/usecases/adapter-interfaces/SilentSessionNotificationRepository.ts +0 -6
  683. package/src/domain/usecases/adapter-interfaces/SlackRepository.ts +0 -20
  684. package/src/domain/usecases/adapter-interfaces/Sleeper.ts +0 -3
  685. package/src/domain/usecases/adapter-interfaces/SpreadsheetRepository.ts +0 -18
  686. package/src/domain/usecases/adapter-interfaces/StatusDefaultRepository.ts +0 -5
  687. package/src/domain/usecases/adapter-interfaces/SubAgentLivenessResolver.ts +0 -6
  688. package/src/domain/usecases/adapter-interfaces/SubAgentProcessLister.ts +0 -8
  689. package/src/domain/usecases/adapter-interfaces/SubAgentSilentSecondsResolver.ts +0 -3
  690. package/src/domain/usecases/adapter-interfaces/SubAgentTranscriptDirectoryResolver.ts +0 -6
  691. package/src/domain/usecases/adapter-interfaces/TakeOwnershipSpawnRepository.ts +0 -9
  692. package/src/domain/usecases/adapter-interfaces/TmuxSessionRepository.ts +0 -20
  693. package/src/domain/usecases/adapter-interfaces/TokenExhaustionHandoverStateRepository.ts +0 -6
  694. package/src/domain/usecases/adapter-interfaces/TokenRateLimitSnapshotRepository.ts +0 -22
  695. package/src/domain/usecases/adapter-interfaces/WebhookRepository.ts +0 -3
  696. package/src/domain/usecases/agentReportPrefix.ts +0 -1
  697. package/src/domain/usecases/autoStatusCheckComments.ts +0 -1
  698. package/src/domain/usecases/console/.gitkeep +0 -0
  699. package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +0 -887
  700. package/src/domain/usecases/console/GenerateConsoleListsUseCase.ts +0 -368
  701. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +0 -654
  702. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.ts +0 -318
  703. package/src/domain/usecases/dashboard/DashboardProjectCode.test.ts +0 -34
  704. package/src/domain/usecases/dashboard/DashboardProjectCode.ts +0 -27
  705. package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.test.ts +0 -160
  706. package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.ts +0 -69
  707. package/src/domain/usecases/dashboard/GenerateTokenStatusUseCase.test.ts +0 -362
  708. package/src/domain/usecases/dashboard/GenerateTokenStatusUseCase.ts +0 -234
  709. package/src/domain/usecases/ensureAgentOptionAndGetId.ts +0 -47
  710. package/src/domain/usecases/extractFencedJsonBlocks.test.ts +0 -40
  711. package/src/domain/usecases/extractFencedJsonBlocks.ts +0 -21
  712. package/src/domain/usecases/extractNextStepAgent.test.ts +0 -58
  713. package/src/domain/usecases/extractNextStepAgent.ts +0 -18
  714. package/src/domain/usecases/extractNextStepAgentFromComments.ts +0 -13
  715. package/src/domain/usecases/findLastAgentReport.test.ts +0 -121
  716. package/src/domain/usecases/findLastAgentReport.ts +0 -14
  717. package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.test.ts +0 -339
  718. package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.ts +0 -188
  719. package/src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.test.ts +0 -389
  720. package/src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.ts +0 -103
  721. package/src/domain/usecases/intmux/OwnerCallFile.test.ts +0 -184
  722. package/src/domain/usecases/intmux/OwnerCallFile.ts +0 -80
  723. package/src/domain/usecases/isAgentReportBody.test.ts +0 -108
  724. package/src/domain/usecases/isAgentReportBody.ts +0 -52
  725. package/src/domain/usecases/isAuthorAuthorizedForAutoStatusCheck.ts +0 -12
  726. package/src/domain/usecases/isHumanComment.test.ts +0 -77
  727. package/src/domain/usecases/isHumanComment.ts +0 -23
  728. package/src/domain/usecases/isRecord.ts +0 -2
  729. package/src/domain/usecases/issueReactivationTriggerIsPending.test.ts +0 -541
  730. package/src/domain/usecases/issueReactivationTriggerIsPending.ts +0 -25
  731. package/src/domain/usecases/nextStepAgentDispatchRepeatedMessage.ts +0 -2
  732. package/src/domain/usecases/normalizeReportBody.test.ts +0 -24
  733. package/src/domain/usecases/normalizeReportBody.ts +0 -2
  734. package/src/domain/usecases/resolveAllowedIssueAuthors.test.ts +0 -51
  735. package/src/domain/usecases/resolveAllowedIssueAuthors.ts +0 -6
  736. package/src/domain/usecases/resolveLabelsAsLlmAgentName.test.ts +0 -42
  737. package/src/domain/usecases/resolveLabelsAsLlmAgentName.ts +0 -6
  738. package/src/domain/usecases/resolveLabelsNotRequiringPullRequest.test.ts +0 -33
  739. package/src/domain/usecases/resolveLabelsNotRequiringPullRequest.ts +0 -7
  740. package/src/domain/usecases/resolveNextStepAgentDispatchRepetition.test.ts +0 -337
  741. package/src/domain/usecases/resolveNextStepAgentDispatchRepetition.ts +0 -133
  742. package/src/domain/usecases/silentSessionReminderSentinel.ts +0 -9
  743. package/src/domain/usecases/triagerAgentName.ts +0 -4
  744. package/src/domain/usecases/utils.test.ts +0 -35
  745. package/src/domain/usecases/utils.ts +0 -6
  746. package/src/index.test.ts +0 -8
  747. package/src/index.ts +0 -10
  748. package/src/releaseConfig.test.ts +0 -40
  749. package/tsconfig.build.json +0 -18
  750. package/tsconfig.json +0 -25
  751. package/types/adapter/entry-points/handlers/resolveUnansweredOwnerCalls.d.ts +0 -13
  752. package/types/adapter/entry-points/handlers/resolveUnansweredOwnerCalls.d.ts.map +0 -1
  753. package/types/adapter/repositories/FileSystemSilentSessionNotifiedStateRepository.d.ts +0 -16
  754. package/types/adapter/repositories/FileSystemSilentSessionNotifiedStateRepository.d.ts.map +0 -1
  755. package/types/adapter/repositories/issue/issueTimelineUtils.d.ts +0 -12
  756. package/types/adapter/repositories/issue/issueTimelineUtils.d.ts.map +0 -1
  757. package/types/domain/entities/UnansweredOwnerCall.d.ts +0 -5
  758. package/types/domain/entities/UnansweredOwnerCall.d.ts.map +0 -1
  759. package/types/domain/entities/WorkingTime.d.ts +0 -8
  760. package/types/domain/entities/WorkingTime.d.ts.map +0 -1
  761. package/types/domain/usecases/ChangeStatusLongInReviewIssueUseCase.d.ts +0 -17
  762. package/types/domain/usecases/ChangeStatusLongInReviewIssueUseCase.d.ts.map +0 -1
  763. package/types/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.d.ts +0 -23
  764. package/types/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.d.ts.map +0 -1
  765. package/types/domain/usecases/GenerateWorkingTimeReportUseCase.d.ts +0 -50
  766. package/types/domain/usecases/GenerateWorkingTimeReportUseCase.d.ts.map +0 -1
  767. package/types/domain/usecases/TriagerApprovalDispatchUseCase.d.ts +0 -15
  768. package/types/domain/usecases/TriagerApprovalDispatchUseCase.d.ts.map +0 -1
  769. package/types/domain/usecases/adapter-interfaces/SilentSessionNotifiedStateRepository.d.ts +0 -11
  770. package/types/domain/usecases/adapter-interfaces/SilentSessionNotifiedStateRepository.d.ts.map +0 -1
  771. package/types/domain/usecases/awaitingOwnerApprovalMessage.d.ts +0 -3
  772. package/types/domain/usecases/awaitingOwnerApprovalMessage.d.ts.map +0 -1
  773. package/types/domain/usecases/findLastAgentDeclaringReport.d.ts +0 -5
  774. package/types/domain/usecases/findLastAgentDeclaringReport.d.ts.map +0 -1
  775. package/types/domain/usecases/isPullRequestDeclaredUnnecessary.d.ts +0 -5
  776. package/types/domain/usecases/isPullRequestDeclaredUnnecessary.d.ts.map +0 -1
  777. package/types/domain/usecases/isWaitingForOwnerApproval.d.ts +0 -2
  778. package/types/domain/usecases/isWaitingForOwnerApproval.d.ts.map +0 -1
  779. package/types/domain/usecases/returnedToAwaitingWorkspaceMessage.d.ts +0 -3
  780. package/types/domain/usecases/returnedToAwaitingWorkspaceMessage.d.ts.map +0 -1
@@ -1,2392 +0,0 @@
1
- import { RevertOrphanedPreparationUseCase } from './RevertOrphanedPreparationUseCase';
2
- import { IssueRepository } from './adapter-interfaces/IssueRepository';
3
- import { IssueCommentRepository } from './adapter-interfaces/IssueCommentRepository';
4
- import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
5
- import { LocalCommandRunner } from './adapter-interfaces/LocalCommandRunner';
6
- import { Issue } from '../entities/Issue';
7
- import { Project } from '../entities/Project';
8
-
9
- type Mocked<T> = jest.Mocked<T> & jest.MockedObject<T>;
10
-
11
- const createMockIssue = (overrides: Partial<Issue> = {}): Issue => ({
12
- nameWithOwner: 'user/repo',
13
- number: 1,
14
- title: 'Test Issue',
15
- state: 'OPEN',
16
- status: 'Backlog',
17
- story: 'Default Story',
18
- nextActionDate: null,
19
- nextActionHour: null,
20
- estimationMinutes: null,
21
- dependedIssueUrls: [],
22
- completionDate50PercentConfidence: null,
23
- url: 'https://github.com/user/repo/issues/1',
24
- assignees: [],
25
- labels: [],
26
- org: 'user',
27
- repo: 'repo',
28
- body: '',
29
- itemId: 'item-1',
30
- isPr: false,
31
- isInProgress: false,
32
- isClosed: false,
33
- createdAt: new Date(),
34
- author: '',
35
- closingIssueReferenceUrls: [],
36
- agent: null,
37
- stateReason: null,
38
- ...overrides,
39
- });
40
-
41
- const createMockProject = (): Project => ({
42
- id: 'project-1',
43
- url: 'https://github.com/orgs/user/projects/1',
44
- databaseId: 1,
45
- name: 'Test Project',
46
- status: {
47
- name: 'Status',
48
- fieldId: 'status-field-id',
49
- statuses: [
50
- { id: '1', name: 'Awaiting Workspace', color: 'GRAY', description: '' },
51
- { id: '2', name: 'Preparation', color: 'YELLOW', description: '' },
52
- { id: '3', name: 'Done', color: 'GREEN', description: '' },
53
- {
54
- id: '4',
55
- name: 'Awaiting Quality Check',
56
- color: 'BLUE',
57
- description: '',
58
- },
59
- {
60
- id: '5',
61
- name: 'Failed Preparation',
62
- color: 'RED',
63
- description: '',
64
- },
65
- {
66
- id: '6',
67
- name: 'Todo by human',
68
- color: 'GREEN',
69
- description: '',
70
- },
71
- ],
72
- },
73
- nextActionDate: null,
74
- nextActionHour: null,
75
- story: {
76
- name: 'Story',
77
- fieldId: 'story-field-id',
78
- databaseId: 1,
79
- stories: [
80
- {
81
- id: 'story-1',
82
- name: 'Default Story',
83
- color: 'GRAY',
84
- description: '',
85
- },
86
- ],
87
- workflowManagementStory: {
88
- id: 'wf-1',
89
- name: 'Workflow Management',
90
- },
91
- },
92
- remainingEstimationMinutes: null,
93
- dependedIssueUrlSeparatedByComma: null,
94
- completionDate50PercentConfidence: null,
95
- agent: null,
96
- });
97
-
98
- const createPassingPr = () => ({
99
- url: 'https://github.com/user/repo/pull/5',
100
- branchName: 'i1',
101
- createdAt: new Date('2024-01-01T00:00:00Z'),
102
- isDraft: false,
103
- isConflicted: false,
104
- mergeable: null,
105
- isPassedAllCiJob: true,
106
- isCiStateSuccess: true,
107
- isResolvedAllReviewComments: true,
108
- isBranchOutOfDate: false,
109
- missingRequiredCheckNames: [],
110
- });
111
-
112
- describe('RevertOrphanedPreparationUseCase', () => {
113
- let useCase: RevertOrphanedPreparationUseCase;
114
- let mockProjectRepository: Mocked<
115
- Pick<
116
- ProjectRepository,
117
- | 'findProjectIdByUrl'
118
- | 'getProject'
119
- | 'createField'
120
- | 'getByUrl'
121
- | 'updateAgentList'
122
- >
123
- >;
124
- let mockIssueRepository: Mocked<
125
- Pick<
126
- IssueRepository,
127
- | 'getAllIssues'
128
- | 'updateStatus'
129
- | 'findRelatedOpenPRs'
130
- | 'getOpenPullRequest'
131
- | 'get'
132
- | 'setIssueAgentField'
133
- >
134
- >;
135
- let mockIssueCommentRepository: Mocked<
136
- Pick<IssueCommentRepository, 'getCommentsFromIssue' | 'createComment'>
137
- >;
138
- let mockLocalCommandRunner: Mocked<LocalCommandRunner>;
139
- let mockProject: Project;
140
-
141
- beforeEach(() => {
142
- jest.resetAllMocks();
143
- mockProject = createMockProject();
144
- mockProjectRepository = {
145
- findProjectIdByUrl: jest.fn().mockResolvedValue('project-1'),
146
- getProject: jest.fn().mockResolvedValue(mockProject),
147
- createField: jest.fn().mockResolvedValue(undefined),
148
- getByUrl: jest.fn().mockResolvedValue(mockProject),
149
- updateAgentList: jest.fn().mockResolvedValue([]),
150
- };
151
- mockIssueRepository = {
152
- getAllIssues: jest.fn().mockResolvedValue({
153
- project: mockProject,
154
- issues: [],
155
- cacheUsed: false,
156
- }),
157
- updateStatus: jest.fn().mockResolvedValue(undefined),
158
- findRelatedOpenPRs: jest.fn().mockResolvedValue([]),
159
- getOpenPullRequest: jest.fn().mockResolvedValue(null),
160
- get: jest
161
- .fn()
162
- .mockImplementation(async (issueUrl: string) =>
163
- createMockIssue({ url: issueUrl, status: 'Preparation' }),
164
- ),
165
- setIssueAgentField: jest.fn().mockResolvedValue(undefined),
166
- };
167
- mockIssueCommentRepository = {
168
- getCommentsFromIssue: jest.fn().mockResolvedValue([]),
169
- createComment: jest.fn().mockResolvedValue(undefined),
170
- };
171
- mockLocalCommandRunner = {
172
- runCommand: jest.fn(),
173
- spawnInteractive: jest.fn(),
174
- };
175
- useCase = new RevertOrphanedPreparationUseCase(
176
- mockProjectRepository,
177
- mockIssueRepository,
178
- mockIssueCommentRepository,
179
- mockLocalCommandRunner,
180
- );
181
- });
182
-
183
- it('should revert stuck-Preparation issue to Awaiting Workspace when check command exits non-zero and no agent report present', async () => {
184
- const stuckIssue = createMockIssue({
185
- url: 'https://github.com/user/repo/issues/10',
186
- status: 'Preparation',
187
- });
188
- mockIssueRepository.getAllIssues.mockResolvedValue({
189
- project: mockProject,
190
- issues: [stuckIssue],
191
- cacheUsed: false,
192
- });
193
- mockLocalCommandRunner.runCommand.mockResolvedValue({
194
- stdout: '',
195
- stderr: '',
196
- exitCode: 1,
197
- });
198
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([]);
199
-
200
- await useCase.run({
201
- projectUrl: 'https://github.com/user/repo',
202
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
203
- thresholdForAutoReject: 3,
204
- });
205
-
206
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
207
- expect(mockIssueRepository.updateStatus.mock.calls[0][0]).toBe(mockProject);
208
- expect(mockIssueRepository.updateStatus.mock.calls[0][1]).toBe(stuckIssue);
209
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
210
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
211
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe('sh');
212
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
213
- '-c',
214
- 'pgrep -fa "claude-agent.*$1"',
215
- '--',
216
- 'https://github.com/user/repo/issues/10',
217
- ]);
218
- });
219
-
220
- it('should set the designated next step agent and return the orphaned issue to Awaiting Workspace', async () => {
221
- mockProject.agent = {
222
- name: 'agent',
223
- fieldId: 'agent-field-id',
224
- options: [
225
- {
226
- id: 'agent-option-developer',
227
- name: 'developer',
228
- color: 'GRAY',
229
- description: '',
230
- },
231
- ],
232
- };
233
- const stuckIssue = createMockIssue({
234
- url: 'https://github.com/user/repo/issues/10',
235
- status: 'Preparation',
236
- agent: 'triager',
237
- });
238
- mockIssueRepository.getAllIssues.mockResolvedValue({
239
- project: mockProject,
240
- issues: [stuckIssue],
241
- cacheUsed: false,
242
- });
243
- mockLocalCommandRunner.runCommand.mockResolvedValue({
244
- stdout: '',
245
- stderr: '',
246
- exitCode: 1,
247
- });
248
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
249
- {
250
- author: 'bot',
251
- content:
252
- 'From: :robot: triager\n\n```json\n{"nextStep":null,"nextStepAgent":"developer"}\n```',
253
- createdAt: new Date('2024-01-02T00:00:00Z'),
254
- },
255
- ]);
256
-
257
- await useCase.run({
258
- projectUrl: 'https://github.com/user/repo',
259
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
260
- thresholdForAutoReject: 3,
261
- allowedIssueAuthors: ['bot'],
262
- });
263
-
264
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
265
- [stuckIssue.url, mockProject, 'agent-option-developer'],
266
- ]);
267
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
268
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
269
- });
270
-
271
- it('should transition to Failed Preparation when nextStepAgent is not in configured agents list', async () => {
272
- const stuckIssue = createMockIssue({
273
- url: 'https://github.com/user/repo/issues/10',
274
- status: 'Preparation',
275
- });
276
- mockIssueRepository.getAllIssues.mockResolvedValue({
277
- project: mockProject,
278
- issues: [stuckIssue],
279
- cacheUsed: false,
280
- });
281
- mockLocalCommandRunner.runCommand.mockResolvedValue({
282
- stdout: '',
283
- stderr: '',
284
- exitCode: 1,
285
- });
286
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
287
- {
288
- author: 'bot',
289
- content:
290
- 'From: :robot: triager\n\n```json\n{"nextStep":null,"nextStepAgent":"unknown-agent"}\n```',
291
- createdAt: new Date('2024-01-02T00:00:00Z'),
292
- },
293
- ]);
294
-
295
- await useCase.run({
296
- projectUrl: 'https://github.com/user/repo',
297
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
298
- thresholdForAutoReject: 3,
299
- allowedIssueAuthors: ['bot'],
300
- agents: ['developer', 'triager'],
301
- });
302
-
303
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([]);
304
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
305
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('5');
306
- expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
307
- stuckIssue,
308
- expect.stringContaining('unknown-agent'),
309
- );
310
- expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
311
- stuckIssue,
312
- expect.stringContaining('not in the configured agents list'),
313
- );
314
- });
315
-
316
- it('should transition to Failed Preparation when the declared next step agent is already assigned and the repetition threshold is met', async () => {
317
- mockProject.agent = {
318
- name: 'agent',
319
- fieldId: 'agent-field-id',
320
- options: [
321
- {
322
- id: 'agent-option-developer',
323
- name: 'developer',
324
- color: 'GRAY',
325
- description: '',
326
- },
327
- ],
328
- };
329
- const stuckIssue = createMockIssue({
330
- url: 'https://github.com/user/repo/issues/10',
331
- status: 'Preparation',
332
- agent: 'developer',
333
- });
334
- mockIssueRepository.getAllIssues.mockResolvedValue({
335
- project: mockProject,
336
- issues: [stuckIssue],
337
- cacheUsed: false,
338
- });
339
- mockLocalCommandRunner.runCommand.mockResolvedValue({
340
- stdout: '',
341
- stderr: '',
342
- exitCode: 1,
343
- });
344
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
345
- {
346
- author: 'bot',
347
- content:
348
- 'From: :robot: triager\n\n```json\n{"nextStep":null,"nextStepAgent":"developer"}\n```',
349
- createdAt: new Date('2024-01-02T00:00:00Z'),
350
- },
351
- {
352
- author: 'bot',
353
- content: 'Next step agent dispatch repeated: developer',
354
- createdAt: new Date('2024-01-02T01:00:00Z'),
355
- },
356
- {
357
- author: 'bot',
358
- content: 'Next step agent dispatch repeated: developer',
359
- createdAt: new Date('2024-01-02T02:00:00Z'),
360
- },
361
- ]);
362
-
363
- await useCase.run({
364
- projectUrl: 'https://github.com/user/repo',
365
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
366
- thresholdForAutoReject: 3,
367
- allowedIssueAuthors: ['bot'],
368
- });
369
-
370
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([]);
371
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
372
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('5');
373
- expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
374
- stuckIssue,
375
- expect.stringContaining(
376
- 'Failed to receive a report from the dispatched agent for 3 times',
377
- ),
378
- );
379
- });
380
-
381
- it('should record the repeated dispatch even when the project has no Failed Preparation status', async () => {
382
- mockProject.status.statuses = mockProject.status.statuses.filter(
383
- (status) => status.name !== 'Failed Preparation',
384
- );
385
- mockProject.agent = {
386
- name: 'agent',
387
- fieldId: 'agent-field-id',
388
- options: [
389
- {
390
- id: 'agent-option-developer',
391
- name: 'developer',
392
- color: 'GRAY',
393
- description: '',
394
- },
395
- ],
396
- };
397
- const stuckIssue = createMockIssue({
398
- url: 'https://github.com/user/repo/issues/10',
399
- status: 'Preparation',
400
- agent: 'developer',
401
- });
402
- mockIssueRepository.getAllIssues.mockResolvedValue({
403
- project: mockProject,
404
- issues: [stuckIssue],
405
- cacheUsed: false,
406
- });
407
- mockLocalCommandRunner.runCommand.mockResolvedValue({
408
- stdout: '',
409
- stderr: '',
410
- exitCode: 1,
411
- });
412
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
413
- {
414
- author: 'bot',
415
- content:
416
- 'From: :robot: triager\n\n```json\n{"nextStep":null,"nextStepAgent":"developer"}\n```',
417
- createdAt: new Date('2024-01-02T00:00:00Z'),
418
- },
419
- {
420
- author: 'bot',
421
- content: 'Next step agent dispatch repeated: developer',
422
- createdAt: new Date('2024-01-02T01:00:00Z'),
423
- },
424
- {
425
- author: 'bot',
426
- content: 'Next step agent dispatch repeated: developer',
427
- createdAt: new Date('2024-01-02T02:00:00Z'),
428
- },
429
- ]);
430
-
431
- await useCase.run({
432
- projectUrl: 'https://github.com/user/repo',
433
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
434
- thresholdForAutoReject: 3,
435
- allowedIssueAuthors: ['bot'],
436
- });
437
-
438
- expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
439
- stuckIssue,
440
- expect.stringContaining('Next step agent dispatch repeated: developer'),
441
- );
442
- });
443
-
444
- it('should ignore a next step agent designated by an author outside the allowed issue authors', async () => {
445
- mockProject.agent = {
446
- name: 'agent',
447
- fieldId: 'agent-field-id',
448
- options: [
449
- {
450
- id: 'agent-option-developer',
451
- name: 'developer',
452
- color: 'GRAY',
453
- description: '',
454
- },
455
- ],
456
- };
457
- const stuckIssue = createMockIssue({
458
- url: 'https://github.com/user/repo/issues/10',
459
- status: 'Preparation',
460
- agent: 'triager',
461
- });
462
- mockIssueRepository.getAllIssues.mockResolvedValue({
463
- project: mockProject,
464
- issues: [stuckIssue],
465
- cacheUsed: false,
466
- });
467
- mockLocalCommandRunner.runCommand.mockResolvedValue({
468
- stdout: '',
469
- stderr: '',
470
- exitCode: 1,
471
- });
472
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
473
- {
474
- author: 'outsider',
475
- content:
476
- 'From: :robot: triager\n\n```json\n{"nextStep":null,"nextStepAgent":"developer"}\n```',
477
- createdAt: new Date('2024-01-02T00:00:00Z'),
478
- },
479
- ]);
480
-
481
- await useCase.run({
482
- projectUrl: 'https://github.com/user/repo',
483
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
484
- thresholdForAutoReject: 3,
485
- allowedIssueAuthors: ['bot'],
486
- });
487
-
488
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([]);
489
- });
490
-
491
- it('should advance orphaned issue to Awaiting Quality Check when agent report and passing PR are present', async () => {
492
- const stuckIssue = createMockIssue({
493
- url: 'https://github.com/user/repo/issues/10',
494
- status: 'Preparation',
495
- });
496
- mockIssueRepository.getAllIssues.mockResolvedValue({
497
- project: mockProject,
498
- issues: [stuckIssue],
499
- cacheUsed: false,
500
- });
501
- mockLocalCommandRunner.runCommand.mockResolvedValue({
502
- stdout: '',
503
- stderr: '',
504
- exitCode: 1,
505
- });
506
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
507
- {
508
- author: 'bot',
509
- content: 'From: :robot: agent report',
510
- createdAt: new Date(),
511
- },
512
- ]);
513
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
514
- createPassingPr(),
515
- ]);
516
-
517
- await useCase.run({
518
- projectUrl: 'https://github.com/user/repo',
519
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
520
- thresholdForAutoReject: 3,
521
- });
522
-
523
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
524
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
525
- });
526
-
527
- it('should revert orphaned issue to Awaiting Workspace when agent report present but PR CI is failing', async () => {
528
- const stuckIssue = createMockIssue({
529
- url: 'https://github.com/user/repo/issues/10',
530
- status: 'Preparation',
531
- });
532
- mockIssueRepository.getAllIssues.mockResolvedValue({
533
- project: mockProject,
534
- issues: [stuckIssue],
535
- cacheUsed: false,
536
- });
537
- mockLocalCommandRunner.runCommand.mockResolvedValue({
538
- stdout: '',
539
- stderr: '',
540
- exitCode: 1,
541
- });
542
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
543
- {
544
- author: 'bot',
545
- content: 'From: :robot: agent report',
546
- createdAt: new Date(),
547
- },
548
- ]);
549
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
550
- {
551
- ...createPassingPr(),
552
- isPassedAllCiJob: false,
553
- },
554
- ]);
555
-
556
- await useCase.run({
557
- projectUrl: 'https://github.com/user/repo',
558
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
559
- thresholdForAutoReject: 3,
560
- });
561
-
562
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
563
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
564
- });
565
-
566
- it('should revert orphaned issue to Awaiting Workspace when agent report present but no PR found', async () => {
567
- const stuckIssue = createMockIssue({
568
- url: 'https://github.com/user/repo/issues/10',
569
- status: 'Preparation',
570
- });
571
- mockIssueRepository.getAllIssues.mockResolvedValue({
572
- project: mockProject,
573
- issues: [stuckIssue],
574
- cacheUsed: false,
575
- });
576
- mockLocalCommandRunner.runCommand.mockResolvedValue({
577
- stdout: '',
578
- stderr: '',
579
- exitCode: 1,
580
- });
581
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
582
- {
583
- author: 'bot',
584
- content: 'From: :robot: agent report',
585
- createdAt: new Date(),
586
- },
587
- ]);
588
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
589
-
590
- await useCase.run({
591
- projectUrl: 'https://github.com/user/repo',
592
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
593
- thresholdForAutoReject: 3,
594
- });
595
-
596
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
597
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
598
- });
599
-
600
- it('should keep rejecting an orphaned issue whose own status comments follow a report that declares nothing', async () => {
601
- const stuckIssue = createMockIssue({
602
- url: 'https://github.com/user/repo/issues/10',
603
- status: 'Preparation',
604
- });
605
- mockIssueRepository.getAllIssues.mockResolvedValue({
606
- project: mockProject,
607
- issues: [stuckIssue],
608
- cacheUsed: false,
609
- });
610
- mockLocalCommandRunner.runCommand.mockResolvedValue({
611
- stdout: '',
612
- stderr: '',
613
- exitCode: 1,
614
- });
615
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
616
- {
617
- author: 'agent-bot',
618
- content: 'From: :robot: agent report of an earlier session',
619
- createdAt: new Date(),
620
- },
621
- {
622
- author: 'agent-bot',
623
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
624
- createdAt: new Date(),
625
- },
626
- ]);
627
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
628
-
629
- await useCase.run({
630
- projectUrl: 'https://github.com/user/repo',
631
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
632
- thresholdForAutoReject: 3,
633
- allowedIssueAuthors: ['agent-bot'],
634
- });
635
-
636
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
637
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
638
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
639
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toContain(
640
- 'Auto Status Check: REJECTED',
641
- );
642
- });
643
-
644
- it('should advance orphaned issue with non-developer agent field to Awaiting Quality Check when no linked PRs exist', async () => {
645
- const stuckIssue = createMockIssue({
646
- url: 'https://github.com/user/repo/issues/10',
647
- status: 'Preparation',
648
- labels: [],
649
- agent: 'chore',
650
- });
651
- mockIssueRepository.getAllIssues.mockResolvedValue({
652
- project: mockProject,
653
- issues: [stuckIssue],
654
- cacheUsed: false,
655
- });
656
- mockLocalCommandRunner.runCommand.mockResolvedValue({
657
- stdout: '',
658
- stderr: '',
659
- exitCode: 1,
660
- });
661
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
662
- {
663
- author: 'bot',
664
- content: 'From: :robot: agent report',
665
- createdAt: new Date(),
666
- },
667
- ]);
668
-
669
- await useCase.run({
670
- projectUrl: 'https://github.com/user/repo',
671
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
672
- thresholdForAutoReject: 3,
673
- });
674
-
675
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(1);
676
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
677
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
678
- });
679
-
680
- it('should reject orphaned issue with non-developer agent field to Awaiting Workspace when PR is conflicted', async () => {
681
- const stuckIssue = createMockIssue({
682
- url: 'https://github.com/user/repo/issues/10',
683
- status: 'Preparation',
684
- labels: [],
685
- agent: 'chore',
686
- });
687
- mockIssueRepository.getAllIssues.mockResolvedValue({
688
- project: mockProject,
689
- issues: [stuckIssue],
690
- cacheUsed: false,
691
- });
692
- mockLocalCommandRunner.runCommand.mockResolvedValue({
693
- stdout: '',
694
- stderr: '',
695
- exitCode: 1,
696
- });
697
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
698
- {
699
- author: 'bot',
700
- content: 'From: :robot: agent report',
701
- createdAt: new Date(),
702
- },
703
- ]);
704
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
705
- { ...createPassingPr(), isConflicted: true },
706
- ]);
707
-
708
- await useCase.run({
709
- projectUrl: 'https://github.com/user/repo',
710
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
711
- thresholdForAutoReject: 3,
712
- });
713
-
714
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
715
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
716
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
717
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toContain(
718
- 'Auto Status Check: REJECTED',
719
- );
720
- });
721
-
722
- it('should check PR for orphaned issue with developer agent field', async () => {
723
- const stuckIssue = createMockIssue({
724
- url: 'https://github.com/user/repo/issues/10',
725
- status: 'Preparation',
726
- labels: ['llm-agent:developer'],
727
- agent: 'developer',
728
- });
729
- mockIssueRepository.getAllIssues.mockResolvedValue({
730
- project: mockProject,
731
- issues: [stuckIssue],
732
- cacheUsed: false,
733
- });
734
- mockLocalCommandRunner.runCommand.mockResolvedValue({
735
- stdout: '',
736
- stderr: '',
737
- exitCode: 1,
738
- });
739
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
740
- {
741
- author: 'bot',
742
- content: 'From: :robot: agent report',
743
- createdAt: new Date(),
744
- },
745
- ]);
746
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
747
-
748
- await useCase.run({
749
- projectUrl: 'https://github.com/user/repo',
750
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
751
- thresholdForAutoReject: 3,
752
- });
753
-
754
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(1);
755
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
756
- });
757
-
758
- it('should advance orphaned issue with a labelsAsLlmAgentName label (story) to Awaiting Quality Check when no conflicting PR exists', async () => {
759
- const stuckIssue = createMockIssue({
760
- url: 'https://github.com/user/repo/issues/10',
761
- status: 'Preparation',
762
- labels: ['story'],
763
- });
764
- mockIssueRepository.getAllIssues.mockResolvedValue({
765
- project: mockProject,
766
- issues: [stuckIssue],
767
- cacheUsed: false,
768
- });
769
- mockLocalCommandRunner.runCommand.mockResolvedValue({
770
- stdout: '',
771
- stderr: '',
772
- exitCode: 1,
773
- });
774
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
775
- {
776
- author: 'bot',
777
- content: 'From: :robot: agent report',
778
- createdAt: new Date(),
779
- },
780
- ]);
781
-
782
- await useCase.run({
783
- projectUrl: 'https://github.com/user/repo',
784
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
785
- thresholdForAutoReject: 3,
786
- labelsAsLlmAgentName: ['story'],
787
- });
788
-
789
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(1);
790
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
791
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
792
- });
793
-
794
- it('should advance an orphaned issue whose label is only in labelsNotRequiringPullRequest to Awaiting Quality Check when no conflicting PR exists', async () => {
795
- const stuckIssue = createMockIssue({
796
- url: 'https://github.com/user/repo/issues/10',
797
- status: 'Preparation',
798
- labels: ['story'],
799
- });
800
- mockIssueRepository.getAllIssues.mockResolvedValue({
801
- project: mockProject,
802
- issues: [stuckIssue],
803
- cacheUsed: false,
804
- });
805
- mockLocalCommandRunner.runCommand.mockResolvedValue({
806
- stdout: '',
807
- stderr: '',
808
- exitCode: 1,
809
- });
810
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
811
- {
812
- author: 'bot',
813
- content: 'From: :robot: agent report',
814
- createdAt: new Date(),
815
- },
816
- ]);
817
-
818
- await useCase.run({
819
- projectUrl: 'https://github.com/user/repo',
820
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
821
- thresholdForAutoReject: 3,
822
- labelsAsLlmAgentName: ['chore'],
823
- labelsNotRequiringPullRequest: ['story'],
824
- });
825
-
826
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(1);
827
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
828
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
829
- });
830
-
831
- it('should reject orphaned issue with labelsNotRequiringPullRequest label to Awaiting Workspace when PR is conflicted', async () => {
832
- const stuckIssue = createMockIssue({
833
- url: 'https://github.com/user/repo/issues/10',
834
- status: 'Preparation',
835
- labels: ['story'],
836
- });
837
- mockIssueRepository.getAllIssues.mockResolvedValue({
838
- project: mockProject,
839
- issues: [stuckIssue],
840
- cacheUsed: false,
841
- });
842
- mockLocalCommandRunner.runCommand.mockResolvedValue({
843
- stdout: '',
844
- stderr: '',
845
- exitCode: 1,
846
- });
847
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
848
- {
849
- author: 'bot',
850
- content: 'From: :robot: agent report',
851
- createdAt: new Date(),
852
- },
853
- ]);
854
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
855
- { ...createPassingPr(), isConflicted: true },
856
- ]);
857
-
858
- await useCase.run({
859
- projectUrl: 'https://github.com/user/repo',
860
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
861
- thresholdForAutoReject: 3,
862
- labelsAsLlmAgentName: ['chore'],
863
- labelsNotRequiringPullRequest: ['story'],
864
- });
865
-
866
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
867
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
868
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
869
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toContain(
870
- 'Auto Status Check: REJECTED',
871
- );
872
- });
873
-
874
- it('should advance orphaned issue with non-e2e category label to Awaiting Quality Check when no conflicting PR exists', async () => {
875
- const stuckIssue = createMockIssue({
876
- url: 'https://github.com/user/repo/issues/10',
877
- status: 'Preparation',
878
- labels: ['category:bug'],
879
- });
880
- mockIssueRepository.getAllIssues.mockResolvedValue({
881
- project: mockProject,
882
- issues: [stuckIssue],
883
- cacheUsed: false,
884
- });
885
- mockLocalCommandRunner.runCommand.mockResolvedValue({
886
- stdout: '',
887
- stderr: '',
888
- exitCode: 1,
889
- });
890
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
891
- {
892
- author: 'bot',
893
- content: 'From: :robot: agent report',
894
- createdAt: new Date(),
895
- },
896
- ]);
897
-
898
- await useCase.run({
899
- projectUrl: 'https://github.com/user/repo',
900
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
901
- thresholdForAutoReject: 3,
902
- });
903
-
904
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(1);
905
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
906
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
907
- });
908
-
909
- it('should reject orphaned issue with non-e2e category label to Awaiting Workspace when PR is conflicted', async () => {
910
- const stuckIssue = createMockIssue({
911
- url: 'https://github.com/user/repo/issues/10',
912
- status: 'Preparation',
913
- labels: ['category:bug'],
914
- });
915
- mockIssueRepository.getAllIssues.mockResolvedValue({
916
- project: mockProject,
917
- issues: [stuckIssue],
918
- cacheUsed: false,
919
- });
920
- mockLocalCommandRunner.runCommand.mockResolvedValue({
921
- stdout: '',
922
- stderr: '',
923
- exitCode: 1,
924
- });
925
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
926
- {
927
- author: 'bot',
928
- content: 'From: :robot: agent report',
929
- createdAt: new Date(),
930
- },
931
- ]);
932
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
933
- { ...createPassingPr(), isConflicted: true },
934
- ]);
935
-
936
- await useCase.run({
937
- projectUrl: 'https://github.com/user/repo',
938
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
939
- thresholdForAutoReject: 3,
940
- });
941
-
942
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(1);
943
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
944
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
945
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
946
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toContain(
947
- 'Auto Status Check: REJECTED',
948
- );
949
- });
950
-
951
- it('should revert orphaned issue to Awaiting Workspace when its label is not in labelsAsLlmAgentName and no PR is found', async () => {
952
- const stuckIssue = createMockIssue({
953
- url: 'https://github.com/user/repo/issues/10',
954
- status: 'Preparation',
955
- labels: ['story'],
956
- });
957
- mockIssueRepository.getAllIssues.mockResolvedValue({
958
- project: mockProject,
959
- issues: [stuckIssue],
960
- cacheUsed: false,
961
- });
962
- mockLocalCommandRunner.runCommand.mockResolvedValue({
963
- stdout: '',
964
- stderr: '',
965
- exitCode: 1,
966
- });
967
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
968
- {
969
- author: 'bot',
970
- content: 'From: :robot: agent report',
971
- createdAt: new Date(),
972
- },
973
- ]);
974
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
975
-
976
- await useCase.run({
977
- projectUrl: 'https://github.com/user/repo',
978
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
979
- thresholdForAutoReject: 3,
980
- labelsAsLlmAgentName: ['bug'],
981
- });
982
-
983
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(1);
984
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
985
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
986
- });
987
-
988
- it('should revert orphaned issue to Awaiting Workspace when report has nextStep set', async () => {
989
- const stuckIssue = createMockIssue({
990
- url: 'https://github.com/user/repo/issues/10',
991
- status: 'Preparation',
992
- });
993
- mockIssueRepository.getAllIssues.mockResolvedValue({
994
- project: mockProject,
995
- issues: [stuckIssue],
996
- cacheUsed: false,
997
- });
998
- mockLocalCommandRunner.runCommand.mockResolvedValue({
999
- stdout: '',
1000
- stderr: '',
1001
- exitCode: 1,
1002
- });
1003
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1004
- {
1005
- author: 'bot',
1006
- content:
1007
- 'From: :robot: agent report\n```json\n{"nextStep": "do something"}\n```',
1008
- createdAt: new Date(),
1009
- },
1010
- ]);
1011
-
1012
- await useCase.run({
1013
- projectUrl: 'https://github.com/user/repo',
1014
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1015
- thresholdForAutoReject: 3,
1016
- });
1017
-
1018
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1019
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
1020
- });
1021
-
1022
- it('should revert orphaned issue to Awaiting Workspace when last comment is a cross-issue notification starting with From: :warning:', async () => {
1023
- const stuckIssue = createMockIssue({
1024
- url: 'https://github.com/user/repo/issues/10',
1025
- status: 'Preparation',
1026
- });
1027
- mockIssueRepository.getAllIssues.mockResolvedValue({
1028
- project: mockProject,
1029
- issues: [stuckIssue],
1030
- cacheUsed: false,
1031
- });
1032
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1033
- stdout: '',
1034
- stderr: '',
1035
- exitCode: 1,
1036
- });
1037
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1038
- {
1039
- author: 'bot',
1040
- content:
1041
- 'From: :warning: This message is from https://github.com/user/repo/tree/i999 AI HS Implement AI Agent (claude-sonnet-4-6)',
1042
- createdAt: new Date(),
1043
- },
1044
- ]);
1045
-
1046
- await useCase.run({
1047
- projectUrl: 'https://github.com/user/repo',
1048
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1049
- thresholdForAutoReject: 3,
1050
- });
1051
-
1052
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1053
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
1054
- });
1055
-
1056
- it('should post Auto Status Check: REJECTED comment when orphan path reverts to Awaiting Workspace', async () => {
1057
- const stuckIssue = createMockIssue({
1058
- url: 'https://github.com/user/repo/issues/10',
1059
- status: 'Preparation',
1060
- });
1061
- mockIssueRepository.getAllIssues.mockResolvedValue({
1062
- project: mockProject,
1063
- issues: [stuckIssue],
1064
- cacheUsed: false,
1065
- });
1066
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1067
- stdout: '',
1068
- stderr: '',
1069
- exitCode: 1,
1070
- });
1071
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([]);
1072
-
1073
- await useCase.run({
1074
- projectUrl: 'https://github.com/user/repo',
1075
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1076
- thresholdForAutoReject: 3,
1077
- });
1078
-
1079
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1080
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
1081
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
1082
- expect(mockIssueCommentRepository.createComment.mock.calls[0][0]).toBe(
1083
- stuckIssue,
1084
- );
1085
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toBe(
1086
- 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1087
- );
1088
- });
1089
-
1090
- it('should leave in-flight Preparation issue untouched when check command exits zero', async () => {
1091
- const inFlightIssue = createMockIssue({
1092
- url: 'https://github.com/user/repo/issues/20',
1093
- status: 'Preparation',
1094
- });
1095
- mockIssueRepository.getAllIssues.mockResolvedValue({
1096
- project: mockProject,
1097
- issues: [inFlightIssue],
1098
- cacheUsed: false,
1099
- });
1100
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1101
- stdout: 'claude-agent process found',
1102
- stderr: '',
1103
- exitCode: 0,
1104
- });
1105
-
1106
- await useCase.run({
1107
- projectUrl: 'https://github.com/user/repo',
1108
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1109
- thresholdForAutoReject: 3,
1110
- });
1111
-
1112
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1113
- expect(
1114
- mockIssueCommentRepository.getCommentsFromIssue.mock.calls,
1115
- ).toHaveLength(0);
1116
- });
1117
-
1118
- it('should only process issues in Preparation status and skip others', async () => {
1119
- const preparationIssue = createMockIssue({
1120
- url: 'https://github.com/user/repo/issues/10',
1121
- status: 'Preparation',
1122
- });
1123
- const awaitingIssue = createMockIssue({
1124
- url: 'https://github.com/user/repo/issues/11',
1125
- status: 'Awaiting Workspace',
1126
- });
1127
- mockIssueRepository.getAllIssues.mockResolvedValue({
1128
- project: mockProject,
1129
- issues: [preparationIssue, awaitingIssue],
1130
- cacheUsed: false,
1131
- });
1132
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1133
- stdout: '',
1134
- stderr: '',
1135
- exitCode: 1,
1136
- });
1137
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([]);
1138
-
1139
- await useCase.run({
1140
- projectUrl: 'https://github.com/user/repo',
1141
- preparationProcessCheckCommand: 'check {URL}',
1142
- thresholdForAutoReject: 3,
1143
- });
1144
-
1145
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
1146
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe('sh');
1147
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
1148
- '-c',
1149
- 'check $1',
1150
- '--',
1151
- 'https://github.com/user/repo/issues/10',
1152
- ]);
1153
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1154
- });
1155
-
1156
- it('should handle mixed in-flight and stuck Preparation issues correctly', async () => {
1157
- const stuckIssue = createMockIssue({
1158
- url: 'https://github.com/user/repo/issues/10',
1159
- status: 'Preparation',
1160
- });
1161
- const inFlightIssue = createMockIssue({
1162
- url: 'https://github.com/user/repo/issues/20',
1163
- status: 'Preparation',
1164
- });
1165
- mockIssueRepository.getAllIssues.mockResolvedValue({
1166
- project: mockProject,
1167
- issues: [stuckIssue, inFlightIssue],
1168
- cacheUsed: false,
1169
- });
1170
- mockLocalCommandRunner.runCommand
1171
- .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 1 })
1172
- .mockResolvedValueOnce({
1173
- stdout: 'found',
1174
- stderr: '',
1175
- exitCode: 0,
1176
- });
1177
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([]);
1178
-
1179
- await useCase.run({
1180
- projectUrl: 'https://github.com/user/repo',
1181
- preparationProcessCheckCommand: 'check {URL}',
1182
- thresholdForAutoReject: 3,
1183
- });
1184
-
1185
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1186
- expect(mockIssueRepository.updateStatus.mock.calls[0][1]).toBe(stuckIssue);
1187
- });
1188
-
1189
- it('should throw when project is not found by URL', async () => {
1190
- mockProjectRepository.findProjectIdByUrl.mockResolvedValue(null);
1191
-
1192
- await expect(
1193
- useCase.run({
1194
- projectUrl: 'https://github.com/user/repo',
1195
- preparationProcessCheckCommand: 'check {URL}',
1196
- thresholdForAutoReject: 3,
1197
- }),
1198
- ).rejects.toThrow('Project not found');
1199
- });
1200
-
1201
- it('should throw when getProject returns null after findProjectIdByUrl succeeds', async () => {
1202
- mockProjectRepository.findProjectIdByUrl.mockResolvedValue('project-1');
1203
- mockProjectRepository.getProject.mockResolvedValue(null);
1204
-
1205
- await expect(
1206
- useCase.run({
1207
- projectUrl: 'https://github.com/user/repo',
1208
- preparationProcessCheckCommand: 'check {URL}',
1209
- thresholdForAutoReject: 3,
1210
- }),
1211
- ).rejects.toThrow('Project not found. projectId: project-1');
1212
- });
1213
-
1214
- it('should do nothing when Awaiting Workspace status is not found in project statuses', async () => {
1215
- const preparationIssue = createMockIssue({
1216
- url: 'https://github.com/user/repo/issues/10',
1217
- status: 'Preparation',
1218
- });
1219
- const projectWithoutAwaitingWorkspace = {
1220
- ...mockProject,
1221
- status: {
1222
- ...mockProject.status,
1223
- statuses: mockProject.status.statuses.filter(
1224
- (s) => s.name !== 'Awaiting Workspace',
1225
- ),
1226
- },
1227
- };
1228
- mockProjectRepository.getProject.mockResolvedValue(
1229
- projectWithoutAwaitingWorkspace,
1230
- );
1231
- mockIssueRepository.getAllIssues.mockResolvedValue({
1232
- project: mockProject,
1233
- issues: [preparationIssue],
1234
- cacheUsed: false,
1235
- });
1236
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1237
- stdout: '',
1238
- stderr: '',
1239
- exitCode: 1,
1240
- });
1241
-
1242
- await useCase.run({
1243
- projectUrl: 'https://github.com/user/repo',
1244
- preparationProcessCheckCommand: 'check {URL}',
1245
- thresholdForAutoReject: 3,
1246
- });
1247
-
1248
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1249
- });
1250
-
1251
- it('should do nothing when there are no Preparation issues', async () => {
1252
- mockIssueRepository.getAllIssues.mockResolvedValue({
1253
- project: mockProject,
1254
- issues: [
1255
- createMockIssue({ status: 'Awaiting Workspace' }),
1256
- createMockIssue({ status: 'Done' }),
1257
- ],
1258
- cacheUsed: false,
1259
- });
1260
-
1261
- await useCase.run({
1262
- projectUrl: 'https://github.com/user/repo',
1263
- preparationProcessCheckCommand: 'check {URL}',
1264
- thresholdForAutoReject: 3,
1265
- });
1266
-
1267
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(0);
1268
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1269
- });
1270
-
1271
- it('should revert zombie-wrapper issue when pgrep exits zero but aw log file is stale', async () => {
1272
- const zombieIssue = createMockIssue({
1273
- url: 'https://github.com/myorg/myrepo/issues/42',
1274
- org: 'myorg',
1275
- repo: 'myrepo',
1276
- number: 42,
1277
- status: 'Preparation',
1278
- });
1279
- mockIssueRepository.getAllIssues.mockResolvedValue({
1280
- project: mockProject,
1281
- issues: [zombieIssue],
1282
- cacheUsed: false,
1283
- });
1284
- mockLocalCommandRunner.runCommand
1285
- .mockResolvedValueOnce({
1286
- stdout: 'xfce4-terminal found',
1287
- stderr: '',
1288
- exitCode: 0,
1289
- })
1290
- .mockResolvedValueOnce({
1291
- stdout: '/home/user/logs-aw/myorg_myrepo_42_2024.log\n',
1292
- stderr: '',
1293
- exitCode: 0,
1294
- })
1295
- .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 });
1296
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([]);
1297
-
1298
- await useCase.run({
1299
- projectUrl: 'https://github.com/user/repo',
1300
- preparationProcessCheckCommand: 'pgrep -fa "Please handover {URL}"',
1301
- thresholdForAutoReject: 3,
1302
- awLogDirectoryPath: '/home/user/logs-aw',
1303
- awLogStaleThresholdMinutes: 15,
1304
- });
1305
-
1306
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1307
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(3);
1308
- expect(mockLocalCommandRunner.runCommand.mock.calls[1]).toEqual([
1309
- 'sh',
1310
- [
1311
- '-c',
1312
- 'find "$1" -name "$2"',
1313
- '--',
1314
- '/home/user/logs-aw',
1315
- 'myorg_myrepo_42_*',
1316
- ],
1317
- ]);
1318
- expect(mockLocalCommandRunner.runCommand.mock.calls[2]).toEqual([
1319
- 'sh',
1320
- [
1321
- '-c',
1322
- 'find "$1" -name "$2" -mmin -$3',
1323
- '--',
1324
- '/home/user/logs-aw',
1325
- 'myorg_myrepo_42_*',
1326
- '15',
1327
- ],
1328
- ]);
1329
- });
1330
-
1331
- it('should leave issue untouched when pgrep exits zero and aw log file is recent', async () => {
1332
- const activeIssue = createMockIssue({
1333
- url: 'https://github.com/myorg/myrepo/issues/42',
1334
- org: 'myorg',
1335
- repo: 'myrepo',
1336
- number: 42,
1337
- status: 'Preparation',
1338
- });
1339
- mockIssueRepository.getAllIssues.mockResolvedValue({
1340
- project: mockProject,
1341
- issues: [activeIssue],
1342
- cacheUsed: false,
1343
- });
1344
- mockLocalCommandRunner.runCommand
1345
- .mockResolvedValueOnce({
1346
- stdout: 'xfce4-terminal found',
1347
- stderr: '',
1348
- exitCode: 0,
1349
- })
1350
- .mockResolvedValueOnce({
1351
- stdout: '/home/user/logs-aw/myorg_myrepo_42_2024.log\n',
1352
- stderr: '',
1353
- exitCode: 0,
1354
- })
1355
- .mockResolvedValueOnce({
1356
- stdout: '/home/user/logs-aw/myorg_myrepo_42_2024.log\n',
1357
- stderr: '',
1358
- exitCode: 0,
1359
- });
1360
-
1361
- await useCase.run({
1362
- projectUrl: 'https://github.com/user/repo',
1363
- preparationProcessCheckCommand: 'pgrep -fa "Please handover {URL}"',
1364
- thresholdForAutoReject: 3,
1365
- awLogDirectoryPath: '/home/user/logs-aw',
1366
- awLogStaleThresholdMinutes: 15,
1367
- });
1368
-
1369
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1370
- expect(
1371
- mockIssueCommentRepository.getCommentsFromIssue.mock.calls,
1372
- ).toHaveLength(0);
1373
- });
1374
-
1375
- it('should leave issue untouched when pgrep exits zero and no aw log files exist yet', async () => {
1376
- const newIssue = createMockIssue({
1377
- url: 'https://github.com/myorg/myrepo/issues/42',
1378
- org: 'myorg',
1379
- repo: 'myrepo',
1380
- number: 42,
1381
- status: 'Preparation',
1382
- });
1383
- mockIssueRepository.getAllIssues.mockResolvedValue({
1384
- project: mockProject,
1385
- issues: [newIssue],
1386
- cacheUsed: false,
1387
- });
1388
- mockLocalCommandRunner.runCommand
1389
- .mockResolvedValueOnce({
1390
- stdout: 'xfce4-terminal found',
1391
- stderr: '',
1392
- exitCode: 0,
1393
- })
1394
- .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 });
1395
-
1396
- await useCase.run({
1397
- projectUrl: 'https://github.com/user/repo',
1398
- preparationProcessCheckCommand: 'pgrep -fa "Please handover {URL}"',
1399
- thresholdForAutoReject: 3,
1400
- awLogDirectoryPath: '/home/user/logs-aw',
1401
- awLogStaleThresholdMinutes: 15,
1402
- });
1403
-
1404
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1405
- expect(
1406
- mockIssueCommentRepository.getCommentsFromIssue.mock.calls,
1407
- ).toHaveLength(0);
1408
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(2);
1409
- });
1410
-
1411
- it('should skip aw log check when awLogDirectoryPath is not configured', async () => {
1412
- const inFlightIssue = createMockIssue({
1413
- url: 'https://github.com/user/repo/issues/20',
1414
- status: 'Preparation',
1415
- });
1416
- mockIssueRepository.getAllIssues.mockResolvedValue({
1417
- project: mockProject,
1418
- issues: [inFlightIssue],
1419
- cacheUsed: false,
1420
- });
1421
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1422
- stdout: 'claude-agent process found',
1423
- stderr: '',
1424
- exitCode: 0,
1425
- });
1426
-
1427
- await useCase.run({
1428
- projectUrl: 'https://github.com/user/repo',
1429
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1430
- thresholdForAutoReject: 3,
1431
- });
1432
-
1433
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1434
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
1435
- });
1436
-
1437
- it('should revert issue when pgrep exits non-zero even when awLogDirectoryPath is configured', async () => {
1438
- const stuckIssue = createMockIssue({
1439
- url: 'https://github.com/myorg/myrepo/issues/42',
1440
- org: 'myorg',
1441
- repo: 'myrepo',
1442
- number: 42,
1443
- status: 'Preparation',
1444
- });
1445
- mockIssueRepository.getAllIssues.mockResolvedValue({
1446
- project: mockProject,
1447
- issues: [stuckIssue],
1448
- cacheUsed: false,
1449
- });
1450
- mockLocalCommandRunner.runCommand.mockResolvedValueOnce({
1451
- stdout: '',
1452
- stderr: '',
1453
- exitCode: 1,
1454
- });
1455
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([]);
1456
-
1457
- await useCase.run({
1458
- projectUrl: 'https://github.com/user/repo',
1459
- preparationProcessCheckCommand: 'pgrep -fa "Please handover {URL}"',
1460
- thresholdForAutoReject: 3,
1461
- awLogDirectoryPath: '/home/user/logs-aw',
1462
- awLogStaleThresholdMinutes: 15,
1463
- });
1464
-
1465
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1466
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
1467
- });
1468
-
1469
- it('should substitute {URL} placeholder with the issue URL in the check command', async () => {
1470
- const issue = createMockIssue({
1471
- url: 'https://github.com/org/project/issues/99',
1472
- status: 'Preparation',
1473
- });
1474
- mockIssueRepository.getAllIssues.mockResolvedValue({
1475
- project: mockProject,
1476
- issues: [issue],
1477
- cacheUsed: false,
1478
- });
1479
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1480
- stdout: '',
1481
- stderr: '',
1482
- exitCode: 0,
1483
- });
1484
-
1485
- await useCase.run({
1486
- projectUrl: 'https://github.com/user/repo',
1487
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1488
- thresholdForAutoReject: 3,
1489
- });
1490
-
1491
- expect(mockLocalCommandRunner.runCommand.mock.calls).toHaveLength(1);
1492
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][0]).toBe('sh');
1493
- expect(mockLocalCommandRunner.runCommand.mock.calls[0][1]).toEqual([
1494
- '-c',
1495
- 'pgrep -fa "claude-agent.*$1"',
1496
- '--',
1497
- 'https://github.com/org/project/issues/99',
1498
- ]);
1499
- });
1500
-
1501
- it('should advance closed orphaned issue to Awaiting Quality Check without checking comments or PRs', async () => {
1502
- const closedIssue = createMockIssue({
1503
- url: 'https://github.com/user/repo/issues/10',
1504
- status: 'Preparation',
1505
- isClosed: true,
1506
- });
1507
- mockIssueRepository.getAllIssues.mockResolvedValue({
1508
- project: mockProject,
1509
- issues: [closedIssue],
1510
- cacheUsed: false,
1511
- });
1512
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1513
- stdout: '',
1514
- stderr: '',
1515
- exitCode: 1,
1516
- });
1517
-
1518
- await useCase.run({
1519
- projectUrl: 'https://github.com/user/repo',
1520
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1521
- thresholdForAutoReject: 3,
1522
- });
1523
-
1524
- expect(
1525
- mockIssueCommentRepository.getCommentsFromIssue.mock.calls,
1526
- ).toHaveLength(0);
1527
- expect(mockIssueRepository.findRelatedOpenPRs.mock.calls).toHaveLength(0);
1528
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1529
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
1530
- });
1531
-
1532
- it('should transition orphaned issue to Failed Preparation when rejection threshold is met', async () => {
1533
- const stuckIssue = createMockIssue({
1534
- url: 'https://github.com/user/repo/issues/10',
1535
- status: 'Preparation',
1536
- });
1537
- mockIssueRepository.getAllIssues.mockResolvedValue({
1538
- project: mockProject,
1539
- issues: [stuckIssue],
1540
- cacheUsed: false,
1541
- });
1542
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1543
- stdout: '',
1544
- stderr: '',
1545
- exitCode: 1,
1546
- });
1547
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1548
- {
1549
- author: 'bot',
1550
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1551
- createdAt: new Date(),
1552
- },
1553
- {
1554
- author: 'bot',
1555
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1556
- createdAt: new Date(),
1557
- },
1558
- ]);
1559
-
1560
- await useCase.run({
1561
- projectUrl: 'https://github.com/user/repo',
1562
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1563
- thresholdForAutoReject: 3,
1564
- });
1565
-
1566
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1567
- expect(mockIssueRepository.updateStatus.mock.calls[0][0]).toBe(mockProject);
1568
- expect(mockIssueRepository.updateStatus.mock.calls[0][1]).toBe(stuckIssue);
1569
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('5');
1570
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
1571
- expect(mockIssueCommentRepository.createComment.mock.calls[0][0]).toBe(
1572
- stuckIssue,
1573
- );
1574
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toBe(
1575
- 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION\n\nFailed to pass the check automatically for 3 times',
1576
- );
1577
- });
1578
-
1579
- it('should revert orphaned issue to Awaiting Workspace when rejection threshold is not yet met', async () => {
1580
- const stuckIssue = createMockIssue({
1581
- url: 'https://github.com/user/repo/issues/10',
1582
- status: 'Preparation',
1583
- });
1584
- mockIssueRepository.getAllIssues.mockResolvedValue({
1585
- project: mockProject,
1586
- issues: [stuckIssue],
1587
- cacheUsed: false,
1588
- });
1589
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1590
- stdout: '',
1591
- stderr: '',
1592
- exitCode: 1,
1593
- });
1594
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1595
- {
1596
- author: 'bot',
1597
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1598
- createdAt: new Date(),
1599
- },
1600
- ]);
1601
-
1602
- await useCase.run({
1603
- projectUrl: 'https://github.com/user/repo',
1604
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1605
- thresholdForAutoReject: 3,
1606
- });
1607
-
1608
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1609
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
1610
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
1611
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toBe(
1612
- 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1613
- );
1614
- });
1615
-
1616
- it('should not transition to Failed Preparation when an earlier escalation comment is already in the recent window', async () => {
1617
- const stuckIssue = createMockIssue({
1618
- url: 'https://github.com/user/repo/issues/10',
1619
- status: 'Preparation',
1620
- });
1621
- mockIssueRepository.getAllIssues.mockResolvedValue({
1622
- project: mockProject,
1623
- issues: [stuckIssue],
1624
- cacheUsed: false,
1625
- });
1626
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1627
- stdout: '',
1628
- stderr: '',
1629
- exitCode: 1,
1630
- });
1631
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1632
- {
1633
- author: 'bot',
1634
- content:
1635
- 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION\n\nFailed to pass the check automatically for 3 times',
1636
- createdAt: new Date(),
1637
- },
1638
- {
1639
- author: 'bot',
1640
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1641
- createdAt: new Date(),
1642
- },
1643
- {
1644
- author: 'bot',
1645
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1646
- createdAt: new Date(),
1647
- },
1648
- ]);
1649
-
1650
- await useCase.run({
1651
- projectUrl: 'https://github.com/user/repo',
1652
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1653
- thresholdForAutoReject: 3,
1654
- });
1655
-
1656
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1657
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
1658
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
1659
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toBe(
1660
- 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1661
- );
1662
- });
1663
-
1664
- it('should not post a rejection comment when orphaned issue advances to Awaiting Quality Check', async () => {
1665
- const stuckIssue = createMockIssue({
1666
- url: 'https://github.com/user/repo/issues/10',
1667
- status: 'Preparation',
1668
- });
1669
- mockIssueRepository.getAllIssues.mockResolvedValue({
1670
- project: mockProject,
1671
- issues: [stuckIssue],
1672
- cacheUsed: false,
1673
- });
1674
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1675
- stdout: '',
1676
- stderr: '',
1677
- exitCode: 1,
1678
- });
1679
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1680
- {
1681
- author: 'bot',
1682
- content: 'From: :robot: agent report',
1683
- createdAt: new Date(),
1684
- },
1685
- ]);
1686
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1687
- createPassingPr(),
1688
- ]);
1689
-
1690
- await useCase.run({
1691
- projectUrl: 'https://github.com/user/repo',
1692
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1693
- thresholdForAutoReject: 3,
1694
- });
1695
-
1696
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1697
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
1698
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(0);
1699
- });
1700
-
1701
- it('should revert to Awaiting Workspace when Failed Preparation status option is not present even at threshold', async () => {
1702
- const projectWithoutFailedPreparation = {
1703
- ...mockProject,
1704
- status: {
1705
- ...mockProject.status,
1706
- statuses: mockProject.status.statuses.filter(
1707
- (s) => s.name !== 'Failed Preparation',
1708
- ),
1709
- },
1710
- };
1711
- mockProjectRepository.getProject.mockResolvedValue(
1712
- projectWithoutFailedPreparation,
1713
- );
1714
- const stuckIssue = createMockIssue({
1715
- url: 'https://github.com/user/repo/issues/10',
1716
- status: 'Preparation',
1717
- });
1718
- mockIssueRepository.getAllIssues.mockResolvedValue({
1719
- project: mockProject,
1720
- issues: [stuckIssue],
1721
- cacheUsed: false,
1722
- });
1723
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1724
- stdout: '',
1725
- stderr: '',
1726
- exitCode: 1,
1727
- });
1728
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1729
- {
1730
- author: 'bot',
1731
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1732
- createdAt: new Date(),
1733
- },
1734
- {
1735
- author: 'bot',
1736
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1737
- createdAt: new Date(),
1738
- },
1739
- ]);
1740
-
1741
- await useCase.run({
1742
- projectUrl: 'https://github.com/user/repo',
1743
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1744
- thresholdForAutoReject: 3,
1745
- });
1746
-
1747
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1748
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
1749
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
1750
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toBe(
1751
- 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1752
- );
1753
- });
1754
-
1755
- describe('live status re-read before writing', () => {
1756
- const arrangeSnapshotSaysPreparation = (
1757
- liveStatus: string | null,
1758
- comments: { author: string; content: string; createdAt: Date }[],
1759
- ): Issue => {
1760
- const snapshotIssue = createMockIssue({
1761
- url: 'https://github.com/user/repo/issues/10',
1762
- status: 'Preparation',
1763
- });
1764
- mockIssueRepository.getAllIssues.mockResolvedValue({
1765
- project: mockProject,
1766
- issues: [snapshotIssue],
1767
- cacheUsed: false,
1768
- });
1769
- mockIssueRepository.get.mockResolvedValue(
1770
- liveStatus === null
1771
- ? null
1772
- : createMockIssue({
1773
- url: snapshotIssue.url,
1774
- status: liveStatus,
1775
- }),
1776
- );
1777
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1778
- stdout: '',
1779
- stderr: '',
1780
- exitCode: 1,
1781
- });
1782
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue(
1783
- comments,
1784
- );
1785
- return snapshotIssue;
1786
- };
1787
-
1788
- it('does not write Failed Preparation when the live status has already moved to Awaiting Workspace', async () => {
1789
- arrangeSnapshotSaysPreparation('Awaiting Workspace', [
1790
- {
1791
- author: 'bot',
1792
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1793
- createdAt: new Date(),
1794
- },
1795
- {
1796
- author: 'bot',
1797
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1798
- createdAt: new Date(),
1799
- },
1800
- {
1801
- author: 'bot',
1802
- content:
1803
- 'Issue has next action date or hour set: nextActionDate=null, nextActionHour=null',
1804
- createdAt: new Date(),
1805
- },
1806
- ]);
1807
-
1808
- await useCase.run({
1809
- projectUrl: 'https://github.com/user/repo',
1810
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1811
- thresholdForAutoReject: 3,
1812
- });
1813
-
1814
- expect(
1815
- mockIssueRepository.updateStatus.mock.calls.map((call) => call[2]),
1816
- ).toEqual([]);
1817
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(
1818
- 0,
1819
- );
1820
- expect(mockIssueRepository.get.mock.calls).toHaveLength(1);
1821
- expect(mockIssueRepository.get.mock.calls[0][0]).toBe(
1822
- 'https://github.com/user/repo/issues/10',
1823
- );
1824
- expect(mockIssueRepository.get.mock.calls[0][1]).toBe(mockProject);
1825
- });
1826
-
1827
- it('does not write Awaiting Quality Check when the live status has already moved to Awaiting Workspace', async () => {
1828
- arrangeSnapshotSaysPreparation('Awaiting Workspace', [
1829
- {
1830
- author: 'bot',
1831
- content: 'From: :robot: agent',
1832
- createdAt: new Date(),
1833
- },
1834
- ]);
1835
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1836
- createPassingPr(),
1837
- ]);
1838
-
1839
- await useCase.run({
1840
- projectUrl: 'https://github.com/user/repo',
1841
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1842
- thresholdForAutoReject: 3,
1843
- });
1844
-
1845
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1846
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(
1847
- 0,
1848
- );
1849
- });
1850
-
1851
- it('does not write any status when the live read finds no issue', async () => {
1852
- arrangeSnapshotSaysPreparation(null, []);
1853
-
1854
- await useCase.run({
1855
- projectUrl: 'https://github.com/user/repo',
1856
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1857
- thresholdForAutoReject: 3,
1858
- });
1859
-
1860
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(0);
1861
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(
1862
- 0,
1863
- );
1864
- });
1865
-
1866
- it('still writes Failed Preparation when the live status is confirmed as Preparation', async () => {
1867
- const snapshotIssue = arrangeSnapshotSaysPreparation('Preparation', [
1868
- {
1869
- author: 'bot',
1870
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1871
- createdAt: new Date(),
1872
- },
1873
- {
1874
- author: 'bot',
1875
- content: 'Auto Status Check: REJECTED\n- ORPHANED_PREPARATION',
1876
- createdAt: new Date(),
1877
- },
1878
- ]);
1879
-
1880
- await useCase.run({
1881
- projectUrl: 'https://github.com/user/repo',
1882
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1883
- thresholdForAutoReject: 3,
1884
- });
1885
-
1886
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
1887
- expect(mockIssueRepository.updateStatus.mock.calls[0][1]).toBe(
1888
- snapshotIssue,
1889
- );
1890
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('5');
1891
- });
1892
-
1893
- it('logs the error, skips the candidate and keeps processing the next candidate when the live read rejects', async () => {
1894
- const failingIssue = createMockIssue({
1895
- url: 'https://github.com/user/repo/issues/10',
1896
- status: 'Preparation',
1897
- });
1898
- const followingIssue = createMockIssue({
1899
- url: 'https://github.com/user/repo/issues/11',
1900
- number: 11,
1901
- itemId: 'item-11',
1902
- status: 'Preparation',
1903
- });
1904
- mockIssueRepository.getAllIssues.mockResolvedValue({
1905
- project: mockProject,
1906
- issues: [failingIssue, followingIssue],
1907
- cacheUsed: false,
1908
- });
1909
- const liveReadError = new Error(
1910
- 'GitHub GraphQL API returned no data for a single project item read',
1911
- );
1912
- mockIssueRepository.get.mockImplementation(async (issueUrl: string) => {
1913
- if (issueUrl === failingIssue.url) {
1914
- throw liveReadError;
1915
- }
1916
- return createMockIssue({ url: issueUrl, status: 'Preparation' });
1917
- });
1918
- mockLocalCommandRunner.runCommand.mockResolvedValue({
1919
- stdout: '',
1920
- stderr: '',
1921
- exitCode: 1,
1922
- });
1923
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([]);
1924
- const consoleErrorSpy = jest
1925
- .spyOn(console, 'error')
1926
- .mockImplementation(() => undefined);
1927
-
1928
- try {
1929
- await useCase.run({
1930
- projectUrl: 'https://github.com/user/repo',
1931
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
1932
- thresholdForAutoReject: 3,
1933
- });
1934
-
1935
- expect(
1936
- consoleErrorSpy.mock.calls.filter(
1937
- (call) =>
1938
- typeof call[0] === 'string' &&
1939
- call[0].includes(failingIssue.url) &&
1940
- call[1] === liveReadError,
1941
- ),
1942
- ).toHaveLength(1);
1943
- } finally {
1944
- consoleErrorSpy.mockRestore();
1945
- }
1946
-
1947
- expect(
1948
- mockIssueRepository.updateStatus.mock.calls.map((call) => [
1949
- call[1].url,
1950
- call[2],
1951
- ]),
1952
- ).toEqual([[followingIssue.url, '1']]);
1953
- expect(
1954
- mockIssueCommentRepository.createComment.mock.calls.map(
1955
- (call) => call[0].url,
1956
- ),
1957
- ).toEqual([followingIssue.url]);
1958
- });
1959
- });
1960
-
1961
- describe('non-developer agent CI failure reassignment', () => {
1962
- const makeProjectWithDeveloper = (developerName = 'developer') => {
1963
- const project = createMockProject();
1964
- project.agent = {
1965
- name: 'Agent',
1966
- fieldId: 'agent-field-id',
1967
- options: [
1968
- {
1969
- id: 'opt-developer',
1970
- name: developerName,
1971
- color: 'GRAY',
1972
- description: '',
1973
- },
1974
- ],
1975
- };
1976
- return project;
1977
- };
1978
-
1979
- it('should return to Awaiting Workspace and reassign to developer when chore agent has exactly one linked PR with failing CI', async () => {
1980
- const projectWithDeveloper = makeProjectWithDeveloper();
1981
- mockProjectRepository.findProjectIdByUrl.mockResolvedValue('project-1');
1982
- mockProjectRepository.getProject.mockResolvedValue(projectWithDeveloper);
1983
- mockProjectRepository.getByUrl.mockResolvedValue(projectWithDeveloper);
1984
- const stuckIssue = createMockIssue({
1985
- url: 'https://github.com/user/repo/issues/10',
1986
- status: 'Preparation',
1987
- labels: [],
1988
- agent: 'chore',
1989
- });
1990
- mockIssueRepository.getAllIssues.mockResolvedValue({
1991
- project: projectWithDeveloper,
1992
- issues: [stuckIssue],
1993
- cacheUsed: false,
1994
- });
1995
- mockIssueRepository.get.mockImplementation(async (issueUrl: string) =>
1996
- createMockIssue({
1997
- url: issueUrl,
1998
- status: 'Preparation',
1999
- agent: 'chore',
2000
- }),
2001
- );
2002
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2003
- stdout: '',
2004
- stderr: '',
2005
- exitCode: 1,
2006
- });
2007
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2008
- {
2009
- author: 'bot',
2010
- content: 'From: :robot: agent report',
2011
- createdAt: new Date(),
2012
- },
2013
- ]);
2014
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2015
- {
2016
- ...createPassingPr(),
2017
- url: 'https://github.com/user/repo/pull/99',
2018
- isPassedAllCiJob: false,
2019
- isCiStateSuccess: false,
2020
- },
2021
- ]);
2022
-
2023
- await useCase.run({
2024
- projectUrl: 'https://github.com/user/repo',
2025
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2026
- thresholdForAutoReject: 3,
2027
- });
2028
-
2029
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
2030
- [stuckIssue.url, projectWithDeveloper, 'opt-developer'],
2031
- ]);
2032
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2033
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
2034
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(
2035
- 1,
2036
- );
2037
- expect(
2038
- mockIssueCommentRepository.createComment.mock.calls[0][1],
2039
- ).toContain('ANY_CI_JOB_FAILED_OR_IN_PROGRESS');
2040
- expect(
2041
- mockIssueCommentRepository.createComment.mock.calls[0][1],
2042
- ).toContain('https://github.com/user/repo/pull/99');
2043
- });
2044
-
2045
- it('should advance to Awaiting Quality Check when chore agent has exactly one linked PR where all CI passes', async () => {
2046
- const stuckIssue = createMockIssue({
2047
- url: 'https://github.com/user/repo/issues/10',
2048
- status: 'Preparation',
2049
- labels: [],
2050
- agent: 'chore',
2051
- });
2052
- mockIssueRepository.getAllIssues.mockResolvedValue({
2053
- project: mockProject,
2054
- issues: [stuckIssue],
2055
- cacheUsed: false,
2056
- });
2057
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2058
- stdout: '',
2059
- stderr: '',
2060
- exitCode: 1,
2061
- });
2062
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2063
- {
2064
- author: 'bot',
2065
- content: 'From: :robot: agent report',
2066
- createdAt: new Date(),
2067
- },
2068
- ]);
2069
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2070
- createPassingPr(),
2071
- ]);
2072
-
2073
- await useCase.run({
2074
- projectUrl: 'https://github.com/user/repo',
2075
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2076
- thresholdForAutoReject: 3,
2077
- });
2078
-
2079
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2080
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2081
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2082
- });
2083
-
2084
- it('should advance to Awaiting Quality Check when chore agent has no linked PRs', async () => {
2085
- const stuckIssue = createMockIssue({
2086
- url: 'https://github.com/user/repo/issues/10',
2087
- status: 'Preparation',
2088
- labels: [],
2089
- agent: 'chore',
2090
- });
2091
- mockIssueRepository.getAllIssues.mockResolvedValue({
2092
- project: mockProject,
2093
- issues: [stuckIssue],
2094
- cacheUsed: false,
2095
- });
2096
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2097
- stdout: '',
2098
- stderr: '',
2099
- exitCode: 1,
2100
- });
2101
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2102
- {
2103
- author: 'bot',
2104
- content: 'From: :robot: agent report',
2105
- createdAt: new Date(),
2106
- },
2107
- ]);
2108
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
2109
-
2110
- await useCase.run({
2111
- projectUrl: 'https://github.com/user/repo',
2112
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2113
- thresholdForAutoReject: 3,
2114
- });
2115
-
2116
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2117
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2118
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2119
- });
2120
-
2121
- it('should not trigger the new path when developer agent has a failing CI PR', async () => {
2122
- const stuckIssue = createMockIssue({
2123
- url: 'https://github.com/user/repo/issues/10',
2124
- status: 'Preparation',
2125
- labels: ['llm-agent:developer'],
2126
- agent: 'developer',
2127
- });
2128
- mockIssueRepository.getAllIssues.mockResolvedValue({
2129
- project: mockProject,
2130
- issues: [stuckIssue],
2131
- cacheUsed: false,
2132
- });
2133
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2134
- stdout: '',
2135
- stderr: '',
2136
- exitCode: 1,
2137
- });
2138
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2139
- {
2140
- author: 'bot',
2141
- content: 'From: :robot: agent report',
2142
- createdAt: new Date(),
2143
- },
2144
- ]);
2145
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2146
- {
2147
- ...createPassingPr(),
2148
- isPassedAllCiJob: false,
2149
- isCiStateSuccess: false,
2150
- },
2151
- ]);
2152
-
2153
- await useCase.run({
2154
- projectUrl: 'https://github.com/user/repo',
2155
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2156
- thresholdForAutoReject: 3,
2157
- });
2158
-
2159
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2160
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2161
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
2162
- });
2163
-
2164
- it('should not trigger the new path when agent is pr-reviewer and PR has failing CI', async () => {
2165
- const stuckIssue = createMockIssue({
2166
- url: 'https://github.com/user/repo/issues/10',
2167
- status: 'Preparation',
2168
- labels: [],
2169
- agent: 'pr-reviewer',
2170
- });
2171
- mockIssueRepository.getAllIssues.mockResolvedValue({
2172
- project: mockProject,
2173
- issues: [stuckIssue],
2174
- cacheUsed: false,
2175
- });
2176
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2177
- stdout: '',
2178
- stderr: '',
2179
- exitCode: 1,
2180
- });
2181
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2182
- {
2183
- author: 'bot',
2184
- content: 'From: :robot: agent report',
2185
- createdAt: new Date(),
2186
- },
2187
- ]);
2188
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2189
- {
2190
- ...createPassingPr(),
2191
- isPassedAllCiJob: false,
2192
- isCiStateSuccess: false,
2193
- },
2194
- ]);
2195
-
2196
- await useCase.run({
2197
- projectUrl: 'https://github.com/user/repo',
2198
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2199
- thresholdForAutoReject: 3,
2200
- });
2201
-
2202
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2203
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2204
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2205
- });
2206
-
2207
- it('should not trigger the new path when agent is null and PR has failing CI', async () => {
2208
- const stuckIssue = createMockIssue({
2209
- url: 'https://github.com/user/repo/issues/10',
2210
- status: 'Preparation',
2211
- labels: [],
2212
- agent: null,
2213
- });
2214
- mockIssueRepository.getAllIssues.mockResolvedValue({
2215
- project: mockProject,
2216
- issues: [stuckIssue],
2217
- cacheUsed: false,
2218
- });
2219
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2220
- stdout: '',
2221
- stderr: '',
2222
- exitCode: 1,
2223
- });
2224
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2225
- {
2226
- author: 'bot',
2227
- content: 'From: :robot: agent report',
2228
- createdAt: new Date(),
2229
- },
2230
- ]);
2231
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2232
- {
2233
- ...createPassingPr(),
2234
- isPassedAllCiJob: false,
2235
- isCiStateSuccess: false,
2236
- },
2237
- ]);
2238
-
2239
- await useCase.run({
2240
- projectUrl: 'https://github.com/user/repo',
2241
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2242
- thresholdForAutoReject: 3,
2243
- });
2244
-
2245
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2246
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2247
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
2248
- });
2249
-
2250
- it('should not trigger the new path when chore agent has two linked PRs both with failing CI', async () => {
2251
- const stuckIssue = createMockIssue({
2252
- url: 'https://github.com/user/repo/issues/10',
2253
- status: 'Preparation',
2254
- labels: [],
2255
- agent: 'chore',
2256
- });
2257
- mockIssueRepository.getAllIssues.mockResolvedValue({
2258
- project: mockProject,
2259
- issues: [stuckIssue],
2260
- cacheUsed: false,
2261
- });
2262
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2263
- stdout: '',
2264
- stderr: '',
2265
- exitCode: 1,
2266
- });
2267
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2268
- {
2269
- author: 'bot',
2270
- content: 'From: :robot: agent report',
2271
- createdAt: new Date(),
2272
- },
2273
- ]);
2274
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2275
- {
2276
- ...createPassingPr(),
2277
- url: 'https://github.com/user/repo/pull/99',
2278
- isPassedAllCiJob: false,
2279
- },
2280
- {
2281
- ...createPassingPr(),
2282
- url: 'https://github.com/user/repo/pull/100',
2283
- isPassedAllCiJob: false,
2284
- },
2285
- ]);
2286
-
2287
- await useCase.run({
2288
- projectUrl: 'https://github.com/user/repo',
2289
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2290
- thresholdForAutoReject: 3,
2291
- });
2292
-
2293
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toHaveLength(0);
2294
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2295
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('4');
2296
- });
2297
-
2298
- it('should reassign to the configured developerAgentName when chore agent has a failing CI PR', async () => {
2299
- const projectWithCustomDeveloper =
2300
- makeProjectWithDeveloper('custom-developer');
2301
- mockProjectRepository.findProjectIdByUrl.mockResolvedValue('project-1');
2302
- mockProjectRepository.getProject.mockResolvedValue(
2303
- projectWithCustomDeveloper,
2304
- );
2305
- mockProjectRepository.getByUrl.mockResolvedValue(
2306
- projectWithCustomDeveloper,
2307
- );
2308
- const stuckIssue = createMockIssue({
2309
- url: 'https://github.com/user/repo/issues/10',
2310
- status: 'Preparation',
2311
- labels: [],
2312
- agent: 'chore',
2313
- });
2314
- mockIssueRepository.getAllIssues.mockResolvedValue({
2315
- project: projectWithCustomDeveloper,
2316
- issues: [stuckIssue],
2317
- cacheUsed: false,
2318
- });
2319
- mockIssueRepository.get.mockImplementation(async (issueUrl: string) =>
2320
- createMockIssue({
2321
- url: issueUrl,
2322
- status: 'Preparation',
2323
- agent: 'chore',
2324
- }),
2325
- );
2326
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2327
- stdout: '',
2328
- stderr: '',
2329
- exitCode: 1,
2330
- });
2331
- mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
2332
- {
2333
- author: 'bot',
2334
- content: 'From: :robot: agent report',
2335
- createdAt: new Date(),
2336
- },
2337
- ]);
2338
- mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
2339
- {
2340
- ...createPassingPr(),
2341
- url: 'https://github.com/user/repo/pull/99',
2342
- isPassedAllCiJob: false,
2343
- isCiStateSuccess: false,
2344
- },
2345
- ]);
2346
-
2347
- await useCase.run({
2348
- projectUrl: 'https://github.com/user/repo',
2349
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2350
- thresholdForAutoReject: 3,
2351
- developerAgentName: 'custom-developer',
2352
- });
2353
-
2354
- expect(mockIssueRepository.setIssueAgentField.mock.calls).toEqual([
2355
- [stuckIssue.url, projectWithCustomDeveloper, 'opt-developer'],
2356
- ]);
2357
- });
2358
- });
2359
-
2360
- it('should revert orphaned issue to Awaiting Workspace and not throw when getCommentsFromIssue returns 404', async () => {
2361
- const stuckIssue = createMockIssue({
2362
- url: 'https://github.com/user/repo/issues/10',
2363
- status: 'Preparation',
2364
- });
2365
- mockIssueRepository.getAllIssues.mockResolvedValue({
2366
- project: mockProject,
2367
- issues: [stuckIssue],
2368
- cacheUsed: false,
2369
- });
2370
- mockLocalCommandRunner.runCommand.mockResolvedValue({
2371
- stdout: '',
2372
- stderr: '',
2373
- exitCode: 1,
2374
- });
2375
- mockIssueCommentRepository.getCommentsFromIssue.mockRejectedValue(
2376
- new Error('Failed to fetch comments from GitHub REST API: 404 Not Found'),
2377
- );
2378
-
2379
- await useCase.run({
2380
- projectUrl: 'https://github.com/user/repo',
2381
- preparationProcessCheckCommand: 'pgrep -fa "claude-agent.*{URL}"',
2382
- thresholdForAutoReject: 3,
2383
- });
2384
-
2385
- expect(mockIssueRepository.updateStatus.mock.calls).toHaveLength(1);
2386
- expect(mockIssueRepository.updateStatus.mock.calls[0][2]).toBe('1');
2387
- expect(mockIssueCommentRepository.createComment.mock.calls).toHaveLength(1);
2388
- expect(mockIssueCommentRepository.createComment.mock.calls[0][1]).toContain(
2389
- 'Auto Status Check: REJECTED',
2390
- );
2391
- });
2392
- });