Repository: stateful/vscode-runme
Pull request #494 (2023-05-09 17:26:46)

GitHub authentication
This PR register a command to authenticate with GitHub (used for testing purposes) and a new GitHub service that provides access to GitHub API via Octokit.

The command was used to test a workflow dispatch event https://github.com/stateful/runme-canary/actions/runs/4928319668/jobs/8806523478

how to dispatch a workflow with the API:

1. Get a GitHub Access Token 
```
const session = await authentication.getSession('github', ['repo'], { createIfNone: true })
const githubService = new GitHubService(session.accessToken)
```
2.  Dispatch a workflow
```
await githubService.createWorkflowDispatch({
   owner: 'stateful',
    repo: 'runme-canary',
    workflow_id: 'test-inputs.yml',
    ref: 'main',
    inputs: {
      publishMarketplace: 'no',
      publishOpenVSX: 'no',
      releaseChannel: 'edge',
      releaseType: 'patch',
      releaseVersion: 'v5.0.1'
    }
})
```
This PR also introduces a method to download the YAML file contents from a Workflow file.

The above methods can be called from a cell execution (not included in this PR)



Patch:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2e08a244..6551e4b1 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -77,7 +77,7 @@ jobs:
         if: ${{ github.event.inputs.releaseChannel == 'stable' }}
       
       - name: Run Tests
-        uses: GabrielBB/xvfb-action@v1
+        uses: coactions/setup-xvfb@v1
         with:
           run: npm test
           options: "-screen 0 1600x1200x24"
diff --git a/examples/branchGPT.md b/examples/branchGPT.md
index f5af4fa6..2423a421 100644
--- a/examples/branchGPT.md
+++ b/examples/branchGPT.md
@@ -2,17 +2,27 @@
 
 [![](https://badgen.net/badge/Run%20this%20/Demo/5B3ADF?icon=https://runme.dev/img/logo.svg)](https://runme.dev/api/runme?repository=https://github.com/stateful/vscode-runme.git&fileToOpen=examples/branchGPT.md)
 
-Install or download binary at https://github.com/stateful/runme/releases/tag/v1.1.0
+On Windows, install via scoop (https://scoop.sh):
 
 ```sh
-$ npm install -g runme # install via node.js
-$ brew install stateful/tap/runme # install via homebrew on macOS
+$ scoop bucket add stateful https://github.com/stateful/scoop-bucket.git
+$ scoop install stateful/runme
 ```
 
+On macOS, install via Homebrew (https://brew.sh):
+
+```sh
+$ brew install stateful/tap/runme
+```
+
+Binaries are also available at https://github.com/stateful/runme/releases/latest
+
+## Demo
+
 Just enter some free-flow description and voilà, get some branch suggestions:
 
 ```sh
-$ npx runme branchGPT
+$ runme branchGPT
 ```
 
-_Read the docs on [runme.dev](https://www.runme.dev/docs/intro) to learn how to get most out of Runme notebooks!_
+*Read the docs on [runme.dev](https://www.runme.dev/docs/intro) to learn how to get most out of Runme notebooks!*
diff --git a/examples/k8s/README.md b/examples/k8s/README.md
index 1d74af8a..0bd958d7 100644
--- a/examples/k8s/README.md
+++ b/examples/k8s/README.md
@@ -1,6 +1,7 @@
 # Deploying a Dockerized React App to Kubernetes Cluster
 
 ## Prerequisites
+
 * Tutorial was done on macOS.
 * Tutorial assumes you have Homebrew installed on you computer. If not, you can install here: https://brew.sh
 * Tutorial assumes you have Docker installed on your computer. If not, you can install it here: https://docs.docker.com/docker-for-mac/install/
@@ -8,34 +9,36 @@
 ## Step 1: Dockerize app
 
 ### Build Docker image
-```sh
+
+```sh { name=docker-build }
 $ docker build -t runme/demo .
 ```
 
 ### Run image locally to make sure it works
-```sh { interactive=false }
-$ docker run -d -p 3000:3000 runme/demo:latest
+
+```sh { name=docker-run interactive=false }
+$ export RUNME_CID=$(docker run -d -p 3000:3000 runme/demo:latest)
+$ echo "Container running with ID $RUNME_CID"
 ```
 
 ### Open Application
 
 And see it running:
 
-```sh
+```sh { name=open-app interactive=false }
 open http://localhost:3000
 ```
 
 then stop the container:
 
-```sh { interactive=false }
-$ docker ps | grep runme/demo:latest
+```sh { name=docker-inspect interactive=false mimeType=text/x-json promptEnv=false }
+$ docker inspect $RUNME_CID | jq ".[0].State"
 ```
 
 Stop the container via:
 
-```sh
-$ export RUNME_CID=<container-id>
-$ docker stop $RUNME_CID
+```sh { name=docker-stop interactive=false }
+$ docker stop $RUNME_CID > /dev/null && echo "Stopped container with ID $RUNME_CID"
 ```
 
 ## Step 2: Deploy application to Kubernetes Cluster with Linkerd
diff --git a/package-lock.json b/package-lock.json
index 8a3cfa7f..b0efa85a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "runme",
-  "version": "1.2.1-edge.2",
+  "version": "1.3.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "runme",
-      "version": "1.2.1-edge.2",
+      "version": "1.3.0",
       "hasInstallScript": true,
       "license": "Apache-2.0",
       "dependencies": {
@@ -25,6 +25,7 @@
         "get-port": "^6.1.2",
         "got": "^12.5.3",
         "lit": "^2.6.1",
+        "octokit": "^2.0.14",
         "preact": "^10.11.3",
         "undici": "^5.16.0",
         "uuid": "^9.0.0",
@@ -37,6 +38,7 @@
         "xterm-addon-unicode11": "^0.5.0",
         "xterm-addon-web-links": "^0.8.0",
         "xterm-headless": "^5.1.0",
+        "yaml": "^2.2.2",
         "yargs": "^17.6.2",
         "zod": "^3.20.2"
       },
@@ -2994,11 +2996,115 @@
         "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
       }
     },
+    "node_modules/@octokit/app": {
+      "version": "13.1.3",
+      "resolved": "https://registry.npmjs.org/@octokit/app/-/app-13.1.3.tgz",
+      "integrity": "sha512-qG3a3AddK/XLmtpQuB2eICbOUTwwdvqfdnyOzU6PlHhhhVapLfuutkbTOllHB/5OS/slUamIBD3zhOYpKsLFDQ==",
+      "dependencies": {
+        "@octokit/auth-app": "^4.0.8",
+        "@octokit/auth-unauthenticated": "^3.0.0",
+        "@octokit/core": "^4.0.0",
+        "@octokit/oauth-app": "^4.0.7",
+        "@octokit/plugin-paginate-rest": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "@octokit/webhooks": "^10.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/auth-app": {
+      "version": "4.0.10",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.10.tgz",
+      "integrity": "sha512-cLFDd7Z0TkBB0BLt3rWXNS5f2eTeAjzG9iQlFQ6ttNPaXNdYMtnQmr2NBDFq3WnZFSct9dpSdFaVuquRrCY67w==",
+      "dependencies": {
+        "@octokit/auth-oauth-app": "^5.0.0",
+        "@octokit/auth-oauth-user": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/request-error": "^3.0.0",
+        "@octokit/types": "^9.0.0",
+        "@types/lru-cache": "^5.1.0",
+        "deprecation": "^2.3.1",
+        "lru-cache": "^6.0.0",
+        "universal-github-app-jwt": "^1.1.1",
+        "universal-user-agent": "^6.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/auth-app/node_modules/@types/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw=="
+    },
+    "node_modules/@octokit/auth-app/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@octokit/auth-app/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    },
+    "node_modules/@octokit/auth-oauth-app": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.5.tgz",
+      "integrity": "sha512-UPX1su6XpseaeLVCi78s9droxpGtBWIgz9XhXAx9VXabksoF0MyI5vaa1zo1njyYt6VaAjFisC2A2Wchcu2WmQ==",
+      "dependencies": {
+        "@octokit/auth-oauth-device": "^4.0.0",
+        "@octokit/auth-oauth-user": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "@types/btoa-lite": "^1.0.0",
+        "btoa-lite": "^1.0.0",
+        "universal-user-agent": "^6.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/auth-oauth-device": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.4.tgz",
+      "integrity": "sha512-Xl85BZYfqCMv+Uvz33nVVUjE7I/PVySNaK6dRRqlkvYcArSr9vRcZC9KVjXYObGRTCN6mISeYdakAZvWEN4+Jw==",
+      "dependencies": {
+        "@octokit/oauth-methods": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "universal-user-agent": "^6.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/auth-oauth-user": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.1.tgz",
+      "integrity": "sha512-JgqnNNPf9CaWLxWm9uh2WgxcaVYhxBR09NVIPTiMU2dVZ3FObOHs3njBiLNw+zq84k+rEdm5Y7AsiASrZ84Apg==",
+      "dependencies": {
+        "@octokit/auth-oauth-device": "^4.0.0",
+        "@octokit/oauth-methods": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "btoa-lite": "^1.0.0",
+        "universal-user-agent": "^6.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
     "node_modules/@octokit/auth-token": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz",
       "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==",
-      "dev": true,
       "dependencies": {
         "@octokit/types": "^9.0.0"
       },
@@ -3006,11 +3112,22 @@
         "node": ">= 14"
       }
     },
+    "node_modules/@octokit/auth-unauthenticated": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.4.tgz",
+      "integrity": "sha512-AT74XGBylcLr4lmUp1s6mjSUgphGdlse21Qjtv5DzpX1YOl5FXKwvNcZWESdhyBbpDT8VkVyLFqa/7a7eqpPNw==",
+      "dependencies": {
+        "@octokit/request-error": "^3.0.0",
+        "@octokit/types": "^9.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
     "node_modules/@octokit/core": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
       "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
-      "dev": true,
       "dependencies": {
         "@octokit/auth-token": "^3.0.0",
         "@octokit/graphql": "^5.0.0",
@@ -3028,7 +3145,6 @@
       "version": "7.0.5",
       "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz",
       "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==",
-      "dev": true,
       "dependencies": {
         "@octokit/types": "^9.0.0",
         "is-plain-object": "^5.0.0",
@@ -3042,7 +3158,6 @@
       "version": "5.0.5",
       "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz",
       "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==",
-      "dev": true,
       "dependencies": {
         "@octokit/request": "^6.0.0",
         "@octokit/types": "^9.0.0",
@@ -3052,17 +3167,57 @@
         "node": ">= 14"
       }
     },
+    "node_modules/@octokit/oauth-app": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-4.2.1.tgz",
+      "integrity": "sha512-HtRWLzvAAizuFKJEoNlhWOktNNhfnLSXJXu2htt5+x2exhHibHupz/+1AAHU4xlBFtQLQh79OB/bQf+1GP5LBg==",
+      "dependencies": {
+        "@octokit/auth-oauth-app": "^5.0.0",
+        "@octokit/auth-oauth-user": "^2.0.0",
+        "@octokit/auth-unauthenticated": "^3.0.0",
+        "@octokit/core": "^4.0.0",
+        "@octokit/oauth-authorization-url": "^5.0.0",
+        "@octokit/oauth-methods": "^2.0.0",
+        "@types/aws-lambda": "^8.10.83",
+        "fromentries": "^1.3.1",
+        "universal-user-agent": "^6.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/oauth-authorization-url": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz",
+      "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==",
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/oauth-methods": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.5.tgz",
+      "integrity": "sha512-yQP6B5gE3axNxuM3U9KqWs/ErAQ+WLPaPgC/7EjsZsQibkf8sjdAfF8/y/EJW+Dd05XQvadX4WhQZPMnO1SE1A==",
+      "dependencies": {
+        "@octokit/oauth-authorization-url": "^5.0.0",
+        "@octokit/request": "^6.2.3",
+        "@octokit/request-error": "^3.0.3",
+        "@octokit/types": "^9.0.0",
+        "btoa-lite": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
     "node_modules/@octokit/openapi-types": {
       "version": "17.1.1",
       "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.1.1.tgz",
-      "integrity": "sha512-/X7Gh/qWiWaooJmUnYD48SYy72fyrk2ceisOSe89JojK7r0j8YrTwYpDi76kI+c6QiqX1KSgdoBTMJvktsDkYw==",
-      "dev": true
+      "integrity": "sha512-/X7Gh/qWiWaooJmUnYD48SYy72fyrk2ceisOSe89JojK7r0j8YrTwYpDi76kI+c6QiqX1KSgdoBTMJvktsDkYw=="
     },
     "node_modules/@octokit/plugin-paginate-rest": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz",
       "integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==",
-      "dev": true,
       "dependencies": {
         "@octokit/types": "^9.0.0"
       },
@@ -3086,7 +3241,6 @@
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.0.1.tgz",
       "integrity": "sha512-pnCaLwZBudK5xCdrR823xHGNgqOzRnJ/mpC/76YPpNP7DybdsJtP7mdOwh+wYZxK5jqeQuhu59ogMI4NRlBUvA==",
-      "dev": true,
       "dependencies": {
         "@octokit/types": "^9.0.0",
         "deprecation": "^2.3.1"
@@ -3098,11 +3252,40 @@
         "@octokit/core": ">=3"
       }
     },
+    "node_modules/@octokit/plugin-retry": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.1.3.tgz",
+      "integrity": "sha512-3YKBj7d0J/4mpEc4xzMociWsMNl5lZqrpAnYcW6mqiSGF3wFjU+c6GHih6GLClk31JNvKDr0x9jc5cfm7evkZg==",
+      "dependencies": {
+        "@octokit/types": "^9.0.0",
+        "bottleneck": "^2.15.3"
+      },
+      "engines": {
+        "node": ">= 14"
+      },
+      "peerDependencies": {
+        "@octokit/core": ">=3"
+      }
+    },
+    "node_modules/@octokit/plugin-throttling": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.0.tgz",
+      "integrity": "sha512-qWYvVIS1aRC3hN4a0ICWUp51IolHIn7E4iri2AKjbExJaovMDvRtae4nGoxG5pP6+WATk7JZ5epOJobFbGYV1w==",
+      "dependencies": {
+        "@octokit/types": "^9.0.0",
+        "bottleneck": "^2.15.3"
+      },
+      "engines": {
+        "node": ">= 14"
+      },
+      "peerDependencies": {
+        "@octokit/core": "^4.0.0"
+      }
+    },
     "node_modules/@octokit/request": {
       "version": "6.2.3",
       "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz",
       "integrity": "sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==",
-      "dev": true,
       "dependencies": {
         "@octokit/endpoint": "^7.0.0",
         "@octokit/request-error": "^3.0.0",
@@ -3119,7 +3302,6 @@
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
       "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
-      "dev": true,
       "dependencies": {
         "@octokit/types": "^9.0.0",
         "deprecation": "^2.0.0",
@@ -3148,11 +3330,37 @@
       "version": "9.2.1",
       "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.1.tgz",
       "integrity": "sha512-Vx4keMiD/CAiwVFasLcH0xBSVbKIHebIZke9i7ZbUWGNN4vJFWSYH6Nvga7UY9NIJCGa6x3QG849XTbi5wYmkA==",
-      "dev": true,
       "dependencies": {
         "@octokit/openapi-types": "^17.1.1"
       }
     },
+    "node_modules/@octokit/webhooks": {
+      "version": "10.9.1",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-10.9.1.tgz",
+      "integrity": "sha512-5NXU4VfsNOo2VSU/SrLrpPH2Z1ZVDOWFcET4EpnEBX1uh/v8Uz65UVuHIRx5TZiXhnWyRE9AO1PXHa+M/iWwZA==",
+      "dependencies": {
+        "@octokit/request-error": "^3.0.0",
+        "@octokit/webhooks-methods": "^3.0.0",
+        "@octokit/webhooks-types": "6.11.0",
+        "aggregate-error": "^3.1.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/webhooks-methods": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-3.0.2.tgz",
+      "integrity": "sha512-Vlnv5WBscf07tyAvfDbp7pTkMZUwk7z7VwEF32x6HqI+55QRwBTcT+D7DDjZXtad/1dU9E32x0HmtDlF9VIRaQ==",
+      "engines": {
+        "node": ">= 14"
+      }
+    },
+    "node_modules/@octokit/webhooks-types": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-6.11.0.tgz",
+      "integrity": "sha512-AanzbulOHljrku1NGfafxdpTCfw2ENaWzH01N2vqQM+cUFbk868Cgh0xylz0JIM9BoKbfI++bdD6EYX0Q/UTEw=="
+    },
     "node_modules/@pkgjs/parseargs": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -4081,6 +4289,16 @@
       "resolved": "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.2.1.tgz",
       "integrity": "sha512-yMQ6CVgICWtyFNBqJT3zqOc+TnqqEPLo4nKJNPFwcialiylil38Ie6q1ENeFTjvaLOkVim9K5LisHgAKJWidGQ=="
     },
+    "node_modules/@types/aws-lambda": {
+      "version": "8.10.115",
+      "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.115.tgz",
+      "integrity": "sha512-kCZuFXKLV3y8NjSoaD5+qKTpRWvPz3uh3W/u1uwlw3Mg+MtaStg1NWgjAwUXo/VJDb6n6KF1ljykFNlNwEJ53Q=="
+    },
+    "node_modules/@types/btoa-lite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz",
+      "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg=="
+    },
     "node_modules/@types/cacheable-request": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
@@ -4210,6 +4428,14 @@
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
       "dev": true
     },
+    "node_modules/@types/jsonwebtoken": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+      "integrity": "sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/keyv": {
       "version": "3.1.4",
       "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
@@ -7206,8 +7432,7 @@
     "node_modules/before-after-hook": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
-      "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
-      "dev": true
+      "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
     },
     "node_modules/big-integer": {
       "version": "1.6.51",
@@ -7334,6 +7559,11 @@
       "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
       "dev": true
     },
+    "node_modules/bottleneck": {
+      "version": "2.19.5",
+      "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
+      "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
+    },
     "node_modules/bplist-parser": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
@@ -7406,6 +7636,11 @@
         "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
       }
     },
+    "node_modules/btoa-lite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
+      "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA=="
+    },
     "node_modules/buffer": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
@@ -7453,6 +7688,11 @@
         "node": "*"
       }
     },
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
     "node_modules/buffer-fill": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
@@ -8571,6 +8811,15 @@
         "node": ">=10"
       }
     },
+    "node_modules/cosmiconfig/node_modules/yaml": {
+      "version": "1.10.2",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/crc-32": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
@@ -9268,8 +9517,7 @@
     "node_modules/deprecation": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
-      "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
-      "dev": true
+      "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
     },
     "node_modules/dequal": {
       "version": "2.0.3",
@@ -9866,6 +10114,14 @@
         "wcwidth": "^1.0.1"
       }
     },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "node_modules/edge-paths": {
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz",
@@ -12276,6 +12532,25 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "node_modules/fromentries": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
+      "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
     "node_modules/fs-constants": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -13812,7 +14087,6 @@
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
       "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
-      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -14679,6 +14953,21 @@
         "graceful-fs": "^4.1.6"
       }
     },
+    "node_modules/jsonwebtoken": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
+      "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
+      "dependencies": {
+        "jws": "^3.2.2",
+        "lodash": "^4.17.21",
+        "ms": "^2.1.1",
+        "semver": "^7.3.8"
+      },
+      "engines": {
+        "node": ">=12",
+        "npm": ">=6"
+      }
+    },
     "node_modules/jszip": {
       "version": "3.10.1",
       "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
@@ -14733,6 +15022,25 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "node_modules/jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "dependencies": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "node_modules/keytar": {
       "version": "7.9.0",
       "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
@@ -17128,6 +17436,24 @@
       "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==",
       "dev": true
     },
+    "node_modules/octokit": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.14.tgz",
+      "integrity": "sha512-z6cgZBFxirpFEQ1La8Lg83GCs5hOV2EPpkYYdjsGNbfQMv8qUGjq294MiRBCbZqLufviakGsPUxaNKe3JrPmsA==",
+      "dependencies": {
+        "@octokit/app": "^13.1.1",
+        "@octokit/core": "^4.0.4",
+        "@octokit/oauth-app": "^4.0.6",
+        "@octokit/plugin-paginate-rest": "^6.0.0",
+        "@octokit/plugin-rest-endpoint-methods": "^7.0.0",
+        "@octokit/plugin-retry": "^4.0.3",
+        "@octokit/plugin-throttling": "^5.0.0",
+        "@octokit/types": "^9.0.0"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
     "node_modules/on-exit-leak-free": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz",
@@ -17949,14 +18275,6 @@
         }
       }
     },
-    "node_modules/postcss-load-config/node_modules/yaml": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
-      "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
-      "engines": {
-        "node": ">= 14"
-      }
-    },
     "node_modules/postcss-modules": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-6.0.0.tgz",
@@ -21572,11 +21890,19 @@
         "url": "https://opencollective.com/unified"
       }
     },
+    "node_modules/universal-github-app-jwt": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.1.tgz",
+      "integrity": "sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==",
+      "dependencies": {
+        "@types/jsonwebtoken": "^9.0.0",
+        "jsonwebtoken": "^9.0.0"
+      }
+    },
     "node_modules/universal-user-agent": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
-      "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
-      "dev": true
+      "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
     },
     "node_modules/universalify": {
       "version": "0.1.2",
@@ -23540,12 +23866,11 @@
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
     },
     "node_modules/yaml": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
-      "dev": true,
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
+      "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
       "engines": {
-        "node": ">= 6"
+        "node": ">= 14"
       }
     },
     "node_modules/yargs": {
@@ -25955,20 +26280,116 @@
         "json-parse-even-better-errors": "^2.3.1"
       }
     },
+    "@octokit/app": {
+      "version": "13.1.3",
+      "resolved": "https://registry.npmjs.org/@octokit/app/-/app-13.1.3.tgz",
+      "integrity": "sha512-qG3a3AddK/XLmtpQuB2eICbOUTwwdvqfdnyOzU6PlHhhhVapLfuutkbTOllHB/5OS/slUamIBD3zhOYpKsLFDQ==",
+      "requires": {
+        "@octokit/auth-app": "^4.0.8",
+        "@octokit/auth-unauthenticated": "^3.0.0",
+        "@octokit/core": "^4.0.0",
+        "@octokit/oauth-app": "^4.0.7",
+        "@octokit/plugin-paginate-rest": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "@octokit/webhooks": "^10.0.0"
+      }
+    },
+    "@octokit/auth-app": {
+      "version": "4.0.10",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.10.tgz",
+      "integrity": "sha512-cLFDd7Z0TkBB0BLt3rWXNS5f2eTeAjzG9iQlFQ6ttNPaXNdYMtnQmr2NBDFq3WnZFSct9dpSdFaVuquRrCY67w==",
+      "requires": {
+        "@octokit/auth-oauth-app": "^5.0.0",
+        "@octokit/auth-oauth-user": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/request-error": "^3.0.0",
+        "@octokit/types": "^9.0.0",
+        "@types/lru-cache": "^5.1.0",
+        "deprecation": "^2.3.1",
+        "lru-cache": "^6.0.0",
+        "universal-github-app-jwt": "^1.1.1",
+        "universal-user-agent": "^6.0.0"
+      },
+      "dependencies": {
+        "@types/lru-cache": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz",
+          "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw=="
+        },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+        }
+      }
+    },
+    "@octokit/auth-oauth-app": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.5.tgz",
+      "integrity": "sha512-UPX1su6XpseaeLVCi78s9droxpGtBWIgz9XhXAx9VXabksoF0MyI5vaa1zo1njyYt6VaAjFisC2A2Wchcu2WmQ==",
+      "requires": {
+        "@octokit/auth-oauth-device": "^4.0.0",
+        "@octokit/auth-oauth-user": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "@types/btoa-lite": "^1.0.0",
+        "btoa-lite": "^1.0.0",
+        "universal-user-agent": "^6.0.0"
+      }
+    },
+    "@octokit/auth-oauth-device": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.4.tgz",
+      "integrity": "sha512-Xl85BZYfqCMv+Uvz33nVVUjE7I/PVySNaK6dRRqlkvYcArSr9vRcZC9KVjXYObGRTCN6mISeYdakAZvWEN4+Jw==",
+      "requires": {
+        "@octokit/oauth-methods": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "universal-user-agent": "^6.0.0"
+      }
+    },
+    "@octokit/auth-oauth-user": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.1.tgz",
+      "integrity": "sha512-JgqnNNPf9CaWLxWm9uh2WgxcaVYhxBR09NVIPTiMU2dVZ3FObOHs3njBiLNw+zq84k+rEdm5Y7AsiASrZ84Apg==",
+      "requires": {
+        "@octokit/auth-oauth-device": "^4.0.0",
+        "@octokit/oauth-methods": "^2.0.0",
+        "@octokit/request": "^6.0.0",
+        "@octokit/types": "^9.0.0",
+        "btoa-lite": "^1.0.0",
+        "universal-user-agent": "^6.0.0"
+      }
+    },
     "@octokit/auth-token": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz",
       "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==",
-      "dev": true,
       "requires": {
         "@octokit/types": "^9.0.0"
       }
     },
+    "@octokit/auth-unauthenticated": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.4.tgz",
+      "integrity": "sha512-AT74XGBylcLr4lmUp1s6mjSUgphGdlse21Qjtv5DzpX1YOl5FXKwvNcZWESdhyBbpDT8VkVyLFqa/7a7eqpPNw==",
+      "requires": {
+        "@octokit/request-error": "^3.0.0",
+        "@octokit/types": "^9.0.0"
+      }
+    },
     "@octokit/core": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
       "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
-      "dev": true,
       "requires": {
         "@octokit/auth-token": "^3.0.0",
         "@octokit/graphql": "^5.0.0",
@@ -25983,7 +26404,6 @@
       "version": "7.0.5",
       "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz",
       "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==",
-      "dev": true,
       "requires": {
         "@octokit/types": "^9.0.0",
         "is-plain-object": "^5.0.0",
@@ -25994,24 +26414,54 @@
       "version": "5.0.5",
       "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz",
       "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==",
-      "dev": true,
       "requires": {
         "@octokit/request": "^6.0.0",
         "@octokit/types": "^9.0.0",
         "universal-user-agent": "^6.0.0"
       }
     },
+    "@octokit/oauth-app": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-4.2.1.tgz",
+      "integrity": "sha512-HtRWLzvAAizuFKJEoNlhWOktNNhfnLSXJXu2htt5+x2exhHibHupz/+1AAHU4xlBFtQLQh79OB/bQf+1GP5LBg==",
+      "requires": {
+        "@octokit/auth-oauth-app": "^5.0.0",
+        "@octokit/auth-oauth-user": "^2.0.0",
+        "@octokit/auth-unauthenticated": "^3.0.0",
+        "@octokit/core": "^4.0.0",
+        "@octokit/oauth-authorization-url": "^5.0.0",
+        "@octokit/oauth-methods": "^2.0.0",
+        "@types/aws-lambda": "^8.10.83",
+        "fromentries": "^1.3.1",
+        "universal-user-agent": "^6.0.0"
+      }
+    },
+    "@octokit/oauth-authorization-url": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz",
+      "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg=="
+    },
+    "@octokit/oauth-methods": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.5.tgz",
+      "integrity": "sha512-yQP6B5gE3axNxuM3U9KqWs/ErAQ+WLPaPgC/7EjsZsQibkf8sjdAfF8/y/EJW+Dd05XQvadX4WhQZPMnO1SE1A==",
+      "requires": {
+        "@octokit/oauth-authorization-url": "^5.0.0",
+        "@octokit/request": "^6.2.3",
+        "@octokit/request-error": "^3.0.3",
+        "@octokit/types": "^9.0.0",
+        "btoa-lite": "^1.0.0"
+      }
+    },
     "@octokit/openapi-types": {
       "version": "17.1.1",
       "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.1.1.tgz",
-      "integrity": "sha512-/X7Gh/qWiWaooJmUnYD48SYy72fyrk2ceisOSe89JojK7r0j8YrTwYpDi76kI+c6QiqX1KSgdoBTMJvktsDkYw==",
-      "dev": true
+      "integrity": "sha512-/X7Gh/qWiWaooJmUnYD48SYy72fyrk2ceisOSe89JojK7r0j8YrTwYpDi76kI+c6QiqX1KSgdoBTMJvktsDkYw=="
     },
     "@octokit/plugin-paginate-rest": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz",
       "integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==",
-      "dev": true,
       "requires": {
         "@octokit/types": "^9.0.0"
       }
@@ -26027,17 +26477,33 @@
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.0.1.tgz",
       "integrity": "sha512-pnCaLwZBudK5xCdrR823xHGNgqOzRnJ/mpC/76YPpNP7DybdsJtP7mdOwh+wYZxK5jqeQuhu59ogMI4NRlBUvA==",
-      "dev": true,
       "requires": {
         "@octokit/types": "^9.0.0",
         "deprecation": "^2.3.1"
       }
     },
+    "@octokit/plugin-retry": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.1.3.tgz",
+      "integrity": "sha512-3YKBj7d0J/4mpEc4xzMociWsMNl5lZqrpAnYcW6mqiSGF3wFjU+c6GHih6GLClk31JNvKDr0x9jc5cfm7evkZg==",
+      "requires": {
+        "@octokit/types": "^9.0.0",
+        "bottleneck": "^2.15.3"
+      }
+    },
+    "@octokit/plugin-throttling": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.0.tgz",
+      "integrity": "sha512-qWYvVIS1aRC3hN4a0ICWUp51IolHIn7E4iri2AKjbExJaovMDvRtae4nGoxG5pP6+WATk7JZ5epOJobFbGYV1w==",
+      "requires": {
+        "@octokit/types": "^9.0.0",
+        "bottleneck": "^2.15.3"
+      }
+    },
     "@octokit/request": {
       "version": "6.2.3",
       "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz",
       "integrity": "sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==",
-      "dev": true,
       "requires": {
         "@octokit/endpoint": "^7.0.0",
         "@octokit/request-error": "^3.0.0",
@@ -26051,7 +26517,6 @@
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
       "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
-      "dev": true,
       "requires": {
         "@octokit/types": "^9.0.0",
         "deprecation": "^2.0.0",
@@ -26074,11 +26539,31 @@
       "version": "9.2.1",
       "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.1.tgz",
       "integrity": "sha512-Vx4keMiD/CAiwVFasLcH0xBSVbKIHebIZke9i7ZbUWGNN4vJFWSYH6Nvga7UY9NIJCGa6x3QG849XTbi5wYmkA==",
-      "dev": true,
       "requires": {
         "@octokit/openapi-types": "^17.1.1"
       }
     },
+    "@octokit/webhooks": {
+      "version": "10.9.1",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-10.9.1.tgz",
+      "integrity": "sha512-5NXU4VfsNOo2VSU/SrLrpPH2Z1ZVDOWFcET4EpnEBX1uh/v8Uz65UVuHIRx5TZiXhnWyRE9AO1PXHa+M/iWwZA==",
+      "requires": {
+        "@octokit/request-error": "^3.0.0",
+        "@octokit/webhooks-methods": "^3.0.0",
+        "@octokit/webhooks-types": "6.11.0",
+        "aggregate-error": "^3.1.0"
+      }
+    },
+    "@octokit/webhooks-methods": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-3.0.2.tgz",
+      "integrity": "sha512-Vlnv5WBscf07tyAvfDbp7pTkMZUwk7z7VwEF32x6HqI+55QRwBTcT+D7DDjZXtad/1dU9E32x0HmtDlF9VIRaQ=="
+    },
+    "@octokit/webhooks-types": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-6.11.0.tgz",
+      "integrity": "sha512-AanzbulOHljrku1NGfafxdpTCfw2ENaWzH01N2vqQM+cUFbk868Cgh0xylz0JIM9BoKbfI++bdD6EYX0Q/UTEw=="
+    },
     "@pkgjs/parseargs": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -26780,6 +27265,16 @@
       "resolved": "https://registry.npmjs.org/@types/async-retry/-/async-retry-1.2.1.tgz",
       "integrity": "sha512-yMQ6CVgICWtyFNBqJT3zqOc+TnqqEPLo4nKJNPFwcialiylil38Ie6q1ENeFTjvaLOkVim9K5LisHgAKJWidGQ=="
     },
+    "@types/aws-lambda": {
+      "version": "8.10.115",
+      "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.115.tgz",
+      "integrity": "sha512-kCZuFXKLV3y8NjSoaD5+qKTpRWvPz3uh3W/u1uwlw3Mg+MtaStg1NWgjAwUXo/VJDb6n6KF1ljykFNlNwEJ53Q=="
+    },
+    "@types/btoa-lite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz",
+      "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg=="
+    },
     "@types/cacheable-request": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
@@ -26909,6 +27404,14 @@
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
       "dev": true
     },
+    "@types/jsonwebtoken": {
+      "version": "9.0.2",
+      "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+      "integrity": "sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/keyv": {
       "version": "3.1.4",
       "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
@@ -29194,8 +29697,7 @@
     "before-after-hook": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
-      "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
-      "dev": true
+      "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
     },
     "big-integer": {
       "version": "1.6.51",
@@ -29302,6 +29804,11 @@
       "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
       "dev": true
     },
+    "bottleneck": {
+      "version": "2.19.5",
+      "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
+      "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
+    },
     "bplist-parser": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
@@ -29352,6 +29859,11 @@
         "update-browserslist-db": "^1.0.10"
       }
     },
+    "btoa-lite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
+      "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA=="
+    },
     "buffer": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
@@ -29382,6 +29894,11 @@
       "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
       "dev": true
     },
+    "buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
     "buffer-fill": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
@@ -30193,6 +30710,14 @@
         "parse-json": "^5.0.0",
         "path-type": "^4.0.0",
         "yaml": "^1.10.0"
+      },
+      "dependencies": {
+        "yaml": {
+          "version": "1.10.2",
+          "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+          "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+          "dev": true
+        }
       }
     },
     "crc-32": {
@@ -30721,8 +31246,7 @@
     "deprecation": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
-      "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
-      "dev": true
+      "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
     },
     "dequal": {
       "version": "2.0.3",
@@ -31207,6 +31731,14 @@
         "wcwidth": "^1.0.1"
       }
     },
+    "ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "edge-paths": {
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz",
@@ -32953,6 +33485,11 @@
         }
       }
     },
+    "fromentries": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
+      "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg=="
+    },
     "fs-constants": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -34041,8 +34578,7 @@
     "is-plain-object": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
-      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
-      "dev": true
+      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
     },
     "is-reference": {
       "version": "3.0.1",
@@ -34692,6 +35228,17 @@
         "graceful-fs": "^4.1.6"
       }
     },
+    "jsonwebtoken": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
+      "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
+      "requires": {
+        "jws": "^3.2.2",
+        "lodash": "^4.17.21",
+        "ms": "^2.1.1",
+        "semver": "^7.3.8"
+      }
+    },
     "jszip": {
       "version": "3.10.1",
       "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
@@ -34748,6 +35295,25 @@
         }
       }
     },
+    "jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "requires": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "requires": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "keytar": {
       "version": "7.9.0",
       "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
@@ -36485,6 +37051,21 @@
       "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==",
       "dev": true
     },
+    "octokit": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.14.tgz",
+      "integrity": "sha512-z6cgZBFxirpFEQ1La8Lg83GCs5hOV2EPpkYYdjsGNbfQMv8qUGjq294MiRBCbZqLufviakGsPUxaNKe3JrPmsA==",
+      "requires": {
+        "@octokit/app": "^13.1.1",
+        "@octokit/core": "^4.0.4",
+        "@octokit/oauth-app": "^4.0.6",
+        "@octokit/plugin-paginate-rest": "^6.0.0",
+        "@octokit/plugin-rest-endpoint-methods": "^7.0.0",
+        "@octokit/plugin-retry": "^4.0.3",
+        "@octokit/plugin-throttling": "^5.0.0",
+        "@octokit/types": "^9.0.0"
+      }
+    },
     "on-exit-leak-free": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz",
@@ -37080,13 +37661,6 @@
       "requires": {
         "lilconfig": "^2.0.5",
         "yaml": "^2.1.1"
-      },
-      "dependencies": {
-        "yaml": {
-          "version": "2.2.2",
-          "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
-          "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA=="
-        }
       }
     },
     "postcss-modules": {
@@ -39759,11 +40333,19 @@
         "unist-util-is": "^5.0.0"
       }
     },
+    "universal-github-app-jwt": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.1.tgz",
+      "integrity": "sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==",
+      "requires": {
+        "@types/jsonwebtoken": "^9.0.0",
+        "jsonwebtoken": "^9.0.0"
+      }
+    },
     "universal-user-agent": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
-      "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
-      "dev": true
+      "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
     },
     "universalify": {
       "version": "0.1.2",
@@ -41029,10 +41611,9 @@
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
     },
     "yaml": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
-      "dev": true
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
+      "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA=="
     },
     "yargs": {
       "version": "17.7.2",
diff --git a/package.json b/package.json
index 55e57060..49dc02d5 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
 {
   "name": "runme",
-  "version": "1.2.1-edge.2",
+  "version": "1.3.0",
   "publisher": "stateful",
   "displayName": "Runme",
-  "description": "Run your README.md as an interactive notebook",
+  "description": "The next-gen Runner for dev workflows.",
   "author": "Sebastian Tiedtke <sebastian@stateful.com>",
   "contributors": [
     "Christian Bromann <christian@stateful.com>"
@@ -143,6 +143,12 @@
       {
         "command": "runme.file.openInRunme",
         "title": "Open in Runme"
+      },
+      {
+        "command": "runme.authenticateWithGitHub",
+        "title": "Authenticate Runme with GitHub",
+        "category": "Runme",
+        "description": "Give access to Runme to interact with GitHub API"
       }
     ],
     "menus": {
@@ -549,6 +555,7 @@
     "get-port": "^6.1.2",
     "got": "^12.5.3",
     "lit": "^2.6.1",
+    "octokit": "^2.0.14",
     "preact": "^10.11.3",
     "undici": "^5.16.0",
     "uuid": "^9.0.0",
@@ -561,6 +568,7 @@
     "xterm-addon-unicode11": "^0.5.0",
     "xterm-addon-web-links": "^0.8.0",
     "xterm-headless": "^5.1.0",
+    "yaml": "^2.2.2",
     "yargs": "^17.6.2",
     "zod": "^3.20.2"
   }
diff --git a/src/extension/commands/index.ts b/src/extension/commands/index.ts
index affab2be..5abcecdd 100644
--- a/src/extension/commands/index.ts
+++ b/src/extension/commands/index.ts
@@ -2,7 +2,7 @@ import path from 'node:path'
 
 import {
   NotebookCell, Uri, window, env, NotebookDocument, TextDocument, ViewColumn,
-  workspace, NotebookData, commands, NotebookCellData, NotebookCellKind, ExtensionContext
+  workspace, NotebookData, commands, NotebookCellData, NotebookCellKind, ExtensionContext, authentication
 } from 'vscode'
 import { v4 as uuidv4 } from 'uuid'
 
@@ -166,3 +166,11 @@ export async function tryIt (context: ExtensionContext) {
 export async function openFileInRunme (uri: Uri, selection?: Uri[]) {
   await Promise.all((selection ?? [uri]).map(openFileAsRunmeNotebook))
 }
+
+export async function authenticateWithGitHub() {
+  try {
+    await authentication.getSession('github', ['repo'], { createIfNone: true })
+  } catch (error) {
+    window.showErrorMessage('Failed to authenticate with GitHub')
+  }
+}
diff --git a/src/extension/extension.ts b/src/extension/extension.ts
index 6fb1b672..0c86090c 100644
--- a/src/extension/extension.ts
+++ b/src/extension/extension.ts
@@ -23,7 +23,8 @@ import {
   welcome,
   tryIt,
   openFileInRunme,
-  openIntegratedTerminal
+  openIntegratedTerminal,
+  authenticateWithGitHub
 } from './commands'
 import { WasmSerializer, GrpcSerializer } from './serializer'
 import { RunmeLauncherProvider } from './provider/launcher'
@@ -45,7 +46,7 @@ export class RunmeExtension {
       maxNumberOfIntents: 10,
     }, !grpcServer, grpcRunner)
 
-    let runner: IRunner|undefined
+    let runner: IRunner | undefined
     if (grpcRunner) {
       runner = new GrpcRunner(server)
       kernel.useRunner(runner)
@@ -137,7 +138,7 @@ export class RunmeExtension {
       window.registerTreeDataProvider('runme.launcher', treeViewer),
       RunmeExtension.registerCommand('runme.collapseTreeView', treeViewer.collapseAll.bind(treeViewer)),
       RunmeExtension.registerCommand('runme.expandTreeView', treeViewer.expandAll.bind(treeViewer)),
-
+      RunmeExtension.registerCommand('runme.authenticateWithGitHub', authenticateWithGitHub),
       /**
        * Uri handler
        */
diff --git a/src/extension/services/github.ts b/src/extension/services/github.ts
new file mode 100644
index 00000000..dc61dea1
--- /dev/null
+++ b/src/extension/services/github.ts
@@ -0,0 +1,44 @@
+import { Octokit } from 'octokit'
+import { parse } from 'yaml'
+
+import { IWorkflowDispatchOptions, IWorkflowYamlContentRequest } from './types'
+
+export class GitHubService {
+    private octokit: Octokit
+    constructor(accessToken: string) {
+        this.octokit = new Octokit({ auth: accessToken })
+    }
+
+    /**
+     *  Dispatch a workflow
+     */
+    async createWorkflowDispatch(dispatchOptions: IWorkflowDispatchOptions): Promise<void> {
+        const { owner, repo, workflow_id, ref, inputs } = dispatchOptions
+        await this.octokit.rest.actions.createWorkflowDispatch({
+            owner,
+            repo,
+            workflow_id,
+            ref,
+            inputs
+        })
+
+    }
+
+    /**
+     * Download the YAML content from a workflow file
+     * @returns A workflow YAML file in JSON format
+     */
+    async getWorkflowYamlFile(options: IWorkflowYamlContentRequest): Promise<string> {
+        const { owner, repo, name } = options
+        const workflow = await this.octokit.rest.repos.getContent({
+            owner,
+            repo,
+            path: `.github/workflows/${name}.yml`
+        })
+        if (!('content' in workflow.data)) {
+            throw new Error('Failed to get workflow file content')
+        }
+        const decodedContent = Buffer.from((workflow.data as any).content, 'base64').toString()
+        return parse(decodedContent)
+    }
+}
\ No newline at end of file
diff --git a/src/extension/services/index.ts b/src/extension/services/index.ts
new file mode 100644
index 00000000..833a803d
--- /dev/null
+++ b/src/extension/services/index.ts
@@ -0,0 +1,2 @@
+export { GitHubService } from './github'
+export * as types from './types'
\ No newline at end of file
diff --git a/src/extension/services/types.ts b/src/extension/services/types.ts
new file mode 100644
index 00000000..4113d807
--- /dev/null
+++ b/src/extension/services/types.ts
@@ -0,0 +1,13 @@
+export interface IWorkflowDispatchOptions {
+    owner: string
+    repo: string
+    workflow_id: string
+    ref: string
+    inputs: Record<string, string>
+}
+
+export interface IWorkflowYamlContentRequest {
+    owner: string
+    repo: string
+    name: string
+}
\ No newline at end of file


Test patch:
diff --git a/tests/extension/extension.test.ts b/tests/extension/extension.test.ts
index 05b7e686..a96edf12 100644
--- a/tests/extension/extension.test.ts
+++ b/tests/extension/extension.test.ts
@@ -63,7 +63,7 @@ test('initializes all providers', async () => {
   await ext.initialize(context)
   expect(notebooks.registerNotebookCellStatusBarItemProvider).toBeCalledTimes(6)
   expect(workspace.registerNotebookSerializer).toBeCalledTimes(1)
-  expect(commands.registerCommand).toBeCalledTimes(20)
+  expect(commands.registerCommand).toBeCalledTimes(21)
   expect(window.registerTreeDataProvider).toBeCalledTimes(1)
   expect(window.registerUriHandler).toBeCalledTimes(1)