@skyramp/testbot-core 0.13.0-v3.155 → 0.13.0-v3.157

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/post.js CHANGED
@@ -143,8 +143,8 @@ If the error persists, please check whether Actions and API requests are operati
143
143
  The generated tests for this run were delivered to the configured test repo;
144
144
  this change only records the workspace/service configuration (including any
145
145
  additional repositories analyzed in a multi-repo run).`,devPrMergedBreadcrumb:(e,t,r)=>`Dev PR merged \u2014 Testbot PR [#${e}](${t}) is still open, now targeting \`${r}\`.`,devPrClosedBreadcrumb:(e,t)=>`Dev PR closed \u2014 Testbot PR [#${e}](${t}) has been closed automatically.`,testbotPrMergeHint:"Merging this PR adds the generated/maintained tests to the feature branch. Close it if you want to discard them.",testbotPrBacklink:e=>`Generated by Skyramp Testbot for ${e}.`,testbotPrDispatchBacklink:e=>`Generated by Skyramp Testbot from a manual run against \`${e}\`.`,testbotPrMergedBacklink:e=>`Generated by Skyramp Testbot for ${e}, which has since merged; these tests target the base branch.`,staleBannerNoChanges:e=>`> \u26A0\uFE0F The latest push on ${e} did not require any new test changes.`,staleBannerStillOpen:"> This PR still reflects testbot's analysis from an earlier push; consider regenerating via `@skyramp-testbot` or merging as-is if still relevant.",testbotPrNoBaseBranchError:"Skyramp Testbot could not open a Testbot PR because no base branch could be determined (no pull_request context and no checked-out branch). This usually means the workflow ran outside a `pull_request` event and `actions/checkout` left a detached HEAD. Set `generatedTestsMode: same-branch` to commit directly to the feature branch instead.",commitFailureGeneric:(e,t)=>t?`Failed to commit generated tests to the Testbot PR branch: \`${e}\`.`:`Failed to commit generated tests: \`${e}\`.`,commitFailureHookWhereTestbotPr:"so no Testbot PR was created",commitFailureHookWhereSameBranch:"so no changes were committed to the branch",commitFailureHook:(e,t)=>`Your repository's pre-commit hook rejected the generated-test commit, ${t}. Hook error: \`${e}\`.`,gitVerificationBypassed:(e,t,r)=>`Git verification issues: your repository's hooks rejected the \`git ${e}\` of the generated tests, and Testbot tried repairing them first, but ${t}, so they were delivered with \`--no-verify\`. Hook error: \`${r}\`.`,repairTimedOut:e=>`the ${e}-minute repair time ran out`,repairSessionFailed:e=>`the repair session failed (${e})`,gitVerificationBypassedNextStep:"Testbot delivered the generated tests without passing your repository's git hooks. Fix the issues the hooks reported in those tests before merging.",commitFailureHookNextStep:"A pre-commit hook rejected Testbot's generated tests. Fix the issue it reported in the generated tests, or configure the hook/linter to skip Testbot's generated test files. (Both delivery modes run `git commit`, so switching `generatedTestsMode` will not skip the hook.)",testbotPrCreationFailure:(e,t)=>`Could not open the Testbot PR for the generated tests. Error: \`${e}\`. The tests were committed and pushed to \`${t}\` \u2014 open a pull request from that branch to review them.`,sameBranchTestRepoConflictError:"`generatedTestsMode: same-branch` is incompatible with a configured `testRepoPath`: tests were generated into the test repo checkout, but same-branch mode only commits to the primary repo checkout. Use `generatedTestsMode: separate-branch` (the default) with `testRepoPath`, or remove `testRepoPath` to commit generated tests to the same branch.",noNewTestChangesBreadcrumb:e=>`This push produced no new test changes. The prior [testbot PR](${e}) from an earlier push is still open for review.`,testbotPrLabel:(e,t)=>`Testbot PR : [${e}](${t})`,sutAppCrashDetected:e=>`**Application crash detected:** Services (${e}) failed to start due to a code error.`,sutErrorLine:e=>`
146
- **Error:** \`${e}\``,sutFixPrefix:"**Fix:** ",sutServiceNotReachable:e=>`**Service not reachable:** Service at ${e} did not respond before the health-check timeout. The service may still be starting, or the startup command may not have brought it up at all.`,sutServiceNotReachableFix:"**Fix:** Check that `targetSetupCommand` actually starts this service and listens on the expected port. If the command is correct but the service is slow to start, increase `targetReadyCheckTimeout`. For a more reliable readiness signal, configure `targetReadyCheckCommand` to probe a specific health endpoint.",staged:{requestedByPerson:e=>`Requested by ${e}`,requestedByPolicy:e=>`Started by the Validation Policy ${e}`,noLiveApp:e=>`> \u26A0\uFE0F **No live app (SUT) was available this run** \u2014 the ${e} test(s) below were **not executed** (there was no app to run them against). Run them against a running app to confirm they pass (and that any repro test fails as intended).`,unitTestsInFile:(e,t,r)=>`**${e}**: ${t} unit test${t===1?"":"s"}${r?` for ${r}`:""}`,addedToExistingFile:"added to an existing test file",testPackagesHeader:"### \u{1F4E6} Running these tests",testPackageLine:(e,t)=>`\`${e}/\` is a self-contained test package Skyramp Testbot owns and maintains, with its own manifest, lockfile and runner config. Run it with \`${t}\`; to run it on every pull request, add that one command to CI.`,appManifestsUntouched:"The application's own manifests and lockfiles were not changed.",dependencyChangesHeader:"### \u{1F4E6} Changes to the application's dependencies",dependencyChangeLine:(e,t,r)=>`Added \`${e}\` to \`${t}\` (and its lockfile)${r?`: ${r}`:""}`,testMaintenanceHeader:"\u2705 Test Maintenance",keptNot:"kept, not ",declinedPlanned:"(declined the planned ",declinedMaintenanceHeader:"\u21A9\uFE0F Declined Maintenance",existingEvidenceHeader:"\u2705 Existing Evidence",trustedCheckPassed:(e,t)=>`Trusted CI check ${e} passed${t?` on ${t}`:""}, establishing:`,testResultsHeader:"\u{1F9EA} Test Results",resultsTableHeader:"| Test ID | Test Type | Endpoint | Status | Details |",unitResultsTableHeader:"| Test ID | Test Type | Code under test | Test | Cases | Status | Details |",casesPassed:(e,t,r)=>`${e}/${t} passed${r?`, ${r} skipped`:""}`,behaviourCoverageHeader:"\u{1F517} Behaviour Coverage",coverageCaption:(e,t,r,n)=>` (${e} generated \xB7 ${t} modified \xB7 ${r} verified \xB7 ${n} executed)`,coverageTableHeader:"| Behaviour | Source | Tested By | Maintained By |",writtenNotRun:"written, not run",issuesFoundHeader:"\u26A0\uFE0F Issues Found",caveatsHeader:"### \u26A0\uFE0F What This Run Could Not Prove",commentHeader:"### Skyramp Testbot",timedOut:"> \u26A0\uFE0F Run timed out \u2014 the results below are partial.",stopReasons:{},publishFailures:{},maintenanceActions:{},stoppedEarly:(e,t)=>`> \u26A0\uFE0F Run stopped early \u2014 ${e}. The results below are partial.${t}`,viewInSkyramp:e=>` [View in Skyramp](${e})`,setupRunEnds:{finished:"Setup run finished. Skyramp is checking the result.",failed:"Setup run failed.",timedOut:"Setup run ran out of time.",cancelledInSkyramp:"Setup run was cancelled in Skyramp.",stoppedToResume:"Setup run stopped. Resume it in Skyramp."},appUnreachable:e=>`Unable to contact the mothership ${e}. Please try again later.`,couldNotStart:e=>`Skyramp Testbot could not start: ${e}`,assembledAfterFailedChecks:e=>`> \u26A0\uFE0F This report was assembled automatically after the write-up step failed its checks; ${e} check(s) remain unmet \u2014 see the run log for details.`,testbotPrLine:(e,t,r)=>`Testbot PR${e?` (${e})`:""} : [${t}](${r})`,viewRun:e=>`_[View run](${e})_`,testsPrNotOpened:(e,t)=>`The tests PR could not be opened (${e}); the tests were pushed to branch \`${t}\`.`,testsNotPushed:(e,t)=>`The tests could not be pushed (${e}); they remain on the local branch \`${t}\`.`,testsPrRetargeted:e=>`The dev PR merged while tests were being generated \u2014 the tests PR targets its base branch${e?` (\`${e}\`)`:""} instead.`,testsPrUnchanged:"This push required no new test changes; the tests PR below is from an earlier run and was left as is.",committedNoPr:e=>`The tests were committed but no PR was opened: ${e}.`}};var GRe={defaultProgressHeadline:"\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u78BA\u8A8D\u3057\u3066\u30C6\u30B9\u30C8\u3092\u63A8\u5968\u3057\u3066\u3044\u307E\u3059\u3002",stepSettingUpEnvironment:"\u74B0\u5883\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7",stepAnalyzingUserRequest:"\u30E6\u30FC\u30B6\u30FC\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u5206\u6790",stepAnalyzingCodeChanges:"\u30B3\u30FC\u30C9\u5909\u66F4\u306E\u5206\u6790",stepRecommendingTests:"\u30C6\u30B9\u30C8\u306E\u63A8\u5968",stepGeneratingTests:"\u30C6\u30B9\u30C8\u306E\u751F\u6210",stepExecutingTests:"\u30C6\u30B9\u30C8\u306E\u5B9F\u884C",stepGeneratingReport:"\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3068\u30EC\u30DD\u30FC\u30C8\u306E\u751F\u6210",workflowRunLinkLabel:"\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u5B9F\u884C",noReportAvailable:"\u30EC\u30DD\u30FC\u30C8\u306F\u3042\u308A\u307E\u305B\u3093\u3002",cancelledHeader:"### Skyramp Testbot \u2014 \u30AD\u30E3\u30F3\u30BB\u30EB",cancelledBody:"\u3053\u306E\u5B9F\u884C\u306F\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F\u3002",cancelledStepSuffix:"\u30AD\u30E3\u30F3\u30BB\u30EB",abandonedHeader:"### Skyramp Testbot \u2014 \u505C\u6B62",abandonedBody:"\u3053\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u306F\u30DE\u30FC\u30B8\u3055\u308C\u305A\u306B\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u305F\u305F\u3081\u3001\u30C6\u30B9\u30C8\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\u306F\u5B8C\u4E86\u524D\u306B\u505C\u6B62\u3055\u308C\u307E\u3057\u305F\u3002",abandonedStepSuffix:"\u505C\u6B62",followingUserInstruction:e=>`> \u30E6\u30FC\u30B6\u30FC\u6307\u793A\u306B\u5F93\u3063\u3066\u3044\u307E\u3059: *${e}*`,minimalReportHeader:"### \u26A0\uFE0F Skyramp Testbot",testRecommendationsImplementedHeader:e=>`\u{1F4A1} \u5B9F\u88C5\u3057\u305F\u30C6\u30B9\u30C8\u63A8\u5968\uFF08${e}\u4EF6\uFF09`,additionalRecommendationsHeader:e=>`\u{1F4CC} \u8FFD\u52A0\u306E\u30C6\u30B9\u30C8\u63A8\u5968\uFF08${e}\u4EF6\uFF09`,additionalRecommendationsCta:"\u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u3092\u751F\u6210\u3059\u308B\u306B\u306F\u3001\u30B3\u30E1\u30F3\u30C8\u3067 `@skyramp-testbot` \u3092\u30E1\u30F3\u30B7\u30E7\u30F3\u3057\u3066\u8FFD\u52A0\u3092\u4F9D\u983C\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: `@skyramp-testbot /products \u306E\u30B3\u30F3\u30C8\u30E9\u30AF\u30C8\u30C6\u30B9\u30C8\u3092\u8FFD\u52A0\u3057\u3066`\uFF09\u3002",testTypeLabels:{contract:"\u{1F4CB} \u30B3\u30F3\u30C8\u30E9\u30AF\u30C8",integration:"\u{1F517} \u7D71\u5408",e2e:"\u{1F310} E2E",ui:"\u{1F5A5}\uFE0F UI"},testTypeCellLabels:{smoke:"\u30B9\u30E2\u30FC\u30AF",fuzz:"\u30D5\u30A1\u30BA",contract:"\u30B3\u30F3\u30C8\u30E9\u30AF\u30C8",load:"\u8CA0\u8377",integration:"\u7D71\u5408",e2e:"E2E",ui:"UI",unit:"\u30E6\u30CB\u30C3\u30C8"},statusLabels:{Pass:"\u5408\u683C",Fail:"\u4E0D\u5408\u683C",Error:"\u30A8\u30E9\u30FC",Skipped:"\u30B9\u30AD\u30C3\u30D7"},severityLabels:{critical:"\u91CD\u5927",high:"\u9AD8",medium:"\u4E2D",low:"\u4F4E"},reuse:{label:"POM \u518D\u5229\u7528",noPomLayer:"\u30B9\u30AD\u30C3\u30D7 \u2014 \u3053\u306E\u30C6\u30B9\u30C8\u306B\u518D\u5229\u7528\u3067\u304D\u308B\u30DA\u30FC\u30B8\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u5C64\u306F\u691C\u51FA\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",reusedAndVerified:e=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u518D\u5229\u7528\u30FB\u691C\u8A3C\u6E08\u307F`,reusedThenVerified:(e,t)=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u518D\u5229\u7528\uFF08\u3046\u3061 ${t} \u4EF6\u3092\u691C\u8A3C\u6E08\u307F\uFF09`,reused:e=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u518D\u5229\u7528`,verified:e=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u691C\u8A3C\u6E08\u307F`,unresolved:e=>`${e} \u4EF6\u306F POM \u30BD\u30FC\u30B9\u307E\u3067\u89E3\u6C7A\u3067\u304D\u305A\uFF08\u53C2\u8003\u60C5\u5831\u3067\u3042\u308A\u3001\u9664\u5916\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09`,candidates:e=>`\u5019\u88DC\u3068\u306A\u308B POM \u30D5\u30A1\u30A4\u30EB ${e} \u4EF6\u3092\u691C\u51FA`,verificationPassed:"\u691C\u8A3C\u306B\u5408\u683C",verificationFailed:"\u26A0\uFE0F \u691C\u8A3C\u306B\u5408\u683C\u3057\u307E\u305B\u3093\u3067\u3057\u305F",keptInline:e=>`\u30A4\u30F3\u30E9\u30A4\u30F3\u306E\u307E\u307E: ${e}`,gate:{"not-mapped":"\u30DE\u30C3\u30D4\u30F3\u30B0\u5BFE\u8C61\u5916","demoted-by-verify":"\u691C\u8A3C\u3067\u5DEE\u3057\u623B\u3057"}},testMaintenanceHeader:e=>`\u2705 \u30C6\u30B9\u30C8\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\uFF08${e}\u4EF6\uFF09`,maintenanceTableHeader:"| \u30C6\u30B9\u30C8\u7A2E\u5225 | \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 | \u30D5\u30A1\u30A4\u30EB | \u5909\u66F4\u5185\u5BB9 | \u5909\u66F4\u524D | \u5909\u66F4\u5F8C |",testResultsHeader:e=>`\u{1F9EA} \u30C6\u30B9\u30C8\u7D50\u679C\uFF08${e}\u4EF6\uFF09`,columnTestType:"\u30C6\u30B9\u30C8\u7A2E\u5225",columnEndpoint:"\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8",columnStatus:"\u30B9\u30C6\u30FC\u30BF\u30B9",columnDetails:"\u8A73\u7D30",columnRepo:"\u30EA\u30DD\u30B8\u30C8\u30EA",repoColumnPrimary:"\u30D7\u30E9\u30A4\u30DE\u30EA",columnVideo:"\u30D3\u30C7\u30AA",videoDownloadLink:e=>`[\u{1F4F9} \u30C0\u30A6\u30F3\u30ED\u30FC\u30C9](${e})`,videosArtifactFallback:e=>`\u{1F4F9} \u9332\u753B\u3055\u308C\u305F UI \u30C6\u30B9\u30C8\u30D3\u30C7\u30AA: [\u5B9F\u884C\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u304B\u3089\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9](${e})`,issuesFoundHeader:e=>`\u26A0\uFE0F \u691C\u51FA\u3055\u308C\u305F\u554F\u984C\uFF08${e}\u4EF6\uFF09`,configErrorsHeader:"\u2699\uFE0F \u8A2D\u5B9A\u30A8\u30E9\u30FC",nextStepsHeader:"### \u{1F4A1} \u6B21\u306E\u30B9\u30C6\u30C3\u30D7",caveatsHeader:"### \u26A0\uFE0F \u3053\u306E\u5B9F\u884C\u3067\u78BA\u8A8D\u3067\u304D\u306A\u304B\u3063\u305F\u3053\u3068",rows:{passed:e=>e?"\u8D77\u52D5\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u6210\u529F\u3057\u307E\u3057\u305F":"\u6210\u529F\u3057\u307E\u3057\u305F",notRun:e=>e?"\u3053\u306E\u5B9F\u884C\u3067\u306F\u30E9\u30A4\u30D6\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F":"\u3053\u306E\u5B9F\u884C\u3067\u306F\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",failedBug:e=>e?"\u8D77\u52D5\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5931\u6557\u3057\u307E\u3057\u305F":"\u5931\u6557\u3057\u307E\u3057\u305F",executedOf:(e,t)=>t?`\u3001\u305D\u306E\u3046\u3061 ${e} \u4EF6\u3092\u8D77\u52D5\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3057\u307E\u3057\u305F\u3002`:`\u3001\u305D\u306E\u3046\u3061 ${e} \u4EF6\u3092\u5B9F\u884C\u3057\u307E\u3057\u305F\u3002`,noneExecuted:e=>e?"\u3002\u3053\u306E\u5B9F\u884C\u3067\u306F\u30E9\u30A4\u30D6\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3055\u308C\u305F\u3082\u306E\u306F\u3042\u308A\u307E\u305B\u3093\u3002":"\u3002\u3053\u306E\u5B9F\u884C\u3067\u306F\u5B9F\u884C\u3055\u308C\u305F\u3082\u306E\u306F\u3042\u308A\u307E\u305B\u3093\u3002"},caveats:{deployFailed:"\u30A2\u30D7\u30EA\u3092\u8D77\u52D5\u3067\u304D\u306A\u304B\u3063\u305F\u305F\u3081\u3001\u3053\u3053\u306B\u793A\u3059\u5185\u5BB9\u306F\u7A3C\u50CD\u4E2D\u306E\u30B7\u30B9\u30C6\u30E0\u306B\u5BFE\u3057\u3066\u691C\u8A3C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",changeBrokeBringup:"\u3053\u306E\u5909\u66F4\u306B\u3088\u308A\u30A2\u30D7\u30EA\u306E\u8D77\u52D5\u304C\u58CA\u308C\u305F\u3068\u601D\u308F\u308C\u307E\u3059\u3002PR \u3092\u9069\u7528\u3057\u305F\u72B6\u614B\u3067\u8D77\u52D5\u3067\u304D\u305A\u3001\u30C6\u30B9\u30C8\u306F\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",bringupFailed:"\u3053\u306E PR \u3068\u306F\u7121\u95A2\u4FC2\u306E\u7406\u7531\u3067\u30A2\u30D7\u30EA\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3059\u308B\u30C6\u30B9\u30C8\u306F\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",testsNotExecuted:"\u3053\u306E\u5B9F\u884C\u3067\u306F\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u30C6\u30B9\u30C8\u304C\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u672A\u5B9F\u884C\u306E\u30C6\u30B9\u30C8\u306F\u5909\u66F4\u304C\u6B63\u3057\u304F\u52D5\u4F5C\u3059\u308B\u8A3C\u62E0\u306B\u306A\u308A\u307E\u305B\u3093\u3002",recipeDrift:"\u8A18\u9332\u3055\u308C\u3066\u3044\u305F\u30A2\u30D7\u30EA\u306E\u8D77\u52D5\u624B\u9806\u304C\u53E4\u304F\u306A\u3063\u3066\u304A\u308A\u3001\u8D77\u52D5\u524D\u306B\u4FEE\u6B63\u304C\u5FC5\u8981\u3067\u3057\u305F\u3002",mockedDependency:e=>`${e} \u306F\u5B9F\u969B\u306B\u30C7\u30D7\u30ED\u30A4\u3055\u308C\u305A\u30E2\u30C3\u30AF\u5316\u3055\u308C\u307E\u3057\u305F\u3002\u3053\u308C\u306B\u5BFE\u3059\u308B\u6210\u529F\u7D50\u679C\u306F\u8A3C\u660E\u306B\u306F\u306A\u308A\u307E\u305B\u3093\u3002`,finalizeNotReady:e=>`\u30C6\u30B9\u30C8\u306F\u73FE\u72B6\u3067\u306F\u30DE\u30FC\u30B8\u53EF\u80FD\u306A\u72B6\u614B\u3067\u306F\u3042\u308A\u307E\u305B\u3093${e?`: ${e}`:"\u3002"}`,ciNotCovered:"\u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u3092\u5B9F\u884C\u3059\u308B CI \u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C\u306A\u3044\u305F\u3081\u3001\u4ECA\u5F8C\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u306F\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002",sutNotRequired:"\u30A2\u30D7\u30EA\u306F\u8D77\u52D5\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u691C\u8A3C\u30C8\u30EA\u30A2\u30FC\u30B8\u306B\u3088\u308A\u3001\u3053\u306E\u5909\u66F4\u3067\u691C\u8A3C\u304C\u5FC5\u8981\u306A\u30C7\u30D7\u30ED\u30A4\u5F8C\u306E\u632F\u308B\u821E\u3044\u306F\u306A\u3044\u3068\u5224\u65AD\u3055\u308C\u307E\u3057\u305F\u3002",lintNotCovered:e=>`\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30EA\u30F3\u30BF\u30FC\u306F ${e} \u3092\u30C1\u30A7\u30C3\u30AF\u3057\u307E\u305B\u3093\u3002\u30B9\u30BF\u30A4\u30EB\u3084\u578B\u306E\u554F\u984C\u304C\u81EA\u52D5\u7684\u306B\u306F\u691C\u51FA\u3055\u308C\u307E\u305B\u3093\u3002`,analysisUnverified:e=>`\u5909\u66F4\u306E\u5206\u6790\u306E\u4E00\u90E8\u3092\u691C\u8A3C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u672A\u89E3\u6C7A\u306E\u30C1\u30A7\u30C3\u30AF ${e} \u4EF6\uFF09\u3002\u8A72\u5F53\u3059\u308B\u4E3B\u5F35\u306F\u672A\u78BA\u8A8D\u3068\u3057\u3066\u6271\u3044\u3001\u30C6\u30B9\u30C8\u3092\u8A08\u753B\u3057\u307E\u3057\u305F\u3002`,unitTestsNotRun:e=>`Testbot \u306F\u9078\u629E\u3057\u305F\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8\u3092\u5B9F\u884C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u3053\u3053\u306B\u3042\u308B\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8\u306E\u7D50\u679C\u306F Testbot \u81EA\u8EAB\u306E\u518D\u5B9F\u884C\u306B\u3088\u308B\u3082\u306E\u3067\u306F\u3042\u308A\u307E\u305B\u3093: ${e}`,testsCouldNotRunHere:(e,t)=>`\u3053\u306E\u5909\u66F4\u306B\u306F ${e} \u4EF6\u306E\u30C6\u30B9\u30C8\u304C\u3042\u308A\u307E\u3059\u304C\u3001\u3053\u306E\u74B0\u5883\u3067\u306F\u5B9F\u884C\u3067\u304D\u306A\u304B\u3063\u305F\u305F\u3081\u7D50\u679C\u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u30B9\u30AD\u30C3\u30D7\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09: ${t}`},autoCommitHint:"\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3067 `autoCommit: true` \u3092\u6709\u52B9\u306B\u3059\u308B\u3068\u3001Skyramp Testbot \u304C\u751F\u6210\u3057\u305F\u30C6\u30B9\u30C8\u3092\u81EA\u52D5\u7684\u306B\u30B3\u30DF\u30C3\u30C8\u3057\u307E\u3059\u3002",implementRecommendationsCta:"\u8FFD\u52A0\u306E\u30C6\u30B9\u30C8\u63A8\u5968\u3092\u5B9F\u88C5\u3059\u308B\u306B\u306F `@skyramp-testbot` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5DEE\u5206\u306E\u5206\u6790\u306B\u57FA\u3065\u304D\u3001\u4EE5\u4E0B\u3092\u63A8\u5968\u3057\u307E\u3059:",sutServiceErrorsHeadline:":warning: **\u30B5\u30FC\u30D3\u30B9\u304C\u30A8\u30E9\u30FC\u3092\u8FD4\u3057\u3066\u3044\u307E\u3059**",sutCheckedEndpoints:"Testbot \u306F\u30C6\u30B9\u30C8\u5B9F\u884C\u524D\u306B\u30B5\u30FC\u30D3\u30B9\u306E\u8D77\u52D5\u3092\u5F85\u6A5F\u3057\u307E\u3057\u305F\u304C\u3001\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u304C\u901A\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002",sutCheckCodeChanges:"**\u3053\u306E PR \u306E\u30B3\u30FC\u30C9\u5909\u66F4\u304C\u30B5\u30FC\u30D3\u30B9\u969C\u5BB3\u306E\u539F\u56E0\u306B\u306A\u3063\u3066\u3044\u306A\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044** \u2014 \u65B0\u305F\u306B\u6DF7\u5165\u3057\u305F\u30D0\u30B0\u3001\u4F9D\u5B58\u95A2\u4FC2\u306E\u4E0D\u8DB3\u3001\u8A2D\u5B9A\u30DF\u30B9\u306B\u3088\u308A\u3001\u30B5\u30FC\u30D3\u30B9\u304C\u8D77\u52D5\u3067\u304D\u306A\u3044\u30FB\u6B63\u3057\u304F\u5FDC\u7B54\u3067\u304D\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002",viewWorkflowLogs:e=>`[\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u30ED\u30B0\u5168\u6587\u3092\u898B\u308B \u2197](${e})`,sutFixAndRetry:"_\u554F\u984C\u3092\u4FEE\u6B63\u3057\u3066\u518D\u5EA6\u30D7\u30C3\u30B7\u30E5\u3059\u308B\u304B\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002_",internalErrorHeader:"### \u5185\u90E8\u30A8\u30E9\u30FC",internalErrorRenderFailed:"Testbot \u306F\u5B9F\u884C\u3092\u5B8C\u4E86\u3057\u307E\u3057\u305F\u304C\u3001\u30EC\u30DD\u30FC\u30C8\u306E\u751F\u6210\u4E2D\u306B\u4E88\u671F\u3057\u306A\u3044\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002",internalErrorNoReport:"Testbot \u3067\u4E88\u671F\u3057\u306A\u3044\u5185\u90E8\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306F\u6B63\u5E38\u306B\u5B8C\u4E86\u3057\u307E\u3057\u305F\u304C\u3001\u30EC\u30DD\u30FC\u30C8\u304C\u751F\u6210\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002",internalErrorAgentStopped:"Testbot \u306F\u30EC\u30DD\u30FC\u30C8\u3092\u751F\u6210\u3059\u308B\u524D\u306B\u505C\u6B62\u3057\u307E\u3057\u305F\u3002\u539F\u56E0\u306F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u30ED\u30B0\u3067\u78BA\u8A8D\u3067\u304D\u307E\u3059\u3002",internalErrorRawReportAvailable:"\u751F\u6210\u3055\u308C\u305F `report.json` \u306F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u304B\u3089\u53D6\u5F97\u3067\u304D\u307E\u3059\u3002\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\uFF08\u3042\u308C\u3070\uFF09\u306F\u901A\u5E38\u3069\u304A\u308A\u30B3\u30DF\u30C3\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\u3002",internalErrorRetriedTimes:e=>`${e} \u56DE\u30EA\u30C8\u30E9\u30A4\u3057\u307E\u3057\u305F\u304C\u6210\u529F\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002`,internalErrorFileIssue:"\u554F\u984C\u304C\u89E3\u6C7A\u3057\u306A\u3044\u5834\u5408\u306F https://github.com/skyramp/testbot/issues \u306B\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u5B9F\u884C\u3078\u306E\u30EA\u30F3\u30AF\u3092\u6DFB\u3048\u3066 issue \u3092\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerNotYourCode:"\u3053\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u5909\u66F4\u304C\u539F\u56E0\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u30C6\u30B9\u30C8\u306F\u751F\u6210\u3082\u5B9F\u884C\u3082\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",providerOutageHeadline:(e,t)=>`${e} \u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002Testbot \u306F ${t} \u56DE\u8A66\u884C\u3057\u307E\u3057\u305F\u304C\u5931\u6557\u3057\u307E\u3057\u305F\u3002`,providerOutageActionStatusPage:e=>`${e} \u3067\u72B6\u6CC1\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30B5\u30FC\u30D3\u30B9\u304C\u5FA9\u65E7\u3057\u305F\u3089\u3001Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,providerRateLimitHeadline:e=>`${e} \u306E\u30EC\u30FC\u30C8\u5236\u9650\u306B\u3088\u308A\u5B9F\u884C\u304C\u4E2D\u65AD\u3055\u308C\u307E\u3057\u305F (HTTP 429)\u3002`,providerRateLimitAction:"\u5236\u9650\u304C\u89E3\u9664\u3055\u308C\u308B\u307E\u3067\u5F85\u3063\u3066\u304B\u3089\u3001Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u7E70\u308A\u8FD4\u3059\u5834\u5408\u306F\u3001\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C\u4F7F\u7528\u3059\u308B\u8A8D\u8A3C\u60C5\u5831\u306E\u30EC\u30FC\u30C8\u5236\u9650\u3092\u5F15\u304D\u4E0A\u3052\u308B\u304B\u3001\u540C\u6642\u306B\u5B9F\u884C\u3059\u308B PR \u306E\u6570\u3092\u6E1B\u3089\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerUsageLimitHeadline:e=>`${e} \u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u5229\u7528\u4E0A\u9650\u306B\u9054\u3057\u307E\u3057\u305F\u3002`,providerUsageLimitAction:"\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E\u8A8D\u8A3C\u60C5\u5831\u306B\u7D10\u3065\u304F\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u5229\u7528\u4E0A\u9650\u3092\u5F15\u304D\u4E0A\u3052\u3066\u304B\u3089\u3001Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerAuthExpiredHeadline:e=>`\u5B9F\u884C\u4E2D\u306B\u3001Testbot \u304C ${e} \u3078\u63A5\u7D9A\u3059\u308B\u305F\u3081\u306E\u8A8D\u8A3C\u60C5\u5831\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u307E\u3057\u305F\u3002`,providerAuthExpiredAction:"\u8A8D\u8A3C\u60C5\u5831\u306E\u6709\u52B9\u671F\u9593\u306F\u56FA\u5B9A\u306E\u305F\u3081\u3001\u5B9F\u884C\u6642\u9593\u304C\u9577\u3044\u3068\u305D\u306E\u671F\u9593\u3092\u8D85\u3048\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u5B9F\u884C\u304C\u6709\u52B9\u671F\u9593\u3092\u5E38\u306B\u8D85\u3048\u308B\u5834\u5408\u306F\u3001\u30B8\u30E7\u30D6\u3054\u3068\u306B\u8A8D\u8A3C\u60C5\u5831\u3092\u767A\u884C\u3059\u308B\u304B\u3001\u5404\u30B8\u30E7\u30D6\u304C\u6709\u52B9\u671F\u9593\u5185\u306B\u53CE\u307E\u308B\u3088\u3046\u5B9F\u884C\u3092\u5206\u5272\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerTimeoutHeadline:e=>`Testbot \u306F\u5236\u9650\u6642\u9593 ${e} \u5206\u3092\u8D85\u3048\u305F\u305F\u3081\u505C\u6B62\u3055\u308C\u307E\u3057\u305F\u3002`,providerTimeoutAction:"\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u5B9F\u884C\u306B\u672C\u5F53\u306B\u6642\u9593\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E `testbotTimeout` \u5165\u529B\u5024\u3092\u5927\u304D\u304F\u3057\u3066\u304F\u3060\u3055\u3044\u3002",workspaceTestbotPrTitle:"Skyramp Testbot: \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u8A2D\u5B9A\u306E\u66F4\u65B0",workspaceTestbotPrHeader:"### Skyramp Testbot \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u8A2D\u5B9A\u306E\u66F4\u65B0",workspaceTestbotPrBody:"\u3053\u306E PR \u306F\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u7D71\u5408 `.skyramp/workspace.yml` \u3092\u66F4\u65B0\u3057\u307E\u3059\u3002\n\u4ECA\u56DE\u306E\u5B9F\u884C\u3067\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306F\u3001\u8A2D\u5B9A\u3055\u308C\u305F\u30C6\u30B9\u30C8\u30EA\u30DD\u30B8\u30C8\u30EA\u306B\u914D\u7F6E\u3055\u308C\u307E\u3057\u305F\u3002\u3053\u306E\u5909\u66F4\u306F\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\uFF0F\u30B5\u30FC\u30D3\u30B9\u8A2D\u5B9A\uFF08\u30DE\u30EB\u30C1\u30EA\u30DD\u30B8\u30C8\u30EA\u5B9F\u884C\u3067\u5206\u6790\u3055\u308C\u305F\u8FFD\u52A0\u30EA\u30DD\u30B8\u30C8\u30EA\u3092\u542B\u3080\uFF09\u306E\u307F\u3092\u8A18\u9332\u3057\u307E\u3059\u3002",devPrMergedBreadcrumb:(e,t,r)=>`\u958B\u767A PR \u304C\u30DE\u30FC\u30B8\u3055\u308C\u307E\u3057\u305F \u2014 Testbot PR [#${e}](${t}) \u306F\u5F15\u304D\u7D9A\u304D\u30AA\u30FC\u30D7\u30F3\u3067\u3001\u73FE\u5728\u306E\u30BF\u30FC\u30B2\u30C3\u30C8\u306F \`${r}\` \u3067\u3059\u3002`,devPrClosedBreadcrumb:(e,t)=>`\u958B\u767A PR \u304C\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u307E\u3057\u305F \u2014 Testbot PR [#${e}](${t}) \u306F\u81EA\u52D5\u7684\u306B\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u307E\u3057\u305F\u3002`,testbotPrMergeHint:"\u3053\u306E PR \u3092\u30DE\u30FC\u30B8\u3059\u308B\u3068\u3001\u751F\u6210/\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\u3055\u308C\u305F\u30C6\u30B9\u30C8\u304C\u30D5\u30A3\u30FC\u30C1\u30E3\u30FC\u30D6\u30E9\u30F3\u30C1\u306B\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002\u7834\u68C4\u3057\u305F\u3044\u5834\u5408\u306F\u30AF\u30ED\u30FC\u30BA\u3057\u3066\u304F\u3060\u3055\u3044\u3002",testbotPrBacklink:e=>`${e} \u7528\u306B Skyramp Testbot \u304C\u751F\u6210\u3057\u307E\u3057\u305F\u3002`,testbotPrDispatchBacklink:e=>`\`${e}\` \u306B\u5BFE\u3059\u308B\u624B\u52D5\u5B9F\u884C\u306B\u3088\u308A Skyramp Testbot \u304C\u751F\u6210\u3057\u307E\u3057\u305F\u3002`,testbotPrMergedBacklink:e=>`${e} \u7528\u306B Skyramp Testbot \u304C\u751F\u6210\u3057\u307E\u3057\u305F\u3002\u5143\u306E PR \u306F\u3059\u3067\u306B\u30DE\u30FC\u30B8\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u306F\u30D9\u30FC\u30B9\u30D6\u30E9\u30F3\u30C1\u3092\u5BFE\u8C61\u3068\u3057\u3066\u3044\u307E\u3059\u3002`,staleBannerNoChanges:e=>`> \u26A0\uFE0F ${e} \u3078\u306E\u6700\u65B0\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u306F\u3001\u65B0\u3057\u3044\u30C6\u30B9\u30C8\u5909\u66F4\u306F\u5FC5\u8981\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002`,staleBannerStillOpen:"> \u3053\u306E PR \u306F\u4EE5\u524D\u306E\u30D7\u30C3\u30B7\u30E5\u6642\u70B9\u306E testbot \u306E\u5206\u6790\u7D50\u679C\u306E\u307E\u307E\u3067\u3059\u3002`@skyramp-testbot` \u3067\u518D\u751F\u6210\u3059\u308B\u304B\u3001\u5185\u5BB9\u304C\u4ECA\u3082\u6709\u52B9\u3067\u3042\u308C\u3070\u305D\u306E\u307E\u307E\u30DE\u30FC\u30B8\u3059\u308B\u3053\u3068\u3092\u691C\u8A0E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",testbotPrNoBaseBranchError:"\u30D9\u30FC\u30B9\u30D6\u30E9\u30F3\u30C1\u3092\u7279\u5B9A\u3067\u304D\u306A\u304B\u3063\u305F\u305F\u3081\u3001Skyramp Testbot \u306F Testbot PR \u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F\uFF08pull_request \u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3082\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8\u6E08\u307F\u30D6\u30E9\u30F3\u30C1\u3082\u3042\u308A\u307E\u305B\u3093\uFF09\u3002\u901A\u5E38\u306F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C `pull_request` \u30A4\u30D9\u30F3\u30C8\u4EE5\u5916\u3067\u5B9F\u884C\u3055\u308C\u3001`actions/checkout` \u304C detached HEAD \u306E\u72B6\u614B\u3092\u6B8B\u3057\u305F\u3053\u3068\u304C\u539F\u56E0\u3067\u3059\u3002\u4EE3\u308F\u308A\u306B\u30D5\u30A3\u30FC\u30C1\u30E3\u30FC\u30D6\u30E9\u30F3\u30C1\u3078\u76F4\u63A5\u30B3\u30DF\u30C3\u30C8\u3059\u308B\u306B\u306F `generatedTestsMode: same-branch` \u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002",commitFailureGeneric:(e,t)=>t?`\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E Testbot PR \u30D6\u30E9\u30F3\u30C1\u3078\u306E\u30B3\u30DF\u30C3\u30C8\u306B\u5931\u6557\u3057\u307E\u3057\u305F: \`${e}\`\u3002`:`\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E\u30B3\u30DF\u30C3\u30C8\u306B\u5931\u6557\u3057\u307E\u3057\u305F: \`${e}\`\u3002`,commitFailureHookWhereTestbotPr:"\u305D\u306E\u305F\u3081 Testbot PR \u306F\u4F5C\u6210\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",commitFailureHookWhereSameBranch:"\u305D\u306E\u305F\u3081\u5909\u66F4\u306F\u30D6\u30E9\u30F3\u30C1\u306B\u30B3\u30DF\u30C3\u30C8\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",commitFailureHook:(e,t)=>`\u30EA\u30DD\u30B8\u30C8\u30EA\u306E pre-commit \u30D5\u30C3\u30AF\u304C\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E\u30B3\u30DF\u30C3\u30C8\u3092\u62D2\u5426\u3057\u305F\u305F\u3081\u3001${t}\u3002\u30D5\u30C3\u30AF\u306E\u30A8\u30E9\u30FC: \`${e}\`\u3002`,gitVerificationBypassed:(e,t,r)=>`Git \u306E\u691C\u8A3C\u306E\u554F\u984C: \u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30D5\u30C3\u30AF\u304C\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E \`git ${e}\` \u3092\u62D2\u5426\u3057\u305F\u305F\u3081 Testbot \u306F\u307E\u305A\u4FEE\u6B63\u3092\u8A66\u307F\u307E\u3057\u305F\u304C\u3001${t}\u305F\u3081\u3001\`--no-verify\` \u3067\u914D\u4FE1\u3057\u307E\u3057\u305F\u3002\u30D5\u30C3\u30AF\u306E\u30A8\u30E9\u30FC: \`${r}\`\u3002`,repairTimedOut:e=>`${e} \u5206\u306E\u4FEE\u6B63\u6642\u9593\u3092\u4F7F\u3044\u5207\u3063\u305F`,repairSessionFailed:e=>`\u4FEE\u6B63\u30BB\u30C3\u30B7\u30E7\u30F3\u304C\u5931\u6557\u3057\u305F\uFF08${e}\uFF09`,gitVerificationBypassedNextStep:"Testbot \u306F\u30EA\u30DD\u30B8\u30C8\u30EA\u306E git \u30D5\u30C3\u30AF\u3092\u901A\u904E\u3057\u306A\u3044\u307E\u307E\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u3092\u914D\u4FE1\u3057\u307E\u3057\u305F\u3002\u30DE\u30FC\u30B8\u3059\u308B\u524D\u306B\u3001\u30D5\u30C3\u30AF\u304C\u5831\u544A\u3057\u305F\u554F\u984C\u3092\u305D\u308C\u3089\u306E\u30C6\u30B9\u30C8\u3067\u4FEE\u6B63\u3057\u3066\u304F\u3060\u3055\u3044\u3002",commitFailureHookNextStep:"pre-commit \u30D5\u30C3\u30AF\u304C Testbot \u306E\u751F\u6210\u3057\u305F\u30C6\u30B9\u30C8\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002\u30D5\u30C3\u30AF\u304C\u5831\u544A\u3057\u305F\u554F\u984C\u3092\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u5185\u3067\u4FEE\u6B63\u3059\u308B\u304B\u3001Testbot \u306E\u751F\u6210\u3057\u305F\u30C6\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u3092\u30B9\u30AD\u30C3\u30D7\u3059\u308B\u3088\u3046\u30D5\u30C3\u30AF\uFF0F\u30EA\u30F3\u30BF\u30FC\u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\uFF08\u3069\u3061\u3089\u306E\u914D\u4FE1\u30E2\u30FC\u30C9\u3067\u3082 `git commit` \u3092\u5B9F\u884C\u3059\u308B\u305F\u3081\u3001`generatedTestsMode` \u3092\u5207\u308A\u66FF\u3048\u3066\u3082\u30D5\u30C3\u30AF\u306F\u30B9\u30AD\u30C3\u30D7\u3055\u308C\u307E\u305B\u3093\u3002\uFF09",testbotPrCreationFailure:(e,t)=>`\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E Testbot PR \u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30A8\u30E9\u30FC: \`${e}\`\u3002\u30C6\u30B9\u30C8\u306F \`${t}\` \u306B\u30B3\u30DF\u30C3\u30C8\u30FB\u30D7\u30C3\u30B7\u30E5\u6E08\u307F\u3067\u3059\u3002\u3053\u306E\u30D6\u30E9\u30F3\u30C1\u304B\u3089\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u4F5C\u6210\u3057\u3066\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,sameBranchTestRepoConflictError:"`generatedTestsMode: same-branch` \u306F `testRepoPath` \u306E\u8A2D\u5B9A\u3068\u4F75\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30C6\u30B9\u30C8\u306F\u30C6\u30B9\u30C8\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8\u5074\u306B\u751F\u6210\u3055\u308C\u307E\u3057\u305F\u304C\u3001same-branch \u30E2\u30FC\u30C9\u306F\u30D7\u30E9\u30A4\u30DE\u30EA\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8\u306B\u306E\u307F\u30B3\u30DF\u30C3\u30C8\u3057\u307E\u3059\u3002`testRepoPath` \u3092\u4F7F\u3046\u5834\u5408\u306F `generatedTestsMode: separate-branch`\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8\uFF09\u3092\u4F7F\u7528\u3059\u308B\u304B\u3001`testRepoPath` \u3092\u524A\u9664\u3057\u3066\u540C\u3058\u30D6\u30E9\u30F3\u30C1\u306B\u30C6\u30B9\u30C8\u3092\u30B3\u30DF\u30C3\u30C8\u3057\u3066\u304F\u3060\u3055\u3044\u3002",noNewTestChangesBreadcrumb:e=>`\u3053\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u306F\u65B0\u3057\u3044\u30C6\u30B9\u30C8\u5909\u66F4\u306F\u767A\u751F\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u4EE5\u524D\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u4F5C\u6210\u3055\u308C\u305F [testbot PR](${e}) \u306F\u5F15\u304D\u7D9A\u304D\u30EC\u30D3\u30E5\u30FC\u5F85\u3061\u3067\u30AA\u30FC\u30D7\u30F3\u3067\u3059\u3002`,testbotPrLabel:(e,t)=>`Testbot PR: [${e}](${t})`,sutAppCrashDetected:e=>`**\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30AF\u30E9\u30C3\u30B7\u30E5\u3092\u691C\u51FA:** \u30B5\u30FC\u30D3\u30B9\uFF08${e}\uFF09\u304C\u30B3\u30FC\u30C9\u30A8\u30E9\u30FC\u306B\u3088\u308A\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002`,sutErrorLine:e=>`
147
- **\u30A8\u30E9\u30FC:** \`${e}\``,sutFixPrefix:"**\u4FEE\u6B63\u65B9\u6CD5:** ",sutServiceNotReachable:e=>`**\u30B5\u30FC\u30D3\u30B9\u306B\u5230\u9054\u3067\u304D\u307E\u305B\u3093:** ${e} \u306E\u30B5\u30FC\u30D3\u30B9\u304C\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u306E\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u307E\u3067\u306B\u5FDC\u7B54\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30B5\u30FC\u30D3\u30B9\u304C\u307E\u3060\u8D77\u52D5\u4E2D\u3067\u3042\u308B\u304B\u3001\u8D77\u52D5\u30B3\u30DE\u30F3\u30C9\u304C\u30B5\u30FC\u30D3\u30B9\u3092\u7ACB\u3061\u4E0A\u3052\u3089\u308C\u3066\u3044\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002`,sutServiceNotReachableFix:"**\u4FEE\u6B63\u65B9\u6CD5:** `targetSetupCommand` \u304C\u3053\u306E\u30B5\u30FC\u30D3\u30B9\u3092\u5B9F\u969B\u306B\u8D77\u52D5\u3057\u3001\u60F3\u5B9A\u3057\u305F\u30DD\u30FC\u30C8\u3067\u5F85\u3061\u53D7\u3051\u3066\u3044\u308B\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30B3\u30DE\u30F3\u30C9\u81EA\u4F53\u306F\u6B63\u3057\u3044\u304C\u30B5\u30FC\u30D3\u30B9\u306E\u8D77\u52D5\u304C\u9045\u3044\u5834\u5408\u306F\u3001`targetReadyCheckTimeout` \u3092\u5897\u3084\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u3088\u308A\u78BA\u5B9F\u306A\u8D77\u52D5\u5224\u5B9A\u3092\u884C\u3046\u306B\u306F\u3001`targetReadyCheckCommand` \u3067\u7279\u5B9A\u306E\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u30D7\u30ED\u30FC\u30D6\u3059\u308B\u3088\u3046\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002",staged:{requestedByPerson:e=>`${e} \u3055\u3093\u306E\u4F9D\u983C\u3067\u5B9F\u884C`,requestedByPolicy:e=>`\u691C\u8A3C\u30DD\u30EA\u30B7\u30FC ${e} \u306B\u3088\u308A\u5B9F\u884C`,noLiveApp:e=>`> \u26A0\uFE0F **\u3053\u306E\u5B9F\u884C\u3067\u306F\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\uFF08SUT\uFF09\u304C\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F** \u2014 \u4EE5\u4E0B\u306E ${e} \u4EF6\u306E\u30C6\u30B9\u30C8\u306F**\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093**\uFF08\u5B9F\u884C\u5BFE\u8C61\u306E\u30A2\u30D7\u30EA\u304C\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\uFF09\u3002\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3057\u3001\u5408\u683C\u3059\u308B\u3053\u3068\uFF08\u304A\u3088\u3073\u518D\u73FE\u30C6\u30B9\u30C8\u304C\u610F\u56F3\u3069\u304A\u308A\u5931\u6557\u3059\u308B\u3053\u3068\uFF09\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,unitTestsInFile:(e,t,r)=>`**${e}**: ${r?`${r} \u306E`:""}\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8 ${t} \u4EF6`,addedToExistingFile:"\u65E2\u5B58\u306E\u30C6\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u306B\u8FFD\u52A0",testPackagesHeader:"### \u{1F4E6} \u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u306E\u5B9F\u884C\u65B9\u6CD5",testPackageLine:(e,t)=>`\`${e}/\` \u306F Skyramp Testbot \u304C\u6240\u6709\u30FB\u4FDD\u5B88\u3059\u308B\u72EC\u7ACB\u3057\u305F\u30C6\u30B9\u30C8\u30D1\u30C3\u30B1\u30FC\u30B8\u3067\u3001\u72EC\u81EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u3001\u30ED\u30C3\u30AF\u30D5\u30A1\u30A4\u30EB\u3001\u30E9\u30F3\u30CA\u30FC\u8A2D\u5B9A\u3092\u6301\u3061\u307E\u3059\u3002\`${t}\` \u3067\u5B9F\u884C\u3067\u304D\u307E\u3059\u3002\u3059\u3079\u3066\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u5B9F\u884C\u3059\u308B\u306B\u306F\u3001\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u3092 CI \u306B\u8FFD\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,appManifestsUntouched:"\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u81EA\u8EAB\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u3068\u30ED\u30C3\u30AF\u30D5\u30A1\u30A4\u30EB\u306F\u5909\u66F4\u3057\u3066\u3044\u307E\u305B\u3093\u3002",dependencyChangesHeader:"### \u{1F4E6} \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u4F9D\u5B58\u95A2\u4FC2\u306E\u5909\u66F4",dependencyChangeLine:(e,t,r)=>`\`${t}\`\uFF08\u304A\u3088\u3073\u305D\u306E\u30ED\u30C3\u30AF\u30D5\u30A1\u30A4\u30EB\uFF09\u306B \`${e}\` \u3092\u8FFD\u52A0${r?`: ${r}`:""}`,testMaintenanceHeader:"\u2705 \u30C6\u30B9\u30C8\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9",keptNot:"\u5909\u66F4\u305B\u305A\u7DAD\u6301 \u2014 \u898B\u9001\u3063\u305F\u64CD\u4F5C: ",declinedPlanned:"(\u4E88\u5B9A\u3057\u3066\u3044\u305F\u64CD\u4F5C\u3092\u898B\u9001\u308A: ",declinedMaintenanceHeader:"\u21A9\uFE0F \u898B\u9001\u3063\u305F\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9",existingEvidenceHeader:"\u2705 \u65E2\u5B58\u306E\u30A8\u30D3\u30C7\u30F3\u30B9",trustedCheckPassed:(e,t)=>`\u4FE1\u983C\u6E08\u307F\u306E CI \u30C1\u30A7\u30C3\u30AF ${e} \u304C${t?` ${t} \u3067`:""}\u5408\u683C\u3057\u3001\u6B21\u3092\u78BA\u8A8D\u3057\u307E\u3057\u305F:`,testResultsHeader:"\u{1F9EA} \u30C6\u30B9\u30C8\u7D50\u679C",resultsTableHeader:"| \u30C6\u30B9\u30C8 ID | \u30C6\u30B9\u30C8\u7A2E\u5225 | \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 | \u30B9\u30C6\u30FC\u30BF\u30B9 | \u8A73\u7D30 |",unitResultsTableHeader:"| \u30C6\u30B9\u30C8 ID | \u30C6\u30B9\u30C8\u7A2E\u5225 | \u30C6\u30B9\u30C8\u5BFE\u8C61\u306E\u30B3\u30FC\u30C9 | \u30C6\u30B9\u30C8 | \u30B1\u30FC\u30B9\u6570 | \u30B9\u30C6\u30FC\u30BF\u30B9 | \u8A73\u7D30 |",casesPassed:(e,t,r)=>`${t} \u4EF6\u4E2D ${e} \u4EF6\u5408\u683C${r?`\u3001${r} \u4EF6\u30B9\u30AD\u30C3\u30D7`:""}`,behaviourCoverageHeader:"\u{1F517} \u632F\u308B\u821E\u3044\u306E\u30AB\u30D0\u30EC\u30C3\u30B8",coverageCaption:(e,t,r,n)=>`\uFF08\u751F\u6210 ${e} \xB7 \u5909\u66F4 ${t} \xB7 \u691C\u8A3C ${r} \xB7 \u5B9F\u884C ${n}\uFF09`,coverageTableHeader:"| \u632F\u308B\u821E\u3044 | \u30BD\u30FC\u30B9 | \u30C6\u30B9\u30C8 | \u30E1\u30F3\u30C6\u30CA\u30F3\u30B9 |",writtenNotRun:"\u4F5C\u6210\u6E08\u307F\u30FB\u672A\u5B9F\u884C",issuesFoundHeader:"\u26A0\uFE0F \u691C\u51FA\u3055\u308C\u305F\u554F\u984C",caveatsHeader:"### \u26A0\uFE0F \u3053\u306E\u5B9F\u884C\u3067\u78BA\u8A8D\u3067\u304D\u306A\u304B\u3063\u305F\u3053\u3068",commentHeader:"### Skyramp Testbot",timedOut:"> \u26A0\uFE0F \u5B9F\u884C\u304C\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F \u2014 \u4EE5\u4E0B\u306E\u7D50\u679C\u306F\u4E00\u90E8\u306E\u307F\u3067\u3059\u3002",stopReasons:{"pr-closed":"\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u30DE\u30FC\u30B8\u3055\u308C\u305A\u306B\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u307E\u3057\u305F",cancelled:"\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u305F\u304B\u3001\u30E9\u30F3\u30CA\u30FC\u304C\u505C\u6B62\u3057\u307E\u3057\u305F","attempt-cancelled":"Skyramp \u3067\u3053\u306E\u5B9F\u884C\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F","attempt-closed":"Skyramp \u304C\u3053\u306E\u5B9F\u884C\u3092\u7D42\u4E86\u3057\u307E\u3057\u305F"},maintenanceActions:{update:"\u66F4\u65B0",regenerate:"\u518D\u751F\u6210",delete:"\u524A\u9664",verify:"\u691C\u8A3C",updated:"\u66F4\u65B0",regenerated:"\u518D\u751F\u6210",deleted:"\u524A\u9664",verified:"\u691C\u8A3C"},publishFailures:{push:"\u30D7\u30C3\u30B7\u30E5\u306B\u5931\u6557",auth:"\u8A8D\u8A3C\u30A8\u30E9\u30FC",conflict:"\u7AF6\u5408",unknown:"\u4E0D\u660E\u306A\u30A8\u30E9\u30FC"},stoppedEarly:(e,t)=>`> \u26A0\uFE0F \u5B9F\u884C\u304C\u9014\u4E2D\u3067\u505C\u6B62\u3057\u307E\u3057\u305F \u2014 ${e}\u3002\u4EE5\u4E0B\u306E\u7D50\u679C\u306F\u4E00\u90E8\u306E\u307F\u3067\u3059\u3002${t}`,viewInSkyramp:e=>` [Skyramp \u3067\u8868\u793A](${e})`,setupRunEnds:{finished:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F\u3002Skyramp \u304C\u7D50\u679C\u3092\u78BA\u8A8D\u3057\u3066\u3044\u307E\u3059\u3002",failed:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002",timedOut:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u304C\u6642\u9593\u5207\u308C\u306B\u306A\u308A\u307E\u3057\u305F\u3002",cancelledInSkyramp:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u306F Skyramp \u3067\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F\u3002",stoppedToResume:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u3092\u505C\u6B62\u3057\u307E\u3057\u305F\u3002Skyramp \u3067\u518D\u958B\u3067\u304D\u307E\u3059\u3002"},appUnreachable:e=>`Skyramp\uFF08${e}\uFF09\u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3002\u3057\u3070\u3089\u304F\u3057\u3066\u304B\u3089\u518D\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044\u3002`,couldNotStart:e=>`Skyramp Testbot \u3092\u958B\u59CB\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: ${e}`,assembledAfterFailedChecks:e=>`> \u26A0\uFE0F \u4F5C\u6210\u30B9\u30C6\u30C3\u30D7\u304C\u30C1\u30A7\u30C3\u30AF\u306B\u5408\u683C\u3057\u306A\u304B\u3063\u305F\u305F\u3081\u3001\u3053\u306E\u30EC\u30DD\u30FC\u30C8\u306F\u81EA\u52D5\u3067\u7D44\u307F\u7ACB\u3066\u3089\u308C\u307E\u3057\u305F\u3002${e} \u4EF6\u306E\u30C1\u30A7\u30C3\u30AF\u304C\u672A\u9054\u6210\u3067\u3059 \u2014 \u8A73\u7D30\u306F\u5B9F\u884C\u30ED\u30B0\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,testbotPrLine:(e,t,r)=>`Testbot PR${e?`\uFF08${e}\uFF09`:""}: [${t}](${r})`,viewRun:e=>`_[\u5B9F\u884C\u3092\u8868\u793A](${e})_`,testsPrNotOpened:(e,t)=>`\u30C6\u30B9\u30C8 PR \u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${e}\uFF09\u3002\u30C6\u30B9\u30C8\u306F\u30D6\u30E9\u30F3\u30C1 \`${t}\` \u306B\u30D7\u30C3\u30B7\u30E5\u3055\u308C\u3066\u3044\u307E\u3059\u3002`,testsNotPushed:(e,t)=>`\u30C6\u30B9\u30C8\u3092\u30D7\u30C3\u30B7\u30E5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${e}\uFF09\u3002\u30C6\u30B9\u30C8\u306F\u30ED\u30FC\u30AB\u30EB\u30D6\u30E9\u30F3\u30C1 \`${t}\` \u306B\u6B8B\u3063\u3066\u3044\u307E\u3059\u3002`,testsPrRetargeted:e=>`\u30C6\u30B9\u30C8\u306E\u751F\u6210\u4E2D\u306B\u958B\u767A PR \u304C\u30DE\u30FC\u30B8\u3055\u308C\u307E\u3057\u305F \u2014 \u30C6\u30B9\u30C8 PR \u306F\u4EE3\u308F\u308A\u306B\u30D9\u30FC\u30B9\u30D6\u30E9\u30F3\u30C1${e?`\uFF08\`${e}\`\uFF09`:""}\u3092\u5BFE\u8C61\u306B\u3057\u3066\u3044\u307E\u3059\u3002`,testsPrUnchanged:"\u3053\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u306F\u65B0\u3057\u3044\u30C6\u30B9\u30C8\u306E\u5909\u66F4\u306F\u4E0D\u8981\u3067\u3057\u305F\u3002\u4EE5\u4E0B\u306E\u30C6\u30B9\u30C8 PR \u306F\u4EE5\u524D\u306E\u5B9F\u884C\u306E\u3082\u306E\u3067\u3001\u305D\u306E\u307E\u307E\u306B\u3057\u3066\u3044\u307E\u3059\u3002",committedNoPr:e=>`\u30C6\u30B9\u30C8\u306F\u30B3\u30DF\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F\u304C\u3001PR \u306F\u4F5C\u6210\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F: ${e}\u3002`}};var $P=(r=>(r.En="en",r.Ja="ja",r))($P||{}),LEt={en:mr,ja:GRe},HRe="en";function HI(e){let t=e.trim().toLowerCase();if(t==="")return"en";let r=Object.values($P);return r.includes(t)?t:(Oe(`Invalid language '${e}'. Supported: ${r.join(", ")}. Falling back to 'en'.`),"en")}function g3(e){HRe=e}function jI(e,t){return(Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0)??t}function ve(){return LEt[HRe]}var qP=(a=>(a.ProviderOutage="provider_outage",a.ProviderRateLimit="provider_rate_limit",a.ProviderUsageLimit="provider_usage_limit",a.ProviderAuthExpired="provider_auth_expired",a.Timeout="timeout",a.NoReport="no_report",a.RenderFailure="render_failure",a))(qP||{});(t=>{function e(r,n){switch(r){case"provider_outage":return{headline:ve().providerOutageHeadline(n.provider.name,n.maxRetries),action:ve().providerOutageActionStatusPage(n.provider.statusUrl)};case"provider_rate_limit":return{headline:ve().providerRateLimitHeadline(n.provider.name),action:ve().providerRateLimitAction};case"provider_usage_limit":return{headline:ve().providerUsageLimitHeadline(n.provider.name),action:ve().providerUsageLimitAction};case"provider_auth_expired":return{headline:ve().providerAuthExpiredHeadline(n.provider.name),action:ve().providerAuthExpiredAction};case"timeout":return{headline:ve().providerTimeoutHeadline(n.timeoutMinutes),action:ve().providerTimeoutAction};case"no_report":case"render_failure":return}}t.buildNotice=e})(qP||={});var GP=(r=>(r.SameBranch="same-branch",r.SeparateBranch="separate-branch",r))(GP||{});var zRe=(r=>(r.Sonnet="sonnet",r.Opus="opus",r))(zRe||{}),VRe="opus",UEt={sonnet:"claude-sonnet-5[1m]",opus:"claude-opus-5-5[1m]"},msr=UEt[VRe];function A3(e){return Object.values(zRe).includes(e)}function WRe(e){let t=(e??"").trim();if(t==="")return VRe;let r=t.toLowerCase();return A3(r)?r:t}var HP=(i=>(i.Low="low",i.Medium="medium",i.High="high",i.XHigh="xhigh",i.Max="max",i))(HP||{}),jP="high";function YRe(e){return Object.values(HP).includes(e)}var JRe=5;function $Et(e){let t=e.split(/\r?\n/).map(r=>r.trim()).filter(Boolean);if(t.length>JRe)throw new Error(`relatedRepoPaths supports at most ${JRe} entries (got ${t.length}); the cap limits how much cross-repo context is loaded to avoid overflowing Testbot's context window.`);return t}function qEt(e){let t=e.trim().toLowerCase();return t===""?"separate-branch":Object.values(GP).includes(t)?t:(Oe(`Invalid generatedTestsMode '${e}'. Falling back to 'separate-branch'.`),"separate-branch")}function GEt(e){let t=(e??"").trim();if(t!==""){if(/^(?:[1-9]|10)$/.test(t))return Number(t);Oe(`Ignoring perTestMaxFixAttempts="${e}": expected a whole number from 1 to 10; the Skyramp MCP default applies`)}}function HEt(e){let t=(e??"").trim().toLowerCase();return t===""?jP:YRe(t)?t:(Oe(`Ignoring effort="${e}": expected one of ${Object.values(HP).join(", ")}; using "${jP}"`),jP)}function KRe(){let e=WRe(qe("model"));return A3(e)||Oe(`model '${e}' is not a tested alias (sonnet, opus); passing it to the agent verbatim as a raw model id.`),{skyrampLicenseFile:qe("skyrampLicenseFile"),cursorApiKey:qe("cursorApiKey"),copilotApiKey:qe("copilotApiKey"),anthropicApiKey:qe("anthropicApiKey"),useBedrock:lu("useBedrock"),awsRegion:qe("awsRegion"),useLocalAuth:qe("useLocalAuth").toLowerCase()==="true",model:e,effort:HEt(qe("effort")),targetSetupCommand:qe("targetSetupCommand"),authTokenCommand:qe("authTokenCommand"),uiCredentials:qe("uiCredentials"),targetTeardownCommand:qe("targetTeardownCommand"),skipTargetTeardown:lu("skipTargetTeardown"),skyrampExecutorVersion:qe("skyrampExecutorVersion"),skyrampMcpVersion:qe("skyrampMcpVersion"),skyrampMcpSource:qe("skyrampMcpSource"),skyrampMcpGithubToken:qe("skyrampMcpGithubToken"),skyrampMcpGithubRef:qe("skyrampMcpGithubRef"),nodeVersion:qe("nodeVersion"),skipTargetSetup:lu("skipTargetSetup"),targetReadyCheckCommand:qe("targetReadyCheckCommand"),targetReadyCheckTimeout:(()=>{let r=parseInt(qe("targetReadyCheckTimeout"),10)||1800;return r<1?(Oe(`targetReadyCheckTimeout must be at least 1 second, got ${r}. Using 1s.`),1):r})(),targetReadyCheckInterval:(()=>{let r=parseInt(qe("targetReadyCheckInterval"),10),n=isNaN(r)?30:r;return n<1?(Oe(`targetReadyCheckInterval must be at least 1 second, got ${n}. Using 1s.`),1):n})(),targetReadyCheckDiagnosticsCommand:(()=>{let r=qe("targetReadyCheckDiagnosticsCommand");return r.trim().toLowerCase()==="none"?"":r})(),workingDirectory:qe("workingDirectory"),autoCommit:lu("autoCommit"),commitMessage:qe("commitMessage"),generatedTestsMode:qEt(qe("generatedTestsMode")),postPrComment:lu("postPrComment"),testExecutionTimeout:parseInt(qe("testExecutionTimeout"),10)||300,maxRecommendations:(()=>{let r=parseInt(qe("maxRecommendations"),10);return isNaN(r)?void 0:Math.max(0,r)})(),maxGenerate:(()=>{let r=parseInt(qe("maxGenerate"),10);return isNaN(r)?void 0:Math.max(0,r)})(),perTestMaxFixAttempts:GEt(qe("perTestMaxFixAttempts")),testbotMaxRetries:parseInt(qe("testbotMaxRetries"),10)||3,testbotRetryDelay:parseInt(qe("testbotRetryDelay"),10)||10,testbotTimeout:parseInt(qe("testbotTimeout"),10)||60,targetSetupRetries:parseInt(qe("targetSetupRetries"),10)||3,targetSetupRetryDelay:parseInt(qe("targetSetupRetryDelay"),10)||10,authTokenRetries:(()=>{let r=parseInt(qe("authTokenRetries"),10);return Number.isFinite(r)&&r>=1?r:6})(),authTokenRetryDelay:(()=>{let r=parseInt(qe("authTokenRetryDelay"),10);return Number.isFinite(r)&&r>=0?r:10})(),reportCollapsed:lu("reportCollapsed"),language:HI(qe("language")),enableDebug:lu("enableDebug"),testRepoPath:qe("testRepoPath")||void 0,relatedRepoPaths:$Et(qe("relatedRepoPaths")),allowedAuthors:qe("allowedAuthors").split(/\r?\n/).map(r=>r.trim()).filter(Boolean)}}var jEt={useBedrock:"false",skipTargetTeardown:"false",skyrampMcpSource:"npm",skyrampMcpGithubRef:"main",nodeVersion:"lts/*",skipTargetSetup:"false",targetReadyCheckTimeout:"1800",targetReadyCheckInterval:"30",targetReadyCheckDiagnosticsCommand:`docker ps -a --format 'table {{.Names}} {{.Status}} {{.Ports}}' && docker ps -a --format '{{.Names}}' | while read name; do [ -n "$name" ] && echo "--- logs $name (last 30) ---" && docker logs --tail 30 "$name"; done`,workingDirectory:".",autoCommit:"true",commitMessage:"Skyramp Testbot: test maintenance suggestions",generatedTestsMode:"separate-branch",pipeline:"classic",postPrComment:"true",testbotMaxRetries:"3",testbotRetryDelay:"10",testExecutionTimeout:"300",testbotTimeout:"60",targetSetupRetries:"3",targetSetupRetryDelay:"10",authTokenRetries:"6",authTokenRetryDelay:"10",reportCollapsed:"true",language:"en",enableDebug:"true",sutSetupMode:"none"};function XRe(e=process.env){for(let[t,r]of Object.entries(jEt)){let n=`INPUT_${t.replace(/ /g,"_").toUpperCase()}`;(e[n]??"").trim()===""&&(e[n]=r)}}ft();var $0e=j(require("path"));var hb=require("fs"),Ju=j(require("path"),1),jke=require("child_process"),zke=require("util");function zEt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Es={},zP={},Vp={},ZRe;function zI(){if(ZRe)return Vp;ZRe=1;function e(o){return typeof o>"u"||o===null}function t(o){return typeof o=="object"&&o!==null}function r(o){return Array.isArray(o)?o:e(o)?[]:[o]}function n(o,a){if(a){let c=Object.keys(a);for(let l=0,u=c.length;l<u;l+=1){let d=c[l];o[d]=a[d]}}return o}function s(o,a){let c="";for(let l=0;l<a;l+=1)c+=o;return c}function i(o){return o===0&&Number.NEGATIVE_INFINITY===1/o}return Vp.isNothing=e,Vp.isObject=t,Vp.toArray=r,Vp.repeat=s,Vp.isNegativeZero=i,Vp.extend=n,Vp}var y3,eke;function VI(){if(eke)return y3;eke=1;function e(r,n){let s="",i=r.reason||"(unknown reason)";return r.mark?(r.mark.name&&(s+='in "'+r.mark.name+'" '),s+="("+(r.mark.line+1)+":"+(r.mark.column+1)+")",!n&&r.mark.snippet&&(s+=`
146
+ **Error:** \`${e}\``,sutFixPrefix:"**Fix:** ",sutServiceNotReachable:e=>`**Service not reachable:** Service at ${e} did not respond before the health-check timeout. The service may still be starting, or the startup command may not have brought it up at all.`,sutServiceNotReachableFix:"**Fix:** Check that `targetSetupCommand` actually starts this service and listens on the expected port. If the command is correct but the service is slow to start, increase `targetReadyCheckTimeout`. For a more reliable readiness signal, configure `targetReadyCheckCommand` to probe a specific health endpoint.",staged:{requestedByPerson:e=>`Requested by ${e}`,requestedByPolicy:e=>`Started by the Validation Policy ${e}`,noLiveApp:e=>`> \u26A0\uFE0F **No live app (SUT) was available this run** \u2014 the ${e} test(s) below were **not executed** (there was no app to run them against). Run them against a running app to confirm they pass (and that any repro test fails as intended).`,unitTestsInFile:(e,t,r)=>`**${e}**: ${t} unit test${t===1?"":"s"}${r?` for ${r}`:""}`,addedToExistingFile:"added to an existing test file",testPackagesHeader:"### \u{1F4E6} Running these tests",testPackageLine:(e,t)=>`\`${e}/\` is a self-contained test package Skyramp Testbot owns and maintains, with its own manifest, lockfile and runner config. Run it with \`${t}\`; to run it on every pull request, add that one command to CI.`,appManifestsUntouched:"The application's own manifests and lockfiles were not changed.",dependencyChangesHeader:"### \u{1F4E6} Changes to the application's dependencies",dependencyChangeLine:(e,t,r)=>`Added \`${e}\` to \`${t}\` (and its lockfile)${r?`: ${r}`:""}`,testMaintenanceHeader:"\u2705 Test Maintenance",keptNot:"kept, not ",declinedPlanned:"(declined the planned ",declinedMaintenanceHeader:"\u21A9\uFE0F Declined Maintenance",existingEvidenceHeader:"\u2705 Existing Evidence",trustedCheckPassed:(e,t)=>`Trusted CI check ${e} passed${t?` on ${t}`:""}, establishing:`,testResultsHeader:"\u{1F9EA} Test Results",resultsTableHeader:"| Test ID | Test Type | Endpoint | Status | Details |",unitResultsTableHeader:"| Test ID | Test Type | Code under test | Test | Cases | Status | Details |",casesPassed:(e,t,r)=>`${e}/${t} passed${r?`, ${r} skipped`:""}`,behaviourCoverageHeader:"\u{1F517} Behaviour Coverage",coverageCaption:(e,t,r,n)=>` (${e} generated \xB7 ${t} modified \xB7 ${r} verified \xB7 ${n} executed)`,coverageTableHeader:"| Behaviour | Source | Tested By | Maintained By |",writtenNotRun:"written, not run",issuesFoundHeader:"\u26A0\uFE0F Issues Found",caveatsHeader:"### \u26A0\uFE0F What This Run Could Not Prove",commentHeader:"### Skyramp Testbot",timedOut:"> \u26A0\uFE0F Run timed out \u2014 the results below are partial.",stopReasons:{},publishFailures:{},maintenanceActions:{},stoppedEarly:(e,t)=>`> \u26A0\uFE0F Run stopped early \u2014 ${e}. The results below are partial.${t}`,viewInSkyramp:e=>` [View in Skyramp](${e})`,descriptionCut:(e,t,r)=>`_\u2026 The rest is left out${t===void 0?", with more test results":t?`, with ${t} more test result${t===1?"":"s"}`:""}: Azure DevOps takes at most ${e} characters.${r?` [Full report](${r})`:""}_`,setupRunEnds:{finished:"Setup run finished. Skyramp is checking the result.",failed:"Setup run failed.",timedOut:"Setup run ran out of time.",cancelledInSkyramp:"Setup run was cancelled in Skyramp.",stoppedToResume:"Setup run stopped. Resume it in Skyramp."},appUnreachable:e=>`Unable to contact the mothership ${e}. Please try again later.`,couldNotStart:e=>`Skyramp Testbot could not start: ${e}`,assembledAfterFailedChecks:e=>`> \u26A0\uFE0F This report was assembled automatically after the write-up step failed its checks; ${e} check(s) remain unmet \u2014 see the run log for details.`,testbotPrLine:(e,t,r)=>`Testbot PR${e?` (${e})`:""} : [${t}](${r})`,viewRun:e=>`_[View run](${e})_`,testsPrNotOpened:(e,t)=>`The tests PR could not be opened (${e}); the tests were pushed to branch \`${t}\`.`,testsNotPushed:(e,t)=>`The tests could not be pushed (${e}); they remain on the local branch \`${t}\`.`,testsPrRetargeted:e=>`The dev PR merged while tests were being generated \u2014 the tests PR targets its base branch${e?` (\`${e}\`)`:""} instead.`,testsPrUnchanged:"This push required no new test changes; the tests PR below is from an earlier run and was left as is.",committedNoPr:e=>`The tests were committed but no PR was opened: ${e}.`}};var GRe={defaultProgressHeadline:"\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u78BA\u8A8D\u3057\u3066\u30C6\u30B9\u30C8\u3092\u63A8\u5968\u3057\u3066\u3044\u307E\u3059\u3002",stepSettingUpEnvironment:"\u74B0\u5883\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7",stepAnalyzingUserRequest:"\u30E6\u30FC\u30B6\u30FC\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u5206\u6790",stepAnalyzingCodeChanges:"\u30B3\u30FC\u30C9\u5909\u66F4\u306E\u5206\u6790",stepRecommendingTests:"\u30C6\u30B9\u30C8\u306E\u63A8\u5968",stepGeneratingTests:"\u30C6\u30B9\u30C8\u306E\u751F\u6210",stepExecutingTests:"\u30C6\u30B9\u30C8\u306E\u5B9F\u884C",stepGeneratingReport:"\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3068\u30EC\u30DD\u30FC\u30C8\u306E\u751F\u6210",workflowRunLinkLabel:"\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u5B9F\u884C",noReportAvailable:"\u30EC\u30DD\u30FC\u30C8\u306F\u3042\u308A\u307E\u305B\u3093\u3002",cancelledHeader:"### Skyramp Testbot \u2014 \u30AD\u30E3\u30F3\u30BB\u30EB",cancelledBody:"\u3053\u306E\u5B9F\u884C\u306F\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F\u3002",cancelledStepSuffix:"\u30AD\u30E3\u30F3\u30BB\u30EB",abandonedHeader:"### Skyramp Testbot \u2014 \u505C\u6B62",abandonedBody:"\u3053\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u306F\u30DE\u30FC\u30B8\u3055\u308C\u305A\u306B\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u305F\u305F\u3081\u3001\u30C6\u30B9\u30C8\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\u306F\u5B8C\u4E86\u524D\u306B\u505C\u6B62\u3055\u308C\u307E\u3057\u305F\u3002",abandonedStepSuffix:"\u505C\u6B62",followingUserInstruction:e=>`> \u30E6\u30FC\u30B6\u30FC\u6307\u793A\u306B\u5F93\u3063\u3066\u3044\u307E\u3059: *${e}*`,minimalReportHeader:"### \u26A0\uFE0F Skyramp Testbot",testRecommendationsImplementedHeader:e=>`\u{1F4A1} \u5B9F\u88C5\u3057\u305F\u30C6\u30B9\u30C8\u63A8\u5968\uFF08${e}\u4EF6\uFF09`,additionalRecommendationsHeader:e=>`\u{1F4CC} \u8FFD\u52A0\u306E\u30C6\u30B9\u30C8\u63A8\u5968\uFF08${e}\u4EF6\uFF09`,additionalRecommendationsCta:"\u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u3092\u751F\u6210\u3059\u308B\u306B\u306F\u3001\u30B3\u30E1\u30F3\u30C8\u3067 `@skyramp-testbot` \u3092\u30E1\u30F3\u30B7\u30E7\u30F3\u3057\u3066\u8FFD\u52A0\u3092\u4F9D\u983C\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: `@skyramp-testbot /products \u306E\u30B3\u30F3\u30C8\u30E9\u30AF\u30C8\u30C6\u30B9\u30C8\u3092\u8FFD\u52A0\u3057\u3066`\uFF09\u3002",testTypeLabels:{contract:"\u{1F4CB} \u30B3\u30F3\u30C8\u30E9\u30AF\u30C8",integration:"\u{1F517} \u7D71\u5408",e2e:"\u{1F310} E2E",ui:"\u{1F5A5}\uFE0F UI"},testTypeCellLabels:{smoke:"\u30B9\u30E2\u30FC\u30AF",fuzz:"\u30D5\u30A1\u30BA",contract:"\u30B3\u30F3\u30C8\u30E9\u30AF\u30C8",load:"\u8CA0\u8377",integration:"\u7D71\u5408",e2e:"E2E",ui:"UI",unit:"\u30E6\u30CB\u30C3\u30C8"},statusLabels:{Pass:"\u5408\u683C",Fail:"\u4E0D\u5408\u683C",Error:"\u30A8\u30E9\u30FC",Skipped:"\u30B9\u30AD\u30C3\u30D7"},severityLabels:{critical:"\u91CD\u5927",high:"\u9AD8",medium:"\u4E2D",low:"\u4F4E"},reuse:{label:"POM \u518D\u5229\u7528",noPomLayer:"\u30B9\u30AD\u30C3\u30D7 \u2014 \u3053\u306E\u30C6\u30B9\u30C8\u306B\u518D\u5229\u7528\u3067\u304D\u308B\u30DA\u30FC\u30B8\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u5C64\u306F\u691C\u51FA\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",reusedAndVerified:e=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u518D\u5229\u7528\u30FB\u691C\u8A3C\u6E08\u307F`,reusedThenVerified:(e,t)=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u518D\u5229\u7528\uFF08\u3046\u3061 ${t} \u4EF6\u3092\u691C\u8A3C\u6E08\u307F\uFF09`,reused:e=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u518D\u5229\u7528`,verified:e=>`POM \u547C\u3073\u51FA\u3057 ${e} \u4EF6\u3092\u691C\u8A3C\u6E08\u307F`,unresolved:e=>`${e} \u4EF6\u306F POM \u30BD\u30FC\u30B9\u307E\u3067\u89E3\u6C7A\u3067\u304D\u305A\uFF08\u53C2\u8003\u60C5\u5831\u3067\u3042\u308A\u3001\u9664\u5916\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09`,candidates:e=>`\u5019\u88DC\u3068\u306A\u308B POM \u30D5\u30A1\u30A4\u30EB ${e} \u4EF6\u3092\u691C\u51FA`,verificationPassed:"\u691C\u8A3C\u306B\u5408\u683C",verificationFailed:"\u26A0\uFE0F \u691C\u8A3C\u306B\u5408\u683C\u3057\u307E\u305B\u3093\u3067\u3057\u305F",keptInline:e=>`\u30A4\u30F3\u30E9\u30A4\u30F3\u306E\u307E\u307E: ${e}`,gate:{"not-mapped":"\u30DE\u30C3\u30D4\u30F3\u30B0\u5BFE\u8C61\u5916","demoted-by-verify":"\u691C\u8A3C\u3067\u5DEE\u3057\u623B\u3057"}},testMaintenanceHeader:e=>`\u2705 \u30C6\u30B9\u30C8\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\uFF08${e}\u4EF6\uFF09`,maintenanceTableHeader:"| \u30C6\u30B9\u30C8\u7A2E\u5225 | \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 | \u30D5\u30A1\u30A4\u30EB | \u5909\u66F4\u5185\u5BB9 | \u5909\u66F4\u524D | \u5909\u66F4\u5F8C |",testResultsHeader:e=>`\u{1F9EA} \u30C6\u30B9\u30C8\u7D50\u679C\uFF08${e}\u4EF6\uFF09`,columnTestType:"\u30C6\u30B9\u30C8\u7A2E\u5225",columnEndpoint:"\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8",columnStatus:"\u30B9\u30C6\u30FC\u30BF\u30B9",columnDetails:"\u8A73\u7D30",columnRepo:"\u30EA\u30DD\u30B8\u30C8\u30EA",repoColumnPrimary:"\u30D7\u30E9\u30A4\u30DE\u30EA",columnVideo:"\u30D3\u30C7\u30AA",videoDownloadLink:e=>`[\u{1F4F9} \u30C0\u30A6\u30F3\u30ED\u30FC\u30C9](${e})`,videosArtifactFallback:e=>`\u{1F4F9} \u9332\u753B\u3055\u308C\u305F UI \u30C6\u30B9\u30C8\u30D3\u30C7\u30AA: [\u5B9F\u884C\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u304B\u3089\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9](${e})`,issuesFoundHeader:e=>`\u26A0\uFE0F \u691C\u51FA\u3055\u308C\u305F\u554F\u984C\uFF08${e}\u4EF6\uFF09`,configErrorsHeader:"\u2699\uFE0F \u8A2D\u5B9A\u30A8\u30E9\u30FC",nextStepsHeader:"### \u{1F4A1} \u6B21\u306E\u30B9\u30C6\u30C3\u30D7",caveatsHeader:"### \u26A0\uFE0F \u3053\u306E\u5B9F\u884C\u3067\u78BA\u8A8D\u3067\u304D\u306A\u304B\u3063\u305F\u3053\u3068",rows:{passed:e=>e?"\u8D77\u52D5\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u6210\u529F\u3057\u307E\u3057\u305F":"\u6210\u529F\u3057\u307E\u3057\u305F",notRun:e=>e?"\u3053\u306E\u5B9F\u884C\u3067\u306F\u30E9\u30A4\u30D6\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F":"\u3053\u306E\u5B9F\u884C\u3067\u306F\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",failedBug:e=>e?"\u8D77\u52D5\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5931\u6557\u3057\u307E\u3057\u305F":"\u5931\u6557\u3057\u307E\u3057\u305F",executedOf:(e,t)=>t?`\u3001\u305D\u306E\u3046\u3061 ${e} \u4EF6\u3092\u8D77\u52D5\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3057\u307E\u3057\u305F\u3002`:`\u3001\u305D\u306E\u3046\u3061 ${e} \u4EF6\u3092\u5B9F\u884C\u3057\u307E\u3057\u305F\u3002`,noneExecuted:e=>e?"\u3002\u3053\u306E\u5B9F\u884C\u3067\u306F\u30E9\u30A4\u30D6\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3055\u308C\u305F\u3082\u306E\u306F\u3042\u308A\u307E\u305B\u3093\u3002":"\u3002\u3053\u306E\u5B9F\u884C\u3067\u306F\u5B9F\u884C\u3055\u308C\u305F\u3082\u306E\u306F\u3042\u308A\u307E\u305B\u3093\u3002"},caveats:{deployFailed:"\u30A2\u30D7\u30EA\u3092\u8D77\u52D5\u3067\u304D\u306A\u304B\u3063\u305F\u305F\u3081\u3001\u3053\u3053\u306B\u793A\u3059\u5185\u5BB9\u306F\u7A3C\u50CD\u4E2D\u306E\u30B7\u30B9\u30C6\u30E0\u306B\u5BFE\u3057\u3066\u691C\u8A3C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",changeBrokeBringup:"\u3053\u306E\u5909\u66F4\u306B\u3088\u308A\u30A2\u30D7\u30EA\u306E\u8D77\u52D5\u304C\u58CA\u308C\u305F\u3068\u601D\u308F\u308C\u307E\u3059\u3002PR \u3092\u9069\u7528\u3057\u305F\u72B6\u614B\u3067\u8D77\u52D5\u3067\u304D\u305A\u3001\u30C6\u30B9\u30C8\u306F\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",bringupFailed:"\u3053\u306E PR \u3068\u306F\u7121\u95A2\u4FC2\u306E\u7406\u7531\u3067\u30A2\u30D7\u30EA\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3059\u308B\u30C6\u30B9\u30C8\u306F\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",testsNotExecuted:"\u3053\u306E\u5B9F\u884C\u3067\u306F\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u30C6\u30B9\u30C8\u304C\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u672A\u5B9F\u884C\u306E\u30C6\u30B9\u30C8\u306F\u5909\u66F4\u304C\u6B63\u3057\u304F\u52D5\u4F5C\u3059\u308B\u8A3C\u62E0\u306B\u306A\u308A\u307E\u305B\u3093\u3002",recipeDrift:"\u8A18\u9332\u3055\u308C\u3066\u3044\u305F\u30A2\u30D7\u30EA\u306E\u8D77\u52D5\u624B\u9806\u304C\u53E4\u304F\u306A\u3063\u3066\u304A\u308A\u3001\u8D77\u52D5\u524D\u306B\u4FEE\u6B63\u304C\u5FC5\u8981\u3067\u3057\u305F\u3002",mockedDependency:e=>`${e} \u306F\u5B9F\u969B\u306B\u30C7\u30D7\u30ED\u30A4\u3055\u308C\u305A\u30E2\u30C3\u30AF\u5316\u3055\u308C\u307E\u3057\u305F\u3002\u3053\u308C\u306B\u5BFE\u3059\u308B\u6210\u529F\u7D50\u679C\u306F\u8A3C\u660E\u306B\u306F\u306A\u308A\u307E\u305B\u3093\u3002`,finalizeNotReady:e=>`\u30C6\u30B9\u30C8\u306F\u73FE\u72B6\u3067\u306F\u30DE\u30FC\u30B8\u53EF\u80FD\u306A\u72B6\u614B\u3067\u306F\u3042\u308A\u307E\u305B\u3093${e?`: ${e}`:"\u3002"}`,ciNotCovered:"\u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u3092\u5B9F\u884C\u3059\u308B CI \u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C\u306A\u3044\u305F\u3081\u3001\u4ECA\u5F8C\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u306F\u5B9F\u884C\u3055\u308C\u307E\u305B\u3093\u3002",sutNotRequired:"\u30A2\u30D7\u30EA\u306F\u8D77\u52D5\u3057\u3066\u3044\u307E\u305B\u3093\u3002\u691C\u8A3C\u30C8\u30EA\u30A2\u30FC\u30B8\u306B\u3088\u308A\u3001\u3053\u306E\u5909\u66F4\u3067\u691C\u8A3C\u304C\u5FC5\u8981\u306A\u30C7\u30D7\u30ED\u30A4\u5F8C\u306E\u632F\u308B\u821E\u3044\u306F\u306A\u3044\u3068\u5224\u65AD\u3055\u308C\u307E\u3057\u305F\u3002",lintNotCovered:e=>`\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30EA\u30F3\u30BF\u30FC\u306F ${e} \u3092\u30C1\u30A7\u30C3\u30AF\u3057\u307E\u305B\u3093\u3002\u30B9\u30BF\u30A4\u30EB\u3084\u578B\u306E\u554F\u984C\u304C\u81EA\u52D5\u7684\u306B\u306F\u691C\u51FA\u3055\u308C\u307E\u305B\u3093\u3002`,analysisUnverified:e=>`\u5909\u66F4\u306E\u5206\u6790\u306E\u4E00\u90E8\u3092\u691C\u8A3C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u672A\u89E3\u6C7A\u306E\u30C1\u30A7\u30C3\u30AF ${e} \u4EF6\uFF09\u3002\u8A72\u5F53\u3059\u308B\u4E3B\u5F35\u306F\u672A\u78BA\u8A8D\u3068\u3057\u3066\u6271\u3044\u3001\u30C6\u30B9\u30C8\u3092\u8A08\u753B\u3057\u307E\u3057\u305F\u3002`,unitTestsNotRun:e=>`Testbot \u306F\u9078\u629E\u3057\u305F\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8\u3092\u5B9F\u884C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u3053\u3053\u306B\u3042\u308B\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8\u306E\u7D50\u679C\u306F Testbot \u81EA\u8EAB\u306E\u518D\u5B9F\u884C\u306B\u3088\u308B\u3082\u306E\u3067\u306F\u3042\u308A\u307E\u305B\u3093: ${e}`,testsCouldNotRunHere:(e,t)=>`\u3053\u306E\u5909\u66F4\u306B\u306F ${e} \u4EF6\u306E\u30C6\u30B9\u30C8\u304C\u3042\u308A\u307E\u3059\u304C\u3001\u3053\u306E\u74B0\u5883\u3067\u306F\u5B9F\u884C\u3067\u304D\u306A\u304B\u3063\u305F\u305F\u3081\u7D50\u679C\u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u30B9\u30AD\u30C3\u30D7\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09: ${t}`},autoCommitHint:"\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3067 `autoCommit: true` \u3092\u6709\u52B9\u306B\u3059\u308B\u3068\u3001Skyramp Testbot \u304C\u751F\u6210\u3057\u305F\u30C6\u30B9\u30C8\u3092\u81EA\u52D5\u7684\u306B\u30B3\u30DF\u30C3\u30C8\u3057\u307E\u3059\u3002",implementRecommendationsCta:"\u8FFD\u52A0\u306E\u30C6\u30B9\u30C8\u63A8\u5968\u3092\u5B9F\u88C5\u3059\u308B\u306B\u306F `@skyramp-testbot` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5DEE\u5206\u306E\u5206\u6790\u306B\u57FA\u3065\u304D\u3001\u4EE5\u4E0B\u3092\u63A8\u5968\u3057\u307E\u3059:",sutServiceErrorsHeadline:":warning: **\u30B5\u30FC\u30D3\u30B9\u304C\u30A8\u30E9\u30FC\u3092\u8FD4\u3057\u3066\u3044\u307E\u3059**",sutCheckedEndpoints:"Testbot \u306F\u30C6\u30B9\u30C8\u5B9F\u884C\u524D\u306B\u30B5\u30FC\u30D3\u30B9\u306E\u8D77\u52D5\u3092\u5F85\u6A5F\u3057\u307E\u3057\u305F\u304C\u3001\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u304C\u901A\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002",sutCheckCodeChanges:"**\u3053\u306E PR \u306E\u30B3\u30FC\u30C9\u5909\u66F4\u304C\u30B5\u30FC\u30D3\u30B9\u969C\u5BB3\u306E\u539F\u56E0\u306B\u306A\u3063\u3066\u3044\u306A\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044** \u2014 \u65B0\u305F\u306B\u6DF7\u5165\u3057\u305F\u30D0\u30B0\u3001\u4F9D\u5B58\u95A2\u4FC2\u306E\u4E0D\u8DB3\u3001\u8A2D\u5B9A\u30DF\u30B9\u306B\u3088\u308A\u3001\u30B5\u30FC\u30D3\u30B9\u304C\u8D77\u52D5\u3067\u304D\u306A\u3044\u30FB\u6B63\u3057\u304F\u5FDC\u7B54\u3067\u304D\u306A\u3044\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002",viewWorkflowLogs:e=>`[\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u30ED\u30B0\u5168\u6587\u3092\u898B\u308B \u2197](${e})`,sutFixAndRetry:"_\u554F\u984C\u3092\u4FEE\u6B63\u3057\u3066\u518D\u5EA6\u30D7\u30C3\u30B7\u30E5\u3059\u308B\u304B\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002_",internalErrorHeader:"### \u5185\u90E8\u30A8\u30E9\u30FC",internalErrorRenderFailed:"Testbot \u306F\u5B9F\u884C\u3092\u5B8C\u4E86\u3057\u307E\u3057\u305F\u304C\u3001\u30EC\u30DD\u30FC\u30C8\u306E\u751F\u6210\u4E2D\u306B\u4E88\u671F\u3057\u306A\u3044\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002",internalErrorNoReport:"Testbot \u3067\u4E88\u671F\u3057\u306A\u3044\u5185\u90E8\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306F\u6B63\u5E38\u306B\u5B8C\u4E86\u3057\u307E\u3057\u305F\u304C\u3001\u30EC\u30DD\u30FC\u30C8\u304C\u751F\u6210\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002",internalErrorAgentStopped:"Testbot \u306F\u30EC\u30DD\u30FC\u30C8\u3092\u751F\u6210\u3059\u308B\u524D\u306B\u505C\u6B62\u3057\u307E\u3057\u305F\u3002\u539F\u56E0\u306F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u30ED\u30B0\u3067\u78BA\u8A8D\u3067\u304D\u307E\u3059\u3002",internalErrorRawReportAvailable:"\u751F\u6210\u3055\u308C\u305F `report.json` \u306F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u30A2\u30FC\u30C6\u30A3\u30D5\u30A1\u30AF\u30C8\u304B\u3089\u53D6\u5F97\u3067\u304D\u307E\u3059\u3002\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\uFF08\u3042\u308C\u3070\uFF09\u306F\u901A\u5E38\u3069\u304A\u308A\u30B3\u30DF\u30C3\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\u3002",internalErrorRetriedTimes:e=>`${e} \u56DE\u30EA\u30C8\u30E9\u30A4\u3057\u307E\u3057\u305F\u304C\u6210\u529F\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002`,internalErrorFileIssue:"\u554F\u984C\u304C\u89E3\u6C7A\u3057\u306A\u3044\u5834\u5408\u306F https://github.com/skyramp/testbot/issues \u306B\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u5B9F\u884C\u3078\u306E\u30EA\u30F3\u30AF\u3092\u6DFB\u3048\u3066 issue \u3092\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerNotYourCode:"\u3053\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u5909\u66F4\u304C\u539F\u56E0\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u30C6\u30B9\u30C8\u306F\u751F\u6210\u3082\u5B9F\u884C\u3082\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",providerOutageHeadline:(e,t)=>`${e} \u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002Testbot \u306F ${t} \u56DE\u8A66\u884C\u3057\u307E\u3057\u305F\u304C\u5931\u6557\u3057\u307E\u3057\u305F\u3002`,providerOutageActionStatusPage:e=>`${e} \u3067\u72B6\u6CC1\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30B5\u30FC\u30D3\u30B9\u304C\u5FA9\u65E7\u3057\u305F\u3089\u3001Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,providerRateLimitHeadline:e=>`${e} \u306E\u30EC\u30FC\u30C8\u5236\u9650\u306B\u3088\u308A\u5B9F\u884C\u304C\u4E2D\u65AD\u3055\u308C\u307E\u3057\u305F (HTTP 429)\u3002`,providerRateLimitAction:"\u5236\u9650\u304C\u89E3\u9664\u3055\u308C\u308B\u307E\u3067\u5F85\u3063\u3066\u304B\u3089\u3001Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u7E70\u308A\u8FD4\u3059\u5834\u5408\u306F\u3001\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C\u4F7F\u7528\u3059\u308B\u8A8D\u8A3C\u60C5\u5831\u306E\u30EC\u30FC\u30C8\u5236\u9650\u3092\u5F15\u304D\u4E0A\u3052\u308B\u304B\u3001\u540C\u6642\u306B\u5B9F\u884C\u3059\u308B PR \u306E\u6570\u3092\u6E1B\u3089\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerUsageLimitHeadline:e=>`${e} \u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u5229\u7528\u4E0A\u9650\u306B\u9054\u3057\u307E\u3057\u305F\u3002`,providerUsageLimitAction:"\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E\u8A8D\u8A3C\u60C5\u5831\u306B\u7D10\u3065\u304F\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u5229\u7528\u4E0A\u9650\u3092\u5F15\u304D\u4E0A\u3052\u3066\u304B\u3089\u3001Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerAuthExpiredHeadline:e=>`\u5B9F\u884C\u4E2D\u306B\u3001Testbot \u304C ${e} \u3078\u63A5\u7D9A\u3059\u308B\u305F\u3081\u306E\u8A8D\u8A3C\u60C5\u5831\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u307E\u3057\u305F\u3002`,providerAuthExpiredAction:"\u8A8D\u8A3C\u60C5\u5831\u306E\u6709\u52B9\u671F\u9593\u306F\u56FA\u5B9A\u306E\u305F\u3081\u3001\u5B9F\u884C\u6642\u9593\u304C\u9577\u3044\u3068\u305D\u306E\u671F\u9593\u3092\u8D85\u3048\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002Actions \u30BF\u30D6\u306E\u5B9F\u884C\u30DA\u30FC\u30B8\u304B\u3089\u3053\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u3092\u518D\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u5B9F\u884C\u304C\u6709\u52B9\u671F\u9593\u3092\u5E38\u306B\u8D85\u3048\u308B\u5834\u5408\u306F\u3001\u30B8\u30E7\u30D6\u3054\u3068\u306B\u8A8D\u8A3C\u60C5\u5831\u3092\u767A\u884C\u3059\u308B\u304B\u3001\u5404\u30B8\u30E7\u30D6\u304C\u6709\u52B9\u671F\u9593\u5185\u306B\u53CE\u307E\u308B\u3088\u3046\u5B9F\u884C\u3092\u5206\u5272\u3057\u3066\u304F\u3060\u3055\u3044\u3002",providerTimeoutHeadline:e=>`Testbot \u306F\u5236\u9650\u6642\u9593 ${e} \u5206\u3092\u8D85\u3048\u305F\u305F\u3081\u505C\u6B62\u3055\u308C\u307E\u3057\u305F\u3002`,providerTimeoutAction:"\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u5B9F\u884C\u306B\u672C\u5F53\u306B\u6642\u9593\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E `testbotTimeout` \u5165\u529B\u5024\u3092\u5927\u304D\u304F\u3057\u3066\u304F\u3060\u3055\u3044\u3002",workspaceTestbotPrTitle:"Skyramp Testbot: \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u8A2D\u5B9A\u306E\u66F4\u65B0",workspaceTestbotPrHeader:"### Skyramp Testbot \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u8A2D\u5B9A\u306E\u66F4\u65B0",workspaceTestbotPrBody:"\u3053\u306E PR \u306F\u3053\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u7D71\u5408 `.skyramp/workspace.yml` \u3092\u66F4\u65B0\u3057\u307E\u3059\u3002\n\u4ECA\u56DE\u306E\u5B9F\u884C\u3067\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306F\u3001\u8A2D\u5B9A\u3055\u308C\u305F\u30C6\u30B9\u30C8\u30EA\u30DD\u30B8\u30C8\u30EA\u306B\u914D\u7F6E\u3055\u308C\u307E\u3057\u305F\u3002\u3053\u306E\u5909\u66F4\u306F\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\uFF0F\u30B5\u30FC\u30D3\u30B9\u8A2D\u5B9A\uFF08\u30DE\u30EB\u30C1\u30EA\u30DD\u30B8\u30C8\u30EA\u5B9F\u884C\u3067\u5206\u6790\u3055\u308C\u305F\u8FFD\u52A0\u30EA\u30DD\u30B8\u30C8\u30EA\u3092\u542B\u3080\uFF09\u306E\u307F\u3092\u8A18\u9332\u3057\u307E\u3059\u3002",devPrMergedBreadcrumb:(e,t,r)=>`\u958B\u767A PR \u304C\u30DE\u30FC\u30B8\u3055\u308C\u307E\u3057\u305F \u2014 Testbot PR [#${e}](${t}) \u306F\u5F15\u304D\u7D9A\u304D\u30AA\u30FC\u30D7\u30F3\u3067\u3001\u73FE\u5728\u306E\u30BF\u30FC\u30B2\u30C3\u30C8\u306F \`${r}\` \u3067\u3059\u3002`,devPrClosedBreadcrumb:(e,t)=>`\u958B\u767A PR \u304C\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u307E\u3057\u305F \u2014 Testbot PR [#${e}](${t}) \u306F\u81EA\u52D5\u7684\u306B\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u307E\u3057\u305F\u3002`,testbotPrMergeHint:"\u3053\u306E PR \u3092\u30DE\u30FC\u30B8\u3059\u308B\u3068\u3001\u751F\u6210/\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\u3055\u308C\u305F\u30C6\u30B9\u30C8\u304C\u30D5\u30A3\u30FC\u30C1\u30E3\u30FC\u30D6\u30E9\u30F3\u30C1\u306B\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002\u7834\u68C4\u3057\u305F\u3044\u5834\u5408\u306F\u30AF\u30ED\u30FC\u30BA\u3057\u3066\u304F\u3060\u3055\u3044\u3002",testbotPrBacklink:e=>`${e} \u7528\u306B Skyramp Testbot \u304C\u751F\u6210\u3057\u307E\u3057\u305F\u3002`,testbotPrDispatchBacklink:e=>`\`${e}\` \u306B\u5BFE\u3059\u308B\u624B\u52D5\u5B9F\u884C\u306B\u3088\u308A Skyramp Testbot \u304C\u751F\u6210\u3057\u307E\u3057\u305F\u3002`,testbotPrMergedBacklink:e=>`${e} \u7528\u306B Skyramp Testbot \u304C\u751F\u6210\u3057\u307E\u3057\u305F\u3002\u5143\u306E PR \u306F\u3059\u3067\u306B\u30DE\u30FC\u30B8\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u3001\u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u306F\u30D9\u30FC\u30B9\u30D6\u30E9\u30F3\u30C1\u3092\u5BFE\u8C61\u3068\u3057\u3066\u3044\u307E\u3059\u3002`,staleBannerNoChanges:e=>`> \u26A0\uFE0F ${e} \u3078\u306E\u6700\u65B0\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u306F\u3001\u65B0\u3057\u3044\u30C6\u30B9\u30C8\u5909\u66F4\u306F\u5FC5\u8981\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002`,staleBannerStillOpen:"> \u3053\u306E PR \u306F\u4EE5\u524D\u306E\u30D7\u30C3\u30B7\u30E5\u6642\u70B9\u306E testbot \u306E\u5206\u6790\u7D50\u679C\u306E\u307E\u307E\u3067\u3059\u3002`@skyramp-testbot` \u3067\u518D\u751F\u6210\u3059\u308B\u304B\u3001\u5185\u5BB9\u304C\u4ECA\u3082\u6709\u52B9\u3067\u3042\u308C\u3070\u305D\u306E\u307E\u307E\u30DE\u30FC\u30B8\u3059\u308B\u3053\u3068\u3092\u691C\u8A0E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",testbotPrNoBaseBranchError:"\u30D9\u30FC\u30B9\u30D6\u30E9\u30F3\u30C1\u3092\u7279\u5B9A\u3067\u304D\u306A\u304B\u3063\u305F\u305F\u3081\u3001Skyramp Testbot \u306F Testbot PR \u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F\uFF08pull_request \u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3082\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8\u6E08\u307F\u30D6\u30E9\u30F3\u30C1\u3082\u3042\u308A\u307E\u305B\u3093\uFF09\u3002\u901A\u5E38\u306F\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C `pull_request` \u30A4\u30D9\u30F3\u30C8\u4EE5\u5916\u3067\u5B9F\u884C\u3055\u308C\u3001`actions/checkout` \u304C detached HEAD \u306E\u72B6\u614B\u3092\u6B8B\u3057\u305F\u3053\u3068\u304C\u539F\u56E0\u3067\u3059\u3002\u4EE3\u308F\u308A\u306B\u30D5\u30A3\u30FC\u30C1\u30E3\u30FC\u30D6\u30E9\u30F3\u30C1\u3078\u76F4\u63A5\u30B3\u30DF\u30C3\u30C8\u3059\u308B\u306B\u306F `generatedTestsMode: same-branch` \u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002",commitFailureGeneric:(e,t)=>t?`\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E Testbot PR \u30D6\u30E9\u30F3\u30C1\u3078\u306E\u30B3\u30DF\u30C3\u30C8\u306B\u5931\u6557\u3057\u307E\u3057\u305F: \`${e}\`\u3002`:`\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E\u30B3\u30DF\u30C3\u30C8\u306B\u5931\u6557\u3057\u307E\u3057\u305F: \`${e}\`\u3002`,commitFailureHookWhereTestbotPr:"\u305D\u306E\u305F\u3081 Testbot PR \u306F\u4F5C\u6210\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",commitFailureHookWhereSameBranch:"\u305D\u306E\u305F\u3081\u5909\u66F4\u306F\u30D6\u30E9\u30F3\u30C1\u306B\u30B3\u30DF\u30C3\u30C8\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F",commitFailureHook:(e,t)=>`\u30EA\u30DD\u30B8\u30C8\u30EA\u306E pre-commit \u30D5\u30C3\u30AF\u304C\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E\u30B3\u30DF\u30C3\u30C8\u3092\u62D2\u5426\u3057\u305F\u305F\u3081\u3001${t}\u3002\u30D5\u30C3\u30AF\u306E\u30A8\u30E9\u30FC: \`${e}\`\u3002`,gitVerificationBypassed:(e,t,r)=>`Git \u306E\u691C\u8A3C\u306E\u554F\u984C: \u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30D5\u30C3\u30AF\u304C\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E \`git ${e}\` \u3092\u62D2\u5426\u3057\u305F\u305F\u3081 Testbot \u306F\u307E\u305A\u4FEE\u6B63\u3092\u8A66\u307F\u307E\u3057\u305F\u304C\u3001${t}\u305F\u3081\u3001\`--no-verify\` \u3067\u914D\u4FE1\u3057\u307E\u3057\u305F\u3002\u30D5\u30C3\u30AF\u306E\u30A8\u30E9\u30FC: \`${r}\`\u3002`,repairTimedOut:e=>`${e} \u5206\u306E\u4FEE\u6B63\u6642\u9593\u3092\u4F7F\u3044\u5207\u3063\u305F`,repairSessionFailed:e=>`\u4FEE\u6B63\u30BB\u30C3\u30B7\u30E7\u30F3\u304C\u5931\u6557\u3057\u305F\uFF08${e}\uFF09`,gitVerificationBypassedNextStep:"Testbot \u306F\u30EA\u30DD\u30B8\u30C8\u30EA\u306E git \u30D5\u30C3\u30AF\u3092\u901A\u904E\u3057\u306A\u3044\u307E\u307E\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u3092\u914D\u4FE1\u3057\u307E\u3057\u305F\u3002\u30DE\u30FC\u30B8\u3059\u308B\u524D\u306B\u3001\u30D5\u30C3\u30AF\u304C\u5831\u544A\u3057\u305F\u554F\u984C\u3092\u305D\u308C\u3089\u306E\u30C6\u30B9\u30C8\u3067\u4FEE\u6B63\u3057\u3066\u304F\u3060\u3055\u3044\u3002",commitFailureHookNextStep:"pre-commit \u30D5\u30C3\u30AF\u304C Testbot \u306E\u751F\u6210\u3057\u305F\u30C6\u30B9\u30C8\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002\u30D5\u30C3\u30AF\u304C\u5831\u544A\u3057\u305F\u554F\u984C\u3092\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u5185\u3067\u4FEE\u6B63\u3059\u308B\u304B\u3001Testbot \u306E\u751F\u6210\u3057\u305F\u30C6\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u3092\u30B9\u30AD\u30C3\u30D7\u3059\u308B\u3088\u3046\u30D5\u30C3\u30AF\uFF0F\u30EA\u30F3\u30BF\u30FC\u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\uFF08\u3069\u3061\u3089\u306E\u914D\u4FE1\u30E2\u30FC\u30C9\u3067\u3082 `git commit` \u3092\u5B9F\u884C\u3059\u308B\u305F\u3081\u3001`generatedTestsMode` \u3092\u5207\u308A\u66FF\u3048\u3066\u3082\u30D5\u30C3\u30AF\u306F\u30B9\u30AD\u30C3\u30D7\u3055\u308C\u307E\u305B\u3093\u3002\uFF09",testbotPrCreationFailure:(e,t)=>`\u751F\u6210\u3055\u308C\u305F\u30C6\u30B9\u30C8\u306E Testbot PR \u3092\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30A8\u30E9\u30FC: \`${e}\`\u3002\u30C6\u30B9\u30C8\u306F \`${t}\` \u306B\u30B3\u30DF\u30C3\u30C8\u30FB\u30D7\u30C3\u30B7\u30E5\u6E08\u307F\u3067\u3059\u3002\u3053\u306E\u30D6\u30E9\u30F3\u30C1\u304B\u3089\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u4F5C\u6210\u3057\u3066\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,sameBranchTestRepoConflictError:"`generatedTestsMode: same-branch` \u306F `testRepoPath` \u306E\u8A2D\u5B9A\u3068\u4F75\u7528\u3067\u304D\u307E\u305B\u3093\u3002\u30C6\u30B9\u30C8\u306F\u30C6\u30B9\u30C8\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8\u5074\u306B\u751F\u6210\u3055\u308C\u307E\u3057\u305F\u304C\u3001same-branch \u30E2\u30FC\u30C9\u306F\u30D7\u30E9\u30A4\u30DE\u30EA\u30EA\u30DD\u30B8\u30C8\u30EA\u306E\u30C1\u30A7\u30C3\u30AF\u30A2\u30A6\u30C8\u306B\u306E\u307F\u30B3\u30DF\u30C3\u30C8\u3057\u307E\u3059\u3002`testRepoPath` \u3092\u4F7F\u3046\u5834\u5408\u306F `generatedTestsMode: separate-branch`\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8\uFF09\u3092\u4F7F\u7528\u3059\u308B\u304B\u3001`testRepoPath` \u3092\u524A\u9664\u3057\u3066\u540C\u3058\u30D6\u30E9\u30F3\u30C1\u306B\u30C6\u30B9\u30C8\u3092\u30B3\u30DF\u30C3\u30C8\u3057\u3066\u304F\u3060\u3055\u3044\u3002",noNewTestChangesBreadcrumb:e=>`\u3053\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u306F\u65B0\u3057\u3044\u30C6\u30B9\u30C8\u5909\u66F4\u306F\u767A\u751F\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u4EE5\u524D\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u4F5C\u6210\u3055\u308C\u305F [testbot PR](${e}) \u306F\u5F15\u304D\u7D9A\u304D\u30EC\u30D3\u30E5\u30FC\u5F85\u3061\u3067\u30AA\u30FC\u30D7\u30F3\u3067\u3059\u3002`,testbotPrLabel:(e,t)=>`Testbot PR: [${e}](${t})`,sutAppCrashDetected:e=>`**\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30AF\u30E9\u30C3\u30B7\u30E5\u3092\u691C\u51FA:** \u30B5\u30FC\u30D3\u30B9\uFF08${e}\uFF09\u304C\u30B3\u30FC\u30C9\u30A8\u30E9\u30FC\u306B\u3088\u308A\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002`,sutErrorLine:e=>`
147
+ **\u30A8\u30E9\u30FC:** \`${e}\``,sutFixPrefix:"**\u4FEE\u6B63\u65B9\u6CD5:** ",sutServiceNotReachable:e=>`**\u30B5\u30FC\u30D3\u30B9\u306B\u5230\u9054\u3067\u304D\u307E\u305B\u3093:** ${e} \u306E\u30B5\u30FC\u30D3\u30B9\u304C\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u306E\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u307E\u3067\u306B\u5FDC\u7B54\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30B5\u30FC\u30D3\u30B9\u304C\u307E\u3060\u8D77\u52D5\u4E2D\u3067\u3042\u308B\u304B\u3001\u8D77\u52D5\u30B3\u30DE\u30F3\u30C9\u304C\u30B5\u30FC\u30D3\u30B9\u3092\u7ACB\u3061\u4E0A\u3052\u3089\u308C\u3066\u3044\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002`,sutServiceNotReachableFix:"**\u4FEE\u6B63\u65B9\u6CD5:** `targetSetupCommand` \u304C\u3053\u306E\u30B5\u30FC\u30D3\u30B9\u3092\u5B9F\u969B\u306B\u8D77\u52D5\u3057\u3001\u60F3\u5B9A\u3057\u305F\u30DD\u30FC\u30C8\u3067\u5F85\u3061\u53D7\u3051\u3066\u3044\u308B\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30B3\u30DE\u30F3\u30C9\u81EA\u4F53\u306F\u6B63\u3057\u3044\u304C\u30B5\u30FC\u30D3\u30B9\u306E\u8D77\u52D5\u304C\u9045\u3044\u5834\u5408\u306F\u3001`targetReadyCheckTimeout` \u3092\u5897\u3084\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u3088\u308A\u78BA\u5B9F\u306A\u8D77\u52D5\u5224\u5B9A\u3092\u884C\u3046\u306B\u306F\u3001`targetReadyCheckCommand` \u3067\u7279\u5B9A\u306E\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u30D7\u30ED\u30FC\u30D6\u3059\u308B\u3088\u3046\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002",staged:{requestedByPerson:e=>`${e} \u3055\u3093\u306E\u4F9D\u983C\u3067\u5B9F\u884C`,requestedByPolicy:e=>`\u691C\u8A3C\u30DD\u30EA\u30B7\u30FC ${e} \u306B\u3088\u308A\u5B9F\u884C`,noLiveApp:e=>`> \u26A0\uFE0F **\u3053\u306E\u5B9F\u884C\u3067\u306F\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\uFF08SUT\uFF09\u304C\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F** \u2014 \u4EE5\u4E0B\u306E ${e} \u4EF6\u306E\u30C6\u30B9\u30C8\u306F**\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093**\uFF08\u5B9F\u884C\u5BFE\u8C61\u306E\u30A2\u30D7\u30EA\u304C\u3042\u308A\u307E\u305B\u3093\u3067\u3057\u305F\uFF09\u3002\u7A3C\u50CD\u4E2D\u306E\u30A2\u30D7\u30EA\u306B\u5BFE\u3057\u3066\u5B9F\u884C\u3057\u3001\u5408\u683C\u3059\u308B\u3053\u3068\uFF08\u304A\u3088\u3073\u518D\u73FE\u30C6\u30B9\u30C8\u304C\u610F\u56F3\u3069\u304A\u308A\u5931\u6557\u3059\u308B\u3053\u3068\uFF09\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,unitTestsInFile:(e,t,r)=>`**${e}**: ${r?`${r} \u306E`:""}\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8 ${t} \u4EF6`,addedToExistingFile:"\u65E2\u5B58\u306E\u30C6\u30B9\u30C8\u30D5\u30A1\u30A4\u30EB\u306B\u8FFD\u52A0",testPackagesHeader:"### \u{1F4E6} \u3053\u308C\u3089\u306E\u30C6\u30B9\u30C8\u306E\u5B9F\u884C\u65B9\u6CD5",testPackageLine:(e,t)=>`\`${e}/\` \u306F Skyramp Testbot \u304C\u6240\u6709\u30FB\u4FDD\u5B88\u3059\u308B\u72EC\u7ACB\u3057\u305F\u30C6\u30B9\u30C8\u30D1\u30C3\u30B1\u30FC\u30B8\u3067\u3001\u72EC\u81EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u3001\u30ED\u30C3\u30AF\u30D5\u30A1\u30A4\u30EB\u3001\u30E9\u30F3\u30CA\u30FC\u8A2D\u5B9A\u3092\u6301\u3061\u307E\u3059\u3002\`${t}\` \u3067\u5B9F\u884C\u3067\u304D\u307E\u3059\u3002\u3059\u3079\u3066\u306E\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u3067\u5B9F\u884C\u3059\u308B\u306B\u306F\u3001\u3053\u306E\u30B3\u30DE\u30F3\u30C9\u3092 CI \u306B\u8FFD\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,appManifestsUntouched:"\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u81EA\u8EAB\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u3068\u30ED\u30C3\u30AF\u30D5\u30A1\u30A4\u30EB\u306F\u5909\u66F4\u3057\u3066\u3044\u307E\u305B\u3093\u3002",dependencyChangesHeader:"### \u{1F4E6} \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u4F9D\u5B58\u95A2\u4FC2\u306E\u5909\u66F4",dependencyChangeLine:(e,t,r)=>`\`${t}\`\uFF08\u304A\u3088\u3073\u305D\u306E\u30ED\u30C3\u30AF\u30D5\u30A1\u30A4\u30EB\uFF09\u306B \`${e}\` \u3092\u8FFD\u52A0${r?`: ${r}`:""}`,testMaintenanceHeader:"\u2705 \u30C6\u30B9\u30C8\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9",keptNot:"\u5909\u66F4\u305B\u305A\u7DAD\u6301 \u2014 \u898B\u9001\u3063\u305F\u64CD\u4F5C: ",declinedPlanned:"(\u4E88\u5B9A\u3057\u3066\u3044\u305F\u64CD\u4F5C\u3092\u898B\u9001\u308A: ",declinedMaintenanceHeader:"\u21A9\uFE0F \u898B\u9001\u3063\u305F\u30E1\u30F3\u30C6\u30CA\u30F3\u30B9",existingEvidenceHeader:"\u2705 \u65E2\u5B58\u306E\u30A8\u30D3\u30C7\u30F3\u30B9",trustedCheckPassed:(e,t)=>`\u4FE1\u983C\u6E08\u307F\u306E CI \u30C1\u30A7\u30C3\u30AF ${e} \u304C${t?` ${t} \u3067`:""}\u5408\u683C\u3057\u3001\u6B21\u3092\u78BA\u8A8D\u3057\u307E\u3057\u305F:`,testResultsHeader:"\u{1F9EA} \u30C6\u30B9\u30C8\u7D50\u679C",resultsTableHeader:"| \u30C6\u30B9\u30C8 ID | \u30C6\u30B9\u30C8\u7A2E\u5225 | \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8 | \u30B9\u30C6\u30FC\u30BF\u30B9 | \u8A73\u7D30 |",unitResultsTableHeader:"| \u30C6\u30B9\u30C8 ID | \u30C6\u30B9\u30C8\u7A2E\u5225 | \u30C6\u30B9\u30C8\u5BFE\u8C61\u306E\u30B3\u30FC\u30C9 | \u30C6\u30B9\u30C8 | \u30B1\u30FC\u30B9\u6570 | \u30B9\u30C6\u30FC\u30BF\u30B9 | \u8A73\u7D30 |",casesPassed:(e,t,r)=>`${t} \u4EF6\u4E2D ${e} \u4EF6\u5408\u683C${r?`\u3001${r} \u4EF6\u30B9\u30AD\u30C3\u30D7`:""}`,behaviourCoverageHeader:"\u{1F517} \u632F\u308B\u821E\u3044\u306E\u30AB\u30D0\u30EC\u30C3\u30B8",coverageCaption:(e,t,r,n)=>`\uFF08\u751F\u6210 ${e} \xB7 \u5909\u66F4 ${t} \xB7 \u691C\u8A3C ${r} \xB7 \u5B9F\u884C ${n}\uFF09`,coverageTableHeader:"| \u632F\u308B\u821E\u3044 | \u30BD\u30FC\u30B9 | \u30C6\u30B9\u30C8 | \u30E1\u30F3\u30C6\u30CA\u30F3\u30B9 |",writtenNotRun:"\u4F5C\u6210\u6E08\u307F\u30FB\u672A\u5B9F\u884C",issuesFoundHeader:"\u26A0\uFE0F \u691C\u51FA\u3055\u308C\u305F\u554F\u984C",caveatsHeader:"### \u26A0\uFE0F \u3053\u306E\u5B9F\u884C\u3067\u78BA\u8A8D\u3067\u304D\u306A\u304B\u3063\u305F\u3053\u3068",commentHeader:"### Skyramp Testbot",timedOut:"> \u26A0\uFE0F \u5B9F\u884C\u304C\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F \u2014 \u4EE5\u4E0B\u306E\u7D50\u679C\u306F\u4E00\u90E8\u306E\u307F\u3067\u3059\u3002",stopReasons:{"pr-closed":"\u30D7\u30EB\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u30DE\u30FC\u30B8\u3055\u308C\u305A\u306B\u30AF\u30ED\u30FC\u30BA\u3055\u308C\u307E\u3057\u305F",cancelled:"\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u305F\u304B\u3001\u30E9\u30F3\u30CA\u30FC\u304C\u505C\u6B62\u3057\u307E\u3057\u305F","attempt-cancelled":"Skyramp \u3067\u3053\u306E\u5B9F\u884C\u304C\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F","attempt-closed":"Skyramp \u304C\u3053\u306E\u5B9F\u884C\u3092\u7D42\u4E86\u3057\u307E\u3057\u305F"},maintenanceActions:{update:"\u66F4\u65B0",regenerate:"\u518D\u751F\u6210",delete:"\u524A\u9664",verify:"\u691C\u8A3C",updated:"\u66F4\u65B0",regenerated:"\u518D\u751F\u6210",deleted:"\u524A\u9664",verified:"\u691C\u8A3C"},publishFailures:{push:"\u30D7\u30C3\u30B7\u30E5\u306B\u5931\u6557",auth:"\u8A8D\u8A3C\u30A8\u30E9\u30FC",conflict:"\u7AF6\u5408",unknown:"\u4E0D\u660E\u306A\u30A8\u30E9\u30FC"},stoppedEarly:(e,t)=>`> \u26A0\uFE0F \u5B9F\u884C\u304C\u9014\u4E2D\u3067\u505C\u6B62\u3057\u307E\u3057\u305F \u2014 ${e}\u3002\u4EE5\u4E0B\u306E\u7D50\u679C\u306F\u4E00\u90E8\u306E\u307F\u3067\u3059\u3002${t}`,viewInSkyramp:e=>` [Skyramp \u3067\u8868\u793A](${e})`,descriptionCut:(e,t,r)=>`_\u2026 \u6B8B\u308A\u306F\u7701\u7565\u3057\u307E\u3057\u305F${t===void 0?"\uFF08\u30C6\u30B9\u30C8\u7D50\u679C\u3092\u542B\u3080\uFF09":t?`\uFF08\u30C6\u30B9\u30C8\u7D50\u679C ${t} \u4EF6\u3092\u542B\u3080\uFF09`:""}\u3002Azure DevOps \u306E\u8AAC\u660E\u306F ${e} \u6587\u5B57\u307E\u3067\u3067\u3059\u3002${r?` [\u5B8C\u5168\u306A\u30EC\u30DD\u30FC\u30C8](${r})`:""}_`,setupRunEnds:{finished:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F\u3002Skyramp \u304C\u7D50\u679C\u3092\u78BA\u8A8D\u3057\u3066\u3044\u307E\u3059\u3002",failed:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002",timedOut:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u304C\u6642\u9593\u5207\u308C\u306B\u306A\u308A\u307E\u3057\u305F\u3002",cancelledInSkyramp:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u306F Skyramp \u3067\u30AD\u30E3\u30F3\u30BB\u30EB\u3055\u308C\u307E\u3057\u305F\u3002",stoppedToResume:"\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B9F\u884C\u3092\u505C\u6B62\u3057\u307E\u3057\u305F\u3002Skyramp \u3067\u518D\u958B\u3067\u304D\u307E\u3059\u3002"},appUnreachable:e=>`Skyramp\uFF08${e}\uFF09\u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3002\u3057\u3070\u3089\u304F\u3057\u3066\u304B\u3089\u518D\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044\u3002`,couldNotStart:e=>`Skyramp Testbot \u3092\u958B\u59CB\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: ${e}`,assembledAfterFailedChecks:e=>`> \u26A0\uFE0F \u4F5C\u6210\u30B9\u30C6\u30C3\u30D7\u304C\u30C1\u30A7\u30C3\u30AF\u306B\u5408\u683C\u3057\u306A\u304B\u3063\u305F\u305F\u3081\u3001\u3053\u306E\u30EC\u30DD\u30FC\u30C8\u306F\u81EA\u52D5\u3067\u7D44\u307F\u7ACB\u3066\u3089\u308C\u307E\u3057\u305F\u3002${e} \u4EF6\u306E\u30C1\u30A7\u30C3\u30AF\u304C\u672A\u9054\u6210\u3067\u3059 \u2014 \u8A73\u7D30\u306F\u5B9F\u884C\u30ED\u30B0\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,testbotPrLine:(e,t,r)=>`Testbot PR${e?`\uFF08${e}\uFF09`:""}: [${t}](${r})`,viewRun:e=>`_[\u5B9F\u884C\u3092\u8868\u793A](${e})_`,testsPrNotOpened:(e,t)=>`\u30C6\u30B9\u30C8 PR \u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${e}\uFF09\u3002\u30C6\u30B9\u30C8\u306F\u30D6\u30E9\u30F3\u30C1 \`${t}\` \u306B\u30D7\u30C3\u30B7\u30E5\u3055\u308C\u3066\u3044\u307E\u3059\u3002`,testsNotPushed:(e,t)=>`\u30C6\u30B9\u30C8\u3092\u30D7\u30C3\u30B7\u30E5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${e}\uFF09\u3002\u30C6\u30B9\u30C8\u306F\u30ED\u30FC\u30AB\u30EB\u30D6\u30E9\u30F3\u30C1 \`${t}\` \u306B\u6B8B\u3063\u3066\u3044\u307E\u3059\u3002`,testsPrRetargeted:e=>`\u30C6\u30B9\u30C8\u306E\u751F\u6210\u4E2D\u306B\u958B\u767A PR \u304C\u30DE\u30FC\u30B8\u3055\u308C\u307E\u3057\u305F \u2014 \u30C6\u30B9\u30C8 PR \u306F\u4EE3\u308F\u308A\u306B\u30D9\u30FC\u30B9\u30D6\u30E9\u30F3\u30C1${e?`\uFF08\`${e}\`\uFF09`:""}\u3092\u5BFE\u8C61\u306B\u3057\u3066\u3044\u307E\u3059\u3002`,testsPrUnchanged:"\u3053\u306E\u30D7\u30C3\u30B7\u30E5\u3067\u306F\u65B0\u3057\u3044\u30C6\u30B9\u30C8\u306E\u5909\u66F4\u306F\u4E0D\u8981\u3067\u3057\u305F\u3002\u4EE5\u4E0B\u306E\u30C6\u30B9\u30C8 PR \u306F\u4EE5\u524D\u306E\u5B9F\u884C\u306E\u3082\u306E\u3067\u3001\u305D\u306E\u307E\u307E\u306B\u3057\u3066\u3044\u307E\u3059\u3002",committedNoPr:e=>`\u30C6\u30B9\u30C8\u306F\u30B3\u30DF\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F\u304C\u3001PR \u306F\u4F5C\u6210\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F: ${e}\u3002`}};var $P=(r=>(r.En="en",r.Ja="ja",r))($P||{}),LEt={en:mr,ja:GRe},HRe="en";function HI(e){let t=e.trim().toLowerCase();if(t==="")return"en";let r=Object.values($P);return r.includes(t)?t:(Oe(`Invalid language '${e}'. Supported: ${r.join(", ")}. Falling back to 'en'.`),"en")}function g3(e){HRe=e}function jI(e,t){return(Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0)??t}function ve(){return LEt[HRe]}var qP=(a=>(a.ProviderOutage="provider_outage",a.ProviderRateLimit="provider_rate_limit",a.ProviderUsageLimit="provider_usage_limit",a.ProviderAuthExpired="provider_auth_expired",a.Timeout="timeout",a.NoReport="no_report",a.RenderFailure="render_failure",a))(qP||{});(t=>{function e(r,n){switch(r){case"provider_outage":return{headline:ve().providerOutageHeadline(n.provider.name,n.maxRetries),action:ve().providerOutageActionStatusPage(n.provider.statusUrl)};case"provider_rate_limit":return{headline:ve().providerRateLimitHeadline(n.provider.name),action:ve().providerRateLimitAction};case"provider_usage_limit":return{headline:ve().providerUsageLimitHeadline(n.provider.name),action:ve().providerUsageLimitAction};case"provider_auth_expired":return{headline:ve().providerAuthExpiredHeadline(n.provider.name),action:ve().providerAuthExpiredAction};case"timeout":return{headline:ve().providerTimeoutHeadline(n.timeoutMinutes),action:ve().providerTimeoutAction};case"no_report":case"render_failure":return}}t.buildNotice=e})(qP||={});var GP=(r=>(r.SameBranch="same-branch",r.SeparateBranch="separate-branch",r))(GP||{});var zRe=(r=>(r.Sonnet="sonnet",r.Opus="opus",r))(zRe||{}),VRe="opus",UEt={sonnet:"claude-sonnet-5[1m]",opus:"claude-opus-5-5[1m]"},msr=UEt[VRe];function A3(e){return Object.values(zRe).includes(e)}function WRe(e){let t=(e??"").trim();if(t==="")return VRe;let r=t.toLowerCase();return A3(r)?r:t}var HP=(i=>(i.Low="low",i.Medium="medium",i.High="high",i.XHigh="xhigh",i.Max="max",i))(HP||{}),jP="high";function YRe(e){return Object.values(HP).includes(e)}var JRe=5;function $Et(e){let t=e.split(/\r?\n/).map(r=>r.trim()).filter(Boolean);if(t.length>JRe)throw new Error(`relatedRepoPaths supports at most ${JRe} entries (got ${t.length}); the cap limits how much cross-repo context is loaded to avoid overflowing Testbot's context window.`);return t}function qEt(e){let t=e.trim().toLowerCase();return t===""?"separate-branch":Object.values(GP).includes(t)?t:(Oe(`Invalid generatedTestsMode '${e}'. Falling back to 'separate-branch'.`),"separate-branch")}function GEt(e){let t=(e??"").trim();if(t!==""){if(/^(?:[1-9]|10)$/.test(t))return Number(t);Oe(`Ignoring perTestMaxFixAttempts="${e}": expected a whole number from 1 to 10; the Skyramp MCP default applies`)}}function HEt(e){let t=(e??"").trim().toLowerCase();return t===""?jP:YRe(t)?t:(Oe(`Ignoring effort="${e}": expected one of ${Object.values(HP).join(", ")}; using "${jP}"`),jP)}function KRe(){let e=WRe(qe("model"));return A3(e)||Oe(`model '${e}' is not a tested alias (sonnet, opus); passing it to the agent verbatim as a raw model id.`),{skyrampLicenseFile:qe("skyrampLicenseFile"),cursorApiKey:qe("cursorApiKey"),copilotApiKey:qe("copilotApiKey"),anthropicApiKey:qe("anthropicApiKey"),useBedrock:lu("useBedrock"),awsRegion:qe("awsRegion"),useLocalAuth:qe("useLocalAuth").toLowerCase()==="true",model:e,effort:HEt(qe("effort")),targetSetupCommand:qe("targetSetupCommand"),authTokenCommand:qe("authTokenCommand"),uiCredentials:qe("uiCredentials"),targetTeardownCommand:qe("targetTeardownCommand"),skipTargetTeardown:lu("skipTargetTeardown"),skyrampExecutorVersion:qe("skyrampExecutorVersion"),skyrampMcpVersion:qe("skyrampMcpVersion"),skyrampMcpSource:qe("skyrampMcpSource"),skyrampMcpGithubToken:qe("skyrampMcpGithubToken"),skyrampMcpGithubRef:qe("skyrampMcpGithubRef"),nodeVersion:qe("nodeVersion"),skipTargetSetup:lu("skipTargetSetup"),targetReadyCheckCommand:qe("targetReadyCheckCommand"),targetReadyCheckTimeout:(()=>{let r=parseInt(qe("targetReadyCheckTimeout"),10)||1800;return r<1?(Oe(`targetReadyCheckTimeout must be at least 1 second, got ${r}. Using 1s.`),1):r})(),targetReadyCheckInterval:(()=>{let r=parseInt(qe("targetReadyCheckInterval"),10),n=isNaN(r)?30:r;return n<1?(Oe(`targetReadyCheckInterval must be at least 1 second, got ${n}. Using 1s.`),1):n})(),targetReadyCheckDiagnosticsCommand:(()=>{let r=qe("targetReadyCheckDiagnosticsCommand");return r.trim().toLowerCase()==="none"?"":r})(),workingDirectory:qe("workingDirectory"),autoCommit:lu("autoCommit"),commitMessage:qe("commitMessage"),generatedTestsMode:qEt(qe("generatedTestsMode")),postPrComment:lu("postPrComment"),testExecutionTimeout:parseInt(qe("testExecutionTimeout"),10)||300,maxRecommendations:(()=>{let r=parseInt(qe("maxRecommendations"),10);return isNaN(r)?void 0:Math.max(0,r)})(),maxGenerate:(()=>{let r=parseInt(qe("maxGenerate"),10);return isNaN(r)?void 0:Math.max(0,r)})(),perTestMaxFixAttempts:GEt(qe("perTestMaxFixAttempts")),testbotMaxRetries:parseInt(qe("testbotMaxRetries"),10)||3,testbotRetryDelay:parseInt(qe("testbotRetryDelay"),10)||10,testbotTimeout:parseInt(qe("testbotTimeout"),10)||60,targetSetupRetries:parseInt(qe("targetSetupRetries"),10)||3,targetSetupRetryDelay:parseInt(qe("targetSetupRetryDelay"),10)||10,authTokenRetries:(()=>{let r=parseInt(qe("authTokenRetries"),10);return Number.isFinite(r)&&r>=1?r:6})(),authTokenRetryDelay:(()=>{let r=parseInt(qe("authTokenRetryDelay"),10);return Number.isFinite(r)&&r>=0?r:10})(),reportCollapsed:lu("reportCollapsed"),language:HI(qe("language")),enableDebug:lu("enableDebug"),testRepoPath:qe("testRepoPath")||void 0,relatedRepoPaths:$Et(qe("relatedRepoPaths")),allowedAuthors:qe("allowedAuthors").split(/\r?\n/).map(r=>r.trim()).filter(Boolean)}}var jEt={useBedrock:"false",skipTargetTeardown:"false",skyrampMcpSource:"npm",skyrampMcpGithubRef:"main",nodeVersion:"lts/*",skipTargetSetup:"false",targetReadyCheckTimeout:"1800",targetReadyCheckInterval:"30",targetReadyCheckDiagnosticsCommand:`docker ps -a --format 'table {{.Names}} {{.Status}} {{.Ports}}' && docker ps -a --format '{{.Names}}' | while read name; do [ -n "$name" ] && echo "--- logs $name (last 30) ---" && docker logs --tail 30 "$name"; done`,workingDirectory:".",autoCommit:"true",commitMessage:"Skyramp Testbot: test maintenance suggestions",generatedTestsMode:"separate-branch",pipeline:"classic",postPrComment:"true",testbotMaxRetries:"3",testbotRetryDelay:"10",testExecutionTimeout:"300",testbotTimeout:"60",targetSetupRetries:"3",targetSetupRetryDelay:"10",authTokenRetries:"6",authTokenRetryDelay:"10",reportCollapsed:"true",language:"en",enableDebug:"true",sutSetupMode:"none"};function XRe(e=process.env){for(let[t,r]of Object.entries(jEt)){let n=`INPUT_${t.replace(/ /g,"_").toUpperCase()}`;(e[n]??"").trim()===""&&(e[n]=r)}}ft();var $0e=j(require("path"));var hb=require("fs"),Ju=j(require("path"),1),jke=require("child_process"),zke=require("util");function zEt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Es={},zP={},Vp={},ZRe;function zI(){if(ZRe)return Vp;ZRe=1;function e(o){return typeof o>"u"||o===null}function t(o){return typeof o=="object"&&o!==null}function r(o){return Array.isArray(o)?o:e(o)?[]:[o]}function n(o,a){if(a){let c=Object.keys(a);for(let l=0,u=c.length;l<u;l+=1){let d=c[l];o[d]=a[d]}}return o}function s(o,a){let c="";for(let l=0;l<a;l+=1)c+=o;return c}function i(o){return o===0&&Number.NEGATIVE_INFINITY===1/o}return Vp.isNothing=e,Vp.isObject=t,Vp.toArray=r,Vp.repeat=s,Vp.isNegativeZero=i,Vp.extend=n,Vp}var y3,eke;function VI(){if(eke)return y3;eke=1;function e(r,n){let s="",i=r.reason||"(unknown reason)";return r.mark?(r.mark.name&&(s+='in "'+r.mark.name+'" '),s+="("+(r.mark.line+1)+":"+(r.mark.column+1)+")",!n&&r.mark.snippet&&(s+=`
148
148
 
149
149
  `+r.mark.snippet),i+" "+s):i}function t(r,n){Error.call(this),this.name="YAMLException",this.reason=r,this.mark=n,this.message=e(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}return t.prototype=Object.create(Error.prototype),t.prototype.constructor=t,t.prototype.toString=function(n){return this.name+": "+e(this,n)},y3=t,y3}var b3,tke;function VEt(){if(tke)return b3;tke=1;let e=zI();function t(s,i,o,a,c){let l="",u="",d=Math.floor(c/2)-1;return a-i>d&&(l=" ... ",i=a-d+l.length),o-a>d&&(u=" ...",o=a+d-u.length),{str:l+s.slice(i,o).replace(/\t/g,"\u2192")+u,pos:a-i+l.length}}function r(s,i){return e.repeat(" ",i-s.length)+s}function n(s,i){if(i=Object.create(i||null),!s.buffer)return null;i.maxLength||(i.maxLength=79),typeof i.indent!="number"&&(i.indent=1),typeof i.linesBefore!="number"&&(i.linesBefore=3),typeof i.linesAfter!="number"&&(i.linesAfter=2);let o=/\r?\n|\r|\0/g,a=[0],c=[],l,u=-1;for(;l=o.exec(s.buffer);)c.push(l.index),a.push(l.index+l[0].length),s.position<=l.index&&u<0&&(u=a.length-2);u<0&&(u=a.length-1);let d="",p=Math.min(s.line+i.linesAfter,c.length).toString().length,f=i.maxLength-(i.indent+p+3);for(let A=1;A<=i.linesBefore&&!(u-A<0);A++){let C=t(s.buffer,a[u-A],c[u-A],s.position-(a[u]-a[u-A]),f);d=e.repeat(" ",i.indent)+r((s.line-A+1).toString(),p)+" | "+C.str+`
150
150
  `+d}let h=t(s.buffer,a[u],c[u],s.position,f);d+=e.repeat(" ",i.indent)+r((s.line+1).toString(),p)+" | "+h.str+`
@@ -226,7 +226,7 @@ ${nTe(t)}}`}case"ZodArray":{let i=n.element;return`[ ${sv(i,t,r)}, \u2026 ]`}cas
226
226
  # Written by ${r}: the recorded command, which needed a shell to run.
227
227
  set -euo pipefail
228
228
  ${n}
229
- `,{mode:493})}catch{return}return`bash ${oo(t)}`}}function oo(e){return`'${e.split("'").join("'\\''")}'`}var mTe=require("child_process"),ua=j(require("fs")),vn=j(require("path"));var Lwt=vn.join(".skyramp","workspace.yml"),gTe=new Set(["playwright","cypress","selenium"]);function Xp(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function ao(e){let t=vn.join(e,Lwt);if(!ua.existsSync(t))return[];let r;try{r=El(ua.readFileSync(t,"utf-8"))}catch{return[]}let n=r?.services;if(!Array.isArray(n))return[];let s=[];for(let i of n){if(typeof i!="object"||i===null)continue;let o=i,a=o.api??{},c=Xp(o.serviceName);c&&s.push({serviceName:c,language:Xp(o.language),framework:Xp(o.framework),testDirectory:Xp(o.testDirectory),schemaPath:Xp(a.schemaPath),authType:Xp(a.authType),authHeader:Xp(a.authHeader),baseUrl:Xp(a.baseUrl)})}return s}function Rb(e){return e.filter(t=>!t.framework||!gTe.has(t.framework.toLowerCase()))}function ATe(e){return[...new Set(Rb(e).map(t=>t.testDirectory?.replace(/\/+$/,"")).filter(t=>!!t))]}function yTe(e){return[...new Set(e.filter(t=>iv(t.framework)).map(t=>t.testDirectory?.replace(/\/+$/,"")).filter(t=>!!t))]}function iv(e){return!!(e&&gTe.has(e.toLowerCase()))}var Uwt={golang:"go",py:"python",py3:"python",python3:"python",ts:"typescript",js:"javascript","c++":"cpp",cplusplus:"cpp",cxx:"cpp",node:"javascript",nodejs:"javascript",rb:"ruby",cs:"csharp","c#":"csharp"};function Ci(e){let t=e?.trim().toLowerCase();if(t)return Uwt[t]??t}var bTe={py:"python",go:"go",java:"java",kt:"kotlin",rb:"ruby",cs:"csharp",ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",mjs:"javascript",cjs:"javascript",kts:"kotlin",rs:"rust",php:"php",scala:"scala",swift:"swift",ex:"elixir",exs:"elixir",dart:"dart",c:"c",h:"c",cpp:"cpp",cc:"cpp",cxx:"cpp",hpp:"cpp",hh:"cpp",groovy:"groovy"},$wt=new Set(["feature"]);function ETe(e){let t=e.lastIndexOf(".");return t>=0&&$wt.has(e.slice(t+1).toLowerCase())}var qwt=new Set(Object.values(bTe));function wTe(e){let t=Ci(e);return t!==void 0&&qwt.has(t)}function Bm(e){let t=e.lastIndexOf(".");if(!(t<0))return bTe[e.slice(t+1).toLowerCase()]}function C4(e){return[...new Set(Rb(e).map(t=>Ci(t.language)).filter(t=>!!t))]}function kb(e,t=[]){let r=C4(ao(e));return r.length?r:[...new Set(t.map(n=>Ci(n)).filter(n=>!!n))]}function CTe(e,t,r=[]){let n=kb(e,r);if(n.length===0)return!0;let s=Ci(t);return s!==void 0&&n.includes(s)}var ov=(s=>(s.Python="python",s.Node="node",s.Jvm="jvm",s.Go="go",s))(ov||{}),Gwt={python:"python",typescript:"node",javascript:"node",java:"jvm",kotlin:"jvm",go:"go"};function wi(e){let t=Ci(e);return t?Gwt[t]:void 0}var STe={python:["pyproject.toml","requirements.txt","setup.py","setup.cfg","Pipfile"],node:["package.json"],jvm:["pom.xml","build.gradle","build.gradle.kts"],go:["go.mod"]},Hwt=new Set(["node_modules",".git",".venv","venv","dist","build","target","vendor",".skyramp","__pycache__"]),jwt=3;function zwt(e,t){let r=[],n=(s,i)=>{let o=vn.join(e,s);if(STe[t].some(c=>ua.existsSync(vn.join(o,c)))&&r.push(s),i>=jwt)return;let a;try{a=ua.readdirSync(o,{withFileTypes:!0})}catch{return}for(let c of a)c.isDirectory()&&!Hwt.has(c.name)&&!c.name.startsWith(".")&&n(s==="."?c.name:vn.join(s,c.name),i+1)};return n(".",0),r}function Vwt(e,t){return ua.existsSync(vn.join(e,t,"tsconfig.json"))?"typescript":"javascript"}function Wwt(e,t,r){let n=vn.normalize(t??".");for(;;){if(STe[r].some(s=>ua.existsSync(vn.join(e,n,s))))return n;if(n==="."||n===vn.sep||n==="")return".";n=vn.dirname(n)}}function Ywt(e,t){let r;try{r=ua.readdirSync(vn.join(e,t))}catch{return!1}if(r.some(n=>/^playwright\.config\.[cm]?[jt]s$/.test(n)||/^cypress\.config\.[cm]?[jt]s$/.test(n)))return!0;for(let n of["package.json","pyproject.toml","requirements.txt"])try{if(/playwright|cypress|selenium/i.test(ua.readFileSync(vn.join(e,t,n),"utf-8")))return!0}catch{}return!1}function Zp(e,t){let r=ao(e),n=t==="ui"?r.filter(o=>iv(o.framework)):Rb(r),s=[];for(let o of n){let a=Ci(o.language),c=wi(a);a&&s.push({language:a,dir:c?Wwt(e,o.testDirectory,c):"."})}if(s.length)return hTe(s);let i=[];for(let o of Object.values(ov))for(let a of zwt(e,o)){if(t==="ui"&&!Ywt(e,a))continue;let c=o==="node"?Vwt(e,a):o==="jvm"?"java":o;i.push({language:c,dir:a})}return hTe(i)}function hTe(e){let t=new Set;return e.filter(r=>{let n=`${r.language}::${r.dir}`;return t.has(n)?!1:(t.add(n),!0)})}var Jwt=/"(?:react|react-dom|vue|svelte|@sveltejs\/kit|@angular\/core|next|nuxt|solid-js|preact)"\s*:/,Kwt={python:"py",typescript:"ts",javascript:"js",java:"java",kotlin:"kt",go:"go",ruby:"rb",csharp:"cs",php:"php",rust:"rs"};function Xwt(e){let t=new Map(Object.entries(Kwt).map(([s,i])=>[i,s])),r=new Map,n;try{n=(0,mTe.execFileSync)("git",["-C",e,"ls-files","-z","--",...[...t.keys()].map(s=>`*.${s}`)],{encoding:"utf-8",maxBuffer:64*1024*1024}).split("\0").filter(Boolean)}catch{return r}for(let s of n){let i=t.get(vn.extname(s).slice(1));i&&r.set(i,(r.get(i)??0)+1)}return r}function ITe(e){let t=Rb(ao(e)).map(l=>Ci(l.language)).filter(l=>!!l);if(t.length)return t[0];let r=Zp(e,"backend"),n=l=>{try{return Jwt.test(ua.readFileSync(vn.join(e,l,"package.json"),"utf-8"))}catch{return!1}},s=r.filter(l=>!(wi(l.language)==="node"&&n(l.dir))),i=Xwt(e),o=l=>i.get(l)??0,a=[...i.keys()].filter(l=>!wi(l)).sort((l,u)=>o(u)-o(l))[0],c=[...new Set([...(s.length?s:r).map(l=>l.language),...a?[a]:[]])];return c.length<=1?c[0]:c.sort((l,u)=>o(u)-o(l))[0]}function wQ(e){try{return new URL(e).hostname.replace(/^\[|\]$/g,"").toLowerCase()||void 0}catch{return}}function S4(e){if(!e)return!1;let t=e.toLowerCase();return t==="localhost"||t.endsWith(".localhost")||t==="::1"||t==="0.0.0.0"||/^127(\.\d{1,3}){3}$/.test(t)}function I4(e){let t=new Set;for(let r of ao(e)){let n=r.baseUrl&&wQ(r.baseUrl);n&&t.add(n)}return t}function CQ(e,t,r=I4(t)){let n;try{n=new URL(e).protocol}catch{return!1}if(n!=="http:"&&n!=="https:")return!1;let s=wQ(e);return s?S4(s)||r.has(s):!1}var tc=(s=>(s.Clean="clean",s.RecipeDrift="recipe-drift",s.ChangeBrokeBringup="change-broke-bringup",s.BringupFailed="bringup-failed",s))(tc||{}),ef=g.string().trim().min(1),Zwt=g.object({url:g.string().optional().describe("the URL probed, if the check is an HTTP request"),command:g.string().optional().describe("the command run, if the check is a script \u2014 preferred when auth is needed"),headers:g.record(g.string()).optional(),status:g.union([g.number(),g.string()]).optional().describe("expected HTTP status for a url check (default 200)"),output:ef.describe("what the check returned, VERBATIM \u2014 the bytes, nothing appended; this gate RE-RUNS the check")}),av=g.object({schemaVersion:g.literal(1),baseUrls:g.record(g.string()).optional().describe("service \u2192 base URL of the running app; omit on a failed bring-up, never invent one"),health:Zwt.optional(),teardown:ef.describe("command that tears the SUT down"),dependencies:g.record(g.boolean()).optional().describe("EVERY backing service: true = really deployed, false = mocked; REQUIRED when the app came up"),outcome:g.nativeEnum(tc).describe("clean | recipe-drift (you corrected the recipe) | change-broke-bringup (the PR broke it) | bringup-failed (environment, not the PR)"),recipeFixes:g.array(g.string()).optional().describe("required when outcome is recipe-drift: what was corrected"),bringupError:g.object({command:ef,output:ef}).optional().describe("required when bring-up failed: the exact failing command and what it printed"),suspectFiles:g.array(g.string()).optional().describe("required for change-broke-bringup: files THIS PR changed that the failure points at, relative to your working directory (a file in another checkout of the run: its absolute path)"),seeded:g.boolean(),startedAt:ef.describe("ISO timestamp"),revisions:g.array(g.object({component:ef.describe("a shared component listed above"),url:ef.describe("the URL on the component's own origin (scheme, host and port) that answers with its deployed commit"),output:ef.describe("what the URL returned, VERBATIM; this gate FETCHES each url")})).optional().describe("only when shared components are listed above: one check per component whose deployed commit you found")});function v4(e){let t=[],r=s=>!!s&&typeof s=="object"&&!Array.isArray(s);return e.outcome!=="change-broke-bringup"&&e.outcome!=="bringup-failed"?(!r(e.baseUrls)||Object.keys(e.baseUrls).length===0?t.push("baseUrls must be a non-empty object of service \u2192 url"):Object.values(e.baseUrls).every(s=>typeof s=="string"&&s.trim())||t.push("every baseUrls value must be a non-empty url string"),r(e.health)?!(typeof e.health.url=="string"&&e.health.url.trim())&&!(typeof e.health.command=="string"&&e.health.command.trim())&&t.push("health must record a url or a command (what you actually ran)"):t.push("health must be an object"),(!r(e.dependencies)||Object.keys(e.dependencies).length===0)&&t.push("dependencies must be a non-empty object of name \u2192 boolean (real vs mocked) when the SUT came up \u2014 account for every backing service so a mocked one can't be hidden behind a green run")):(r(e.bringupError)||t.push(`outcome "${String(e.outcome)}" requires bringupError { command, output } \u2014 the exact failing bring-up command and what it printed`),e.outcome==="change-broke-bringup"&&!(Array.isArray(e.suspectFiles)&&e.suspectFiles.length>0&&e.suspectFiles.every(s=>typeof s=="string"&&s.trim()))&&t.push("change-broke-bringup requires non-empty suspectFiles[] \u2014 the changed file(s) the failure points at; if you cannot point at a file this PR changed, the outcome is bringup-failed (environment/harness), not the PR's fault")),e.outcome==="recipe-drift"&&!(Array.isArray(e.recipeFixes)&&e.recipeFixes.length>0)&&t.push("recipe-drift outcome requires a non-empty recipeFixes[] describing what was corrected"),t}var Tb=(r=>(r.Full="full",r.Static="static",r))(Tb||{}),da=(n=>(n.Contract="contract",n.Integration="integration",n.Ui="ui",n))(da||{}),cv=(i=>(i.OwnSurface="own_surface",i.StateReadBack="state_read_back",i.Referential="referential",i.Lifecycle="lifecycle",i.Boundaries="boundaries",i))(cv||{}),Nm=(s=>(s.Update="update",s.Regenerate="regenerate",s.Delete="delete",s.Verify="verify",s))(Nm||{}),lv=(l=>(l.Equals="equals",l.NotEquals="not_equals",l.GreaterThan="greater_than",l.LessThan="less_than",l.Contains="contains",l.NotContains="not_contains",l.Matches="matches",l.Absent="absent",l.Present="present",l))(lv||{}),SQ=["absent","present"],co=g.string().trim().min(1),eCt=g.object({subject:co.describe('what the test READS: a response field path, the literal "status", or the on-screen text for a ui case \u2014 the FINAL read in a multi-step case'),comparator:g.nativeEnum(lv),value:g.union([g.string(),g.number(),g.boolean(),g.null()]).optional().describe("the ONE value a broken build would not produce; OMIT for absent/present")}),tCt=g.object({test:co.describe("existing test path, relative to its repository"),repository:co.optional().describe("owner/repo the test lives in, when the run has several checkouts; omit for the working checkout"),action:g.nativeEnum(Nm),evidence:co.describe("why \u2014 drift vs the diff, or a finding"),covers_behaviors:g.array(g.string()).optional().describe("analyze behavior ids this maintenance covers")}),rCt=g.object({surface:co.describe("a surface from the list, copied verbatim"),axis:g.nativeEnum(cv)}),nCt=g.object({id:co.describe("short-slug, unique across generate[]"),type:g.nativeEnum(da),target:co.describe('"METHOD /path", or a business-flow name'),from_finding:g.string().optional().describe("analyze finding id this case catches"),from_behavior:g.string().optional().describe("analyze behavior id this case pins"),derived_from:rCt.optional().describe("the surface \xD7 axis this case pins when no analyze behavior or finding names it \u2014 one of the three is required"),rationale:co.describe("why this test matters"),expected_observable:co.describe("one sentence for a human: what a catching test asserts, and what a broken build does instead"),expected:eCt.describe("the same intent AS DATA \u2014 see the rules below"),seededPrecondition:co.optional().describe("seeded non-initial state + how to reach it; only when a seeded-state transition applies"),verifiable:g.boolean().describe("true only when a live SUT could confirm this test (full mode)")}),sCt=g.object({covered:g.array(g.string()).optional(),abstain:g.string().optional()}).superRefine((e,t)=>{let r=Array.isArray(e.covered),n=typeof e.abstain=="string";if(r===n)return void t.addIssue({code:g.ZodIssueCode.custom,message:"must have exactly one of covered[] or abstain"});r&&e.covered.length===0&&t.addIssue({code:g.ZodIssueCode.custom,path:["covered"],message:"must list at least one id (else abstain)"}),n&&!e.abstain.trim()&&t.addIssue({code:g.ZodIssueCode.custom,path:["abstain"],message:"must give a reason"})}).describe('{ "covered": [ids] } OR { "abstain": "reason" } \u2014 exactly one'),iCt=g.object({surface:co.describe("a surface from the list, copied verbatim"),axes:g.object(Object.fromEntries(Object.values(cv).map(e=>[e,sCt])))}),uv=g.object({schemaVersion:g.literal(1),mode:g.nativeEnum(Tb),maintenance:g.array(tCt),generate:g.array(nCt),surfaces:g.array(iCt).describe("one entry per changed surface in the list \u2014 none missing, none invented"),budget:g.object({total:g.number().describe("case count"),rationale:co}),summary:co.describe("one paragraph")});function IQ(e,t,r){let n=s=>{if(!s||!Array.isArray(s.covered))return s;let i=s.covered.filter(o=>!t.has(o));return i.length>0?{covered:i}:{abstain:`its only case(s) were ${r}: ${s.covered.join(", ")}`}};return e.map(s=>({...s,axes:Object.fromEntries(Object.entries(s.axes??{}).map(([i,o])=>[i,n(o)]))}))}function vTe(e){let t=[],r=new Set;if(Array.isArray(e.generate)&&e.generate.forEach((n,s)=>{let i=n?.id;typeof i=="string"&&(r.has(i)&&t.push(`generate[${s}].id "${i}" is duplicated`),r.add(i))}),Array.isArray(e.generate)&&e.generate.forEach((n,s)=>{let i=n;!i.from_finding&&!i.from_behavior&&!i.derived_from&&t.push(`generate[${s}] carries none of from_behavior, from_finding or derived_from \u2014 say what obligation it pins`)}),Array.isArray(e.surfaces)){let n=new Set;e.surfaces.forEach((s,i)=>{let o=s;if(typeof o.surface=="string"){let a=o.surface.trim().toLowerCase();n.has(a)&&t.push(`surfaces[${i}] "${o.surface}" is listed twice`),n.add(a)}for(let[a,c]of Object.entries(o.axes??{})){let l=c?.covered;if(Array.isArray(l))for(let u of l)(typeof u!="string"||!r.has(u))&&t.push(`surfaces[${i}].axes.${a}.covered references unknown generate id ${JSON.stringify(u)}`)}})}return t}var _m=(r=>(r.Ready="ready",r.Blocked="blocked",r))(_m||{}),zr=g.string().trim().min(1),oCt=g.object({action:g.enum(["start","run","wait"]),text:zr,source:g.enum(["file","notes","testbot"]).describe("file: a file in the repository; notes: the Target's notes; testbot: Testbot's own finding"),file:zr.nullable().describe("the file the step came from, relative to the component's repository; null unless source is file")}).strict().refine(e=>e.source==="file"==(e.file!==null),{path:["file"],message:"a file exactly when the step came from one"}),aCt=/^[A-Za-z_][A-Za-z0-9_]*$/,Bb=/^(?!GITHUB_)(?!SKYRAMP_RUNNER_)[A-Z][A-Z0-9_]{0,99}$/,Nb=(o=>(o.VersionEndpoint="version_endpoint",o.DeployWorkflow="deploy_workflow",o.KubernetesLabels="kubernetes_labels",o.Command="command",o.Api="api",o.NotTracked="not_tracked",o))(Nb||{}),Vn="shared",cCt=zr.refine(e=>{try{let t=new URL(e);return["http:","https:"].includes(t.protocol)&&!t.username&&!t.password}catch{return!1}},"an http(s) URL with no login in it"),_b=g.object({address:cCt,readyWhen:zr.nullable(),credentials:g.array(g.string().regex(Bb)).max(50),revisionSources:g.array(g.object({method:g.nativeEnum(Nb),detail:zr.describe("what Testbot reads, such as GET /version or the deploy workflow's name; for not_tracked, why nothing shows it"),components:g.array(zr).min(1).describe("the components it tells the revision of, by name")}).strict()).max(50)}).strict(),x4={steps:g.array(oCt).max(20).optional().describe("how it starts, in order"),kind:g.enum(["web_app","service","database","external_service"]).optional(),from:g.object({file:zr,service:zr.nullable()}).strict().optional(),credentials:g.array(g.string().max(100).regex(aCt)).max(50).optional().describe("the Target's credentials this component's recipe uses: a sign-in (a test user, password or token) or an API key, which the workflow supplies from a GitHub Actions secret as the environment variable of the credential's name; give each name exactly as the recipe reads it. Names only, never a value, and not a secret the recipe generates itself")},lCt=g.object({name:zr,repository:zr.describe("owner/repo of the Target repository the component is built or started from, such as the one whose compose file starts its database"),healthy:g.boolean(),...x4,deployed:zr.nullable().optional().describe('only with "environment": the revision the component runs, as you read it from its revision source, or null when you could not tell')}),uCt=g.object({component:zr,problem:zr,evidence:zr.describe("the exact command and output that shows it"),fix:zr.describe("what the user must provide, and where")}),dCt=g.object({framework:zr,file:zr.describe("the test file run, relative to its repository root"),result:g.enum(["pass","fail","error"])}),pCt=g.object({input:zr.describe("the part of the user's SUT input, as given"),reason:zr}),dv=g.object({schemaVersion:g.literal(1),status:g.nativeEnum(_m).describe("ready only if every component came up healthy and the recipe is written"),components:g.array(lCt),suites:g.array(dCt).default([]).describe("one run per test suite the Target's repositories have; empty when they have none"),inputsUsed:g.array(zr).default([]).describe("the parts of the user's SUT input the recipe used"),inputsUsedHow:g.array(g.object({input:zr.describe("exactly as written in inputsUsed; an entry that is not there is left out"),how:zr.describe("what the recipe did with it")})).optional(),inputsNotUsed:g.array(pCt).default([]).describe("the parts it did not use, and why"),blockers:g.array(uCt).describe("required (non-empty) when status is blocked"),environment:_b.optional().describe("only when the whole SUT is an existing deployment you tested where it runs, building and starting nothing: its address, what says it is ready, the credentials that reach it, and how to read what each component runs. Leave it out when any part was built or started on the runner, or reaching it needed something there (a tunnel, port-forward, proxy or client certificate)")});function R4(e){let t=fCt(e);if(t.length>0)return t;if(e.status==="blocked"&&!(Array.isArray(e.blockers)&&e.blockers.length>0))return['status "blocked" requires at least one blocker { component, problem, evidence, fix } \u2014 say what stopped the bring-up'];if(e.status==="ready"){let r=Array.isArray(e.components)?e.components:[];if(r.length===0)return['status "ready" requires at least one component \u2014 name each component the recipe brought up healthy'];let n=r.filter(s=>s?.healthy!==!0).map(s=>String(s?.name??"?"));if(n.length>0)return[`status "ready" requires every component healthy; not healthy: ${n.join(", ")} \u2014 answer "blocked" with a blocker for each, or bring them up and answer "ready" again`]}return[]}function fCt(e){let t=Array.isArray(e.components)?e.components:[],r=e.environment;if(!r){let a=t.filter(c=>c?.deployed!==void 0||c?.repository===Vn).map(c=>String(c?.name??"?"));return a.length>0?[`"deployed" and a "${Vn}" repository belong only to an answer with "environment"; remove them from: ${a.join(", ")}`]:[]}let n=[],s=t.filter(a=>a?.deployed===void 0).map(a=>String(a?.name??"?"));s.length>0&&n.push(`with "environment", every component says what it runs in "deployed" (null when you could not tell); missing for: ${s.join(", ")}`);let i=new Set(t.map(a=>a?.name)),o=(r.revisionSources??[]).flatMap(a=>a?.components??[]).filter(a=>!i.has(a));return o.length>0&&n.push(`each revision source names components of this answer; not one of them: ${o.map(String).join(", ")}`),n}var Pm=64*1024,Qm=512*1024,vQ=/[\u0000-\u0008\u000b\u000e-\u001f\u007f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;var Pb=".skyramp/sut/deployed-revisions.sh",k4=(r=>(r.Running="running",r.Requested="requested",r))(k4||{});var Bor=new Set(Object.values(k4));var hCt=/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/,xTe=e=>hCt.test(e);function xQ(e){return e?.find(t=>t.path===Pb)}var Nor=`Fix ${Pb} so it prints the full commit each component runs, then set it up again.`;function T4(e,t){let r=new Set(t.filter(s=>s.method!=="not_tracked").flatMap(s=>s.components)),n=new Set(t.filter(s=>s.method==="not_tracked").flatMap(s=>s.components));return e.filter(s=>r.has(s.name)||!n.has(s.name))}var Ys="shared-environment",gCt=1e4,RTe=5,TTe=64*1024,_4=300,ACt=200,yCt=/\b[0-9a-fA-F]{7,64}\b/g,bCt=/\bsha256:[0-9a-fA-F]{64}\b/g,ECt=/\b(commit|sha|revision|rev|hash)\b/i,wCt=(e,t)=>new RegExp(`(?<![A-Za-z0-9])(commit|sha|revision|rev|hash)["']?\\s*[:=]?\\s*["']?${t}(?![0-9A-Za-z])`,"i").test(e),Qb=e=>e.slice(0,_4),pv=e=>Qb(e.trim())||"(empty response)";function kTe(e,t){let r=e.split(/\r?\n/).find(s=>s.toLowerCase().includes(t)).trim(),n=r.toLowerCase().indexOf(t);return r.length<=_4?r:r.slice(Math.max(0,n-100),Math.max(0,n-100)+_4)}function fv(e,t){if("error"in t)return{status:"unverifiable",observedRevision:null,evidence:pv(t.error)};let r=e.toLowerCase(),n=l=>ECt.test(kTe(t.body,l)),s=l=>r?r.startsWith(l)&&n(l):wCt(t.body,l),i=(t.body.replace(bCt," ").match(yCt)??[]).map(l=>l.toLowerCase()).filter(l=>/[a-f]/.test(l)||s(l)),o=[...new Set(i)].filter((l,u,d)=>!d.some(p=>p!==l&&p.startsWith(l)));if(o.length>1)return{status:"unverifiable",observedRevision:null,evidence:pv(`The answer names more than one revision: ${o.join(", ")}`)};let[a]=o;return a?{status:r.startsWith(a)?"verified":"mismatch",observedRevision:a,evidence:kTe(t.body,a)}:{status:"unverifiable",observedRevision:null,evidence:pv(t.body)}}async function CCt(e){if(!e.body)return"";let t=e.body.getReader(),r=[],n=0;for(;;){let{done:s,value:i}=await t.read();if(s)return Buffer.concat(r).toString("utf-8");if(n+=i.byteLength,n>TTe){await t.cancel();return}r.push(i)}}async function hv(e,t=fetch){try{let r=AbortSignal.timeout(gCt),n=new URL(e).origin,s=new URL(e);for(let i=0;;i+=1){let o=await t(s,{redirect:"manual",signal:r}),a=o.status>=300&&o.status<400?o.headers.get("location"):null;if(a){let l=new URL(a,s);if(l.origin!==n)return{error:`${e} redirects to another origin (${l.origin})`};if(i>=RTe)return{error:`${e} redirects more than ${RTe} times`};s=l;continue}let c=await CCt(o);return c===void 0?{error:`${e} answered more than ${TTe/1024} KiB`}:o.ok?{body:c}:{error:`${e} answered ${o.status}: ${c.trim()}`}}}catch(r){let n=r instanceof Error&&r.cause instanceof Error?`: ${r.cause.message}`:"";return{error:`${e} could not be read: ${r instanceof Error?r.message:String(r)}${n}`}}}var qor=new Set(["version_endpoint","api"]);function Db(e){return(e?.components??[]).filter(t=>!!t.repository&&!!t.expectedRevision)}function RQ(e){return Db(e.sharedEnvironment).filter(t=>!t.revisionUrl&&!t.revisionScript)}async function SCt(e,t,r=[]){let{name:n,url:s}=e;if(!e.versionUrl)return{name:n,url:s,version:null,evidence:"No version URL is configured."};let i=gr(await hv(e.versionUrl,t),r);if("error"in i)return{name:n,url:s,version:null,evidence:pv(i.error)};let o=i.body.split(/\r?\n/).map(a=>a.trim()).find(Boolean);return{name:n,url:s,version:o?o.slice(0,ACt):null,evidence:pv(o??"")}}var P4=(e,t)=>!!e&&!!t&&e.toLowerCase()===t.toLowerCase(),BTe=(e,t)=>e.name===t.name&&P4(e.repository,t.repository);async function ICt(e,t,r){let{frozen:n,mergeCommit:s,mergedHead:i}=t;return!s||!i?"not_contained":i.toLowerCase()===n.toLowerCase()?"contained":r?.commitContains?r.commitContains({repository:e,ancestor:n,descendant:i}):"unknown"}async function B4(e,t,r){let n=t.observedRevision;if(t.status!=="mismatch"||!n||!e.acceptedRevisions)return t;let{frozen:s,mergeCommit:i,mergedHead:o}=e.acceptedRevisions,a=await ICt(e.repository,e.acceptedRevisions,r),c=[s,...i&&a==="contained"?[i]:[]],l=f=>`${f===s?"the frozen revision":"the merge commit"} ${jn(f)}`,u=(f,h)=>({status:f,observedRevision:n,evidence:Qb(`${h} (${t.evidence})`)}),d=c.find(f=>f.toLowerCase().startsWith(n));if(d)return u("verified",`observed ${jn(n)} is ${l(d)}`);if(!r?.commitContains)return u("unverifiable",`could not tell whether observed ${jn(n)} contains ${c.map(jn).join(" or ")}: this run cannot compare commits`);let p=[];for(let f of c){let h=await r.commitContains({repository:e.repository,ancestor:f,descendant:n});if(h==="contained")return u("verified",`observed ${jn(n)} contains ${l(f)}`);h==="unknown"&&p.push(f)}return p.length?u("unverifiable",`could not tell whether observed ${jn(n)} contains ${p.map(jn).join(" or ")}: GitHub did not answer the compare`):a==="unknown"&&o?u("unverifiable",`could not tell whether the merged head ${jn(o)} contains ${jn(s)}: GitHub did not answer the compare`):u("mismatch",`observed ${jn(n)} does not contain ${c.map(jn).join(" or ")}`)}function NTe(e,t){let r=(i,o=null)=>({status:"unverifiable",observedRevision:o,evidence:Qb(i)});if(!t)return r("Not checked: this run cannot run deployed-revisions.sh.");if(!t.ok)return r(t.error);let n=t.revisions[e.name];return n?xTe(n.revision)?n.state==="requested"?r(`deployed-revisions.sh reports only the requested state for ${e.name} (${n.revision}), which alone does not show what runs.`,n.revision):{status:e.expectedRevision.toLowerCase().startsWith(n.revision)?"verified":"mismatch",observedRevision:n.revision,evidence:Qb(`deployed-revisions.sh: ${e.name} runs ${n.revision}`)}:r(`deployed-revisions.sh printed ${n.revision} for ${e.name}, which is not a full commit.`):r(`deployed-revisions.sh printed no revision for ${e.name}.`)}async function kQ(e,t,r,n=[],s,i){let o=(c,l)=>fv(c,gr(l,n));return{components:await Promise.all(Db(e).map(async c=>{let l={name:c.name,repository:c.repository,url:c.url,expectedRevision:c.expectedRevision};if(c.revisionScript)return{...l,source:"probe",...await B4(c,NTe(c,i),s)};if(c.revisionUrl)return{...l,source:"probe",...await B4(c,o(c.expectedRevision,await hv(c.revisionUrl,r)),s)};let u=t.find(p=>p.component===c.name),d=o(c.expectedRevision,u?{body:u.output}:{error:"Deploy cited no check of its deployed revision."});return{...l,source:"agent",...await B4(c,d,s)}})),dependencies:await Promise.all(e.dependencies.map(c=>SCt(c,r,n)))}}async function vCt(e,t,r,n){if(e.revisionScript){let o=NTe(e,n);return{failed:!n?.ok,now:o,noCommit:o.status==="unverifiable"}}let s=gr(await hv(e.revisionUrl,t),r),i=fv(e.expectedRevision,s);return{failed:"error"in s,now:i,noCommit:!i.observedRevision}}async function xCt(e,t,r,n=[],s){let i=await Promise.all(t.components.map(async o=>{let a=e.components.find(p=>BTe(p,o)),c=o.observedRevision?.toLowerCase();if(!c||!(a?.revisionUrl||a?.revisionScript))return o;let{failed:l,now:u,noCommit:d}=await vCt({...a,expectedRevision:o.expectedRevision},r,n,s);if(d){let p=l?"second read failed":"second read names no one commit",f=`first read ${jn(o.observedRevision??c)}; ${p}: ${u.evidence}`;return{...o,status:"unverifiable",observedRevision:null,evidence:Qb(f)}}return u.observedRevision.startsWith(c)||c.startsWith(u.observedRevision)?o:{...o,status:"unverifiable",observedRevision:u.observedRevision,evidence:Qb(`changed from ${o.observedRevision} to ${u.observedRevision} during the run`)}}));return{...t,components:i}}async function Q4(e,t){return t.components.some(r=>r.revisionScript)?e.deployedRevisions?.():void 0}async function _Te(e,t){let r=e.inputs.sharedEnvironment,n=ee(e,`${Ys}.json`);if(!e.inputs.appRunning||!r||!n)return;let s=await xCt(r,n,t,e.secretValues??[],await Q4(e,r));ot(e,Ys,gr(s,e.secretValues??[]),[])}function mv(e){return Db(e).length>0||(e?.dependencies.length??0)>0}function D4(e){let t=e.inputs?.sharedEnvironment;if(!mv(t))return;let r=ee(e,`${Ys}.json`);if(r)return{components:QTe(t,r.components),dependencies:r.dependencies};let n="Not checked: deploy did not complete.";return{components:Db(t).map(s=>PTe(s,n)),dependencies:t.dependencies.map(s=>({name:s.name,url:s.url,version:null,evidence:n}))}}function TQ(e){return e?.components.length?[`Testbot read which commit each component runs, before this session: ${e.components.map(r=>{let n=r.observedRevision?`${r.name} runs ${jn(r.observedRevision)}`:`${r.name} answered no commit`,s=r.status==="verified"?"verified":"not proven to run the change";return`${n}, ${s} (${r.evidence})`}).join("; ")}.`,"Which commit is deployed is Testbot's to check, not yours: record no gap, finding, issue or next step about it, and don't compare the deployed commit with your checkout."].join(" "):void 0}var PTe=(e,t)=>({name:e.name,repository:e.repository,url:e.url,expectedRevision:e.expectedRevision,observedRevision:null,status:"unverifiable",source:e.revisionUrl||e.revisionScript?"probe":"agent",evidence:t});function QTe(e,t){let r=new Set(t.map(s=>s.name.toLowerCase())),n=Db(e).filter(s=>s.touched&&!r.has(s.name.toLowerCase()));return[...t,...n.map(s=>PTe(s,"Not checked: the run recorded no read of it."))]}function Ob(e){return(D4(e)?.components??[]).filter(t=>t.status!=="verified")}function O4(e,t,r){if(!e.appRunning||r===!1)return[];let n=(e.sharedEnvironment?.components??[]).filter(s=>s.touched);return QTe(e.sharedEnvironment,t?.components??[]).filter(s=>s.status!=="verified"&&n.some(i=>BTe(i,s)))}function DTe(e){let t=r=>{let n=r.observedRevision?`runs ${jn(r.observedRevision)}`:"no revision could be read";return`${r.name} (${r.repository}) must run ${jn(r.expectedRevision)}, but ${n}: ${r.evidence}`};return e.length?`the Test Environment does not verifiably run the change: ${e.map(t).join("; ")}`:void 0}function BQ(e){return(e?.components??[]).filter(t=>!!t.repository&&!t.expectedRevision)}function OTe(e,t=!1){return`${e.name}: ${e.repository} is not one of the run's sources, so its revision cannot be verified and ${MTe(t)}`}var MTe=e=>e?"runtime tests against it do not validate this change":"no runtime test ran against it";function FTe(e,t=!1){let r=jn(e.expectedRevision),n=e.status==="mismatch"?`the shared environment runs ${e.repository} at ${e.observedRevision}, not ${r}`:`could not verify that the shared environment runs ${e.repository} at ${r}`;return`${e.name}: ${n}, so ${MTe(t)}`}var RCt=/^\s*(POST|PUT|PATCH|DELETE)\s/i,N4=e=>e.mutates===!0;function Dm(e){return(e?.components??[]).filter(t=>!!t.repository)}function lo(e){let t=e.sharedEnvironment;return!!t&&Dm(t).length>0&&!t.allowMutation&&!e.planOnly}function kCt(e){let t=n=>RCt.test(n.target)||N4(n),r=[...e.generate.filter(t).map(n=>({id:n.id,target:n.target})),...e.maintenance.filter(N4).map(n=>({id:n.test}))];return{...e,generate:e.generate.filter(n=>!t(n)),surfaces:IQ(e.surfaces,new Set(r.map(n=>n.id)),"withheld because they change a shared environment the policy protects"),maintenance:e.maintenance.filter(n=>!N4(n)),withheld:r}}function Mb(e,t){return t&&lo(e)?kCt(t):t}function NQ(e){return ee(e,"recommend.json")?.withheld??[]}function LTe(e){return`${e.id}${e.target?` (${e.target})`:""}: needs a shared-environment mutation the policy does not allow`}var TCt=40,jTe="health.command cannot be re-executed: ",UTe=4e3,BCt=9e4,NCt=5e3;function _Ct(e,t){let r=e.slice(0,UTe),n=t.slice(0,UTe);if(!r||!n)return"";let s=new Uint32Array(n.length+1),i=new Uint32Array(n.length+1),o=0,a=0;for(let c=1;c<=r.length;c++){for(let u=1;u<=n.length;u++){if(r[c-1]!==n[u-1]){i[u]=0;continue}i[u]=s[u-1]+1,i[u]>o&&(o=i[u],a=c)}let l=s;s=i,i=l}return r.slice(a-o,a)}function $Te(e){let t=e.search(/[[{]/);if(t<0)return;let r=e[t],n=r==="{"?"}":"]",s=0,i=!1,o=!1;for(let a=t;a<e.length;a++){let c=e[a];if(i){o?o=!1:c==="\\"?o=!0:c==='"'&&(i=!1);continue}if(c==='"')i=!0;else if(c===r)s++;else if(c===n&&--s===0)try{return JSON.parse(e.slice(t,a+1))}catch{return}}}function _Q(e,t=0){return t>4?"\u2026":e===null?"null":Array.isArray(e)?e.length===0?"[]":`[${[...new Set(e.map(r=>_Q(r,t+1)))].sort().join("|")}]`:typeof e=="object"?`{${Object.keys(e).sort().map(r=>`${r}:${_Q(e[r],t+1)}`).join(",")}}`:typeof e}function qTe(e,t){let r=$Te(e),n=$Te(t);if(r!==void 0&&n!==void 0){let a=_Q(r),c=_Q(n);return a===c?{ok:!0}:{ok:!1,why:`it answered ${c.slice(0,200)}, but the recorded check answered ${a.slice(0,200)}`}}let s=e.split(`
229
+ `,{mode:493})}catch{return}return`bash ${oo(t)}`}}function oo(e){return`'${e.split("'").join("'\\''")}'`}var mTe=require("child_process"),ua=j(require("fs")),vn=j(require("path"));var Lwt=vn.join(".skyramp","workspace.yml"),gTe=new Set(["playwright","cypress","selenium"]);function Xp(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function ao(e){let t=vn.join(e,Lwt);if(!ua.existsSync(t))return[];let r;try{r=El(ua.readFileSync(t,"utf-8"))}catch{return[]}let n=r?.services;if(!Array.isArray(n))return[];let s=[];for(let i of n){if(typeof i!="object"||i===null)continue;let o=i,a=o.api??{},c=Xp(o.serviceName);c&&s.push({serviceName:c,language:Xp(o.language),framework:Xp(o.framework),testDirectory:Xp(o.testDirectory),schemaPath:Xp(a.schemaPath),authType:Xp(a.authType),authHeader:Xp(a.authHeader),baseUrl:Xp(a.baseUrl)})}return s}function Rb(e){return e.filter(t=>!t.framework||!gTe.has(t.framework.toLowerCase()))}function ATe(e){return[...new Set(Rb(e).map(t=>t.testDirectory?.replace(/\/+$/,"")).filter(t=>!!t))]}function yTe(e){return[...new Set(e.filter(t=>iv(t.framework)).map(t=>t.testDirectory?.replace(/\/+$/,"")).filter(t=>!!t))]}function iv(e){return!!(e&&gTe.has(e.toLowerCase()))}var Uwt={golang:"go",py:"python",py3:"python",python3:"python",ts:"typescript",js:"javascript","c++":"cpp",cplusplus:"cpp",cxx:"cpp",node:"javascript",nodejs:"javascript",rb:"ruby",cs:"csharp","c#":"csharp"};function Ci(e){let t=e?.trim().toLowerCase();if(t)return Uwt[t]??t}var bTe={py:"python",go:"go",java:"java",kt:"kotlin",rb:"ruby",cs:"csharp",ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",mjs:"javascript",cjs:"javascript",kts:"kotlin",rs:"rust",php:"php",scala:"scala",swift:"swift",ex:"elixir",exs:"elixir",dart:"dart",c:"c",h:"c",cpp:"cpp",cc:"cpp",cxx:"cpp",hpp:"cpp",hh:"cpp",groovy:"groovy"},$wt=new Set(["feature"]);function ETe(e){let t=e.lastIndexOf(".");return t>=0&&$wt.has(e.slice(t+1).toLowerCase())}var qwt=new Set(Object.values(bTe));function wTe(e){let t=Ci(e);return t!==void 0&&qwt.has(t)}function Bm(e){let t=e.lastIndexOf(".");if(!(t<0))return bTe[e.slice(t+1).toLowerCase()]}function C4(e){return[...new Set(Rb(e).map(t=>Ci(t.language)).filter(t=>!!t))]}function kb(e,t=[]){let r=C4(ao(e));return r.length?r:[...new Set(t.map(n=>Ci(n)).filter(n=>!!n))]}function CTe(e,t,r=[]){let n=kb(e,r);if(n.length===0)return!0;let s=Ci(t);return s!==void 0&&n.includes(s)}var ov=(s=>(s.Python="python",s.Node="node",s.Jvm="jvm",s.Go="go",s))(ov||{}),Gwt={python:"python",typescript:"node",javascript:"node",java:"jvm",kotlin:"jvm",go:"go"};function wi(e){let t=Ci(e);return t?Gwt[t]:void 0}var STe={python:["pyproject.toml","requirements.txt","setup.py","setup.cfg","Pipfile"],node:["package.json"],jvm:["pom.xml","build.gradle","build.gradle.kts"],go:["go.mod"]},Hwt=new Set(["node_modules",".git",".venv","venv","dist","build","target","vendor",".skyramp","__pycache__"]),jwt=3;function zwt(e,t){let r=[],n=(s,i)=>{let o=vn.join(e,s);if(STe[t].some(c=>ua.existsSync(vn.join(o,c)))&&r.push(s),i>=jwt)return;let a;try{a=ua.readdirSync(o,{withFileTypes:!0})}catch{return}for(let c of a)c.isDirectory()&&!Hwt.has(c.name)&&!c.name.startsWith(".")&&n(s==="."?c.name:vn.join(s,c.name),i+1)};return n(".",0),r}function Vwt(e,t){return ua.existsSync(vn.join(e,t,"tsconfig.json"))?"typescript":"javascript"}function Wwt(e,t,r){let n=vn.normalize(t??".");for(;;){if(STe[r].some(s=>ua.existsSync(vn.join(e,n,s))))return n;if(n==="."||n===vn.sep||n==="")return".";n=vn.dirname(n)}}function Ywt(e,t){let r;try{r=ua.readdirSync(vn.join(e,t))}catch{return!1}if(r.some(n=>/^playwright\.config\.[cm]?[jt]s$/.test(n)||/^cypress\.config\.[cm]?[jt]s$/.test(n)))return!0;for(let n of["package.json","pyproject.toml","requirements.txt"])try{if(/playwright|cypress|selenium/i.test(ua.readFileSync(vn.join(e,t,n),"utf-8")))return!0}catch{}return!1}function Zp(e,t){let r=ao(e),n=t==="ui"?r.filter(o=>iv(o.framework)):Rb(r),s=[];for(let o of n){let a=Ci(o.language),c=wi(a);a&&s.push({language:a,dir:c?Wwt(e,o.testDirectory,c):"."})}if(s.length)return hTe(s);let i=[];for(let o of Object.values(ov))for(let a of zwt(e,o)){if(t==="ui"&&!Ywt(e,a))continue;let c=o==="node"?Vwt(e,a):o==="jvm"?"java":o;i.push({language:c,dir:a})}return hTe(i)}function hTe(e){let t=new Set;return e.filter(r=>{let n=`${r.language}::${r.dir}`;return t.has(n)?!1:(t.add(n),!0)})}var Jwt=/"(?:react|react-dom|vue|svelte|@sveltejs\/kit|@angular\/core|next|nuxt|solid-js|preact)"\s*:/,Kwt={python:"py",typescript:"ts",javascript:"js",java:"java",kotlin:"kt",go:"go",ruby:"rb",csharp:"cs",php:"php",rust:"rs"};function Xwt(e){let t=new Map(Object.entries(Kwt).map(([s,i])=>[i,s])),r=new Map,n;try{n=(0,mTe.execFileSync)("git",["-C",e,"ls-files","-z","--",...[...t.keys()].map(s=>`*.${s}`)],{encoding:"utf-8",maxBuffer:64*1024*1024}).split("\0").filter(Boolean)}catch{return r}for(let s of n){let i=t.get(vn.extname(s).slice(1));i&&r.set(i,(r.get(i)??0)+1)}return r}function ITe(e){let t=Rb(ao(e)).map(l=>Ci(l.language)).filter(l=>!!l);if(t.length)return t[0];let r=Zp(e,"backend"),n=l=>{try{return Jwt.test(ua.readFileSync(vn.join(e,l,"package.json"),"utf-8"))}catch{return!1}},s=r.filter(l=>!(wi(l.language)==="node"&&n(l.dir))),i=Xwt(e),o=l=>i.get(l)??0,a=[...i.keys()].filter(l=>!wi(l)).sort((l,u)=>o(u)-o(l))[0],c=[...new Set([...(s.length?s:r).map(l=>l.language),...a?[a]:[]])];return c.length<=1?c[0]:c.sort((l,u)=>o(u)-o(l))[0]}function wQ(e){try{return new URL(e).hostname.replace(/^\[|\]$/g,"").toLowerCase()||void 0}catch{return}}function S4(e){if(!e)return!1;let t=e.toLowerCase();return t==="localhost"||t.endsWith(".localhost")||t==="::1"||t==="0.0.0.0"||/^127(\.\d{1,3}){3}$/.test(t)}function I4(e){let t=new Set;for(let r of ao(e)){let n=r.baseUrl&&wQ(r.baseUrl);n&&t.add(n)}return t}function CQ(e,t,r=I4(t)){let n;try{n=new URL(e).protocol}catch{return!1}if(n!=="http:"&&n!=="https:")return!1;let s=wQ(e);return s?S4(s)||r.has(s):!1}var tc=(s=>(s.Clean="clean",s.RecipeDrift="recipe-drift",s.ChangeBrokeBringup="change-broke-bringup",s.BringupFailed="bringup-failed",s))(tc||{}),ef=g.string().trim().min(1),Zwt=g.object({url:g.string().optional().describe("the URL probed, if the check is an HTTP request"),command:g.string().optional().describe("the command run, if the check is a script \u2014 preferred when auth is needed"),headers:g.record(g.string()).optional(),status:g.union([g.number(),g.string()]).optional().describe("expected HTTP status for a url check (default 200)"),output:ef.describe("what the check returned, VERBATIM \u2014 the bytes, nothing appended; this gate RE-RUNS the check")}),av=g.object({schemaVersion:g.literal(1),baseUrls:g.record(g.string()).optional().describe("service \u2192 base URL of the running app; omit on a failed bring-up, never invent one"),health:Zwt.optional(),teardown:ef.describe("command that tears the SUT down"),dependencies:g.record(g.boolean()).optional().describe("EVERY backing service: true = really deployed, false = mocked; REQUIRED when the app came up"),outcome:g.nativeEnum(tc).describe("clean | recipe-drift (you corrected the recipe) | change-broke-bringup (the PR broke it) | bringup-failed (environment, not the PR)"),recipeFixes:g.array(g.string()).optional().describe("required when outcome is recipe-drift: what was corrected"),bringupError:g.object({command:ef,output:ef}).optional().describe("required when bring-up failed: the exact failing command and what it printed"),suspectFiles:g.array(g.string()).optional().describe("required for change-broke-bringup: files THIS PR changed that the failure points at, relative to your working directory (a file in another checkout of the run: its absolute path)"),seeded:g.boolean(),startedAt:ef.describe("ISO timestamp"),revisions:g.array(g.object({component:ef.describe("a shared component listed above"),url:ef.describe("the URL on the component's own origin (scheme, host and port) that answers with its deployed commit"),output:ef.describe("what the URL returned, VERBATIM; this gate FETCHES each url")})).optional().describe("only when shared components are listed above: one check per component whose deployed commit you found")});function v4(e){let t=[],r=s=>!!s&&typeof s=="object"&&!Array.isArray(s);return e.outcome!=="change-broke-bringup"&&e.outcome!=="bringup-failed"?(!r(e.baseUrls)||Object.keys(e.baseUrls).length===0?t.push("baseUrls must be a non-empty object of service \u2192 url"):Object.values(e.baseUrls).every(s=>typeof s=="string"&&s.trim())||t.push("every baseUrls value must be a non-empty url string"),r(e.health)?!(typeof e.health.url=="string"&&e.health.url.trim())&&!(typeof e.health.command=="string"&&e.health.command.trim())&&t.push("health must record a url or a command (what you actually ran)"):t.push("health must be an object"),(!r(e.dependencies)||Object.keys(e.dependencies).length===0)&&t.push("dependencies must be a non-empty object of name \u2192 boolean (real vs mocked) when the SUT came up \u2014 account for every backing service so a mocked one can't be hidden behind a green run")):(r(e.bringupError)||t.push(`outcome "${String(e.outcome)}" requires bringupError { command, output } \u2014 the exact failing bring-up command and what it printed`),e.outcome==="change-broke-bringup"&&!(Array.isArray(e.suspectFiles)&&e.suspectFiles.length>0&&e.suspectFiles.every(s=>typeof s=="string"&&s.trim()))&&t.push("change-broke-bringup requires non-empty suspectFiles[] \u2014 the changed file(s) the failure points at; if you cannot point at a file this PR changed, the outcome is bringup-failed (environment/harness), not the PR's fault")),e.outcome==="recipe-drift"&&!(Array.isArray(e.recipeFixes)&&e.recipeFixes.length>0)&&t.push("recipe-drift outcome requires a non-empty recipeFixes[] describing what was corrected"),t}var Tb=(r=>(r.Full="full",r.Static="static",r))(Tb||{}),da=(n=>(n.Contract="contract",n.Integration="integration",n.Ui="ui",n))(da||{}),cv=(i=>(i.OwnSurface="own_surface",i.StateReadBack="state_read_back",i.Referential="referential",i.Lifecycle="lifecycle",i.Boundaries="boundaries",i))(cv||{}),Nm=(s=>(s.Update="update",s.Regenerate="regenerate",s.Delete="delete",s.Verify="verify",s))(Nm||{}),lv=(l=>(l.Equals="equals",l.NotEquals="not_equals",l.GreaterThan="greater_than",l.LessThan="less_than",l.Contains="contains",l.NotContains="not_contains",l.Matches="matches",l.Absent="absent",l.Present="present",l))(lv||{}),SQ=["absent","present"],co=g.string().trim().min(1),eCt=g.object({subject:co.describe('what the test READS: a response field path, the literal "status", or the on-screen text for a ui case \u2014 the FINAL read in a multi-step case'),comparator:g.nativeEnum(lv),value:g.union([g.string(),g.number(),g.boolean(),g.null()]).optional().describe("the ONE value a broken build would not produce; OMIT for absent/present")}),tCt=g.object({test:co.describe("existing test path, relative to its repository"),repository:co.optional().describe("owner/repo the test lives in, when the run has several checkouts; omit for the working checkout"),action:g.nativeEnum(Nm),evidence:co.describe("why \u2014 drift vs the diff, or a finding"),covers_behaviors:g.array(g.string()).optional().describe("analyze behavior ids this maintenance covers")}),rCt=g.object({surface:co.describe("a surface from the list, copied verbatim"),axis:g.nativeEnum(cv)}),nCt=g.object({id:co.describe("short-slug, unique across generate[]"),type:g.nativeEnum(da),target:co.describe('"METHOD /path", or a business-flow name'),from_finding:g.string().optional().describe("analyze finding id this case catches"),from_behavior:g.string().optional().describe("analyze behavior id this case pins"),derived_from:rCt.optional().describe("the surface \xD7 axis this case pins when no analyze behavior or finding names it \u2014 one of the three is required"),rationale:co.describe("why this test matters"),expected_observable:co.describe("one sentence for a human: what a catching test asserts, and what a broken build does instead"),expected:eCt.describe("the same intent AS DATA \u2014 see the rules below"),seededPrecondition:co.optional().describe("seeded non-initial state + how to reach it; only when a seeded-state transition applies"),verifiable:g.boolean().describe("true only when a live SUT could confirm this test (full mode)")}),sCt=g.object({covered:g.array(g.string()).optional(),abstain:g.string().optional()}).superRefine((e,t)=>{let r=Array.isArray(e.covered),n=typeof e.abstain=="string";if(r===n)return void t.addIssue({code:g.ZodIssueCode.custom,message:"must have exactly one of covered[] or abstain"});r&&e.covered.length===0&&t.addIssue({code:g.ZodIssueCode.custom,path:["covered"],message:"must list at least one id (else abstain)"}),n&&!e.abstain.trim()&&t.addIssue({code:g.ZodIssueCode.custom,path:["abstain"],message:"must give a reason"})}).describe('{ "covered": [ids] } OR { "abstain": "reason" } \u2014 exactly one'),iCt=g.object({surface:co.describe("a surface from the list, copied verbatim"),axes:g.object(Object.fromEntries(Object.values(cv).map(e=>[e,sCt])))}),uv=g.object({schemaVersion:g.literal(1),mode:g.nativeEnum(Tb),maintenance:g.array(tCt),generate:g.array(nCt),surfaces:g.array(iCt).describe("one entry per changed surface in the list \u2014 none missing, none invented"),budget:g.object({total:g.number().describe("case count"),rationale:co}),summary:co.describe("one paragraph")});function IQ(e,t,r){let n=s=>{if(!s||!Array.isArray(s.covered))return s;let i=s.covered.filter(o=>!t.has(o));return i.length>0?{covered:i}:{abstain:`its only case(s) were ${r}: ${s.covered.join(", ")}`}};return e.map(s=>({...s,axes:Object.fromEntries(Object.entries(s.axes??{}).map(([i,o])=>[i,n(o)]))}))}function vTe(e){let t=[],r=new Set;if(Array.isArray(e.generate)&&e.generate.forEach((n,s)=>{let i=n?.id;typeof i=="string"&&(r.has(i)&&t.push(`generate[${s}].id "${i}" is duplicated`),r.add(i))}),Array.isArray(e.generate)&&e.generate.forEach((n,s)=>{let i=n;!i.from_finding&&!i.from_behavior&&!i.derived_from&&t.push(`generate[${s}] carries none of from_behavior, from_finding or derived_from \u2014 say what obligation it pins`)}),Array.isArray(e.surfaces)){let n=new Set;e.surfaces.forEach((s,i)=>{let o=s;if(typeof o.surface=="string"){let a=o.surface.trim().toLowerCase();n.has(a)&&t.push(`surfaces[${i}] "${o.surface}" is listed twice`),n.add(a)}for(let[a,c]of Object.entries(o.axes??{})){let l=c?.covered;if(Array.isArray(l))for(let u of l)(typeof u!="string"||!r.has(u))&&t.push(`surfaces[${i}].axes.${a}.covered references unknown generate id ${JSON.stringify(u)}`)}})}return t}var _m=(r=>(r.Ready="ready",r.Blocked="blocked",r))(_m||{}),zr=g.string().trim().min(1),oCt=g.object({action:g.enum(["start","run","wait"]),text:zr,source:g.enum(["file","notes","testbot"]).describe("file: a file in the repository; notes: the Target's notes; testbot: Testbot's own finding"),file:zr.nullable().describe("the file the step came from, relative to the component's repository; null unless source is file")}).strict().refine(e=>e.source==="file"==(e.file!==null),{path:["file"],message:"a file exactly when the step came from one"}),aCt=/^[A-Za-z_][A-Za-z0-9_]*$/,Bb=/^(?!GITHUB_)(?!SKYRAMP_RUNNER_)[A-Z][A-Z0-9_]{0,99}$/,Nb=(o=>(o.VersionEndpoint="version_endpoint",o.DeployWorkflow="deploy_workflow",o.KubernetesLabels="kubernetes_labels",o.Command="command",o.Api="api",o.NotTracked="not_tracked",o))(Nb||{}),Vn="shared",cCt=zr.refine(e=>{try{let t=new URL(e);return["http:","https:"].includes(t.protocol)&&!t.username&&!t.password}catch{return!1}},"an http(s) URL with no login in it"),_b=g.object({address:cCt,readyWhen:zr.nullable(),credentials:g.array(g.string().regex(Bb)).max(50),revisionSources:g.array(g.object({method:g.nativeEnum(Nb),detail:zr.describe("what Testbot reads, such as GET /version or the deploy workflow's name; for not_tracked, why nothing shows it"),components:g.array(zr).min(1).describe("the components it tells the revision of, by name")}).strict()).max(50)}).strict(),x4={steps:g.array(oCt).max(20).optional().describe("how it starts, in order"),kind:g.enum(["web_app","service","database","external_service"]).optional(),from:g.object({file:zr,service:zr.nullable()}).strict().optional(),credentials:g.array(g.string().max(100).regex(aCt)).max(50).optional().describe("the Target's credentials this component's recipe uses: a sign-in (a test user, password or token) or an API key, which the workflow supplies from a GitHub Actions secret as the environment variable of the credential's name; give each name exactly as the recipe reads it. Names only, never a value, and not a secret the recipe generates itself")},lCt=g.object({name:zr,repository:zr.describe("owner/repo of the Target repository the component is built or started from, such as the one whose compose file starts its database"),healthy:g.boolean(),...x4,deployed:zr.nullable().optional().describe('only with "environment": the revision the component runs, as you read it from its revision source, or null when you could not tell')}),uCt=g.object({component:zr,problem:zr,evidence:zr.describe("the exact command and output that shows it"),fix:zr.describe("what the user must provide, and where")}),dCt=g.object({framework:zr,file:zr.describe("the test file run, relative to its repository root"),result:g.enum(["pass","fail","error"])}),pCt=g.object({input:zr.describe("the part of the user's SUT input, as given"),reason:zr}),dv=g.object({schemaVersion:g.literal(1),status:g.nativeEnum(_m).describe("ready only if every component came up healthy and the recipe is written"),components:g.array(lCt),suites:g.array(dCt).default([]).describe("one run per test suite the Target's repositories have; empty when they have none"),inputsUsed:g.array(zr).default([]).describe("the parts of the user's SUT input the recipe used as given"),inputsUsedHow:g.array(g.object({input:zr.describe("exactly as written in inputsUsed; an entry that is not there is left out"),how:zr.describe("what the recipe did with it")})).optional(),inputsNotUsed:g.array(pCt).default([]).describe("the parts it did not use, and why. A part that is wrong goes here, with what was wrong, even when the recipe does something like it instead: one that names a file, command, port, route or setting that does not exist or does not work (SKYR-5265)"),blockers:g.array(uCt).describe("required (non-empty) when status is blocked"),environment:_b.optional().describe("only when the whole SUT is an existing deployment you tested where it runs, building and starting nothing: its address, what says it is ready, the credentials that reach it, and how to read what each component runs. Leave it out when any part was built or started on the runner, or reaching it needed something there (a tunnel, port-forward, proxy or client certificate)")});function R4(e){let t=fCt(e);if(t.length>0)return t;if(e.status==="blocked"&&!(Array.isArray(e.blockers)&&e.blockers.length>0))return['status "blocked" requires at least one blocker { component, problem, evidence, fix } \u2014 say what stopped the bring-up'];if(e.status==="ready"){let r=Array.isArray(e.components)?e.components:[];if(r.length===0)return['status "ready" requires at least one component \u2014 name each component the recipe brought up healthy'];let n=r.filter(s=>s?.healthy!==!0).map(s=>String(s?.name??"?"));if(n.length>0)return[`status "ready" requires every component healthy; not healthy: ${n.join(", ")} \u2014 answer "blocked" with a blocker for each, or bring them up and answer "ready" again`]}return[]}function fCt(e){let t=Array.isArray(e.components)?e.components:[],r=e.environment;if(!r){let a=t.filter(c=>c?.deployed!==void 0||c?.repository===Vn).map(c=>String(c?.name??"?"));return a.length>0?[`"deployed" and a "${Vn}" repository belong only to an answer with "environment"; remove them from: ${a.join(", ")}`]:[]}let n=[],s=t.filter(a=>a?.deployed===void 0).map(a=>String(a?.name??"?"));s.length>0&&n.push(`with "environment", every component says what it runs in "deployed" (null when you could not tell); missing for: ${s.join(", ")}`);let i=new Set(t.map(a=>a?.name)),o=(r.revisionSources??[]).flatMap(a=>a?.components??[]).filter(a=>!i.has(a));return o.length>0&&n.push(`each revision source names components of this answer; not one of them: ${o.map(String).join(", ")}`),n}var Pm=64*1024,Qm=512*1024,vQ=/[\u0000-\u0008\u000b\u000e-\u001f\u007f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;var Pb=".skyramp/sut/deployed-revisions.sh",k4=(r=>(r.Running="running",r.Requested="requested",r))(k4||{});var Bor=new Set(Object.values(k4));var hCt=/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/,xTe=e=>hCt.test(e);function xQ(e){return e?.find(t=>t.path===Pb)}var Nor=`Fix ${Pb} so it prints the full commit each component runs, then set it up again.`;function T4(e,t){let r=new Set(t.filter(s=>s.method!=="not_tracked").flatMap(s=>s.components)),n=new Set(t.filter(s=>s.method==="not_tracked").flatMap(s=>s.components));return e.filter(s=>r.has(s.name)||!n.has(s.name))}var Ys="shared-environment",gCt=1e4,RTe=5,TTe=64*1024,_4=300,ACt=200,yCt=/\b[0-9a-fA-F]{7,64}\b/g,bCt=/\bsha256:[0-9a-fA-F]{64}\b/g,ECt=/\b(commit|sha|revision|rev|hash)\b/i,wCt=(e,t)=>new RegExp(`(?<![A-Za-z0-9])(commit|sha|revision|rev|hash)["']?\\s*[:=]?\\s*["']?${t}(?![0-9A-Za-z])`,"i").test(e),Qb=e=>e.slice(0,_4),pv=e=>Qb(e.trim())||"(empty response)";function kTe(e,t){let r=e.split(/\r?\n/).find(s=>s.toLowerCase().includes(t)).trim(),n=r.toLowerCase().indexOf(t);return r.length<=_4?r:r.slice(Math.max(0,n-100),Math.max(0,n-100)+_4)}function fv(e,t){if("error"in t)return{status:"unverifiable",observedRevision:null,evidence:pv(t.error)};let r=e.toLowerCase(),n=l=>ECt.test(kTe(t.body,l)),s=l=>r?r.startsWith(l)&&n(l):wCt(t.body,l),i=(t.body.replace(bCt," ").match(yCt)??[]).map(l=>l.toLowerCase()).filter(l=>/[a-f]/.test(l)||s(l)),o=[...new Set(i)].filter((l,u,d)=>!d.some(p=>p!==l&&p.startsWith(l)));if(o.length>1)return{status:"unverifiable",observedRevision:null,evidence:pv(`The answer names more than one revision: ${o.join(", ")}`)};let[a]=o;return a?{status:r.startsWith(a)?"verified":"mismatch",observedRevision:a,evidence:kTe(t.body,a)}:{status:"unverifiable",observedRevision:null,evidence:pv(t.body)}}async function CCt(e){if(!e.body)return"";let t=e.body.getReader(),r=[],n=0;for(;;){let{done:s,value:i}=await t.read();if(s)return Buffer.concat(r).toString("utf-8");if(n+=i.byteLength,n>TTe){await t.cancel();return}r.push(i)}}async function hv(e,t=fetch){try{let r=AbortSignal.timeout(gCt),n=new URL(e).origin,s=new URL(e);for(let i=0;;i+=1){let o=await t(s,{redirect:"manual",signal:r}),a=o.status>=300&&o.status<400?o.headers.get("location"):null;if(a){let l=new URL(a,s);if(l.origin!==n)return{error:`${e} redirects to another origin (${l.origin})`};if(i>=RTe)return{error:`${e} redirects more than ${RTe} times`};s=l;continue}let c=await CCt(o);return c===void 0?{error:`${e} answered more than ${TTe/1024} KiB`}:o.ok?{body:c}:{error:`${e} answered ${o.status}: ${c.trim()}`}}}catch(r){let n=r instanceof Error&&r.cause instanceof Error?`: ${r.cause.message}`:"";return{error:`${e} could not be read: ${r instanceof Error?r.message:String(r)}${n}`}}}var qor=new Set(["version_endpoint","api"]);function Db(e){return(e?.components??[]).filter(t=>!!t.repository&&!!t.expectedRevision)}function RQ(e){return Db(e.sharedEnvironment).filter(t=>!t.revisionUrl&&!t.revisionScript)}async function SCt(e,t,r=[]){let{name:n,url:s}=e;if(!e.versionUrl)return{name:n,url:s,version:null,evidence:"No version URL is configured."};let i=gr(await hv(e.versionUrl,t),r);if("error"in i)return{name:n,url:s,version:null,evidence:pv(i.error)};let o=i.body.split(/\r?\n/).map(a=>a.trim()).find(Boolean);return{name:n,url:s,version:o?o.slice(0,ACt):null,evidence:pv(o??"")}}var P4=(e,t)=>!!e&&!!t&&e.toLowerCase()===t.toLowerCase(),BTe=(e,t)=>e.name===t.name&&P4(e.repository,t.repository);async function ICt(e,t,r){let{frozen:n,mergeCommit:s,mergedHead:i}=t;return!s||!i?"not_contained":i.toLowerCase()===n.toLowerCase()?"contained":r?.commitContains?r.commitContains({repository:e,ancestor:n,descendant:i}):"unknown"}async function B4(e,t,r){let n=t.observedRevision;if(t.status!=="mismatch"||!n||!e.acceptedRevisions)return t;let{frozen:s,mergeCommit:i,mergedHead:o}=e.acceptedRevisions,a=await ICt(e.repository,e.acceptedRevisions,r),c=[s,...i&&a==="contained"?[i]:[]],l=f=>`${f===s?"the frozen revision":"the merge commit"} ${jn(f)}`,u=(f,h)=>({status:f,observedRevision:n,evidence:Qb(`${h} (${t.evidence})`)}),d=c.find(f=>f.toLowerCase().startsWith(n));if(d)return u("verified",`observed ${jn(n)} is ${l(d)}`);if(!r?.commitContains)return u("unverifiable",`could not tell whether observed ${jn(n)} contains ${c.map(jn).join(" or ")}: this run cannot compare commits`);let p=[];for(let f of c){let h=await r.commitContains({repository:e.repository,ancestor:f,descendant:n});if(h==="contained")return u("verified",`observed ${jn(n)} contains ${l(f)}`);h==="unknown"&&p.push(f)}return p.length?u("unverifiable",`could not tell whether observed ${jn(n)} contains ${p.map(jn).join(" or ")}: GitHub did not answer the compare`):a==="unknown"&&o?u("unverifiable",`could not tell whether the merged head ${jn(o)} contains ${jn(s)}: GitHub did not answer the compare`):u("mismatch",`observed ${jn(n)} does not contain ${c.map(jn).join(" or ")}`)}function NTe(e,t){let r=(i,o=null)=>({status:"unverifiable",observedRevision:o,evidence:Qb(i)});if(!t)return r("Not checked: this run cannot run deployed-revisions.sh.");if(!t.ok)return r(t.error);let n=t.revisions[e.name];return n?xTe(n.revision)?n.state==="requested"?r(`deployed-revisions.sh reports only the requested state for ${e.name} (${n.revision}), which alone does not show what runs.`,n.revision):{status:e.expectedRevision.toLowerCase().startsWith(n.revision)?"verified":"mismatch",observedRevision:n.revision,evidence:Qb(`deployed-revisions.sh: ${e.name} runs ${n.revision}`)}:r(`deployed-revisions.sh printed ${n.revision} for ${e.name}, which is not a full commit.`):r(`deployed-revisions.sh printed no revision for ${e.name}.`)}async function kQ(e,t,r,n=[],s,i){let o=(c,l)=>fv(c,gr(l,n));return{components:await Promise.all(Db(e).map(async c=>{let l={name:c.name,repository:c.repository,url:c.url,expectedRevision:c.expectedRevision};if(c.revisionScript)return{...l,source:"probe",...await B4(c,NTe(c,i),s)};if(c.revisionUrl)return{...l,source:"probe",...await B4(c,o(c.expectedRevision,await hv(c.revisionUrl,r)),s)};let u=t.find(p=>p.component===c.name),d=o(c.expectedRevision,u?{body:u.output}:{error:"Deploy cited no check of its deployed revision."});return{...l,source:"agent",...await B4(c,d,s)}})),dependencies:await Promise.all(e.dependencies.map(c=>SCt(c,r,n)))}}async function vCt(e,t,r,n){if(e.revisionScript){let o=NTe(e,n);return{failed:!n?.ok,now:o,noCommit:o.status==="unverifiable"}}let s=gr(await hv(e.revisionUrl,t),r),i=fv(e.expectedRevision,s);return{failed:"error"in s,now:i,noCommit:!i.observedRevision}}async function xCt(e,t,r,n=[],s){let i=await Promise.all(t.components.map(async o=>{let a=e.components.find(p=>BTe(p,o)),c=o.observedRevision?.toLowerCase();if(!c||!(a?.revisionUrl||a?.revisionScript))return o;let{failed:l,now:u,noCommit:d}=await vCt({...a,expectedRevision:o.expectedRevision},r,n,s);if(d){let p=l?"second read failed":"second read names no one commit",f=`first read ${jn(o.observedRevision??c)}; ${p}: ${u.evidence}`;return{...o,status:"unverifiable",observedRevision:null,evidence:Qb(f)}}return u.observedRevision.startsWith(c)||c.startsWith(u.observedRevision)?o:{...o,status:"unverifiable",observedRevision:u.observedRevision,evidence:Qb(`changed from ${o.observedRevision} to ${u.observedRevision} during the run`)}}));return{...t,components:i}}async function Q4(e,t){return t.components.some(r=>r.revisionScript)?e.deployedRevisions?.():void 0}async function _Te(e,t){let r=e.inputs.sharedEnvironment,n=ee(e,`${Ys}.json`);if(!e.inputs.appRunning||!r||!n)return;let s=await xCt(r,n,t,e.secretValues??[],await Q4(e,r));ot(e,Ys,gr(s,e.secretValues??[]),[])}function mv(e){return Db(e).length>0||(e?.dependencies.length??0)>0}function D4(e){let t=e.inputs?.sharedEnvironment;if(!mv(t))return;let r=ee(e,`${Ys}.json`);if(r)return{components:QTe(t,r.components),dependencies:r.dependencies};let n="Not checked: deploy did not complete.";return{components:Db(t).map(s=>PTe(s,n)),dependencies:t.dependencies.map(s=>({name:s.name,url:s.url,version:null,evidence:n}))}}function TQ(e){return e?.components.length?[`Testbot read which commit each component runs, before this session: ${e.components.map(r=>{let n=r.observedRevision?`${r.name} runs ${jn(r.observedRevision)}`:`${r.name} answered no commit`,s=r.status==="verified"?"verified":"not proven to run the change";return`${n}, ${s} (${r.evidence})`}).join("; ")}.`,"Which commit is deployed is Testbot's to check, not yours: record no gap, finding, issue or next step about it, and don't compare the deployed commit with your checkout."].join(" "):void 0}var PTe=(e,t)=>({name:e.name,repository:e.repository,url:e.url,expectedRevision:e.expectedRevision,observedRevision:null,status:"unverifiable",source:e.revisionUrl||e.revisionScript?"probe":"agent",evidence:t});function QTe(e,t){let r=new Set(t.map(s=>s.name.toLowerCase())),n=Db(e).filter(s=>s.touched&&!r.has(s.name.toLowerCase()));return[...t,...n.map(s=>PTe(s,"Not checked: the run recorded no read of it."))]}function Ob(e){return(D4(e)?.components??[]).filter(t=>t.status!=="verified")}function O4(e,t,r){if(!e.appRunning||r===!1)return[];let n=(e.sharedEnvironment?.components??[]).filter(s=>s.touched);return QTe(e.sharedEnvironment,t?.components??[]).filter(s=>s.status!=="verified"&&n.some(i=>BTe(i,s)))}function DTe(e){let t=r=>{let n=r.observedRevision?`runs ${jn(r.observedRevision)}`:"no revision could be read";return`${r.name} (${r.repository}) must run ${jn(r.expectedRevision)}, but ${n}: ${r.evidence}`};return e.length?`the Test Environment does not verifiably run the change: ${e.map(t).join("; ")}`:void 0}function BQ(e){return(e?.components??[]).filter(t=>!!t.repository&&!t.expectedRevision)}function OTe(e,t=!1){return`${e.name}: ${e.repository} is not one of the run's sources, so its revision cannot be verified and ${MTe(t)}`}var MTe=e=>e?"runtime tests against it do not validate this change":"no runtime test ran against it";function FTe(e,t=!1){let r=jn(e.expectedRevision),n=e.status==="mismatch"?`the shared environment runs ${e.repository} at ${e.observedRevision}, not ${r}`:`could not verify that the shared environment runs ${e.repository} at ${r}`;return`${e.name}: ${n}, so ${MTe(t)}`}var RCt=/^\s*(POST|PUT|PATCH|DELETE)\s/i,N4=e=>e.mutates===!0;function Dm(e){return(e?.components??[]).filter(t=>!!t.repository)}function lo(e){let t=e.sharedEnvironment;return!!t&&Dm(t).length>0&&!t.allowMutation&&!e.planOnly}function kCt(e){let t=n=>RCt.test(n.target)||N4(n),r=[...e.generate.filter(t).map(n=>({id:n.id,target:n.target})),...e.maintenance.filter(N4).map(n=>({id:n.test}))];return{...e,generate:e.generate.filter(n=>!t(n)),surfaces:IQ(e.surfaces,new Set(r.map(n=>n.id)),"withheld because they change a shared environment the policy protects"),maintenance:e.maintenance.filter(n=>!N4(n)),withheld:r}}function Mb(e,t){return t&&lo(e)?kCt(t):t}function NQ(e){return ee(e,"recommend.json")?.withheld??[]}function LTe(e){return`${e.id}${e.target?` (${e.target})`:""}: needs a shared-environment mutation the policy does not allow`}var TCt=40,jTe="health.command cannot be re-executed: ",UTe=4e3,BCt=9e4,NCt=5e3;function _Ct(e,t){let r=e.slice(0,UTe),n=t.slice(0,UTe);if(!r||!n)return"";let s=new Uint32Array(n.length+1),i=new Uint32Array(n.length+1),o=0,a=0;for(let c=1;c<=r.length;c++){for(let u=1;u<=n.length;u++){if(r[c-1]!==n[u-1]){i[u]=0;continue}i[u]=s[u-1]+1,i[u]>o&&(o=i[u],a=c)}let l=s;s=i,i=l}return r.slice(a-o,a)}function $Te(e){let t=e.search(/[[{]/);if(t<0)return;let r=e[t],n=r==="{"?"}":"]",s=0,i=!1,o=!1;for(let a=t;a<e.length;a++){let c=e[a];if(i){o?o=!1:c==="\\"?o=!0:c==='"'&&(i=!1);continue}if(c==='"')i=!0;else if(c===r)s++;else if(c===n&&--s===0)try{return JSON.parse(e.slice(t,a+1))}catch{return}}}function _Q(e,t=0){return t>4?"\u2026":e===null?"null":Array.isArray(e)?e.length===0?"[]":`[${[...new Set(e.map(r=>_Q(r,t+1)))].sort().join("|")}]`:typeof e=="object"?`{${Object.keys(e).sort().map(r=>`${r}:${_Q(e[r],t+1)}`).join(",")}}`:typeof e}function qTe(e,t){let r=$Te(e),n=$Te(t);if(r!==void 0&&n!==void 0){let a=_Q(r),c=_Q(n);return a===c?{ok:!0}:{ok:!1,why:`it answered ${c.slice(0,200)}, but the recorded check answered ${a.slice(0,200)}`}}let s=e.split(`
230
230
  `).map(a=>a.trim()).filter(Boolean).sort((a,c)=>c.length-a.length)[0]??e,i=Math.min(s.length,TCt),o=_Ct(s,t);return o.length>=i?{ok:!0}:{ok:!1,why:`nothing in it resembles "${s.slice(0,60)}" (longest run in common: ${o.length} chars, need ${i})`}}function PCt(e){return Ib(av,v4,e).errors}function QCt(e,t=[]){let{value:r,error:n}=Xt(e,t);if(n)return{errors:[n]};let s=PCt(r);return s.length>0?{errors:s}:{deploy:r,errors:[]}}function Om(e,t,r=[]){let n=QCt(e.stdout,r);return n.deploy&&t&&(n.deploy=DCt(n.deploy,t)),n}var GTe=".skyramp/sut/health-check.sh";function DCt(e,t){let r=e.health?.command?.trim();return!r||!e.health||!EQ(r,tf.join(t,GTe),"deploy")?e:{...e,health:{...e.health,command:`bash ${GTe}`}}}function OCt(){return{httpGet(e,t){let r=S4(wQ(e))?["-k"]:[],n=(0,M4.spawnSync)("curl",["-sS",...r,"-m","20","-o","-","-w",`
231
231
  %{http_code}`,...MCt(t),e],{encoding:"utf-8",timeout:25e3});if(n.status!==0)return{error:(n.stderr||n.error?.message||"curl failed").trim()};let s=n.stdout??"",i=s.lastIndexOf(`
232
232
  `),o=Number(s.slice(i+1).trim());return{status:Number.isFinite(o)?o:0,body:s.slice(0,i)}},runCommand(e,t){let{steps:r,reason:n}=rd(e);if(!r)return{exitCode:1,output:`${jTe}${n}`};let s="";for(let i of r){let o=(0,M4.spawnSync)(i[0],i.slice(1),{cwd:t,encoding:"utf-8",timeout:6e4,env:Ye()});if(s+=`${o.stdout??""}${o.stderr??""}`,(o.status??1)!==0)return{exitCode:o.status??1,output:s}}return{exitCode:0,output:s}}}}function MCt(e){return e?Object.entries(e).flatMap(([t,r])=>["-H",`${t}: ${r}`]):[]}function zTe(e){return e.trim().replace(/^\.\//,"").replace(/\/+$/,"")}function FCt(e){if(!e.inputs)return[];let t=sr(e),r=s=>{let i=typeof s=="string"?s:s?.path??s?.file;return typeof i=="string"&&i.trim()?zTe(i):void 0},n=(s,i)=>s?(i??[]).flatMap(o=>{let a=r(o);return a?[{repository:s,path:a}]:[]}):[];return[...n(Qr(e.inputs).slug,[...t?.changedFiles??[],...t?.newFiles??[]]),...(t?.relatedChanges??[]).flatMap(s=>n(s.repository,s.changedFiles))]}function LCt(e,t){let r=tf.resolve(e.inputs.repositoryPath,t.trim()),n=mQ(e.inputs,r),s=n&&tf.relative(n.path,r);return n&&s?{repository:n.slug,path:s.split(tf.sep).join("/")}:void 0}function VTe(e=OCt(),t={}){let r=t.budgetMs??BCt,n=t.intervalMs??NCt,s=t.sleep??(i=>new Promise(o=>setTimeout(o,i)));return{name:"deploy-health",async verify(i,o){let{deploy:a,errors:c}=Om(o,i.inputs?.repositoryPath,i.secretValues);if(!a)return{name:this.name,passed:!1,details:c.slice(0,6).join("; ")};if(a.outcome==="bringup-failed")return{name:this.name,passed:!0};if(a.outcome==="change-broke-bringup"){let I=FCt(i),v=(a.suspectFiles??[]).map(zTe),T=v.filter(k=>{let R=LCt(i,k);return!!R&&vb(I,R.repository,R.path)});return I.length>0&&T.length===0?{name:this.name,passed:!1,details:`change-broke-bringup claimed, but none of suspectFiles [${v.slice(0,4).join(", ")}] is a file this PR changed \u2014 that is not attributable to the PR. Re-run bring-up; if it still fails for a reason outside the diff, record outcome "bringup-failed" (with bringupError) instead.`}:{name:this.name,passed:!0}}let l=a.health;if(!l)return{name:this.name,passed:!1,details:"health is missing although the app is recorded as up"};let u=Object.values(l.headers??{}).some(I=>/<[^>]+>/.test(String(I))),d=(I,v=!1)=>({ok:!1,details:I,transient:v}),p=()=>{if(!CQ(l.url,i.inputs.repositoryPath))return d(`health url ${l.url} is not the app under test \u2014 this gate probes only loopback or a host declared in .skyramp/workspace.yml, never an arbitrary destination. Record the URL the deployed app actually answers on.`);let I=e.httpGet(l.url,l.headers);if("error"in I)return d(`health url ${l.url} unreachable: ${I.error}`,!0);let v=Number(l.status??200);if(I.status!==v)return d(`health url returned ${I.status}, expected ${v}`,!0);if(!I.body.trim())return d("health url returned empty body \u2014 must return data",!0);let T=(l.output??"").trim();if(T){let k=qTe(T,I.body);if(!k.ok)return d(`health url ${l.url} no longer answers as recorded \u2014 ${k.why}. Either the app is not answering as it did at deploy time, or health.output is not verbatim: record ONLY the response body, with no commentary appended.`)}return{ok:!0}},f=()=>{let I=e.runCommand(l.command,i.inputs.repositoryPath),v=I.output.startsWith(jTe);if(I.exitCode!==0)return d(`health command exited ${I.exitCode}: ${I.output.slice(0,200)}`,!v);if(!I.output.trim())return d("health command produced no output",!0);let T=(l.output??"").trim();if(T.length<16)return d(`health command output "${T}" is too thin to be a data check \u2014 the check must return real application data, not a status token`);let k=qTe(T,I.output);return k.ok?{ok:!0}:d(`health command did not reproduce its recorded check \u2014 ${k.why}. Either the app is not answering as it did at deploy time, or health.output is not verbatim: record ONLY what the command wrote, with no commentary appended.`)},h;if(l.command&&(u||!l.url))h=f;else{if(l.url&&u)return{name:this.name,passed:!1,details:`health.headers contains a documented placeholder (${Object.entries(l.headers??{}).filter(([,I])=>/<[^>]+>/.test(String(I))).map(([I])=>I).join(", ")}), and this gate RE-EXECUTES the probe \u2014 a placeholder cannot authenticate. Record a health.command instead (a script that fetches its own token and hits the URL); do not put a real credential in the artifact.`};l.url?h=p:l.command&&(h=f)}if(!h)return{name:this.name,passed:!1,details:"health has neither url nor command"};let A=Date.now(),C=A+r,w=h();for(;!w.ok&&w.transient&&Date.now()+n<C;)await s(n),w=h();if(w.ok)return{name:this.name,passed:!0};let b=Math.round((Date.now()-A)/1e3);return{name:this.name,passed:!1,details:w.transient&&b>0?`${w.details} (still failing after ${b}s)`:w.details}}}}function uo(e){return gv(e)&&Ob(e).length===0&&BQ(e.inputs?.sharedEnvironment).length===0}function gv(e){let t=UCt(e);if(!t&&e.state.stages.deploy?.status!=="passed")return!1;let r=ee(e,"deploy.json");return r?r.outcome==="clean"||r.outcome==="recipe-drift":!t}function UCt(e){let t=e.state.stages.plan,r=e.state.stages.deploy;return!(e.inputs?.pipeline?e.inputs.pipeline==="two-step":!r)||t?.status!=="passed"?!1:!r||r.updatedAt<=t.updatedAt}async function $Ct(e,t,r){let n=new URL(t.url).origin;return(URL.canParse(e.url)?new URL(e.url).origin:e.url)===n?hv(e.url,r):{error:`${e.url} is not on ${n}, where ${t.name} runs`}}function WTe(e){return{name:"shared-revisions",async verify(t,r){let{deploy:n}=Om(r,t.inputs?.repositoryPath,t.secretValues),s=RQ(t.inputs??{}),i=[];for(let o of n?.revisions??[]){let a=s.find(d=>d.name===o.component);if(!a){i.push(`revisions names "${o.component}", which is not a shared component listed for a revision check`);continue}let c=await $Ct(o,a,e);if("error"in c){i.push(`the revision check of ${a.name} could not be re-run: ${gr(c.error,t.secretValues??[]).slice(0,200)}`);continue}let l=fv(a.expectedRevision,{body:o.output}),u=fv(a.expectedRevision,c);l.observedRevision!==u.observedRevision&&i.push(`the revision check of ${a.name} names ${u.observedRevision??"no commit"} when re-run, but its recorded output names ${l.observedRevision??"no commit"} \u2014 record what the check returned, verbatim, or leave the component out`)}return i.length?{name:this.name,passed:!1,details:i.join("; ")}:{name:this.name,passed:!0}}}}async function YTe(e,t,r){let n=e.inputs?.sharedEnvironment;if(!mv(n))return{};let{deploy:s}=Om(t,e.inputs.repositoryPath,e.secretValues),i=await kQ(n,s?.revisions??[],r,e.secretValues??[]);return ot(e,Ys,gr(i,e.secretValues??[]),[])}function JTe(e,t){let{deploy:r,errors:n}=Om(t,e.inputs?.repositoryPath,e.secretValues),s=r?.health?.headers?{...r,health:{...r.health,headers:Object.fromEntries(Object.keys(r.health.headers).map(o=>[o,"<redacted>"]))}}:r,i=gr(s,e.secretValues??[]);return ot(e,"deploy",i,n)}var nd=(o=>(o.Place="place",o.Update="update",o.Regenerate="regenerate",o.Delete="delete",o.Verify="verify",o.None="none",o))(nd||{}),Ii=(n=>(n.Pass="pass",n.Fail="fail",n.Skip="skip",n))(Ii||{}),pa=g.string().trim().min(1),KTe=g.object({case:pa.describe("a covers id \u2014 the recommend case this test realizes"),status:g.nativeEnum(Ii)}),XTe=g.object({exit:g.number({invalid_type_error:"must be a number or null"}).nullable().describe("process exit of the re-run; null when no SUT was available"),details:g.string().optional().describe("what failed, or why a file was not run \u2014 required on any non-zero exit"),tests:g.array(KTe).optional().describe("ONE ENTRY PER CASE the file covers; must agree with exit (0 \u2192 no fail; non-zero \u2192 at least one)")}),ZTe=g.object({from:g.string().optional().describe("staged path \u2014 required for placements"),file:pa.describe("final path relative to its repository, inside that checkout, with a source-file extension"),repository:pa.optional().describe("owner/repo the file lives in, when the run has several checkouts; omit for the working checkout"),action:g.nativeEnum(nd),covers:g.array(g.string()).optional().describe("recommend ids a placed test covers"),repro:g.boolean().optional().describe("this test is MEANT to fail \u2014 it reproduces a reported bug"),finding:g.boolean().optional().describe("a non-repro test that failed on a REAL product bug"),placementBroken:g.boolean().optional().describe('placement/harness problem one repair could not fix \u2014 every reran.tests entry is then "skip"'),keptReason:pa.optional().describe("why a planned delete/regenerate was declined and the file kept"),isolatedRun:pa.optional().describe('only for a test marked "runs alone": the command, from its checkout root and without a shell, that runs only this file and writes its JUnit XML into $SKYRAMP_RESULTS_DIR (named by its path: no shell expands it) \u2014 the harness runs it, so leave reran.exit null'),reran:XTe,assertionCount:g.number().int().nonnegative().optional().describe("[derived] assertions reachable from the file, counted at write time")}).refine(e=>e.action!=="place"||typeof e.from=="string"&&e.from.trim().length>0,{message:'is a place but has no "from" staged path',path:[]}),eBe=(r=>(r.Junit="junit",r.Converter="converter",r))(eBe||{}),qCt=pa.optional().describe("the items[].file this test is in \u2014 needed only when two of this suite's files cover the same case id"),GCt=g.object({results:pa.describe("the JUnit XML file this run wrote, a plain file name inside $SKYRAMP_RESULTS_DIR (e.g. backend.xml)"),source:g.nativeEnum(eBe),run:pa.describe("the command you ran that wrote it, exactly as you ran it (with any converter)"),files:g.array(pa).min(1).describe("the items[].file paths this run covered"),cases:g.array(g.object({test:pa.describe("the test's name as the runner reports it, qualified by its class or file (e.g. tests/test_a.py::test_x) when the bare name repeats"),case:pa.describe("the covers id it realizes"),file:qCt})).describe("map each reported test name to the case it covers")}),HCt=g.object({suites:g.array(GCt).min(1)}),Av=g.object({schemaVersion:g.literal(1),items:g.array(ZTe),runnerResults:HCt.optional().describe("the JUnit XML your test runs wrote into $SKYRAMP_RESULTS_DIR, so the harness reads each test's result from the runner \u2014 omit only when no SUT is available"),ignored:g.array(g.string()).describe("existing tests assessed and deliberately left untouched"),summary:pa.describe("one paragraph")});var sBe=require("child_process"),yv=j(require("fs")),PQ=j(require("path"));var iBe="test-execution-contexts.json",VCt="localhost:35142",oBe=10*6e4,WCt=5e3,tBe=4e3,F4=1e4,rBe=3e4,YCt=2e3;function aBe(e){return Dm(e.sharedEnvironment).length?"shared":"disposable"}function bv(e,t){return e?.length?t||e.some(r=>r.kind!=="seed"||!!r.cleanup):!1}function JCt(e,t,r){if(r)return"its setup would change the shared environment, which the policy does not allow";let n=e.find(i=>i.mechanism==="recipe_override");if(n)return`the Runtime Plan cannot restart a component with an override for ${n.target}`;if(!t?.trim())return"adapt recorded no command that runs it alone";let{reason:s}=rd(t);return s?`its command cannot run without a shell (${s})`:void 0}function QQ(e,t,r){let n=r?Mt(e,r):void 0;return n&&t.find(s=>Mt(e,s.file)===n)?.context||[]}var L4=e=>({status:"not_run",notRunReason:"isolation_unavailable",cleanup:{status:"skipped",detail:`not run: ${e}`}});function cBe(e,t,r){let n=lo(e),s=aBe(e),i=[];for(let o of r){if(o.action==="delete"||!o.from)continue;let a=QQ(e.repositoryPath,t,o.from);if(!bv(a,n))continue;let c=JCt(a,o.isolatedRun,n);i.push({file:o.file,...o.repository?{repository:o.repository}:{},covers:o.covers??[],scope:s,execution:"serial",setup:a,...o.isolatedRun?{run:o.isolatedRun}:{},...c?L4(c):{status:"pending",notRunReason:null,cleanup:{status:"pending",detail:""}}})}return i}function rf(e,t){let r=PQ.join(e.outputsDir,iBe);yv.writeFileSync(`${r}.tmp`,JSON.stringify(gr(t,e.secretValues??[]),null,2)),yv.renameSync(`${r}.tmp`,r)}function Mm(e){let t=Cl(PQ.join(e.outputsDir,iBe));return Array.isArray(t)?t:[]}var U4=e=>e instanceof Error?e.message:String(e),nBe=e=>new Promise(t=>setTimeout(t,e));async function lBe(e,t=YCt){let r=`http://${e}/skyramp/mocks`,n;try{n=await fetch(r,{method:"DELETE",signal:AbortSignal.timeout(F4)})}catch(i){throw new Error(`the Skyramp worker at ${e} could not be reached: ${U4(i)}`)}if(!n.ok)throw new Error(`the Skyramp worker at ${e} answered ${n.status} to removing its mocks`);n.status===202&&await nBe(t);let s=Date.now()+rBe;for(;;){try{let i=await fetch(r,{signal:AbortSignal.timeout(F4)});if(i.ok&&!(await i.text()).trim()&&(await fetch(`http://${e}/readyz`,{signal:AbortSignal.timeout(F4)})).ok)return}catch{}if(Date.now()>s)throw new Error(`the Skyramp worker at ${e} still reports mocks ${rBe/1e3}s after removing them`);await nBe(250)}}var uBe=e=>[...new Set(e.filter(t=>t.kind==="runtime_mock"||t.mechanism==="skyramp_mocker").map(t=>t.worker?.trim()||VCt))];async function DQ(e,t){let r="",n=i=>r=(r+i).slice(-(tBe+1024)),s=()=>_r(r,t.secrets).slice(-tBe);for(let i of e){if(t.signal?.aborted)return{exit:null,output:s(),cancelled:!0};let o=await new Promise(a=>{let c=(0,sBe.spawn)(i[0],i.slice(1),{cwd:t.cwd,env:t.env,stdio:["ignore","pipe","pipe"],detached:!0}),l=w=>{try{c.pid&&process.kill(-c.pid,w)}catch{}},u=!1,d=!1,p;c.stdout.on("data",w=>n(w.toString())),c.stderr.on("data",w=>n(w.toString()));let f=w=>{n(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyramp/testbot-core",
3
- "version": "0.13.0-v3.155",
3
+ "version": "0.13.0-v3.157",
4
4
  "description": "Skyramp Testbot engine: AI-powered deterministic test generation, execution and maintenance",
5
5
  "main": "dist/main.js",
6
6
  "//files": "An explicit allowlist, never a glob. `dist/` is gitignored, so without this key npm's .gitignore fallback would publish a package with no engine in it; with a glob it would publish the sourcemaps, whose sourcesContent embeds every src/*.ts verbatim. eval-entry.js is a development entry and must not ship. dist/VERSION.json exists only in a release-engine.yml build. assets/gen-reference/ is the staged codegen reference corpus, which generate.ts finds at ../assets from dist/.",