diff --git a/.github/workflows/genai-investigator.yml b/.github/workflows/genai-investigator.yml new file mode 100644 index 0000000000..fd5f9bfdf1 --- /dev/null +++ b/.github/workflows/genai-investigator.yml @@ -0,0 +1,27 @@ +name: genai investigator +on: + workflow_run: + workflows: ["build"] + types: + - completed +permissions: + actions: read + pull-requests: write +jobs: + check_failure: + if: ${{ github.event.workflow_run.conclusion == 'failure' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: "recursive" + fetch-depth: 10 + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: yarn + - run: yarn install --frozen-lockfile + - name: compile + run: yarn compile + - name: genai investigator + run: yarn genai gai -prc --vars "failure_run_id=${{ github.event.workflow_run.id }}" --out-trace $GITHUB_STEP_SUMMARY diff --git a/packages/cli/src/run.ts b/packages/cli/src/run.ts index 74c4007d98..05fa72931e 100644 --- a/packages/cli/src/run.ts +++ b/packages/cli/src/run.ts @@ -13,6 +13,7 @@ import { githubCreatePullRequestReviews, githubUpdatePullRequestDescription, githubParseEnv, + GithubConnectionInfo, } from "../../core/src/github" import { HTTPS_REGEX, @@ -61,12 +62,14 @@ import { PromptScriptRunOptions } from "../../core/src/server/messages" import { writeFileEdits } from "../../core/src/edits" import { azureDevOpsCreateIssueComment, + AzureDevOpsEnv, azureDevOpsParseEnv, azureDevOpsUpdatePullRequestDescription, } from "../../core/src/azuredevops" import { resolveTokenEncoder } from "../../core/src/encoders" import { writeFile } from "fs/promises" import { writeFileSync } from "node:fs" +import { prettifyMarkdown } from "../../core/src/markdown" async function setupTraceWriting(trace: MarkdownTrace, filename: string) { logVerbose(`trace: ${filename}`) @@ -424,13 +427,15 @@ export async function runScript( } } + let ghInfo: GithubConnectionInfo = undefined + let adoInfo: AzureDevOpsEnv = undefined if (pullRequestReviews && result.annotations?.length) { // github action or repo - const info = await githubParseEnv(process.env) - if (info.repository && info.issue && info.commitSha) { + ghInfo = ghInfo ?? (await githubParseEnv(process.env)) + if (ghInfo.repository && ghInfo.issue && ghInfo.commitSha) { await githubCreatePullRequestReviews( script, - info, + ghInfo, result.annotations ) } @@ -438,23 +443,23 @@ export async function runScript( if (pullRequestComment && result.text) { // github action or repo - const info = await githubParseEnv(process.env) - if (info.repository && info.issue) { + ghInfo = ghInfo ?? (await githubParseEnv(process.env)) + if (ghInfo.repository && ghInfo.issue) { await githubCreateIssueComment( script, - info, - result.text, + ghInfo, + prettifyMarkdown(result.text), typeof pullRequestComment === "string" ? pullRequestComment : script.id ) } else { - const adoinfo = await azureDevOpsParseEnv(process.env) - if (adoinfo.collectionUri) { + adoInfo = adoInfo ?? (await azureDevOpsParseEnv(process.env)) + if (adoInfo.collectionUri) { await azureDevOpsCreateIssueComment( script, - adoinfo, - result.text, + adoInfo, + prettifyMarkdown(result.text), typeof pullRequestComment === "string" ? pullRequestComment : script.id @@ -468,24 +473,24 @@ export async function runScript( if (pullRequestDescription && result.text) { // github action or repo - const ghinfo = await githubParseEnv(process.env) - if (ghinfo.repository && ghinfo.issue) { + ghInfo = ghInfo ?? (await githubParseEnv(process.env)) + if (ghInfo.repository && ghInfo.issue) { await githubUpdatePullRequestDescription( script, - ghinfo, - result.text, + ghInfo, + prettifyMarkdown(result.text), typeof pullRequestDescription === "string" ? pullRequestDescription : script.id ) } else { // azure devops pipeline - const adoinfo = await azureDevOpsParseEnv(process.env) - if (adoinfo.collectionUri) { + adoInfo = adoInfo ?? (await azureDevOpsParseEnv(process.env)) + if (adoInfo.collectionUri) { await azureDevOpsUpdatePullRequestDescription( script, - adoinfo, - result.text, + adoInfo, + prettifyMarkdown(result.text), typeof pullRequestDescription === "string" ? pullRequestDescription : script.id diff --git a/packages/core/package.json b/packages/core/package.json index 1648f2a68d..003e550f62 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -33,6 +33,7 @@ "cross-fetch": "^4.0.0", "csv-parse": "^5.5.6", "csv-stringify": "^6.5.1", + "diff": "^7.0.0", "dotenv": "^16.4.5", "esbuild": "^0.24.0", "fast-xml-parser": "^4.5.0", @@ -81,6 +82,7 @@ "test": "node --import tsx --test src/**.test.ts" }, "dependencies": { + "@types/diff": "^5.2.2", "@types/turndown": "^5.0.5", "turndown": "^7.2.0" } diff --git a/packages/core/src/chatrender.ts b/packages/core/src/chatrender.ts index 8df2f34ad1..1097c93199 100644 --- a/packages/core/src/chatrender.ts +++ b/packages/core/src/chatrender.ts @@ -20,6 +20,7 @@ import { YAMLStringify } from "./yaml" export function renderShellOutput(output: ShellOutput) { // Destructure the output object to retrieve exitCode, stdout, and stderr. const { exitCode, stdout, stderr } = output + if (exitCode === 0) return stdout return ( [ // Include exit code in the output only if it's non-zero. diff --git a/packages/sample/genaisrc/gai.genai.mts b/packages/sample/genaisrc/gai.genai.mts new file mode 100644 index 0000000000..e8881e0117 --- /dev/null +++ b/packages/sample/genaisrc/gai.genai.mts @@ -0,0 +1,225 @@ +/* spellchecker: disable */ +import { Octokit } from "octokit" +import { createPatch } from "diff" + +const workflow = env.vars.workflow || "build.yml" +const ffid = env.vars.failure_run_id +const lsid = env.vars.success_run_id +const branch = + env.vars.branch || + (await host.exec("git branch --show-current")).stdout.trim() + +const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN, +}) +const { owner, repo } = await getRepoInfo() + +script({ + system: ["system", "system.files"], + cache: "gh-investigator", +}) + +const runs = await listRuns(workflow, branch) + +// first last success +const lsi = lsid + ? runs.findIndex(({ id }) => id === lsid) + : runs.findIndex(({ conclusion }) => conclusion === "success") +const ls = runs[lsi] +console.log( + `> last success: ${ls.id}, ${ls.created_at}, ${ls.head_sha}, ${ls.html_url}` +) +const ff = ffid ? runs.find(({ id }) => id === ffid) : runs[lsi - 1] +if (!ff) cancel("failure run not found") +console.log( + `> first failure: ${ff.id}, ${ff.created_at}, ${ff.head_sha}, ${ff.html_url}` +) +if (ff.conclusion !== "failure") cancel("failure run not found") + +const gitDiff = await host.exec( + `git diff ${ls.head_sha} ${ff.head_sha} -- . :!**/genaiscript.d.ts` +) +console.log(`> source diff: ${(gitDiff.stdout.length / 1000) | 0}kb`) + +// download logs +const lsjobs = await downloadRunLog(ls.id) +const lsjob = lsjobs[0] +const lslog = lsjob.text +console.log( + `> last success log: ${(lslog.length / 1000) | 0}kb ${lsjob.logUrl}` +) +const ffjobs = await downloadRunLog(ff.id) +const ffjob = ffjobs[0] +const fflog = ffjob.text +console.log( + `> first failure log: ${(fflog.length / 1000) | 0}kb ${ffjob.logUrl}` +) + +const logDiff = diffJobLogs(lslog, fflog) +console.log(`> log diff: ${(logDiff.length / 1000) | 0}kb`) + +// include difss +def("GIT_DIFF", gitDiff, { + language: "diff", + maxTokens: 10000, + lineNumbers: true, +}) +def("LOG_DIFF", logDiff, { + language: "diff", + maxTokens: 20000, + lineNumbers: false, +}) +$`Your are an expert software engineer and you are able to analyze the logs and find the root cause of the failure. + +- GIT_DIFF contains a diff of 2 run commits +- LOG_DIFF contains a diff of 2 runs in GitHub Action +- The first run is the last successful run and the second run is the first failed run + +Add links to run logs. + +Analyze the diff in LOG_DIFF and provide a summary of the root cause of the failure. + +If you cannot find the root cause, stop. + +Generate a diff with suggested fixes. Use a diff format.` + +writeText( + `## Investigator report +- [run first failure](${ff.html_url}) +- [run last success](${ls.html_url}) +- [commit diff](https://github.com/${owner}/${repo}/compare/${ls.head_sha}...${ff.head_sha}) + +`, + { assistant: true } +) + +/*----------------------------------------- + +GitHub infra + +-----------------------------------------*/ +async function getRepoInfo() { + const repository = process.env.GITHUB_REPOSITORY + if (repository) { + const [owner, repo] = repository.split("/") + return { owner, repo } + } + const remoteUrl = (await host.exec("git config --get remote.origin.url")) + .stdout + const match = remoteUrl.match(/github\.com\/(?.+)\/(?.+)$/) + if (!match) { + throw new Error( + "Could not parse repository information from remote URL" + ) + } + const { owner, repo } = match.groups + return { owner, repo } +} + +async function listRuns(workflow_id: string, branch: string) { + // Get the workflow runs for the specified workflow file, filtering for failures + const { + data: { workflow_runs }, + } = await octokit.rest.actions.listWorkflowRuns({ + owner, + repo, + workflow_id, + branch, + per_page: 100, + }) + const runs = workflow_runs.filter( + ({ conclusion }) => conclusion !== "skipped" + ) + return runs +} + +async function downloadRunLog(run_id: number) { + const res = [] + // Get the jobs for the specified workflow run + const { + data: { jobs }, + } = await octokit.rest.actions.listJobsForWorkflowRun({ + owner, + repo, + run_id, + }) + for (const job of jobs) { + const { url: logUrl } = + await octokit.rest.actions.downloadJobLogsForWorkflowRun({ + owner, + repo, + job_id: job.id, + }) + const { text } = await fetchText(logUrl) + res.push({ ...job, logUrl, text }) + } + return res +} + +function diffJobLogs(firstLog: string, otherLog: string) { + let firsts = parseJobLog(firstLog) + let others = parseJobLog(otherLog) + + // assumption: the list of steps has not changed + const n = Math.min(firsts.length, others.length) + firsts = firsts.slice(0, n) + others = others.slice(0, n) + + // now do a regular diff + const f = firsts + .map((f) => + f.title ? `##[group]${f.title}\n${f.text}\n##[endgroup]` : f.text + ) + .join("\n") + const l = others + .map((f) => + f.title ? `##[group]${f.title}\n${f.text}\n##[endgroup]` : f.text + ) + .join("\n") + const d = createPatch("log.txt", f, l, undefined, undefined, { + ignoreCase: true, + ignoreWhitespace: true, + }) + return d +} + +function parseJobLog(text: string) { + const lines = cleanLog(text).split(/\r?\n/g) + const groups: { title: string; text: string }[] = [] + let current = groups[0] + for (const line of lines) { + if (line.startsWith("##[group]")) { + current = { title: line.slice("##[group]".length), text: "" } + } else if (line.startsWith("##[endgroup]")) { + if (current) groups.push(current) + current = undefined + } else { + if (!current) current = { title: "", text: "" } + current.text += line + "\n" + } + } + if (current) groups.push(current) + + const ignoreSteps = [ + "Runner Image", + "Fetching the repository", + "Checking out the ref", + "Setting up auth", + "Setting up auth for fetching submodules", + "Getting Git version info", + "Initializing the repository", + "Determining the checkout info", + "Persisting credentials for submodules", + ] + return groups.filter(({ title }) => !ignoreSteps.includes(title)) +} + +function cleanLog(text: string) { + return text + .replace( + // timestamps + /^?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{2,}Z /gm, + "" + ) + .replace(/\x1b\[[0-9;]*m/g, "") // ascii colors +} diff --git a/packages/sample/package.json b/packages/sample/package.json index 8b48e02f7a..b1649ebf15 100644 --- a/packages/sample/package.json +++ b/packages/sample/package.json @@ -22,6 +22,7 @@ "@azure/storage-blob": "^12.24.0", "@tidyjs/tidy": "^2.5.2", "@xenova/transformers": "^2.17.2", + "octokit": "^4.0.2", "p-all": "^5.0.0", "vectorstore": "^0.0.4", "zod": "^3.23.8", diff --git a/yarn.lock b/yarn.lock index 2e87d01f3c..7eee39c3af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1044,6 +1044,221 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@octokit/app@^15.0.0": + version "15.1.0" + resolved "https://registry.yarnpkg.com/@octokit/app/-/app-15.1.0.tgz#b330d8826be088ec8d1d43a59dc27ef57d1232b2" + integrity sha512-TkBr7QgOmE6ORxvIAhDbZsqPkF7RSqTY4pLTtUQCvr6dTXqvi2fFo46q3h1lxlk/sGMQjqyZ0kEahkD/NyzOHg== + dependencies: + "@octokit/auth-app" "^7.0.0" + "@octokit/auth-unauthenticated" "^6.0.0" + "@octokit/core" "^6.1.2" + "@octokit/oauth-app" "^7.0.0" + "@octokit/plugin-paginate-rest" "^11.0.0" + "@octokit/types" "^13.0.0" + "@octokit/webhooks" "^13.0.0" + +"@octokit/auth-app@^7.0.0": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-app/-/auth-app-7.1.1.tgz#d8916ad01e6ffb0a0a50507aa613e91fe7a49b93" + integrity sha512-kRAd6yelV9OgvlEJE88H0VLlQdZcag9UlLr7dV0YYP37X8PPDvhgiTy66QVhDXdyoT0AleFN2w/qXkPdrSzINg== + dependencies: + "@octokit/auth-oauth-app" "^8.1.0" + "@octokit/auth-oauth-user" "^5.1.0" + "@octokit/request" "^9.1.1" + "@octokit/request-error" "^6.1.1" + "@octokit/types" "^13.4.1" + lru-cache "^10.0.0" + universal-github-app-jwt "^2.2.0" + universal-user-agent "^7.0.0" + +"@octokit/auth-oauth-app@^8.0.0", "@octokit/auth-oauth-app@^8.1.0": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-app/-/auth-oauth-app-8.1.1.tgz#6204affa6e86f535016799cadf2af9befe5e893c" + integrity sha512-5UtmxXAvU2wfcHIPPDWzVSAWXVJzG3NWsxb7zCFplCWEmMCArSZV0UQu5jw5goLQXbFyOr5onzEH37UJB3zQQg== + dependencies: + "@octokit/auth-oauth-device" "^7.0.0" + "@octokit/auth-oauth-user" "^5.0.1" + "@octokit/request" "^9.0.0" + "@octokit/types" "^13.0.0" + universal-user-agent "^7.0.0" + +"@octokit/auth-oauth-device@^7.0.0", "@octokit/auth-oauth-device@^7.0.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-device/-/auth-oauth-device-7.1.1.tgz#7b4f8f97cbcadbe9894d48cde4406dbdef39875a" + integrity sha512-HWl8lYueHonuyjrKKIup/1tiy0xcmQCdq5ikvMO1YwkNNkxb6DXfrPjrMYItNLyCP/o2H87WuijuE+SlBTT8eg== + dependencies: + "@octokit/oauth-methods" "^5.0.0" + "@octokit/request" "^9.0.0" + "@octokit/types" "^13.0.0" + universal-user-agent "^7.0.0" + +"@octokit/auth-oauth-user@^5.0.1", "@octokit/auth-oauth-user@^5.1.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-oauth-user/-/auth-oauth-user-5.1.1.tgz#4f1570c6ee15bb9ddc3dcca83308dcaa159e3848" + integrity sha512-rRkMz0ErOppdvEfnemHJXgZ9vTPhBuC6yASeFaB7I2yLMd7QpjfrL1mnvRPlyKo+M6eeLxrKanXJ9Qte29SRsw== + dependencies: + "@octokit/auth-oauth-device" "^7.0.1" + "@octokit/oauth-methods" "^5.0.0" + "@octokit/request" "^9.0.1" + "@octokit/types" "^13.0.0" + universal-user-agent "^7.0.0" + +"@octokit/auth-token@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-5.1.1.tgz#3bbfe905111332a17f72d80bd0b51a3e2fa2cf07" + integrity sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA== + +"@octokit/auth-unauthenticated@^6.0.0", "@octokit/auth-unauthenticated@^6.0.0-beta.1": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@octokit/auth-unauthenticated/-/auth-unauthenticated-6.1.0.tgz#de0fe923bb06ed93aea526ab99972a98c546d0bf" + integrity sha512-zPSmfrUAcspZH/lOFQnVnvjQZsIvmfApQH6GzJrkIunDooU1Su2qt2FfMTSVPRp7WLTQyC20Kd55lF+mIYaohQ== + dependencies: + "@octokit/request-error" "^6.0.1" + "@octokit/types" "^13.0.0" + +"@octokit/core@^6.0.0", "@octokit/core@^6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-6.1.2.tgz#20442d0a97c411612da206411e356014d1d1bd17" + integrity sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg== + dependencies: + "@octokit/auth-token" "^5.0.0" + "@octokit/graphql" "^8.0.0" + "@octokit/request" "^9.0.0" + "@octokit/request-error" "^6.0.1" + "@octokit/types" "^13.0.0" + before-after-hook "^3.0.2" + universal-user-agent "^7.0.0" + +"@octokit/endpoint@^10.0.0": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-10.1.1.tgz#1a9694e7aef6aa9d854dc78dd062945945869bcc" + integrity sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q== + dependencies: + "@octokit/types" "^13.0.0" + universal-user-agent "^7.0.2" + +"@octokit/graphql@^8.0.0": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-8.1.1.tgz#3cacab5f2e55d91c733e3bf481d3a3f8a5f639c4" + integrity sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg== + dependencies: + "@octokit/request" "^9.0.0" + "@octokit/types" "^13.0.0" + universal-user-agent "^7.0.0" + +"@octokit/oauth-app@^7.0.0": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@octokit/oauth-app/-/oauth-app-7.1.3.tgz#a0f256dd185e7c00bfbc3e6bc3c5aad66e42c609" + integrity sha512-EHXbOpBkSGVVGF1W+NLMmsnSsJRkcrnVmDKt0TQYRBb6xWfWzoi9sBD4DIqZ8jGhOWO/V8t4fqFyJ4vDQDn9bg== + dependencies: + "@octokit/auth-oauth-app" "^8.0.0" + "@octokit/auth-oauth-user" "^5.0.1" + "@octokit/auth-unauthenticated" "^6.0.0-beta.1" + "@octokit/core" "^6.0.0" + "@octokit/oauth-authorization-url" "^7.0.0" + "@octokit/oauth-methods" "^5.0.0" + "@types/aws-lambda" "^8.10.83" + universal-user-agent "^7.0.0" + +"@octokit/oauth-authorization-url@^7.0.0": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@octokit/oauth-authorization-url/-/oauth-authorization-url-7.1.1.tgz#0e17c2225eb66b58ec902d02b6f1315ffe9ff04b" + integrity sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA== + +"@octokit/oauth-methods@^5.0.0": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@octokit/oauth-methods/-/oauth-methods-5.1.2.tgz#fd31d2a69f4c91d1abc1ed1814dda5252c697e02" + integrity sha512-C5lglRD+sBlbrhCUTxgJAFjWgJlmTx5bQ7Ch0+2uqRjYv7Cfb5xpX4WuSC9UgQna3sqRGBL9EImX9PvTpMaQ7g== + dependencies: + "@octokit/oauth-authorization-url" "^7.0.0" + "@octokit/request" "^9.1.0" + "@octokit/request-error" "^6.1.0" + "@octokit/types" "^13.0.0" + +"@octokit/openapi-types@^22.2.0": + version "22.2.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-22.2.0.tgz#75aa7dcd440821d99def6a60b5f014207ae4968e" + integrity sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg== + +"@octokit/openapi-webhooks-types@8.3.0": + version "8.3.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-webhooks-types/-/openapi-webhooks-types-8.3.0.tgz#a7a4da00c0f27f7f5708eb3fcebefa08f8d51125" + integrity sha512-vKLsoR4xQxg4Z+6rU/F65ItTUz/EXbD+j/d4mlq2GW8TsA4Tc8Kdma2JTAAJ5hrKWUQzkR/Esn2fjsqiVRYaQg== + +"@octokit/plugin-paginate-graphql@^5.0.0": + version "5.2.3" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-5.2.3.tgz#19882ff4694066b0937aea85b7e8eac512df4e9a" + integrity sha512-EzFueuXVU3VHv5FwEXbdznn9EmyF0vA5LGDX6a8fJ9YJAlDgdYHRKJMO4Ghl2PPPJBxIPMDUJMnlUHqcvP7AnQ== + +"@octokit/plugin-paginate-rest@^11.0.0": + version "11.3.3" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.3.tgz#efc97ba66aae6797e2807a082f99b9cfc0e05aba" + integrity sha512-o4WRoOJZlKqEEgj+i9CpcmnByvtzoUYC6I8PD2SA95M+BJ2x8h7oLcVOg9qcowWXBOdcTRsMZiwvM3EyLm9AfA== + dependencies: + "@octokit/types" "^13.5.0" + +"@octokit/plugin-rest-endpoint-methods@^13.0.0": + version "13.2.4" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.4.tgz#543add032d3fe3f5d2839bfd619cf66d85469f01" + integrity sha512-gusyAVgTrPiuXOdfqOySMDztQHv6928PQ3E4dqVGEtOvRXAKRbJR4b1zQyniIT9waqaWk/UDaoJ2dyPr7Bk7Iw== + dependencies: + "@octokit/types" "^13.5.0" + +"@octokit/plugin-retry@^7.0.0": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-retry/-/plugin-retry-7.1.2.tgz#242e2d19a72a50b5113bb25d7d2c622ce0373fa0" + integrity sha512-XOWnPpH2kJ5VTwozsxGurw+svB2e61aWlmk5EVIYZPwFK5F9h4cyPyj9CIKRyMXMHSwpIsI3mPOdpMmrRhe7UQ== + dependencies: + "@octokit/request-error" "^6.0.0" + "@octokit/types" "^13.0.0" + bottleneck "^2.15.3" + +"@octokit/plugin-throttling@^9.0.0": + version "9.3.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-throttling/-/plugin-throttling-9.3.1.tgz#5648165e1e70e861625f3a16af6c55cafe861061" + integrity sha512-Qd91H4liUBhwLB2h6jZ99bsxoQdhgPk6TdwnClPyTBSDAdviGPceViEgUwj+pcQDmB/rfAXAXK7MTochpHM3yQ== + dependencies: + "@octokit/types" "^13.0.0" + bottleneck "^2.15.3" + +"@octokit/request-error@^6.0.0", "@octokit/request-error@^6.0.1", "@octokit/request-error@^6.1.0", "@octokit/request-error@^6.1.1": + version "6.1.5" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-6.1.5.tgz#907099e341c4e6179db623a0328d678024f54653" + integrity sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ== + dependencies: + "@octokit/types" "^13.0.0" + +"@octokit/request@^9.0.0", "@octokit/request@^9.0.1", "@octokit/request@^9.1.0", "@octokit/request@^9.1.1": + version "9.1.3" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-9.1.3.tgz#42b693bc06238f43af3c037ebfd35621c6457838" + integrity sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA== + dependencies: + "@octokit/endpoint" "^10.0.0" + "@octokit/request-error" "^6.0.1" + "@octokit/types" "^13.1.0" + universal-user-agent "^7.0.2" + +"@octokit/types@^13.0.0", "@octokit/types@^13.1.0", "@octokit/types@^13.4.1", "@octokit/types@^13.5.0": + version "13.5.1" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-13.5.1.tgz#5685a91f295195ddfff39723b093b0df9609ce6e" + integrity sha512-F41lGiWBKPIWPBgjSvaDXTTQptBujnozENAK3S//nj7xsFdYdirImKlBB/hTjr+Vii68SM+8jG3UJWRa6DMuDA== + dependencies: + "@octokit/openapi-types" "^22.2.0" + +"@octokit/webhooks-methods@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-methods/-/webhooks-methods-5.1.0.tgz#13b6c08f89902c1ab0ddf31c6eeeec9c2772cfe6" + integrity sha512-yFZa3UH11VIxYnnoOYCVoJ3q4ChuSOk2IVBBQ0O3xtKX4x9bmKb/1t+Mxixv2iUhzMdOl1qeWJqEhouXXzB3rQ== + +"@octokit/webhooks@^13.0.0": + version "13.3.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks/-/webhooks-13.3.0.tgz#fd5d54d47c789c75d60a00eb04e982152d7c654a" + integrity sha512-TUkJLtI163Bz5+JK0O+zDkQpn4gKwN+BovclUvCj6pI/6RXrFqQvUMRS2M+Rt8Rv0qR3wjoMoOPmpJKeOh0nBg== + dependencies: + "@octokit/openapi-webhooks-types" "8.3.0" + "@octokit/request-error" "^6.0.1" + "@octokit/webhooks-methods" "^5.0.0" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -1140,6 +1355,16 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== +"@types/aws-lambda@^8.10.83": + version "8.10.145" + resolved "https://registry.yarnpkg.com/@types/aws-lambda/-/aws-lambda-8.10.145.tgz#b2d31a987f4888e5553ff1819f57cafa475594d9" + integrity sha512-dtByW6WiFk5W5Jfgz1VM+YPA21xMXTuSFoLYIDY0L44jDLLflVPtZkYuu3/YxpGcvjzKFBZLU+GyKjR0HOYtyw== + +"@types/diff@^5.2.2": + version "5.2.2" + resolved "https://registry.yarnpkg.com/@types/diff/-/diff-5.2.2.tgz#d430dbb1da6739f1e2565c2c80b54184d4c77658" + integrity sha512-qVqLpd49rmJA2nZzLVsmfS/aiiBpfVE95dHhPVwG0NmSBAt+riPxnj53wq2oBq5m4Q2RF1IWFEUpnZTgrQZfEQ== + "@types/docker-modem@*": version "3.0.6" resolved "https://registry.yarnpkg.com/@types/docker-modem/-/docker-modem-3.0.6.tgz#1f9262fcf85425b158ca725699a03eb23cddbf87" @@ -1746,6 +1971,11 @@ bcrypt-pbkdf@^1.0.2: dependencies: tweetnacl "^0.14.3" +before-after-hook@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-3.0.2.tgz#d5665a5fa8b62294a5aa0a499f933f4a1016195d" + integrity sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A== + bl@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" @@ -1770,6 +2000,11 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +bottleneck@^2.15.3: + version "2.19.5" + resolved "https://registry.yarnpkg.com/bottleneck/-/bottleneck-2.19.5.tgz#5df0b90f59fd47656ebe63c78a98419205cadd91" + integrity sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2276,6 +2511,11 @@ detect-libc@^2.0.0, detect-libc@^2.0.2: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== +diff@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a" + integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== + dingbat-to-unicode@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz#5091dd673241453e6b5865e26e5a4452cdef5c83" @@ -3870,6 +4110,11 @@ lowercase-keys@^3.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== +lru-cache@^10.0.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^11.0.0: version "11.0.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.1.tgz#3a732fbfedb82c5ba7bca6564ad3f42afcb6e147" @@ -4313,6 +4558,22 @@ object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" +octokit@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/octokit/-/octokit-4.0.2.tgz#775d68d363cdaec69d7b73d3dc82ae909d30f59b" + integrity sha512-wbqF4uc1YbcldtiBFfkSnquHtECEIpYD78YUXI6ri1Im5OO2NLo6ZVpRdbJpdnpZ05zMrVPssNiEo6JQtea+Qg== + dependencies: + "@octokit/app" "^15.0.0" + "@octokit/core" "^6.0.0" + "@octokit/oauth-app" "^7.0.0" + "@octokit/plugin-paginate-graphql" "^5.0.0" + "@octokit/plugin-paginate-rest" "^11.0.0" + "@octokit/plugin-rest-endpoint-methods" "^13.0.0" + "@octokit/plugin-retry" "^7.0.0" + "@octokit/plugin-throttling" "^9.0.0" + "@octokit/request-error" "^6.0.0" + "@octokit/types" "^13.0.0" + omggif@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" @@ -5771,6 +6032,16 @@ unique-string@^3.0.0: dependencies: crypto-random-string "^4.0.0" +universal-github-app-jwt@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/universal-github-app-jwt/-/universal-github-app-jwt-2.2.0.tgz#dc6c8929e76f1996a766ba2a08fb420f73365d77" + integrity sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ== + +universal-user-agent@^7.0.0, universal-user-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-7.0.2.tgz#52e7d0e9b3dc4df06cc33cb2b9fd79041a54827e" + integrity sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q== + universalify@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"