End-to-end (passkeys, registry, email)
took 3m 22s Raw logs
Matrix: name: passkeys, registry, email, shard: rest
Failed at Run the shard's tests
Process completed with exit code 1. --- duration_ms: 3525.982777 type: 'test' ... # Subtest: a task in my terminal: only on my click, with the CLI signed in there, in a checkout of its own ok 54 - a task in my terminal: only on my click, with the CLI signed in there, in a checkout of its own --- duration_ms: 12092.892928 type: 'test' ... 1..54 # tests 54 # suites 0 # pass 53 # fail 1 # cancelled 0 # skipped 0 # todo 0 # duration_ms 154816.277506
Set up job
##[warning]The platform stopped this job's container while step "Run pnpm --filter @diffinery/app exec playwright install --with-deps chromium" ran. The job can only read (no secrets, deployment environment or token that can write), so Diffinery started the job again from the beginning on a new runner (restart 1 of 2).Diffinery runner: job e2e (End-to-end (passkeys, registry, email)) for codician/diffinery@9cf8731e7740Runner: image diffinery-runner:4d3bf17f06575e64ab4155b3, in dus02, WEUR, container 81232fec4fa88ff283d3904868de77d64a8d86cc9c1023652f0fd83970081f87Runner size: large (4 vCPU, 12 GiB of memory, 20 GB of disk), this job uses what a smaller runner doesn't have; runs-on: diffinery-large (or -medium, -small, -tiny) sets a sizeHost: AMD EPYC (family 25, model 17), 4 vCPUs, 2546 MHzWorkspace: /workspace/diffineryHost: 1% of the vCPUs' time went to other work on the host (steal)Job completed with conclusion: failureResources: 1.5 of 4 vCPUs busy on average (3.2 at the 95th percentile), peak memory 4.6 GiB of 11.9 GiB, peak disk 3.8 GB of 19.2 GB
Run actions/checkout@v41s
##[group]Run actions/checkout@v4##[endgroup]Syncing repository: codician/diffineryFetching the repository (depth 1)remote: Enumerating objects: 875, done. Receiving objects: 0% (1/875) Receiving objects: 1% (9/875) Receiving objects: 2% (18/875) Receiving objects: 3% (27/875) Receiving objects: 4% (35/875) Receiving objects: 5% (44/875) Receiving objects: 6% (53/875) Receiving objects: 7% (62/875) Receiving objects: 8% (70/875) Receiving objects: 9% (79/875) Receiving objects: 10% (88/875) Receiving objects: 11% (97/875) Receiving objects: 12% (105/875) Receiving objects: 13% (114/875) Receiving objects: 14% (123/875) Receiving objects: 15% (132/875) Receiving objects: 16% (140/875) Receiving objects: 17% (149/875) Receiving objects: 18% (158/875) Receiving objects: 19% (167/875) Receiving objects: 20% (175/875) Receiving objects: 21% (184/875) Receiving objects: 22% (193/875) Receiving objects: 23% (202/875) Receiving objects: 24% (210/875) Receiving objects: 25% (219/875) Receiving objects: 26% (228/875) Receiving objects: 27% (237/875) Receiving objects: 28% (245/875) Receiving objects: 29% (254/875) Receiving objects: 30% (263/875) Receiving objects: 31% (272/875) Receiving objects: 32% (280/875) Receiving objects: 33% (289/875) Receiving objects: 34% (298/875) Receiving objects: 35% (307/875) Receiving objects: 36% (315/875) Receiving objects: 37% (324/875) Receiving objects: 38% (333/875) Receiving objects: 39% (342/875) Receiving objects: 40% (350/875) Receiving objects: 41% (359/875) Receiving objects: 42% (368/875) Receiving objects: 43% (377/875) Receiving objects: 44% (385/875) Receiving objects: 45% (394/875) Receiving objects: 46% (403/875) Receiving objects: 47% (412/875) Receiving objects: 48% (420/875) Receiving objects: 49% (429/875) Receiving objects: 50% (438/875) Receiving objects: 51% (447/875) Receiving objects: 52% (455/875) Receiving objects: 53% (464/875) Receiving objects: 54% (473/875) Receiving objects: 55% (482/875) Receiving objects: 56% (490/875) Receiving objects: 57% (499/875) Receiving objects: 58% (508/875) Receiving objects: 59% (517/875) Receiving objects: 60% (525/875) Receiving objects: 61% (534/875) Receiving objects: 62% (543/875) Receiving objects: 63% (552/875) Receiving objects: 64% (560/875) Receiving objects: 65% (569/875) Receiving objects: 66% (578/875) Receiving objects: 67% (587/875) Receiving objects: 68% (595/875) Receiving objects: 69% (604/875) Receiving objects: 70% (613/875) Receiving objects: 71% (622/875) Receiving objects: 72% (630/875) Receiving objects: 73% (639/875) Receiving objects: 74% (648/875) Receiving objects: 75% (657/875) Receiving objects: 76% (665/875) Receiving objects: 77% (674/875) Receiving objects: 78% (683/875) Receiving objects: 79% (692/875) Receiving objects: 80% (700/875) Receiving objects: 81% (709/875) Receiving objects: 82% (718/875) Receiving objects: 83% (727/875) Receiving objects: 84% (735/875) Receiving objects: 85% (744/875) Receiving objects: 86% (753/875) Receiving objects: 87% (762/875) Receiving objects: 88% (770/875) Receiving objects: 89% (779/875) Receiving objects: 90% (788/875) Receiving objects: 91% (797/875) Receiving objects: 92% (805/875) Receiving objects: 93% (814/875) Receiving objects: 94% (823/875) Receiving objects: 95% (832/875) Receiving objects: 96% (840/875) Receiving objects: 97% (849/875) remote: Total 875 (delta 0), reused 875 (delta 0) Receiving objects: 98% (858/875) Receiving objects: 99% (867/875) Receiving objects: 100% (875/875) Receiving objects: 100% (875/875), 3.80 MiB | 28.19 MiB/s, done.From https://diffinery.com/codician/diffinery * [new ref] 9cf8731e7740ed07d0617156641c5433cf5e238c -> origin/diffinery-checkoutNote: switching to '9cf8731e7740ed07d0617156641c5433cf5e238c'.You are in 'detached HEAD' state. You can look around, make experimentalchanges and commit them, and you can discard any commits you make in thisstate without impacting any branches by switching back to a branch.If you want to create a new branch to retain commits you create, you maydo so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name>Or undo this operation with: git switch -Turn off this advice by setting config variable advice.detachedHead to falseHEAD is now at 9cf8731 Merge 5bb69a7b301619b4002cec480cd3fbc228173bc2 into db0badff555154599b606f2bbd04b6f811dca3e9HEAD is now at 9cf8731e7740ed07d0617156641c5433cf5e238c
Run pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b12s
Download action repository 'pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1'##[group]Run pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1with: dest: ~/setup-pnpm run_install: null cache: false cache_dependency_path: pnpm-lock.yaml package_json_file: package.json standalone: false##[endgroup]##[group]Running self-installer...Progress: resolved 1, reused 0, downloaded 0, added 0Packages: +1+Progress: resolved 1, reused 0, downloaded 1, added 1, donedependencies:+ pnpm 10.28.0 (12.15.0 is available)Done in 1.1s##[endgroup]Installation Completed!
Run actions/setup-node@v47s
##[group]Run actions/setup-node@v4with: node-version: 22 cache: pnpm##[endgroup]Found in cache @ 22.22.0 (pre-installed node satisfies '22')Cache Size: ~216 MB (226934503 B)Cache restored from key: node-cache-Linux-x64-pnpm-42d02c0263a3b5f911ed6ae8e9210922b97166ca02e60b2c70c55dfa1f00371b
Run pnpm install --frozen-lockfile3s
##[group]Run pnpm install --frozen-lockfile##[endgroup]Scope: all 8 workspace projectsLockfile is up to date, resolution step is skippedProgress: resolved 1, reused 0, downloaded 0, added 0Packages: +251++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Progress: resolved 251, reused 245, downloaded 0, added 206Progress: resolved 251, reused 245, downloaded 0, added 251, done.../esbuild@0.28.1/node_modules/esbuild postinstall$ node install.js.../esbuild@0.25.12/node_modules/esbuild postinstall$ node install.js.../esbuild@0.25.11/node_modules/esbuild postinstall$ node install.js.../node_modules/workerd postinstall$ node install.js.../node_modules/workerd postinstall$ node install.js.../esbuild@0.25.12/node_modules/esbuild postinstall: Done.../esbuild@0.28.1/node_modules/esbuild postinstall: Done.../esbuild@0.28.2/node_modules/esbuild postinstall$ node install.js.../esbuild@0.25.11/node_modules/esbuild postinstall: Done.../node_modules/workerd postinstall: Done.../node_modules/workerd postinstall: Done.../esbuild@0.28.2/node_modules/esbuild postinstall: DonedevDependencies:+ turbo 2.11.7+ typescript 5.9.3Done in 3.1s using pnpm v10.28.0
Run pnpm -r --if-present build3s
##[group]Run pnpm -r --if-present build##[endgroup]Scope: 7 of 8 workspace projectsapps/cli build$ esbuild src/bin.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/diffinery.mjs "--banner:js=#!/usr/bin/env nodeimport { createRequire as __diffineryCreateRequire } from 'node:module'; const require = __diffineryCreateRequire(import.meta.url);"apps/diffinery build$ node islands/build.mjs && node scripts/build-docs.mjscontainers/runner build$ esbuild src/main.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/agent.mjs --external:bufferutil --external:utf-8-validate "--banner:js=import { createRequire as __diffineryCreateRequire } from 'node:module'; const require = __diffineryCreateRequire(import.meta.url);"apps/cli build: dist/diffinery.mjs 468.9kbapps/cli build: ⚡ Done in 70msapps/cli build: Donecontainers/runner build: dist/agent.mjs 684.1kbcontainers/runner build: ⚡ Done in 76mscontainers/runner build: Doneapps/diffinery build: islands: kumo.js 466 KB, kumo.css 149 KB, terminal.js 286 KBapps/diffinery build: docs: 84 pages (+2 generated at runtime), 19 site pages, 11 images, CLI 0.1.0 (250 KiB), editor extension 0.1.1 (20 KiB), JetBrains plugin 0.1.0 (64 KiB), Claude Code plugins diffinery 0.1.3, diffinery-ci 0.2.3apps/diffinery build: Done
Run pnpm --filter @diffinery/app exec playwright install --with-deps chromium29s
##[group]Run pnpm --filter @diffinery/app exec playwright install --with-deps chromium##[endgroup]Installing dependencies...Get:1 http://archive.ubuntu.com/ubuntu noble InRelease [256 kB]Get:2 https://download.docker.com/linux/ubuntu noble InRelease [48.5 kB]Get:3 https://cli.github.com/packages stable InRelease [3917 B]Get:4 http://archive.ubuntu.com/ubuntu noble-updates InRelease [126 kB]Get:5 http://archive.ubuntu.com/ubuntu noble-backports InRelease [126 kB]Get:6 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages [86.8 kB]Get:7 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]Get:8 https://cli.github.com/packages stable/main amd64 Packages [356 B]Get:9 http://archive.ubuntu.com/ubuntu noble/multiverse amd64 Packages [331 kB]Get:10 http://archive.ubuntu.com/ubuntu noble/restricted amd64 Packages [117 kB]Get:11 http://archive.ubuntu.com/ubuntu noble/main amd64 Packages [1808 kB]Get:12 http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages [19.3 MB]Get:13 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages [1733 kB]Get:14 http://archive.ubuntu.com/ubuntu noble-updates/universe amd64 Packages [2170 kB]Get:15 http://archive.ubuntu.com/ubuntu noble-updates/restricted amd64 Packages [2231 kB]Get:16 http://archive.ubuntu.com/ubuntu noble-updates/multiverse amd64 Packages [61.7 kB]Get:17 http://archive.ubuntu.com/ubuntu noble-backports/main amd64 Packages [49.0 kB]Get:18 http://archive.ubuntu.com/ubuntu noble-backports/universe amd64 Packages [36.0 kB]Get:19 http://archive.ubuntu.com/ubuntu noble-backports/multiverse amd64 Packages [669 B]Get:20 http://security.ubuntu.com/ubuntu noble-security/multiverse amd64 Packages [55.6 kB]Get:21 http://security.ubuntu.com/ubuntu noble-security/restricted amd64 Packages [2122 kB]Get:22 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Packages [1549 kB]Get:23 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages [1411 kB]Fetched 33.8 MB in 1s (22.5 MB/s)Reading package lists...Reading package lists...Building dependency tree...Reading state information...The following additional packages will be installed: at-spi2-common fontconfig fontconfig-config libasound2-data libavahi-client3 libavahi-common-data libavahi-common3 libdatrie1 libdrm-amdgpu1 libdrm-common libdrm-intel1 libelf1t64 libfontenc1 libfribidi0 libgl1 libgl1-mesa-dri libglvnd0 libglx-mesa0 libglx0 libgraphite2-3 libharfbuzz0b libice6 libicu74 libllvm20 libpciaccess0 libpixman-1-0 libpng16-16t64 libsensors-config libsensors5 libsm6 libthai-data libthai0 libunwind8 libvulkan1 libx11-data libx11-xcb1 libxau6 libxaw7 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-randr0 libxcb-render0 libxcb-shm0 libxcb-sync1 libxcb-xfixes0 libxdmcp6 libxfont2 libxi6 libxkbfile1 libxml2 libxmu6 libxmuu1 libxpm4 libxrender1 libxshmfence1 libxt6t64 libxxf86vm1 mesa-libgallium x11-common x11-xkb-utils xauth xfonts-encodings xfonts-utils xkb-data xserver-commonSuggested packages: alsa-utils libasound2-plugins cups-common low-memory-monitor pciutils lm-sensorsRecommended packages: fonts-ipafont-mincho fonts-liberation-sans-narrow fonts-tlwg-loma alsa-ucm-conf alsa-topology-conf at-spi2-core dbus libglib2.0-data shared-mime-info xdg-user-dirs mesa-vulkan-drivers | vulkan-icd xfonts-baseThe following NEW packages will be installed: at-spi2-common fontconfig fontconfig-config fonts-freefont-ttf fonts-ipafont-gothic fonts-liberation fonts-noto-color-emoji fonts-tlwg-loma-otf fonts-unifont fonts-wqy-zenhei libasound2-data libasound2t64 libatk-bridge2.0-0t64 libatk1.0-0t64 libatspi2.0-0t64 libavahi-client3 libavahi-common-data libavahi-common3 libcairo2 libcups2t64 libdatrie1 libdbus-1-3 libdrm-amdgpu1 libdrm-common libdrm-intel1 libdrm2 libelf1t64 libfontconfig1 libfontenc1 libfreetype6 libfribidi0 libgbm1 libgl1 libgl1-mesa-dri libglib2.0-0t64 libglvnd0 libglx-mesa0 libglx0 libgraphite2-3 libharfbuzz0b libice6 libicu74 libllvm20 libnspr4 libnss3 libpango-1.0-0 libpciaccess0 libpixman-1-0 libpng16-16t64 libsensors-config libsensors5 libsm6 libthai-data libthai0 libunwind8 libvulkan1 libx11-6 libx11-data libx11-xcb1 libxau6 libxaw7 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-randr0 libxcb-render0 libxcb-shm0 libxcb-sync1 libxcb-xfixes0 libxcb1 libxcomposite1 libxdamage1 libxdmcp6 libxext6 libxfixes3 libxfont2 libxi6 libxkbcommon0 libxkbfile1 libxml2 libxmu6 libxmuu1 libxpm4 libxrandr2 libxrender1 libxshmfence1 libxt6t64 libxxf86vm1 mesa-libgallium x11-common x11-xkb-utils xauth xfonts-cyrillic xfonts-encodings xfonts-scalable xfonts-utils xkb-data xserver-common xvfb0 upgraded, 99 newly installed, 0 to remove and 5 not upgraded.Need to get 96.8 MB of archives.After this operation, 358 MB of additional disk space will be used.Get:1 http://archive.ubuntu.com/ubuntu noble/universe amd64 fonts-ipafont-gothic all 00303-21ubuntu1 [3513 kB]Get:2 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libdbus-1-3 amd64 1.14.10-4ubuntu4.1 [210 kB]Get:3 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libelf1t64 amd64 0.190-1.1ubuntu0.1 [57.8 kB]Get:4 http://archive.ubuntu.com/ubuntu noble/main amd64 libfribidi0 amd64 1.0.13-3build1 [26.1 kB]Get:5 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libglib2.0-0t64 amd64 2.80.0-6ubuntu3.10 [1548 kB]Get:6 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libicu74 amd64 74.2-1ubuntu3.1 [10.9 MB]Get:7 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libxml2 amd64 2.9.14+dfsg-1.3ubuntu3.10 [764 kB]Get:8 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 xkb-data all 2.41-2ubuntu1.1 [397 kB]Get:9 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libdrm-common all 2.4.125-1ubuntu0.1~24.04.2 [9250 B]Get:10 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libdrm2 amd64 2.4.125-1ubuntu0.1~24.04.2 [41.4 kB]Get:11 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libpng16-16t64 amd64 1.6.43-5ubuntu0.7 [189 kB]Get:12 http://archive.ubuntu.com/ubuntu noble/main amd64 libsensors-config all 1:3.6.0-9build1 [5546 B]Get:13 http://archive.ubuntu.com/ubuntu noble/main amd64 libsensors5 amd64 1:3.6.0-9build1 [26.6 kB]Get:14 http://archive.ubuntu.com/ubuntu noble/main amd64 libxau6 amd64 1:1.0.9-1build6 [7160 B]Get:15 http://archive.ubuntu.com/ubuntu noble/main amd64 libxdmcp6 amd64 1:1.1.3-0ubuntu6 [10.3 kB]Get:16 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb1 amd64 1.15-1ubuntu2 [47.7 kB]Get:17 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libx11-data all 2:1.8.7-1ubuntu0.1 [116 kB]Get:18 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libx11-6 amd64 2:1.8.7-1ubuntu0.1 [653 kB]Get:19 http://archive.ubuntu.com/ubuntu noble/main amd64 libxext6 amd64 2:1.3.4-1build2 [30.4 kB]Get:20 http://archive.ubuntu.com/ubuntu noble/main amd64 libxkbcommon0 amd64 1.6.0-1build1 [122 kB]Get:21 http://archive.ubuntu.com/ubuntu noble/main amd64 libxmuu1 amd64 2:1.1.3-3build2 [8958 B]Get:22 http://archive.ubuntu.com/ubuntu noble/main amd64 xauth amd64 1:1.1.2-1build1 [25.6 kB]Get:23 http://archive.ubuntu.com/ubuntu noble/main amd64 at-spi2-common all 2.52.0-1build1 [8674 B]Get:24 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libfreetype6 amd64 2.13.2+dfsg-1ubuntu0.2 [403 kB]Get:25 http://archive.ubuntu.com/ubuntu noble/main amd64 fonts-liberation all 1:2.1.5-3 [1603 kB]Get:26 http://archive.ubuntu.com/ubuntu noble/main amd64 fonts-freefont-ttf all 20211204+svn4273-2 [5641 kB]Get:27 http://archive.ubuntu.com/ubuntu noble/main amd64 fontconfig-config amd64 2.15.0-1.1ubuntu2 [37.3 kB]Get:28 http://archive.ubuntu.com/ubuntu noble/main amd64 libfontconfig1 amd64 2.15.0-1.1ubuntu2 [139 kB]Get:29 http://archive.ubuntu.com/ubuntu noble/main amd64 fontconfig amd64 2.15.0-1.1ubuntu2 [180 kB]Get:30 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 fonts-noto-color-emoji all 2.047-0ubuntu0.24.04.1 [9764 kB]Get:31 http://archive.ubuntu.com/ubuntu noble/universe amd64 fonts-tlwg-loma-otf all 1:0.7.3-1 [107 kB]Get:32 http://archive.ubuntu.com/ubuntu noble/universe amd64 fonts-unifont all 1:15.1.01-1build1 [2993 kB]Get:33 http://archive.ubuntu.com/ubuntu noble/universe amd64 fonts-wqy-zenhei all 0.9.45-8 [7472 kB]Get:34 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libasound2-data all 1.2.11-1ubuntu0.3 [21.4 kB]Get:35 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libasound2t64 amd64 1.2.11-1ubuntu0.3 [398 kB]Get:36 http://archive.ubuntu.com/ubuntu noble/main amd64 libatk1.0-0t64 amd64 2.52.0-1build1 [55.3 kB]Get:37 http://archive.ubuntu.com/ubuntu noble/main amd64 libxi6 amd64 2:1.8.1-1build1 [32.4 kB]Get:38 http://archive.ubuntu.com/ubuntu noble/main amd64 libatspi2.0-0t64 amd64 2.52.0-1build1 [80.5 kB]Get:39 http://archive.ubuntu.com/ubuntu noble/main amd64 libatk-bridge2.0-0t64 amd64 2.52.0-1build1 [66.0 kB]Get:40 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libavahi-common-data amd64 0.8-13ubuntu6.2 [30.1 kB]Get:41 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libavahi-common3 amd64 0.8-13ubuntu6.2 [23.4 kB]Get:42 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libavahi-client3 amd64 0.8-13ubuntu6.2 [26.8 kB]Get:43 http://archive.ubuntu.com/ubuntu noble/main amd64 libpixman-1-0 amd64 0.42.2-1build1 [279 kB]Get:44 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-render0 amd64 1.15-1ubuntu2 [16.2 kB]Get:45 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-shm0 amd64 1.15-1ubuntu2 [5756 B]Get:46 http://archive.ubuntu.com/ubuntu noble/main amd64 libxrender1 amd64 1:0.9.10-1.1build1 [19.0 kB]Get:47 http://archive.ubuntu.com/ubuntu noble/main amd64 libcairo2 amd64 1.18.0-3build1 [566 kB]Get:48 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libcups2t64 amd64 2.4.7-1.2ubuntu7.14 [274 kB]Get:49 http://archive.ubuntu.com/ubuntu noble/main amd64 libdatrie1 amd64 0.2.13-3build1 [19.0 kB]Get:50 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libdrm-amdgpu1 amd64 2.4.125-1ubuntu0.1~24.04.2 [21.4 kB]Get:51 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libpciaccess0 amd64 0.17-3ubuntu0.24.04.3 [19.2 kB]Get:52 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libdrm-intel1 amd64 2.4.125-1ubuntu0.1~24.04.2 [63.9 kB]Get:53 http://archive.ubuntu.com/ubuntu noble/main amd64 libfontenc1 amd64 1:1.1.8-1build1 [14.0 kB]Get:54 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libllvm20 amd64 1:20.1.2-0ubuntu1~24.04.3 [30.6 MB]Get:55 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libx11-xcb1 amd64 2:1.8.7-1ubuntu0.1 [7796 B]Get:56 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-dri3-0 amd64 1.15-1ubuntu2 [7142 B]Get:57 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-present0 amd64 1.15-1ubuntu2 [5676 B]Get:58 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-randr0 amd64 1.15-1ubuntu2 [17.9 kB]Get:59 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-sync1 amd64 1.15-1ubuntu2 [9312 B]Get:60 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-xfixes0 amd64 1.15-1ubuntu2 [10.2 kB]Get:61 http://archive.ubuntu.com/ubuntu noble/main amd64 libxshmfence1 amd64 1.3-1build5 [4764 B]Get:62 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 mesa-libgallium amd64 25.2.8-0ubuntu0.24.04.4 [10.8 MB]Get:63 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libgbm1 amd64 25.2.8-0ubuntu0.24.04.4 [34.2 kB]Get:64 http://archive.ubuntu.com/ubuntu noble/main amd64 libvulkan1 amd64 1.3.275.0-1build1 [142 kB]Get:65 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libgl1-mesa-dri amd64 25.2.8-0ubuntu0.24.04.4 [38.0 kB]Get:66 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcb-glx0 amd64 1.15-1ubuntu2 [24.8 kB]Get:67 http://archive.ubuntu.com/ubuntu noble/main amd64 libxxf86vm1 amd64 1:1.1.4-1build4 [9282 B]Get:68 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libglx-mesa0 amd64 25.2.8-0ubuntu0.24.04.4 [110 kB]Get:69 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libgraphite2-3 amd64 1.3.14-2ubuntu0.24.04.1 [73.4 kB]Get:70 http://archive.ubuntu.com/ubuntu noble/main amd64 libharfbuzz0b amd64 8.3.0-2build2 [469 kB]Get:71 http://archive.ubuntu.com/ubuntu noble/main amd64 x11-common all 1:7.7+23ubuntu3 [21.7 kB]Get:72 http://archive.ubuntu.com/ubuntu noble/main amd64 libice6 amd64 2:1.0.10-1build3 [41.4 kB]Get:73 http://archive.ubuntu.com/ubuntu noble/main amd64 libnspr4 amd64 2:4.35-1.1build1 [117 kB]Get:74 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libnss3 amd64 2:3.98-1ubuntu0.3 [1445 kB]Get:75 http://archive.ubuntu.com/ubuntu noble/main amd64 libthai-data all 0.1.29-2build1 [158 kB]Get:76 http://archive.ubuntu.com/ubuntu noble/main amd64 libthai0 amd64 0.1.29-2build1 [18.9 kB]Get:77 http://archive.ubuntu.com/ubuntu noble/main amd64 libpango-1.0-0 amd64 1.52.1+ds-1build1 [231 kB]Get:78 http://archive.ubuntu.com/ubuntu noble/main amd64 libsm6 amd64 2:1.2.3-1build3 [15.7 kB]Get:79 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libunwind8 amd64 1.6.2-3build1.1 [55.3 kB]Get:80 http://archive.ubuntu.com/ubuntu noble/main amd64 libxt6t64 amd64 1:1.2.1-1.2build1 [171 kB]Get:81 http://archive.ubuntu.com/ubuntu noble/main amd64 libxmu6 amd64 2:1.1.3-3build2 [47.6 kB]Get:82 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libxpm4 amd64 1:3.5.17-1ubuntu0.24.04.2 [36.7 kB]Get:83 http://archive.ubuntu.com/ubuntu noble/main amd64 libxaw7 amd64 2:1.0.14-1build2 [187 kB]Get:84 http://archive.ubuntu.com/ubuntu noble/main amd64 libxcomposite1 amd64 1:0.4.5-1build3 [6320 B]Get:85 http://archive.ubuntu.com/ubuntu noble/main amd64 libxdamage1 amd64 1:1.1.6-1build1 [6150 B]Get:86 http://archive.ubuntu.com/ubuntu noble/main amd64 libxfixes3 amd64 1:6.0.0-2build1 [10.8 kB]Get:87 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 libxfont2 amd64 1:2.0.6-1+deb13u1build0.24.04.2 [94.0 kB]Get:88 http://archive.ubuntu.com/ubuntu noble/main amd64 libxkbfile1 amd64 1:1.1.0-1build4 [70.0 kB]Get:89 http://archive.ubuntu.com/ubuntu noble/main amd64 libxrandr2 amd64 2:1.5.2-2build1 [19.7 kB]Get:90 http://archive.ubuntu.com/ubuntu noble/main amd64 x11-xkb-utils amd64 7.7+8build2 [170 kB]Get:91 http://archive.ubuntu.com/ubuntu noble/main amd64 xfonts-encodings all 1:1.0.5-0ubuntu2 [578 kB]Get:92 http://archive.ubuntu.com/ubuntu noble/main amd64 xfonts-utils amd64 1:7.7+6build3 [94.4 kB]Get:93 http://archive.ubuntu.com/ubuntu noble/universe amd64 xfonts-cyrillic all 1:1.0.5+nmu1 [384 kB]Get:94 http://archive.ubuntu.com/ubuntu noble/main amd64 xfonts-scalable all 1:1.0.3-1.3 [304 kB]Get:95 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 xserver-common all 2:21.1.12-1ubuntu1.9 [35.0 kB]Get:96 http://archive.ubuntu.com/ubuntu noble/main amd64 libglvnd0 amd64 1.7.0-1build1 [69.6 kB]Get:97 http://archive.ubuntu.com/ubuntu noble/main amd64 libglx0 amd64 1.7.0-1build1 [38.6 kB]Get:98 http://archive.ubuntu.com/ubuntu noble/main amd64 libgl1 amd64 1.7.0-1build1 [102 kB]Get:99 http://archive.ubuntu.com/ubuntu noble-updates/universe amd64 xvfb amd64 2:21.1.12-1ubuntu1.9 [877 kB]debconf: delaying package configuration, since apt-utils is not installedFetched 96.8 MB in 3s (36.9 MB/s)Selecting previously unselected package fonts-ipafont-gothic.(Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 15919 files and directories currently installed.)Preparing to unpack .../00-fonts-ipafont-gothic_00303-21ubuntu1_all.deb ...Unpacking fonts-ipafont-gothic (00303-21ubuntu1) ...Selecting previously unselected package libdbus-1-3:amd64.Preparing to unpack .../01-libdbus-1-3_1.14.10-4ubuntu4.1_amd64.deb ...Unpacking libdbus-1-3:amd64 (1.14.10-4ubuntu4.1) ...Selecting previously unselected package libelf1t64:amd64.Preparing to unpack .../02-libelf1t64_0.190-1.1ubuntu0.1_amd64.deb ...Unpacking libelf1t64:amd64 (0.190-1.1ubuntu0.1) ...Selecting previously unselected package libfribidi0:amd64.Preparing to unpack .../03-libfribidi0_1.0.13-3build1_amd64.deb ...Unpacking libfribidi0:amd64 (1.0.13-3build1) ...Selecting previously unselected package libglib2.0-0t64:amd64.Preparing to unpack .../04-libglib2.0-0t64_2.80.0-6ubuntu3.10_amd64.deb ...Unpacking libglib2.0-0t64:amd64 (2.80.0-6ubuntu3.10) ...Selecting previously unselected package libicu74:amd64.Preparing to unpack .../05-libicu74_74.2-1ubuntu3.1_amd64.deb ...Unpacking libicu74:amd64 (74.2-1ubuntu3.1) ...Selecting previously unselected package libxml2:amd64.Preparing to unpack .../06-libxml2_2.9.14+dfsg-1.3ubuntu3.10_amd64.deb ...Unpacking libxml2:amd64 (2.9.14+dfsg-1.3ubuntu3.10) ...Selecting previously unselected package xkb-data.Preparing to unpack .../07-xkb-data_2.41-2ubuntu1.1_all.deb ...Unpacking xkb-data (2.41-2ubuntu1.1) ...Selecting previously unselected package libdrm-common.Preparing to unpack .../08-libdrm-common_2.4.125-1ubuntu0.1~24.04.2_all.deb ...Unpacking libdrm-common (2.4.125-1ubuntu0.1~24.04.2) ...Selecting previously unselected package libdrm2:amd64.Preparing to unpack .../09-libdrm2_2.4.125-1ubuntu0.1~24.04.2_amd64.deb ...Unpacking libdrm2:amd64 (2.4.125-1ubuntu0.1~24.04.2) ...Selecting previously unselected package libpng16-16t64:amd64.Preparing to unpack .../10-libpng16-16t64_1.6.43-5ubuntu0.7_amd64.deb ...Unpacking libpng16-16t64:amd64 (1.6.43-5ubuntu0.7) ...Selecting previously unselected package libsensors-config.Preparing to unpack .../11-libsensors-config_1%3a3.6.0-9build1_all.deb ...Unpacking libsensors-config (1:3.6.0-9build1) ...Selecting previously unselected package libsensors5:amd64.Preparing to unpack .../12-libsensors5_1%3a3.6.0-9build1_amd64.deb ...Unpacking libsensors5:amd64 (1:3.6.0-9build1) ...Selecting previously unselected package libxau6:amd64.Preparing to unpack .../13-libxau6_1%3a1.0.9-1build6_amd64.deb ...Unpacking libxau6:amd64 (1:1.0.9-1build6) ...Selecting previously unselected package libxdmcp6:amd64.Preparing to unpack .../14-libxdmcp6_1%3a1.1.3-0ubuntu6_amd64.deb ...Unpacking libxdmcp6:amd64 (1:1.1.3-0ubuntu6) ...Selecting previously unselected package libxcb1:amd64.Preparing to unpack .../15-libxcb1_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb1:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libx11-data.Preparing to unpack .../16-libx11-data_2%3a1.8.7-1ubuntu0.1_all.deb ...Unpacking libx11-data (2:1.8.7-1ubuntu0.1) ...Selecting previously unselected package libx11-6:amd64.Preparing to unpack .../17-libx11-6_2%3a1.8.7-1ubuntu0.1_amd64.deb ...Unpacking libx11-6:amd64 (2:1.8.7-1ubuntu0.1) ...Selecting previously unselected package libxext6:amd64.Preparing to unpack .../18-libxext6_2%3a1.3.4-1build2_amd64.deb ...Unpacking libxext6:amd64 (2:1.3.4-1build2) ...Selecting previously unselected package libxkbcommon0:amd64.Preparing to unpack .../19-libxkbcommon0_1.6.0-1build1_amd64.deb ...Unpacking libxkbcommon0:amd64 (1.6.0-1build1) ...Selecting previously unselected package libxmuu1:amd64.Preparing to unpack .../20-libxmuu1_2%3a1.1.3-3build2_amd64.deb ...Unpacking libxmuu1:amd64 (2:1.1.3-3build2) ...Selecting previously unselected package xauth.Preparing to unpack .../21-xauth_1%3a1.1.2-1build1_amd64.deb ...Unpacking xauth (1:1.1.2-1build1) ...Selecting previously unselected package at-spi2-common.Preparing to unpack .../22-at-spi2-common_2.52.0-1build1_all.deb ...Unpacking at-spi2-common (2.52.0-1build1) ...Selecting previously unselected package libfreetype6:amd64.Preparing to unpack .../23-libfreetype6_2.13.2+dfsg-1ubuntu0.2_amd64.deb ...Unpacking libfreetype6:amd64 (2.13.2+dfsg-1ubuntu0.2) ...Selecting previously unselected package fonts-liberation.Preparing to unpack .../24-fonts-liberation_1%3a2.1.5-3_all.deb ...Unpacking fonts-liberation (1:2.1.5-3) ...Selecting previously unselected package fonts-freefont-ttf.Preparing to unpack .../25-fonts-freefont-ttf_20211204+svn4273-2_all.deb ...Unpacking fonts-freefont-ttf (20211204+svn4273-2) ...Selecting previously unselected package fontconfig-config.Preparing to unpack .../26-fontconfig-config_2.15.0-1.1ubuntu2_amd64.deb ...Unpacking fontconfig-config (2.15.0-1.1ubuntu2) ...Selecting previously unselected package libfontconfig1:amd64.Preparing to unpack .../27-libfontconfig1_2.15.0-1.1ubuntu2_amd64.deb ...Unpacking libfontconfig1:amd64 (2.15.0-1.1ubuntu2) ...Selecting previously unselected package fontconfig.Preparing to unpack .../28-fontconfig_2.15.0-1.1ubuntu2_amd64.deb ...Unpacking fontconfig (2.15.0-1.1ubuntu2) ...Selecting previously unselected package fonts-noto-color-emoji.Preparing to unpack .../29-fonts-noto-color-emoji_2.047-0ubuntu0.24.04.1_all.deb ...Unpacking fonts-noto-color-emoji (2.047-0ubuntu0.24.04.1) ...Selecting previously unselected package fonts-tlwg-loma-otf.Preparing to unpack .../30-fonts-tlwg-loma-otf_1%3a0.7.3-1_all.deb ...Unpacking fonts-tlwg-loma-otf (1:0.7.3-1) ...Selecting previously unselected package fonts-unifont.Preparing to unpack .../31-fonts-unifont_1%3a15.1.01-1build1_all.deb ...Unpacking fonts-unifont (1:15.1.01-1build1) ...Selecting previously unselected package fonts-wqy-zenhei.Preparing to unpack .../32-fonts-wqy-zenhei_0.9.45-8_all.deb ...Unpacking fonts-wqy-zenhei (0.9.45-8) ...Selecting previously unselected package libasound2-data.Preparing to unpack .../33-libasound2-data_1.2.11-1ubuntu0.3_all.deb ...Unpacking libasound2-data (1.2.11-1ubuntu0.3) ...Selecting previously unselected package libasound2t64:amd64.Preparing to unpack .../34-libasound2t64_1.2.11-1ubuntu0.3_amd64.deb ...Unpacking libasound2t64:amd64 (1.2.11-1ubuntu0.3) ...Selecting previously unselected package libatk1.0-0t64:amd64.Preparing to unpack .../35-libatk1.0-0t64_2.52.0-1build1_amd64.deb ...Unpacking libatk1.0-0t64:amd64 (2.52.0-1build1) ...Selecting previously unselected package libxi6:amd64.Preparing to unpack .../36-libxi6_2%3a1.8.1-1build1_amd64.deb ...Unpacking libxi6:amd64 (2:1.8.1-1build1) ...Selecting previously unselected package libatspi2.0-0t64:amd64.Preparing to unpack .../37-libatspi2.0-0t64_2.52.0-1build1_amd64.deb ...Unpacking libatspi2.0-0t64:amd64 (2.52.0-1build1) ...Selecting previously unselected package libatk-bridge2.0-0t64:amd64.Preparing to unpack .../38-libatk-bridge2.0-0t64_2.52.0-1build1_amd64.deb ...Unpacking libatk-bridge2.0-0t64:amd64 (2.52.0-1build1) ...Selecting previously unselected package libavahi-common-data:amd64.Preparing to unpack .../39-libavahi-common-data_0.8-13ubuntu6.2_amd64.deb ...Unpacking libavahi-common-data:amd64 (0.8-13ubuntu6.2) ...Selecting previously unselected package libavahi-common3:amd64.Preparing to unpack .../40-libavahi-common3_0.8-13ubuntu6.2_amd64.deb ...Unpacking libavahi-common3:amd64 (0.8-13ubuntu6.2) ...Selecting previously unselected package libavahi-client3:amd64.Preparing to unpack .../41-libavahi-client3_0.8-13ubuntu6.2_amd64.deb ...Unpacking libavahi-client3:amd64 (0.8-13ubuntu6.2) ...Selecting previously unselected package libpixman-1-0:amd64.Preparing to unpack .../42-libpixman-1-0_0.42.2-1build1_amd64.deb ...Unpacking libpixman-1-0:amd64 (0.42.2-1build1) ...Selecting previously unselected package libxcb-render0:amd64.Preparing to unpack .../43-libxcb-render0_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-render0:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxcb-shm0:amd64.Preparing to unpack .../44-libxcb-shm0_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-shm0:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxrender1:amd64.Preparing to unpack .../45-libxrender1_1%3a0.9.10-1.1build1_amd64.deb ...Unpacking libxrender1:amd64 (1:0.9.10-1.1build1) ...Selecting previously unselected package libcairo2:amd64.Preparing to unpack .../46-libcairo2_1.18.0-3build1_amd64.deb ...Unpacking libcairo2:amd64 (1.18.0-3build1) ...Selecting previously unselected package libcups2t64:amd64.Preparing to unpack .../47-libcups2t64_2.4.7-1.2ubuntu7.14_amd64.deb ...Unpacking libcups2t64:amd64 (2.4.7-1.2ubuntu7.14) ...Selecting previously unselected package libdatrie1:amd64.Preparing to unpack .../48-libdatrie1_0.2.13-3build1_amd64.deb ...Unpacking libdatrie1:amd64 (0.2.13-3build1) ...Selecting previously unselected package libdrm-amdgpu1:amd64.Preparing to unpack .../49-libdrm-amdgpu1_2.4.125-1ubuntu0.1~24.04.2_amd64.deb ...Unpacking libdrm-amdgpu1:amd64 (2.4.125-1ubuntu0.1~24.04.2) ...Selecting previously unselected package libpciaccess0:amd64.Preparing to unpack .../50-libpciaccess0_0.17-3ubuntu0.24.04.3_amd64.deb ...Unpacking libpciaccess0:amd64 (0.17-3ubuntu0.24.04.3) ...Selecting previously unselected package libdrm-intel1:amd64.Preparing to unpack .../51-libdrm-intel1_2.4.125-1ubuntu0.1~24.04.2_amd64.deb ...Unpacking libdrm-intel1:amd64 (2.4.125-1ubuntu0.1~24.04.2) ...Selecting previously unselected package libfontenc1:amd64.Preparing to unpack .../52-libfontenc1_1%3a1.1.8-1build1_amd64.deb ...Unpacking libfontenc1:amd64 (1:1.1.8-1build1) ...Selecting previously unselected package libllvm20:amd64.Preparing to unpack .../53-libllvm20_1%3a20.1.2-0ubuntu1~24.04.3_amd64.deb ...Unpacking libllvm20:amd64 (1:20.1.2-0ubuntu1~24.04.3) ...Selecting previously unselected package libx11-xcb1:amd64.Preparing to unpack .../54-libx11-xcb1_2%3a1.8.7-1ubuntu0.1_amd64.deb ...Unpacking libx11-xcb1:amd64 (2:1.8.7-1ubuntu0.1) ...Selecting previously unselected package libxcb-dri3-0:amd64.Preparing to unpack .../55-libxcb-dri3-0_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-dri3-0:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxcb-present0:amd64.Preparing to unpack .../56-libxcb-present0_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-present0:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxcb-randr0:amd64.Preparing to unpack .../57-libxcb-randr0_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-randr0:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxcb-sync1:amd64.Preparing to unpack .../58-libxcb-sync1_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-sync1:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxcb-xfixes0:amd64.Preparing to unpack .../59-libxcb-xfixes0_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-xfixes0:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxshmfence1:amd64.Preparing to unpack .../60-libxshmfence1_1.3-1build5_amd64.deb ...Unpacking libxshmfence1:amd64 (1.3-1build5) ...Selecting previously unselected package mesa-libgallium:amd64.Preparing to unpack .../61-mesa-libgallium_25.2.8-0ubuntu0.24.04.4_amd64.deb ...Unpacking mesa-libgallium:amd64 (25.2.8-0ubuntu0.24.04.4) ...Selecting previously unselected package libgbm1:amd64.Preparing to unpack .../62-libgbm1_25.2.8-0ubuntu0.24.04.4_amd64.deb ...Unpacking libgbm1:amd64 (25.2.8-0ubuntu0.24.04.4) ...Selecting previously unselected package libvulkan1:amd64.Preparing to unpack .../63-libvulkan1_1.3.275.0-1build1_amd64.deb ...Unpacking libvulkan1:amd64 (1.3.275.0-1build1) ...Selecting previously unselected package libgl1-mesa-dri:amd64.Preparing to unpack .../64-libgl1-mesa-dri_25.2.8-0ubuntu0.24.04.4_amd64.deb ...Unpacking libgl1-mesa-dri:amd64 (25.2.8-0ubuntu0.24.04.4) ...Selecting previously unselected package libxcb-glx0:amd64.Preparing to unpack .../65-libxcb-glx0_1.15-1ubuntu2_amd64.deb ...Unpacking libxcb-glx0:amd64 (1.15-1ubuntu2) ...Selecting previously unselected package libxxf86vm1:amd64.Preparing to unpack .../66-libxxf86vm1_1%3a1.1.4-1build4_amd64.deb ...Unpacking libxxf86vm1:amd64 (1:1.1.4-1build4) ...Selecting previously unselected package libglx-mesa0:amd64.Preparing to unpack .../67-libglx-mesa0_25.2.8-0ubuntu0.24.04.4_amd64.deb ...Unpacking libglx-mesa0:amd64 (25.2.8-0ubuntu0.24.04.4) ...Selecting previously unselected package libgraphite2-3:amd64.Preparing to unpack .../68-libgraphite2-3_1.3.14-2ubuntu0.24.04.1_amd64.deb ...Unpacking libgraphite2-3:amd64 (1.3.14-2ubuntu0.24.04.1) ...Selecting previously unselected package libharfbuzz0b:amd64.Preparing to unpack .../69-libharfbuzz0b_8.3.0-2build2_amd64.deb ...Unpacking libharfbuzz0b:amd64 (8.3.0-2build2) ...Selecting previously unselected package x11-common.Preparing to unpack .../70-x11-common_1%3a7.7+23ubuntu3_all.deb ...Unpacking x11-common (1:7.7+23ubuntu3) ...Selecting previously unselected package libice6:amd64.Preparing to unpack .../71-libice6_2%3a1.0.10-1build3_amd64.deb ...Unpacking libice6:amd64 (2:1.0.10-1build3) ...Selecting previously unselected package libnspr4:amd64.Preparing to unpack .../72-libnspr4_2%3a4.35-1.1build1_amd64.deb ...Unpacking libnspr4:amd64 (2:4.35-1.1build1) ...Selecting previously unselected package libnss3:amd64.Preparing to unpack .../73-libnss3_2%3a3.98-1ubuntu0.3_amd64.deb ...Unpacking libnss3:amd64 (2:3.98-1ubuntu0.3) ...Selecting previously unselected package libthai-data.Preparing to unpack .../74-libthai-data_0.1.29-2build1_all.deb ...Unpacking libthai-data (0.1.29-2build1) ...Selecting previously unselected package libthai0:amd64.Preparing to unpack .../75-libthai0_0.1.29-2build1_amd64.deb ...Unpacking libthai0:amd64 (0.1.29-2build1) ...Selecting previously unselected package libpango-1.0-0:amd64.Preparing to unpack .../76-libpango-1.0-0_1.52.1+ds-1build1_amd64.deb ...Unpacking libpango-1.0-0:amd64 (1.52.1+ds-1build1) ...Selecting previously unselected package libsm6:amd64.Preparing to unpack .../77-libsm6_2%3a1.2.3-1build3_amd64.deb ...Unpacking libsm6:amd64 (2:1.2.3-1build3) ...Selecting previously unselected package libunwind8:amd64.Preparing to unpack .../78-libunwind8_1.6.2-3build1.1_amd64.deb ...Unpacking libunwind8:amd64 (1.6.2-3build1.1) ...Selecting previously unselected package libxt6t64:amd64.Preparing to unpack .../79-libxt6t64_1%3a1.2.1-1.2build1_amd64.deb ...Unpacking libxt6t64:amd64 (1:1.2.1-1.2build1) ...Selecting previously unselected package libxmu6:amd64.Preparing to unpack .../80-libxmu6_2%3a1.1.3-3build2_amd64.deb ...Unpacking libxmu6:amd64 (2:1.1.3-3build2) ...Selecting previously unselected package libxpm4:amd64.Preparing to unpack .../81-libxpm4_1%3a3.5.17-1ubuntu0.24.04.2_amd64.deb ...Unpacking libxpm4:amd64 (1:3.5.17-1ubuntu0.24.04.2) ...Selecting previously unselected package libxaw7:amd64.Preparing to unpack .../82-libxaw7_2%3a1.0.14-1build2_amd64.deb ...Unpacking libxaw7:amd64 (2:1.0.14-1build2) ...Selecting previously unselected package libxcomposite1:amd64.Preparing to unpack .../83-libxcomposite1_1%3a0.4.5-1build3_amd64.deb ...Unpacking libxcomposite1:amd64 (1:0.4.5-1build3) ...Selecting previously unselected package libxdamage1:amd64.Preparing to unpack .../84-libxdamage1_1%3a1.1.6-1build1_amd64.deb ...Unpacking libxdamage1:amd64 (1:1.1.6-1build1) ...Selecting previously unselected package libxfixes3:amd64.Preparing to unpack .../85-libxfixes3_1%3a6.0.0-2build1_amd64.deb ...Unpacking libxfixes3:amd64 (1:6.0.0-2build1) ...Selecting previously unselected package libxfont2:amd64.Preparing to unpack .../86-libxfont2_1%3a2.0.6-1+deb13u1build0.24.04.2_amd64.deb ...Unpacking libxfont2:amd64 (1:2.0.6-1+deb13u1build0.24.04.2) ...Selecting previously unselected package libxkbfile1:amd64.Preparing to unpack .../87-libxkbfile1_1%3a1.1.0-1build4_amd64.deb ...Unpacking libxkbfile1:amd64 (1:1.1.0-1build4) ...Selecting previously unselected package libxrandr2:amd64.Preparing to unpack .../88-libxrandr2_2%3a1.5.2-2build1_amd64.deb ...Unpacking libxrandr2:amd64 (2:1.5.2-2build1) ...Selecting previously unselected package x11-xkb-utils.Preparing to unpack .../89-x11-xkb-utils_7.7+8build2_amd64.deb ...Unpacking x11-xkb-utils (7.7+8build2) ...Selecting previously unselected package xfonts-encodings.Preparing to unpack .../90-xfonts-encodings_1%3a1.0.5-0ubuntu2_all.deb ...Unpacking xfonts-encodings (1:1.0.5-0ubuntu2) ...Selecting previously unselected package xfonts-utils.Preparing to unpack .../91-xfonts-utils_1%3a7.7+6build3_amd64.deb ...Unpacking xfonts-utils (1:7.7+6build3) ...Selecting previously unselected package xfonts-cyrillic.Preparing to unpack .../92-xfonts-cyrillic_1%3a1.0.5+nmu1_all.deb ...Unpacking xfonts-cyrillic (1:1.0.5+nmu1) ...Selecting previously unselected package xfonts-scalable.Preparing to unpack .../93-xfonts-scalable_1%3a1.0.3-1.3_all.deb ...Unpacking xfonts-scalable (1:1.0.3-1.3) ...Selecting previously unselected package xserver-common.Preparing to unpack .../94-xserver-common_2%3a21.1.12-1ubuntu1.9_all.deb ...Unpacking xserver-common (2:21.1.12-1ubuntu1.9) ...Selecting previously unselected package libglvnd0:amd64.Preparing to unpack .../95-libglvnd0_1.7.0-1build1_amd64.deb ...Unpacking libglvnd0:amd64 (1.7.0-1build1) ...Selecting previously unselected package libglx0:amd64.Preparing to unpack .../96-libglx0_1.7.0-1build1_amd64.deb ...Unpacking libglx0:amd64 (1.7.0-1build1) ...Selecting previously unselected package libgl1:amd64.Preparing to unpack .../97-libgl1_1.7.0-1build1_amd64.deb ...Unpacking libgl1:amd64 (1.7.0-1build1) ...Selecting previously unselected package xvfb.Preparing to unpack .../98-xvfb_2%3a21.1.12-1ubuntu1.9_amd64.deb ...Unpacking xvfb (2:21.1.12-1ubuntu1.9) ...Setting up libgraphite2-3:amd64 (1.3.14-2ubuntu0.24.04.1) ...Setting up libpixman-1-0:amd64 (0.42.2-1build1) ...Setting up libpciaccess0:amd64 (0.17-3ubuntu0.24.04.3) ...Setting up libxau6:amd64 (1:1.0.9-1build6) ...Setting up libxdmcp6:amd64 (1:1.1.3-0ubuntu6) ...Setting up libxcb1:amd64 (1.15-1ubuntu2) ...Setting up libxcb-xfixes0:amd64 (1.15-1ubuntu2) ...Setting up libdatrie1:amd64 (0.2.13-3build1) ...Setting up fonts-noto-color-emoji (2.047-0ubuntu0.24.04.1) ...Setting up libxcb-render0:amd64 (1.15-1ubuntu2) ...Setting up libglvnd0:amd64 (1.7.0-1build1) ...Setting up libxcb-glx0:amd64 (1.15-1ubuntu2) ...Setting up x11-common (1:7.7+23ubuntu3) ...invoke-rc.d: could not determine current runlevelinvoke-rc.d: policy-rc.d denied execution of start.Setting up libsensors-config (1:3.6.0-9build1) ...Setting up fonts-freefont-ttf (20211204+svn4273-2) ...Setting up xkb-data (2.41-2ubuntu1.1) ...Setting up libxcb-shm0:amd64 (1.15-1ubuntu2) ...Setting up libunwind8:amd64 (1.6.2-3build1.1) ...Setting up libelf1t64:amd64 (0.190-1.1ubuntu0.1) ...Setting up libxcb-present0:amd64 (1.15-1ubuntu2) ...Setting up libasound2-data (1.2.11-1ubuntu0.3) ...Setting up libfontenc1:amd64 (1:1.1.8-1build1) ...Setting up libglib2.0-0t64:amd64 (2.80.0-6ubuntu3.10) ...No schema files found: doing nothing.Setting up libasound2t64:amd64 (1.2.11-1ubuntu0.3) ...Setting up fonts-tlwg-loma-otf (1:0.7.3-1) ...Setting up libx11-data (2:1.8.7-1ubuntu0.1) ...Setting up libnspr4:amd64 (2:4.35-1.1build1) ...Setting up libxcb-sync1:amd64 (1.15-1ubuntu2) ...Setting up libavahi-common-data:amd64 (0.8-13ubuntu6.2) ...Setting up libdbus-1-3:amd64 (1.14.10-4ubuntu4.1) ...Setting up xfonts-encodings (1:1.0.5-0ubuntu2) ...Setting up libfribidi0:amd64 (1.0.13-3build1) ...Setting up libpng16-16t64:amd64 (1.6.43-5ubuntu0.7) ...Setting up libsensors5:amd64 (1:3.6.0-9build1) ...Setting up libvulkan1:amd64 (1.3.275.0-1build1) ...Setting up libicu74:amd64 (74.2-1ubuntu3.1) ...Setting up fonts-ipafont-gothic (00303-21ubuntu1) ...update-alternatives: using /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf to provide /usr/share/fonts/truetype/fonts-japanese-gothic.ttf (fonts-japanese-gothic.ttf) in auto modeSetting up libxshmfence1:amd64 (1.3-1build5) ...Setting up at-spi2-common (2.52.0-1build1) ...Setting up libxcb-randr0:amd64 (1.15-1ubuntu2) ...Setting up fonts-liberation (1:2.1.5-3) ...Setting up libx11-6:amd64 (2:1.8.7-1ubuntu0.1) ...Setting up libthai-data (0.1.29-2build1) ...Setting up libxkbfile1:amd64 (1:1.1.0-1build4) ...Setting up libdrm-common (2.4.125-1ubuntu0.1~24.04.2) ...Setting up libxcomposite1:amd64 (1:0.4.5-1build3) ...Setting up libxml2:amd64 (2.9.14+dfsg-1.3ubuntu3.10) ...Setting up libxmuu1:amd64 (2:1.1.3-3build2) ...Setting up fonts-unifont (1:15.1.01-1build1) ...Setting up libxkbcommon0:amd64 (1.6.0-1build1) ...Setting up libxcb-dri3-0:amd64 (1.15-1ubuntu2) ...Setting up libx11-xcb1:amd64 (2:1.8.7-1ubuntu0.1) ...Setting up libice6:amd64 (2:1.0.10-1build3) ...Setting up libxdamage1:amd64 (1:1.1.6-1build1) ...Setting up libatk1.0-0t64:amd64 (2.52.0-1build1) ...Setting up libxpm4:amd64 (1:3.5.17-1ubuntu0.24.04.2) ...Setting up libxrender1:amd64 (1:0.9.10-1.1build1) ...Setting up fontconfig-config (2.15.0-1.1ubuntu2) ...Setting up libavahi-common3:amd64 (0.8-13ubuntu6.2) ...Setting up libxext6:amd64 (2:1.3.4-1build2) ...Setting up libnss3:amd64 (2:3.98-1ubuntu0.3) ...Setting up libxxf86vm1:amd64 (1:1.1.4-1build4) ...Setting up libthai0:amd64 (0.1.29-2build1) ...Setting up libfreetype6:amd64 (2.13.2+dfsg-1ubuntu0.2) ...Setting up libxfixes3:amd64 (1:6.0.0-2build1) ...Setting up libxrandr2:amd64 (2:1.5.2-2build1) ...Setting up libllvm20:amd64 (1:20.1.2-0ubuntu1~24.04.3) ...Setting up libdrm2:amd64 (2.4.125-1ubuntu0.1~24.04.2) ...Setting up xauth (1:1.1.2-1build1) ...Setting up libharfbuzz0b:amd64 (8.3.0-2build2) ...Setting up libfontconfig1:amd64 (2.15.0-1.1ubuntu2) ...Setting up libsm6:amd64 (2:1.2.3-1build3) ...Setting up libxfont2:amd64 (1:2.0.6-1+deb13u1build0.24.04.2) ...Setting up libavahi-client3:amd64 (0.8-13ubuntu6.2) ...Setting up libdrm-amdgpu1:amd64 (2.4.125-1ubuntu0.1~24.04.2) ...Setting up fontconfig (2.15.0-1.1ubuntu2) ...Regenerating fonts cache... done.Setting up libxi6:amd64 (2:1.8.1-1build1) ...Setting up libpango-1.0-0:amd64 (1.52.1+ds-1build1) ...Setting up libdrm-intel1:amd64 (2.4.125-1ubuntu0.1~24.04.2) ...Setting up fonts-wqy-zenhei (0.9.45-8) ...Setting up xfonts-utils (1:7.7+6build3) ...Setting up libcairo2:amd64 (1.18.0-3build1) ...Setting up libatspi2.0-0t64:amd64 (2.52.0-1build1) ...Setting up libxt6t64:amd64 (1:1.2.1-1.2build1) ...Setting up xfonts-cyrillic (1:1.0.5+nmu1) ...Setting up libcups2t64:amd64 (2.4.7-1.2ubuntu7.14) ...Setting up xfonts-scalable (1:1.0.3-1.3) ...Setting up libatk-bridge2.0-0t64:amd64 (2.52.0-1build1) ...Setting up mesa-libgallium:amd64 (25.2.8-0ubuntu0.24.04.4) ...Setting up libxmu6:amd64 (2:1.1.3-3build2) ...Setting up libgbm1:amd64 (25.2.8-0ubuntu0.24.04.4) ...Setting up libgl1-mesa-dri:amd64 (25.2.8-0ubuntu0.24.04.4) ...Setting up libxaw7:amd64 (2:1.0.14-1build2) ...Setting up libglx-mesa0:amd64 (25.2.8-0ubuntu0.24.04.4) ...Setting up libglx0:amd64 (1.7.0-1build1) ...Setting up x11-xkb-utils (7.7+8build2) ...Setting up libgl1:amd64 (1.7.0-1build1) ...Setting up xserver-common (2:21.1.12-1ubuntu1.9) ...Setting up xvfb (2:21.1.12-1ubuntu1.9) ...Processing triggers for libc-bin (2.39-0ubuntu8.9) ...Downloading Chromium 141.0.7390.37 (playwright build v1194) from https://cdn.playwright.dev/dbazure/download/playwright/builds/chromium/1194/chromium-linux.zip| | 0% of 173.9 MiB|■■■■■■■■ | 10% of 173.9 MiB|■■■■■■■■■■■■■■■■ | 20% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■ | 30% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 40% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 50% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 60% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 70% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 80% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 90% of 173.9 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■| 100% of 173.9 MiBChromium 141.0.7390.37 (playwright build v1194) downloaded to /root/.cache/ms-playwright/chromium-1194Downloading FFMPEG playwright build v1011 from https://cdn.playwright.dev/dbazure/download/playwright/builds/ffmpeg/1011/ffmpeg-linux.zip| | 0% of 2.3 MiB|■■■■■■■■ | 10% of 2.3 MiB|■■■■■■■■■■■■■■■■ | 20% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■ | 30% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 40% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 50% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 60% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 70% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 80% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 90% of 2.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■| 100% of 2.3 MiBFFMPEG playwright build v1011 downloaded to /root/.cache/ms-playwright/ffmpeg-1011Downloading Chromium Headless Shell 141.0.7390.37 (playwright build v1194) from https://cdn.playwright.dev/dbazure/download/playwright/builds/chromium/1194/chromium-headless-shell-linux.zip| | 0% of 104.3 MiB|■■■■■■■■ | 10% of 104.3 MiB|■■■■■■■■■■■■■■■■ | 20% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■ | 30% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 40% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 50% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 60% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 70% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 80% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ | 90% of 104.3 MiB|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■| 100% of 104.3 MiBChromium Headless Shell 141.0.7390.37 (playwright build v1194) downloaded to /root/.cache/ms-playwright/chromium_headless_shell-1194
Run as_root() { if [ "$(id -u)" = 0 ]; then "$@"; else sudo "$@"; fi; }0s
##[group]Run as_root() { if [ "$(id -u)" = 0 ]; then "$@"; else sudo "$@"; fi; }if ! command -v bwrap >/dev/null; then as_root apt-get install -y --no-install-recommends bubblewrap || { as_root apt-get update -qq && as_root apt-get install -y --no-install-recommends bubblewrap; }fias_root sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 2>/dev/null || truebwrap --unshare-all --ro-bind / / --dev /dev --proc /proc -- true##[endgroup]
Run the shard's tests2m 35s
##[group]Run # Shards of similar length; a new test file runs in "rest" unless it's added to another.core='/e2e\.test\.mjs$'agents='/(agentic|review|tasks)\.test\.mjs$'# security.test.mjs, security-*.test.mjs (security-txt's too) and status.test.mjs.security='/(security(-[a-z-]+)?|status)\.test\.mjs$'# The core file's real histories and large pushes take minutes each (jquery's alone 2 to 3 on# Diffinery's runners): two shards of their own, so no part of the file runs into node's# per-file timeout, which is the --test-timeout here.histories='^real histories:'large='^(large files|large pushes):'opts=(--test-timeout=600000)case "rest" in core) files=$(ls test/e2e/*.test.mjs | grep -E "$core"); opts+=(--test-skip-pattern="$histories" --test-skip-pattern="$large") ;; histories) files=$(ls test/e2e/*.test.mjs | grep -E "$core"); opts=(--test-timeout=900000 --test-name-pattern="$histories") ;; large) files=$(ls test/e2e/*.test.mjs | grep -E "$core"); opts+=(--test-name-pattern="$large") ;; agents) files=$(ls test/e2e/*.test.mjs | grep -E "$agents") ;; security) files=$(ls test/e2e/*.test.mjs | grep -E "$security") ;; *) files=$(ls test/e2e/*.test.mjs | grep -vE "$core|$agents|$security") ;;esacecho "$files"# Two files at a time: each starts its own local server on its own port, database and# directory, so they don't share state, and a file's server mostly keeps one core busy.node --test --test-concurrency=2 "${opts[@]}" $files##[endgroup]test/e2e/accounts.test.mjstest/e2e/agent-setup.test.mjstest/e2e/apps.test.mjstest/e2e/early-access.test.mjstest/e2e/email.test.mjstest/e2e/graphql.test.mjstest/e2e/moderation.test.mjstest/e2e/oauth.test.mjstest/e2e/passkeys.test.mjstest/e2e/registry.test.mjstest/e2e/terminals.test.mjsTAP version 13# Subtest: deleting your account: refused while you are an organization's only owner; then everything goes and your comments show as ghostok 1 - deleting your account: refused while you are an organization's only owner; then everything goes and your comments show as ghost --- duration_ms: 24669.973015 type: 'test' ...# Subtest: a site administrator deletes someone's account, signed in recently; their own is refused while they are the only oneok 2 - a site administrator deletes someone's account, signed in recently; their own is refused while they are the only one --- duration_ms: 1145.999721 type: 'test' ...# Subtest: exporting your account: a tar archive with a clonable Git bundle and the issues you wrote, for you onlyok 3 - exporting your account: a tar archive with a clonable Git bundle and the issues you wrote, for you only --- duration_ms: 447.240402 type: 'test' ...# Subtest: site administration: granting and revoking needs a recent sign-in, is audited, and never removes the last site administratorok 4 - site administration: granting and revoking needs a recent sign-in, is audited, and never removes the last site administrator --- duration_ms: 346.485486 type: 'test' ...# Subtest: the page: for people with write access, in a browserok 5 - the page: for people with write access, in a browser --- duration_ms: 24326.375761 type: 'test' ...# Subtest: generating a token makes ada's agent for this repository, and fills it in onceok 6 - generating a token makes ada's agent for this repository, and fills it in once --- duration_ms: 151.389229 type: 'test' ...# Subtest: the hosted script holds no secret, and only answers for names a repository can haveok 7 - the hosted script holds no secret, and only answers for names a repository can have --- duration_ms: 21.311677 type: 'test' ...# Subtest: a fresh machine with only the page's three boxes: everything works and the Check turns greenok 8 - a fresh machine with only the page's three boxes: everything works and the Check turns green --- duration_ms: 3530.187806 type: 'test' ...# Subtest: failures say what to change, and a missing token doesn't fail the sessionok 9 - failures say what to change, and a missing token doesn't fail the session --- duration_ms: 1881.49524 type: 'test' ...# Subtest: the token reaches only its repositoryok 10 - the token reaches only its repository --- duration_ms: 349.548082 type: 'test' ...# Subtest: merging: only what a person approved, never a workflow change, and off when ada says sook 11 - merging: only what a person approved, never a workflow change, and off when ada says so --- duration_ms: 932.773611 type: 'test' ...# Subtest: renew, revoke and regenerate; an admin turns off someone else's agentok 12 - renew, revoke and regenerate; an admin turns off someone else's agent --- duration_ms: 915.512752 type: 'test' ...# Subtest: an app is registered, installed and used as a GitHub App would beok 13 - an app is registered, installed and used as a GitHub App would be --- duration_ms: 10270.577112 type: 'test' ...# Subtest: people register, install and manage apps in the browserok 14 - people register, install and manage apps in the browser --- duration_ms: 4198.219781 type: 'test' ...# Subtest: early access: the sign-in page and closed sign-up lead to the formok 15 - early access: the sign-in page and closed sign-up lead to the form --- duration_ms: 5727.421721 type: 'test' ...# Subtest: early access: a request is confirmed with the link from its email, then waits for site administratorsok 16 - early access: a request is confirmed with the link from its email, then waits for site administrators --- duration_ms: 4454.111308 type: 'test' ...# Subtest: early access: the same answer for an address that already asked or has an account; only its inbox learns whichok 17 - early access: the same answer for an address that already asked or has an account; only its inbox learns which --- duration_ms: 5356.494741 type: 'test' ...# Subtest: early access: bots, bad input and big bodies get nowhereok 18 - early access: bots, bad input and big bodies get nowhere --- duration_ms: 4860.278663 type: 'test' ...# Subtest: early access: only site administrators see requests (404 for anyone else)ok 19 - early access: only site administrators see requests (404 for anyone else) --- duration_ms: 129.040647 type: 'test' ...# Subtest: early access: invite, decline, put back and delete, on the web and through the API, auditedok 20 - early access: invite, decline, put back and delete, on the web and through the API, audited --- duration_ms: 8081.705476 type: 'test' ...# Subtest: early access: people remove their own request with an emailed linkok 21 - early access: people remove their own request with an emailed link --- duration_ms: 8582.937419 type: 'test' ...# Subtest: early access: daily limits per network and per addressok 22 - early access: daily limits per network and per address --- duration_ms: 4937.917215 type: 'test' ...# Subtest: email: security emails, settings, the test email and every templateok 23 - email: security emails, settings, the test email and every template --- duration_ms: 5350.643842 type: 'test' ...# Subtest: email: watching, mentions, own activity, one-click unsubscribe and failed runsok 24 - email: watching, mentions, own activity, one-click unsubscribe and failed runs --- duration_ms: 22674.810666 type: 'test' ...# Subtest: email: a commit blocked by push protection, made without git, is emailed like a blocked pushok 25 - email: a commit blocked by push protection, made without git, is emailed like a blocked push --- duration_ms: 2492.062914 type: 'test' ...# Subtest: email: bounces and complaints suppress an address; its owner lifts it by verifying, an admin removes itok 26 - email: bounces and complaints suppress an address; its owner lifts it by verifying, an admin removes it --- duration_ms: 2532.826336 type: 'test' ...# Subtest: email: the morning digest on its schedule, one-click unsubscribe, and Today on a phone (phase 5c)ok 27 - email: the morning digest on its schedule, one-click unsubscribe, and Today on a phone (phase 5c) --- duration_ms: 7157.695105 type: 'test' ...# Subtest: setup: a private repository with a pull request, two check runs and a commit statusok 28 - setup: a private repository with a pull request, two check runs and a commit status --- duration_ms: 5378.70124 type: 'test' ...# Subtest: Claude Code: the current branch's pull request and its review decisionok 29 - Claude Code: the current branch's pull request and its review decision --- duration_ms: 44.972358 type: 'test' ...# Subtest: Claude Code: CI counts and pull request state for the badgeok 30 - Claude Code: CI counts and pull request state for the badge --- duration_ms: 27.103436 type: 'test' ...# Subtest: gh pr checks and gh pr view: the rollup, node lookup and fields Diffinery doesn't haveok 31 - gh pr checks and gh pr view: the rollup, node lookup and fields Diffinery doesn't have --- duration_ms: 67.174771 type: 'test' ...# Subtest: gh pr ready, edit, comment, close, reopen and mergeok 32 - gh pr ready, edit, comment, close, reopen and merge --- duration_ms: 409.817182 type: 'test' ...# Subtest: sign-in, privacy, limits and GitHub's error shapeok 33 - sign-in, privacy, limits and GitHub's error shape --- duration_ms: 77.590099 type: 'test' ...# Subtest: moderation: reports land in the site administrators' queueok 34 - moderation: reports land in the site administrators' queue --- duration_ms: 6429.942904 type: 'test' ...# Subtest: moderation: a blocked person can't take part in the blocker's repositories, and can elsewhereok 35 - moderation: a blocked person can't take part in the blocker's repositories, and can elsewhere --- duration_ms: 816.912739 type: 'test' ...# Subtest: moderation: a suspended person is stopped and hidden at once, and unsuspending restores themok 36 - moderation: a suspended person is stopped and hidden at once, and unsuspending restores them --- duration_ms: 995.31536 type: 'test' ...# Subtest: moderation: a minimized comment shows collapsedok 37 - moderation: a minimized comment shows collapsed --- duration_ms: 359.274506 type: 'test' ...# Subtest: OAuth for MCP clients: discovery, registration, consent, tokens, refresh and revocationok 38 - OAuth for MCP clients: discovery, registration, consent, tokens, refresh and revocation --- duration_ms: 18324.793774 type: 'test' ...# Subtest: OAuth: a client metadata document as the client_idok 39 - OAuth: a client metadata document as the client_id --- duration_ms: 1137.209713 type: 'test' ...# Subtest: OAuth: Diffinery's own editor extension (apps/vscode)ok 40 - OAuth: Diffinery's own editor extension (apps/vscode) --- duration_ms: 1798.894594 type: 'test' ...# Subtest: OAuth: Diffinery's own plugin for JetBrains IDEs (apps/jetbrains)ok 41 - OAuth: Diffinery's own plugin for JetBrains IDEs (apps/jetbrains) --- duration_ms: 1258.035003 type: 'test' ...# Subtest: passkey sign-in, invites and sign-in linksok 42 - passkey sign-in, invites and sign-in links --- duration_ms: 14355.190826 type: 'test' ...# Subtest: CLI: one-line install, then sign-in in the browser and with a device codeok 43 - CLI: one-line install, then sign-in in the browser and with a device code --- duration_ms: 7552.669835 type: 'test' ...# Subtest: open sign-up: off by default; on, an emailed code, then a passkeyok 44 - open sign-up: off by default; on, an emailed code, then a passkey --- duration_ms: 10157.14106 type: 'test' ...# Subtest: favicons, robots.txt, sitemap and search metadatanot ok 45 - favicons, robots.txt, sitemap and search metadata --- duration_ms: 177.764313 type: 'test' location: '/workspace/diffinery/apps/diffinery/test/e2e/passkeys.test.mjs:570:1' failureType: 'testCodeFailure' error: |- The input did not match the regular expression /<title>Diffinery: GitHub alternative with fast CI, built for AI agents<\/title>/. Input: `<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="color-scheme" content="light dark"/><title>Diffinery: open-source GitHub alternative with fast CI, built for AI agents</title><meta name="description" content="Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails."/><link rel="canonical" href="http://localhost:24249/"/><link rel="icon" href="/favicon.ico" sizes="16x16 32x32 48x48 64x64"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><link rel="icon" href="/favicon-48.png" sizes="48x48" type="image/png"/><link rel="icon" href="/favicon-96.png" sizes="96x96" type="image/png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><link rel="manifest" href="/site.webmanifest"/><meta name="theme-color" content="#f6821f"/><meta name="application-name" content="Diffinery"/><meta name="apple-mobile-web-app-title" content="Diffinery"/><meta property="og:type" content="website"/><meta property="og:site_name" content="Diffinery"/><meta property="og:title" content="Diffinery: open-source GitHub alternative with fast CI, built for AI agents"/><meta property="og:description" content="Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails."/><meta property="og:url" content="http://localhost:24249/"/><meta property="og:image" content="http://localhost:24249/og-image.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="Diffinery: Code hosting and CI for the agentic era"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Diffinery: open-source GitHub alternative with fast CI, built for AI agents"/><meta name="twitter:description" content="Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails."/><meta name="twitter:image" content="http://localhost:24249/og-image.png"/><script type="application/ld+json" nonce="tnwt9WYAuXTpg2S54jPo3g">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"http://localhost:24249/#organization","name":"Diffinery","url":"http://localhost:24249/","logo":{"@type":"ImageObject","url":"http://localhost:24249/icon-512.png","width":512,"height":512},"description":"Diffinery is open-source code hosting and CI for the agentic era: Git repositories, pull requests with intent, GitHub Actions compatible workflows and AI agents as first-class collaborators, running on your own Cloudflare account."},{"@type":"WebSite","@id":"http://localhost:24249/#website","name":"Diffinery","url":"http://localhost:24249/","inLanguage":"en","publisher":{"@id":"http://localhost:24249/#organization"}},{"@type":"SoftwareApplication","@id":"http://localhost:24249/#software","name":"Diffinery","url":"http://localhost:24249/","applicationCategory":"DeveloperApplication","applicationSubCategory":"Git hosting and continuous integration","operatingSystem":"Web","description":"Diffinery is an open-source GitHub alternative for teams of people and AI agents. Git repositories, pull requests, GitHub Actions–compatible CI on fast runners, and agents with their own accounts and guardrails, running entirely on your own Cloudflare account.","featureList":["Git hosting: Clone, fetch and push over HTTPS with Git LFS. Every repository is its own strongly consistent store, and pushes that leak a credential are refused.","Pull requests with intent: Reviews, required approvals and checks, auto-merge and a merge queue. Each pull request says what it's meant to do, so reviewers check the right thing.","GitHub Actions–compatible CI: The same triggers, expressions, matrices, reusable workflows, secrets, OIDC and Docker. Actions from GitHub run as they do there.","Fast, right-sized runners: 4 vCPUs and 12 GiB per job by default, started in seconds. Jobs that only wait move to smaller runners on their own, never at the cost of speed.","AI agents with guardrails: Agents get their own accounts and tokens, an MCP server, sandboxes, tasks and reviews. They can't push to protected branches or reach your secrets.","Secure by default: Passkeys instead of passwords, invite-only sign-up, encrypted secrets, scoped job tokens and an append-only audit log.","Runs entirely on Cloudflare: as far as we know, the only open-source project where Git hosting, pull requests with reviews and GitHub Actions–compatible CI, marketplace actions included, all run on Cloudflare (checked October 25, 2026).","Open source under the Apache License 2.0, deployed to your own Cloudflare account"],"license":"https://www.apache.org/licenses/LICENSE-2.0","isAccessibleForFree":true,"offers":{"@type":"Offer","price":"0","priceCurrency":"USD","description":"Free, open-source software. Your instance's Cloudflare usage is billed by Cloudflare."},"softwareHelp":{"@type":"CreativeWork","url":"http://localhost:24249/docs/self-hosting/deploy"},"publisher":{"@id":"http://localhost:24249/#organization"},"sameAs":["http://localhost:24249/docs","https://diffinery.com/codician/diffinery","https://github.com/codician-team/diffinery"]},{"@type":"SoftwareSourceCode","@id":"http://localhost:24249/#source","name":"Diffinery","description":"The source code of Diffinery, which you deploy to your own Cloudflare account.","codeRepository":"https://diffinery.com/codician/diffinery","sameAs":["https://github.com/codician-team/diffinery"],"license":"https://www.apache.org/licenses/LICENSE-2.0","programmingLanguage":"TypeScript","runtimePlatform":"Cloudflare Workers","isAccessibleForFree":true,"targetProduct":{"@id":"http://localhost:24249/#software"},"publisher":{"@id":"http://localhost:24249/#organization"}},{"@type":"WebPage","@id":"http://localhost:24249/#webpage","url":"http://localhost:24249/","name":"Diffinery: open-source GitHub alternative with fast CI, built for AI agents","description":"Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails.","isPartOf":{"@id":"http://localhost:24249/#website"},"about":{"@id":"http://localhost:24249/#software"},"dateModified":"2026-10-25","inLanguage":"en"},{"@type":"FAQPage","@id":"http://localhost:24249/#faq","url":"http://localhost:24249/","mainEntity":[{"@type":"Question","name":"What is Diffinery?","acceptedAnswer":{"@type":"Answer","text":"Diffinery is a git forge and CI platform for teams of people and AI agents. It hosts Git repositories, pull requests, issues and releases, runs GitHub Actions workflows on its own hosted runners, and gives AI agents their own accounts, tokens and server-enforced guardrails. It runs entirely on Cloudflare, and it's open source under the Apache License 2.0: you deploy it to your own Cloudflare account."}},{"@type":"Question","name":"Is Diffinery an alternative to GitHub?","acceptedAnswer":{"@type":"Answer","text":"Yes, for teams whose work fits it: Diffinery replaces GitHub's code hosting, pull requests and GitHub Actions in one platform. It doesn't have GitHub's hosted macOS and Windows runners, forks, app marketplace, Codespaces, Pages or Discussions. See Diffinery vs GitHub."}},{"@type":"Question","name":"Do my GitHub Actions workflows run on Diffinery?","acceptedAnswer":{"@type":"Answer","text":"Most run without changes. Diffinery reads .github/workflows/*.yml with the same syntax, triggers, expressions and actions. Hosted runners are Linux x64; macOS, Windows and Arm jobs need a self-hosted runner. Every difference is listed in Compatibility with GitHub Actions."}},{"@type":"Question","name":"Is Diffinery built on Cloudflare?","acceptedAnswer":{"@type":"Answer","text":"Yes, entirely, and as far as we know it's the only open-source project where Git hosting, pull requests with reviews and GitHub Actions–compatible CI, marketplace actions included, all run on Cloudflare (checked October 25, 2026). One Cloudflare Worker serves the site, the API, Git and the MCP server; each repository is its own Durable Object, with large objects in R2 and accounts in D1; Workflows and Queues drive CI runs, webhooks and email; and every CI job runs in a Cloudflare Container that exists only while the job runs. There are no servers to manage. See Built on Cloudflare."}},{"@type":"Question","name":"How is Diffinery different from Blacksmith or Depot?","acceptedAnswer":{"@type":"Answer","text":"Blacksmith sells faster runners for GitHub Actions, and Depot sells runners, its own CI engine and container builds. With either, your code and pull requests usually stay on GitHub and jobs run on their machines. Diffinery replaces GitHub and GitHub Actions together, with fast runners built in, as one open-source platform you run on your own Cloudflare account. See Diffinery vs Blacksmith and Diffinery vs Depot."}},{"@type":"Question","name":"How does Diffinery work with Claude Code, Codex and other AI agents?","acceptedAnswer":{"@type":"Answer","text":"Agents connect over MCP at /mcp on your instance with a browser sign-in, or use Git, the GitHub CLI and the REST API with an agent token. Each agent is an account of its own: it can't push to protected branches, its pull requests need a person's approval, and runs of its code get no secrets. See Diffinery for AI agents."}},{"@type":"Question","name":"How do I move from GitHub?","acceptedAnswer":{"@type":"Answer","text":"Diffinery's `... 84457 more characters code: 'ERR_ASSERTION' name: 'AssertionError' expected: actual: |- <!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="color-scheme" content="light dark"/><title>Diffinery: open-source GitHub alternative with fast CI, built for AI agents</title><meta name="description" content="Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails."/><link rel="canonical" href="http://localhost:24249/"/><link rel="icon" href="/favicon.ico" sizes="16x16 32x32 48x48 64x64"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><link rel="icon" href="/favicon-48.png" sizes="48x48" type="image/png"/><link rel="icon" href="/favicon-96.png" sizes="96x96" type="image/png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><link rel="manifest" href="/site.webmanifest"/><meta name="theme-color" content="#f6821f"/><meta name="application-name" content="Diffinery"/><meta name="apple-mobile-web-app-title" content="Diffinery"/><meta property="og:type" content="website"/><meta property="og:site_name" content="Diffinery"/><meta property="og:title" content="Diffinery: open-source GitHub alternative with fast CI, built for AI agents"/><meta property="og:description" content="Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails."/><meta property="og:url" content="http://localhost:24249/"/><meta property="og:image" content="http://localhost:24249/og-image.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="Diffinery: Code hosting and CI for the agentic era"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Diffinery: open-source GitHub alternative with fast CI, built for AI agents"/><meta name="twitter:description" content="Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails."/><meta name="twitter:image" content="http://localhost:24249/og-image.png"/><script type="application/ld+json" nonce="tnwt9WYAuXTpg2S54jPo3g">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"http://localhost:24249/#organization","name":"Diffinery","url":"http://localhost:24249/","logo":{"@type":"ImageObject","url":"http://localhost:24249/icon-512.png","width":512,"height":512},"description":"Diffinery is open-source code hosting and CI for the agentic era: Git repositories, pull requests with intent, GitHub Actions compatible workflows and AI agents as first-class collaborators, running on your own Cloudflare account."},{"@type":"WebSite","@id":"http://localhost:24249/#website","name":"Diffinery","url":"http://localhost:24249/","inLanguage":"en","publisher":{"@id":"http://localhost:24249/#organization"}},{"@type":"SoftwareApplication","@id":"http://localhost:24249/#software","name":"Diffinery","url":"http://localhost:24249/","applicationCategory":"DeveloperApplication","applicationSubCategory":"Git hosting and continuous integration","operatingSystem":"Web","description":"Diffinery is an open-source GitHub alternative for teams of people and AI agents. Git repositories, pull requests, GitHub Actions–compatible CI on fast runners, and agents with their own accounts and guardrails, running entirely on your own Cloudflare account.","featureList":["Git hosting: Clone, fetch and push over HTTPS with Git LFS. Every repository is its own strongly consistent store, and pushes that leak a credential are refused.","Pull requests with intent: Reviews, required approvals and checks, auto-merge and a merge queue. Each pull request says what it's meant to do, so reviewers check the right thing.","GitHub Actions–compatible CI: The same triggers, expressions, matrices, reusable workflows, secrets, OIDC and Docker. Actions from GitHub run as they do there.","Fast, right-sized runners: 4 vCPUs and 12 GiB per job by default, started in seconds. Jobs that only wait move to smaller runners on their own, never at the cost of speed.","AI agents with guardrails: Agents get their own accounts and tokens, an MCP server, sandboxes, tasks and reviews. They can't push to protected branches or reach your secrets.","Secure by default: Passkeys instead of passwords, invite-only sign-up, encrypted secrets, scoped job tokens and an append-only audit log.","Runs entirely on Cloudflare: as far as we know, the only open-source project where Git hosting, pull requests with reviews and GitHub Actions–compatible CI, marketplace actions included, all run on Cloudflare (checked October 25, 2026).","Open source under the Apache License 2.0, deployed to your own Cloudflare account"],"license":"https://www.apache.org/licenses/LICENSE-2.0","isAccessibleForFree":true,"offers":{"@type":"Offer","price":"0","priceCurrency":"USD","description":"Free, open-source software. Your instance's Cloudflare usage is billed by Cloudflare."},"softwareHelp":{"@type":"CreativeWork","url":"http://localhost:24249/docs/self-hosting/deploy"},"publisher":{"@id":"http://localhost:24249/#organization"},"sameAs":["http://localhost:24249/docs","https://diffinery.com/codician/diffinery","https://github.com/codician-team/diffinery"]},{"@type":"SoftwareSourceCode","@id":"http://localhost:24249/#source","name":"Diffinery","description":"The source code of Diffinery, which you deploy to your own Cloudflare account.","codeRepository":"https://diffinery.com/codician/diffinery","sameAs":["https://github.com/codician-team/diffinery"],"license":"https://www.apache.org/licenses/LICENSE-2.0","programmingLanguage":"TypeScript","runtimePlatform":"Cloudflare Workers","isAccessibleForFree":true,"targetProduct":{"@id":"http://localhost:24249/#software"},"publisher":{"@id":"http://localhost:24249/#organization"}},{"@type":"WebPage","@id":"http://localhost:24249/#webpage","url":"http://localhost:24249/","name":"Diffinery: open-source GitHub alternative with fast CI, built for AI agents","description":"Diffinery is open-source code hosting and CI for the agentic era, running on your own Cloudflare account: Git repositories, pull requests, GitHub Actions–compatible CI on 4-vCPU runners, and AI agents with their own accounts and guardrails.","isPartOf":{"@id":"http://localhost:24249/#website"},"about":{"@id":"http://localhost:24249/#software"},"dateModified":"2026-10-25","inLanguage":"en"},{"@type":"FAQPage","@id":"http://localhost:24249/#faq","url":"http://localhost:24249/","mainEntity":[{"@type":"Question","name":"What is Diffinery?","acceptedAnswer":{"@type":"Answer","text":"Diffinery is a git forge and CI platform for teams of people and AI agents. It hosts Git repositories, pull requests, issues and releases, runs GitHub Actions workflows on its own hosted runners, and gives AI agents their own accounts, tokens and server-enforced guardrails. It runs entirely on Cloudflare, and it's open source under the Apache License 2.0: you deploy it to your own Cloudflare account."}},{"@type":"Question","name":"Is Diffinery an alternative to GitHub?","acceptedAnswer":{"@type":"Answer","text":"Yes, for teams whose work fits it: Diffinery replaces GitHub's code hosting, pull requests and GitHub Actions in one platform. It doesn't have GitHub's hosted macOS and Windows runners, forks, app marketplace, Codespaces, Pages or Discussions. See Diffinery vs GitHub."}},{"@type":"Question","name":"Do my GitHub Actions workflows run on Diffinery?","acceptedAnswer":{"@type":"Answer","text":"Most run without changes. Diffinery reads .github/workflows/*.yml with the same syntax, triggers, expressions and actions. Hosted runners are Linux x64; macOS, Windows and Arm jobs need a self-hosted runner. Every difference is listed in Compatibility with GitHub Actions."}},{"@type":"Question","name":"Is Diffinery built on Cloudflare?","acceptedAnswer":{"@type":"Answer","text":"Yes, entirely, and as far as we know it's the only open-source project where Git hosting, pull requests with reviews and GitHub Actions–compatible CI, marketplace actions included, all run on Cloudflare (checked October 25, 2026). One Cloudflare Worker serves the site, the API, Git and the MCP server; each repository is its own Durable Object, with large objects in R2 and accounts in D1; Workflows and Queues drive CI runs, webhooks and email; and every CI job runs in a Cloudflare Container that exists only while the job runs. There are no servers to manage. See Built on Cloudflare."}},{"@type":"Question","name":"How is Diffinery different from Blacksmith or Depot?","acceptedAnswer":{"@type":"Answer","text":"Blacksmith sells faster runners for GitHub Actions, and Depot sells runners, its own CI engine and container builds. With either, your code and pull requests usually stay on GitHub and jobs run on their machines. Diffinery replaces GitHub and GitHub Actions together, with fast runners built in, as one open-source platform you run on your own Cloudflare account. See Diffinery vs Blacksmith and Diffinery vs Depot."}},{"@type":"Question","name":"How does Diffinery work with Claude Code, Codex and other AI agents?","acceptedAnswer":{"@type":"Answer","text":"Agents connect over MCP at /mcp on your instance with a browser sign-in, or use Git, the GitHub CLI and the REST API with an agent token. Each agent is an account of its own: it can't push to protected branches, its pull requests need a person's approval, and runs of its code get no secrets. See Diffinery for AI agents."}},{"@type":"Question","name":"How do I move from GitHub?","acceptedAnswer":{"@type":"Answer","text":"Diffinery's importer copies a repository or a whole organization from GitHub on the server, with history, issues, pull requests, reviews, releases and branch protection, keeping their numbers. Then you enter your secrets' values and push. See Migrate from GitHub."}},{"@type":"Question","name":"Is Diffinery open source?","acceptedAnswer":{"@type":"Answer","text":"Yes, under the Apache License 2.0, with no paid edition and nothing sold. The source code is at diffinery.com/codician/diffinery and mirrored to github.com/codician-team/diffinery. See Open source."}},{"@type":"Question","name":"How do I start using Diffinery, and what does it cost?","acceptedAnswer":{"@type":"Answer","text":"Deploy your own instance to your Cloudflare account and domain with one command, scripts/setup.sh, then sign in as its first administrator and invite your team. See Deploy your own Diffinery. Diffinery is free; you pay Cloudflare for what your instance uses, on the Workers Paid plan (a minimum of $5 USD per month per account, plus usage; Cloudflare's pricing, checked October 25, 2026). There's no hosted service to sign up for: diffinery.com is the project's own instance."}}]}]}</script><style> /* Cascade order: the site's own styles first, then Kumo's (build/islands/kumo.css, confined to .dfy-k islands), then island layout. kumo-reset reverts site styles inside islands so Kumo controls look exactly like Kumo. */ @layer site,kumo-reset,properties,theme,base,components,utilities,islands; @layer site{ :root{color-scheme:light dark; /* Colors, radii and type follow Cloudflare's Kumo design system tokens (kumo-ui.com, MIT). */ --canvas:oklch(98.75% 0 0);--bg:#fff;--bg2:oklch(98% 0 0);--bg3:oklch(96% 0 0);--bg-hover:oklch(97% 0 0); --fg:oklch(21% 0.006 285.885);--fg2:oklch(55.6% 0 0);--fg3:oklch(70.8% 0 0); --border:oklch(14.5% 0 0 / .1);--border2:oklch(93.5% 0 0); --accent:oklch(48.8% 0.243 264.376);--accent-hover:oklch(54.6% 0.245 262.881);--accent-fg:#fff;--accent-soft:oklch(93.2% 0.032 255.6 / .45); --link:oklch(42.4% 0.199 265.638);--focus:oklch(15% 0 0); --green:oklch(43.2% 0.095 166.913);--green-soft:oklch(96.2% 0.043 156.7 / .57);--red:oklch(50.5% 0.213 27.518);--red-soft:oklch(93.6% 0.032 17.7 / .42); --amber:oklch(59.7% 0.144 57.5);--amber-soft:oklch(93.1% 0.107 94.6 / .2); --purple:oklch(55.8% 0.288 302.321);--purple-soft:oklch(55.8% 0.288 302.321 / .1);--blue:oklch(42.4% 0.199 265.638);--blue-soft:oklch(93.2% 0.032 255.6 / .45); --brand:#f6821f; --add-bg:oklch(96.2% 0.043 156.7 / .57);--add-ln:oklch(90.5% 0.093 164.15 / .7);--del-bg:oklch(93.6% 0.032 17.7 / .42);--del-ln:oklch(88.5% 0.062 18.334 / .7);--hunk-bg:oklch(93.2% 0.032 255.6 / .45);--hl:oklch(97.3% 0.071 103.193); --code-bg:oklch(96% 0 0);--shadow:0 0 0 1px oklch(0% 0 0 / .12),0 8px 24px oklch(0% 0 0 / .08);--r:.5rem;--r-sm:.375rem; --mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"} @media (prefers-color-scheme:dark){:root:not([data-theme=light]){--canvas:oklch(10% 0 0);--bg:oklch(17% 0 0);--bg2:oklch(12% 0 0);--bg3:oklch(15% 0 0);--bg-hover:oklch(26.9% 0 0); --fg:oklch(97% 0 0);--fg2:oklch(70.8% 0 0);--fg3:oklch(55.6% 0 0); --border:oklch(32% 0 0);--border2:oklch(26.9% 0 0); --accent:oklch(48.8% 0.243 264.376);--accent-hover:oklch(54.6% 0.245 262.881);--accent-fg:#fff;--accent-soft:oklch(38% 0.145 265.5 / .22); --link:oklch(70.7% 0.165 254.624);--focus:oklch(93.5% 0 0); --green:oklch(76.5% 0.177 163.223);--green-soft:oklch(39.3% 0.096 152.3 / .2);--red:oklch(70.4% 0.191 22.216);--red-soft:oklch(42.9% 0.176 28.7 / .17); --amber:oklch(75% 0.183 55.934);--amber-soft:oklch(35.3% 0.079 65 / .37); --purple:oklch(71.4% 0.203 305.504);--purple-soft:oklch(49.6% 0.265 301.924 / .2);--blue:oklch(70.7% 0.165 254.624);--blue-soft:oklch(38% 0.145 265.5 / .22); --add-bg:oklch(39.3% 0.096 152.3 / .2);--add-ln:oklch(39.3% 0.096 152.3 / .4);--del-bg:oklch(42.9% 0.176 28.7 / .17);--del-ln:oklch(42.9% 0.176 28.7 / .35);--hunk-bg:oklch(38% 0.145 265.5 / .22);--hl:oklch(55.4% 0.135 66.442 / .5); --code-bg:oklch(15% 0 0);--shadow:0 0 0 1px oklch(100% 0 0 / .1),0 8px 24px oklch(0% 0 0 / .3)}}:root[data-theme=dark]{--canvas:oklch(10% 0 0);--bg:oklch(17% 0 0);--bg2:oklch(12% 0 0);--bg3:oklch(15% 0 0);--bg-hover:oklch(26.9% 0 0); --fg:oklch(97% 0 0);--fg2:oklch(70.8% 0 0);--fg3:oklch(55.6% 0 0); --border:oklch(32% 0 0);--border2:oklch(26.9% 0 0); --accent:oklch(48.8% 0.243 264.376);--accent-hover:oklch(54.6% 0.245 262.881);--accent-fg:#fff;--accent-soft:oklch(38% 0.145 265.5 / .22); --link:oklch(70.7% 0.165 254.624);--focus:oklch(93.5% 0 0); --green:oklch(76.5% 0.177 163.223);--green-soft:oklch(39.3% 0.096 152.3 / .2);--red:oklch(70.4% 0.191 22.216);--red-soft:oklch(42.9% 0.176 28.7 / .17); --amber:oklch(75% 0.183 55.934);--amber-soft:oklch(35.3% 0.079 65 / .37); --purple:oklch(71.4% 0.203 305.504);--purple-soft:oklch(49.6% 0.265 301.924 / .2);--blue:oklch(70.7% 0.165 254.624);--blue-soft:oklch(38% 0.145 265.5 / .22); --add-bg:oklch(39.3% 0.096 152.3 / .2);--add-ln:oklch(39.3% 0.096 152.3 / .4);--del-bg:oklch(42.9% 0.176 28.7 / .17);--del-ln:oklch(42.9% 0.176 28.7 / .35);--hunk-bg:oklch(38% 0.145 265.5 / .22);--hl:oklch(55.4% 0.135 66.442 / .5); --code-bg:oklch(15% 0 0);--shadow:0 0 0 1px oklch(100% 0 0 / .1),0 8px 24px oklch(0% 0 0 / .3)} :root[data-theme=light]{color-scheme:light}:root[data-theme=dark]{color-scheme:dark} *{box-sizing:border-box} /* Phosphor icons sit on the text's center line when inline; flex containers center them themselves. */ svg[viewBox="0 0 256 256"]{vertical-align:-3px;flex:none} html{-webkit-text-size-adjust:100%} body{margin:0;background:var(--canvas);color:var(--fg);font:14px/1.5 var(--sans)} a{color:var(--link);text-decoration:none}a:hover{text-decoration:underline} code,pre,kbd,.mono{font-family:var(--mono);font-size:12.5px} kbd{border:1px solid var(--border);border-bottom-width:2px;border-radius:4px;padding:0 5px;background:var(--bg2);font-size:11px;color:var(--fg2)} h1,h2,h3,h4{line-height:1.25;margin:0 0 8px}h1{font-size:22px}h2{font-size:18px}h3{font-size:15px} p{margin:0 0 10px} hr{border:0;border-top:1px solid var(--border);margin:16px 0} .muted{color:var(--fg2)}.faint{color:var(--fg3)}.small{font-size:12px}.nowrap{white-space:nowrap} .ok{color:var(--green)}.bad{color:var(--red)}.warn{color:var(--amber)}.run{color:var(--amber)}.merged{color:var(--purple)} .top{position:sticky;top:0;z-index:20;background:color-mix(in srgb,var(--bg) 88%,transparent);backdrop-filter:saturate(1.6) blur(10px);border-bottom:1px solid var(--border)} .top .wrap{display:flex;align-items:center;gap:14px;height:52px} .brand{display:flex;align-items:center;gap:8px;font-weight:650;color:var(--fg);letter-spacing:-.01em;white-space:nowrap} .brand:hover{text-decoration:none}.brand svg{color:var(--brand)} .top nav{display:flex;align-items:center;gap:4px;margin-left:auto} /* Nav link styles skip buttons (Sign in), so a .btn keeps its own colours and hover. */ .top nav a:not(.btn){color:var(--fg2);padding:6px 10px;border-radius:6px}.top nav a:not(.btn):hover{background:var(--bg-hover);color:var(--fg);text-decoration:none} .pal-btn{display:flex;align-items:center;gap:8px;min-width:220px;padding:5px 10px;border:1px solid var(--border);border-radius:7px;background:var(--bg2);color:var(--fg3);font:inherit;cursor:pointer} .pal-btn:hover{border-color:var(--fg3)}.pal-btn kbd{margin-left:auto;white-space:nowrap} .dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--accent);margin-left:2px;vertical-align:top} .wrap{max-width:1280px;margin:0 auto;padding:0 20px} main.wrap{padding-top:20px;padding-bottom:60px} .flash{border:1px solid;border-radius:var(--r);padding:10px 14px;margin:0 0 16px} .flash.error{border-color:color-mix(in srgb,var(--red) 40%,transparent);background:var(--red-soft);color:var(--red)} .flash.notice{border-color:color-mix(in srgb,var(--green) 40%,transparent);background:var(--green-soft);color:var(--green)} .flash.info{border-color:color-mix(in srgb,var(--blue) 40%,transparent);background:var(--blue-soft)} .flash.warn{border-color:color-mix(in srgb,var(--amber) 40%,transparent);background:var(--amber-soft);color:var(--amber)} /* Footer: full-width band; brand and link columns across the page width, then a bottom bar. */ .site-foot{border-top:1px solid var(--border2);background:var(--bg2);font-size:13px;color:var(--fg3)} .site-foot a{color:var(--fg2)}.site-foot a:hover,.site-foot .brand{color:var(--fg);text-decoration:none} .site-foot .foot-main{display:grid;grid-template-columns:minmax(0,1.7fr) repeat(4,minmax(0,1fr));gap:40px 32px;padding-top:56px;padding-bottom:48px} .foot-brand{display:flex;flex-direction:column;align-items:flex-start;gap:14px}.foot-brand .brand{font-size:16px} .foot-brand p{margin:0;max-width:320px;line-height:1.6;color:var(--fg2)}.foot-brand p strong{color:var(--fg);font-weight:550} .site-foot .foot-brand .btn{color:var(--fg)} .foot-main nav{display:flex;flex-direction:column;align-items:flex-start;gap:11px}.foot-main h2{font-size:13px;font-weight:600;color:var(--fg);margin:0 0 3px} .foot-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px 24px;padding:20px 0 28px;font-size:12px} .foot-main+.wrap>.foot-bar{border-top:1px solid var(--border2)}.foot-bar nav{display:flex;flex-wrap:wrap;gap:20px} @media (max-width:1000px){.site-foot .foot-main{grid-template-columns:repeat(4,minmax(0,1fr));padding-top:44px}.foot-brand{grid-column:1/-1}.foot-brand p{max-width:520px}} @media (max-width:600px){.site-foot .foot-main{grid-template-columns:repeat(2,minmax(0,1fr));gap:32px 16px;padding-top:36px;padding-bottom:36px}.top nav a.nav-site{display:none}} /* Controls follow Kumo sizes: base 36px (buttons, inputs, selects), sm 26px. */ .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:36px;padding:0 12px;border:1px solid var(--border);border-radius:var(--r);background:var(--bg);color:var(--fg);font:500 14px/1 var(--sans);cursor:pointer;white-space:nowrap;text-decoration:none!important;vertical-align:middle;flex:none} .btn svg{flex:none} .btn:hover{background:var(--bg-hover);border-color:var(--fg3)} .btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-fg);box-shadow:inset 0 1px 0 0 oklch(100% 0 0 / .15)}.btn.primary:hover{background:var(--accent-hover)} .btn.green{background:var(--accent);border-color:var(--accent);color:var(--accent-fg)}.btn.green:hover{background:var(--accent-hover)} .btn.danger{color:var(--red)}.btn.danger:hover{background:var(--red);border-color:var(--red);color:#fff} .btn.sm{height:26px;padding:0 8px;gap:4px;font-size:12px;border-radius:var(--r-sm)}.btn.sm svg{width:14px;height:14px}.btn.icon{width:36px;padding:0}.btn.sm.icon{width:26px} .btn.link{border-color:transparent;background:none;color:var(--accent);padding:0;height:auto} .btn[disabled]{opacity:.5;cursor:not-allowed} input[type=text],input[type=search],input[type=email],input[type=number],input[type=url],input[type=password],input:not([type]),textarea{ width:100%;height:36px;padding:0 12px;border:1px solid var(--border);border-radius:var(--r);background:var(--bg);color:var(--fg);font:inherit} input[type=file]{display:block;width:100%;font:inherit;font-size:13px;color:var(--fg2);padding:6px 0} input[type=file]::file-selector-button{height:30px;margin-right:10px;padding:0 12px;border:1px solid var(--border);border-radius:var(--r);background:var(--bg);color:var(--fg);font:500 13px/1 var(--sans);cursor:pointer} input[type=file]::file-selector-button:hover{background:var(--bg-hover)} .checklist{display:flex;flex-direction:column;align-items:flex-start;gap:8px} textarea{height:auto;padding:8px 12px;line-height:1.5;min-height:120px;resize:vertical;font-family:var(--sans)}textarea.code{font-family:var(--mono);font-size:12.5px;min-height:420px;tab-size:4;white-space:pre} input:focus,textarea:focus{outline:2px solid color-mix(in srgb,var(--focus) 25%,transparent);outline-offset:0;border-color:color-mix(in srgb,var(--focus) 50%,transparent)} :focus-visible{outline:2px solid color-mix(in srgb,var(--focus) 35%,transparent);outline-offset:2px} label{display:block;font-weight:550;margin:0 0 4px}label.inline{display:inline-flex;align-items:center;gap:6px;font-weight:400} .field{margin:0 0 14px}.field .hint{font-size:12px;color:var(--fg2);margin-top:4px;font-weight:400} .row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.row.end{justify-content:flex-end}.row.between{justify-content:space-between} .grow{flex:1;min-width:0} .row.nowrap{flex-wrap:nowrap} /* A one-line form: fields and the submit button share a baseline at the control's bottom edge. */ .formrow{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}.formrow>.field{margin:0}.formrow>.field.grow{min-width:220px} .formrow+.hint{font-size:12px;color:var(--fg2);margin-top:8px} /* Settings forms (.fbody): titled sections, a grid of labelled fields that align on their labels and controls (one column when the form is narrow), checkbox lists with the helper text under each label, and a footer for the submit button. */ .fbody{container-type:inline-size} .fsec{padding:20px 0;border-top:1px solid var(--border2)}.fsec:first-of-type{padding-top:0;border-top:0} .fsec>h3{font-size:14px;margin:0 0 12px}.fsec>.fsec-d{font-size:13px;color:var(--fg2);margin:-8px 0 12px} .fsec>:last-child,.fbody .field:last-child{margin-bottom:0} .fgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-items:start;margin:0 0 16px}.fgrid.c3{grid-template-columns:repeat(3,minmax(0,1fr))} .fgrid>.field{margin:0;min-width:0}.fgrid>.span2{grid-column:span 2}.fgrid>.full{grid-column:1/-1} @container (max-width:560px){.fgrid,.fgrid.c3{grid-template-columns:minmax(0,1fr)}.fgrid>.span2{grid-column:auto}} .fchecks{display:flex;flex-direction:column;align-items:flex-start;gap:12px;margin:0 0 16px} .fchecks.cols{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px 16px} .fbody textarea{min-height:0} .factions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-top:20px;padding-top:16px;border-top:1px solid var(--border2)}.fsec+.factions{margin-top:0} /* A setting with its button: text on the left, the button on the right, stacked on phones. */ .drow{display:flex;gap:16px;align-items:center;justify-content:space-between}.drow>div{flex:1;min-width:0} @media (max-width:600px){.drow{flex-direction:column;align-items:flex-start;gap:10px}} .grid{display:grid;grid-template-columns:minmax(0,1fr) 296px;gap:24px} .grid.left{grid-template-columns:260px minmax(0,1fr)} @media (max-width:900px){.grid,.grid.left{grid-template-columns:minmax(0,1fr)}.grid.left>.side.after{order:2}.pal-btn{min-width:0}.pal-btn span{display:none}}@media (max-width:600px){.pal-btn kbd{display:none}.top .wrap{gap:8px}.top nav{gap:0}.top nav a:not(.btn){padding:6px 8px}.top .who>span{display:none}.top .navbtn{padding:6px 8px}}@media (max-width:360px){.brand>span{display:none}} .box{border:1px solid var(--border);border-radius:var(--r);background:var(--bg);margin:0 0 16px;overflow:hidden} .box>.head{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--bg2);border-bottom:1px solid var(--border);flex-wrap:wrap} .box>.body{padding:14px} .box>.head h2,.box>.head h3{margin:0;font-size:14px;display:inline-flex;align-items:center;gap:6px} .list{list-style:none;margin:0;padding:0} .list>li{display:flex;gap:10px;align-items:flex-start;padding:10px 14px;border-top:1px solid var(--border2)} .list>li:first-child{border-top:0}.list>li:hover{background:var(--bg2)} .list>li>.st:first-child,.list>li>svg:first-child{margin-top:2px} .list .title{font-weight:600;color:var(--fg)}.list .title:hover{color:var(--accent)} .list .meta{font-size:12px;color:var(--fg2);margin-top:2px} .empty{padding:32px 16px;text-align:center;color:var(--fg2)} .blank{border:1px dashed var(--border);border-radius:var(--r);padding:32px;text-align:center;color:var(--fg2)} .badge{display:inline-flex;align-items:center;gap:4px;padding:1px 8px;border:1px solid var(--border);border-radius:999px;font-size:12px;font-weight:500;color:var(--fg2);line-height:18px;white-space:nowrap;vertical-align:middle} .badge.agent{border-color:color-mix(in srgb,var(--purple) 45%,transparent);color:var(--purple);background:var(--purple-soft)} .badge.green{border-color:transparent;background:var(--green-soft);color:var(--green)} .badge.red{border-color:transparent;background:var(--red-soft);color:var(--red)} .badge.amber{border-color:transparent;background:var(--amber-soft);color:var(--amber)} .badge.purple{border-color:transparent;background:var(--purple-soft);color:var(--purple)} .badge.blue{border-color:transparent;background:var(--blue-soft);color:var(--blue)} .state{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:999px;font-weight:600;font-size:13px;color:#fff} .state.open{background:var(--green)}.state.closed{background:var(--red)}.state.merged{background:var(--purple)}.state.draft{background:var(--fg3)} .lbl{display:inline-block;padding:0 8px;border-radius:999px;font-size:12px;font-weight:550;line-height:20px;background:color-mix(in srgb,var(--lc) 18%,transparent);color:color-mix(in srgb,var(--lc) 70%,var(--fg));border:1px solid color-mix(in srgb,var(--lc) 40%,transparent);margin-right:4px} .av{display:inline-block;width:20px;height:20px;border-radius:50%;flex:none;vertical-align:middle;object-fit:cover;background:var(--bg3);outline:1px solid var(--border);outline-offset:-1px} .av.lg{width:40px;height:40px}.av.xl{width:96px;height:96px}.av.bot{border-radius:6px}.av.xl.bot{border-radius:16px} input[type=file]{max-width:100%;font:13px/1.4 var(--sans);color:var(--fg2)} input[type=file]::file-selector-button{margin-right:10px;padding:6px 12px;border:1px solid var(--border);border-radius:var(--r);background:var(--bg);color:var(--fg);font:500 13px/1.4 var(--sans);cursor:pointer} input[type=file]::file-selector-button:hover{background:var(--bg-hover);border-color:var(--fg3)} .avpick{display:flex;gap:20px;align-items:center;flex-wrap:wrap}.avpick .grow{min-width:240px} .avpick [data-avatar-status]:empty{display:none} .who{display:inline-flex;align-items:center;gap:6px;font-weight:600;color:var(--fg)}.top .who{white-space:nowrap} .repohead{padding:18px 0 0;border-bottom:1px solid var(--border);background:var(--bg2)} .repohead h1{font-size:19px;font-weight:500;display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 6px} .repohead h1 a{color:var(--fg)}.repohead h1 strong a{font-weight:650} .tabs{display:flex;gap:2px;overflow-x:auto;scrollbar-width:none;margin-top:10px} .tabs a{display:inline-flex;align-items:center;gap:6px;padding:8px 12px;color:var(--fg2);border-bottom:2px solid transparent;white-space:nowrap} .tabs a:hover{color:var(--fg);text-decoration:none;border-bottom-color:var(--border)} .tabs a.on{color:var(--fg);font-weight:600;border-bottom-color:var(--accent)} .tabs .n{background:var(--bg3);border-radius:999px;padding:0 7px;font-size:12px;color:var(--fg2)} .subnav{display:flex;gap:0;border:1px solid var(--border);border-radius:7px;overflow:hidden;width:max-content;max-width:100%} .subnav a{display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 12px;color:var(--fg2);border-left:1px solid var(--border)}.subnav a:first-child{border-left:0} .subnav a.on{background:var(--accent-soft);color:var(--accent);font-weight:600}.subnav a:hover{text-decoration:none;background:var(--bg-hover)} .side .nav h4{font-size:11px;color:var(--fg3);text-transform:uppercase;letter-spacing:.04em;margin:14px 10px 4px} .side h3{font-size:12px;color:var(--fg2);text-transform:uppercase;letter-spacing:.04em;margin:0 0 8px} .side section{padding:0 0 16px;margin:0 0 16px;border-bottom:1px solid var(--border2)} .side .nav a{display:block;padding:6px 10px;border-radius:6px;color:var(--fg)}.side .nav a.on{background:var(--accent-soft);color:var(--accent);font-weight:600}.side .nav a:hover{background:var(--bg-hover);text-decoration:none} details.menu{position:relative;display:inline-block} details.menu>summary{list-style:none;cursor:pointer}details.menu>summary::-webkit-details-marker{display:none} details.menu>.pop{position:absolute;z-index:30;top:calc(100% + 4px);left:0;min-width:260px;max-height:360px;overflow:auto;background:var(--bg);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow);padding:6px} details.menu>.pop.right{left:auto;right:0} details.menu .pop a{display:flex;gap:8px;align-items:center;padding:6px 8px;border-radius:5px;color:var(--fg)}details.menu .pop a:hover{background:var(--bg-hover);text-decoration:none} details.menu .pop button.mi{display:flex;width:100%;gap:8px;align-items:center;padding:6px 8px;border:0;border-radius:5px;background:none;color:var(--fg);font:inherit;text-align:left;cursor:pointer}details.menu .pop button.mi:hover{background:var(--bg-hover)} details.minimized>summary{cursor:pointer;padding:8px 12px;list-style:none}details.minimized>summary::-webkit-details-marker{display:none}details.minimized>summary .small{color:var(--accent)}details.minimized[open]>summary .small{display:none} details.menu .pop h4{font-size:11px;text-transform:uppercase;color:var(--fg3);margin:6px 8px 4px} .crumbs{font-size:15px;display:flex;flex-wrap:wrap;align-items:center;gap:4px}.crumbs a{font-weight:600} table.files{width:100%;border-collapse:collapse} table.files td{padding:7px 14px;border-top:1px solid var(--border2)}table.files tr:first-child td{border-top:0} table.files tr:hover td{background:var(--bg2)}table.files td.ic{width:20px;padding-right:0;color:var(--fg3)} table.files td.sz{text-align:right;color:var(--fg2);width:100px;white-space:nowrap} table.files a{color:var(--fg)}table.files a:hover{color:var(--accent)} .ic-dir{color:var(--accent)!important} .clone{display:flex;gap:6px;align-items:center} .clone input{font-family:var(--mono);font-size:12px} .openin{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:8px} pre.cmd{background:var(--code-bg);border:1px solid var(--border2);border-radius:7px;padding:12px 14px;overflow:auto;margin:0 0 12px} pre.cmd.one{padding:7px 12px;line-height:20px;margin:0;white-space:pre-wrap;word-break:break-all} .code-wrap{overflow:auto} table.blob{border-collapse:collapse;width:100%;font-family:var(--mono);font-size:12.5px;line-height:20px} table.blob td{padding:0 12px;vertical-align:top;white-space:pre} table.blob td.ln{width:1%;min-width:50px;text-align:right;color:var(--fg3);user-select:none;padding-right:10px} table.blob td.ln a{color:inherit}table.blob tr:target td{background:var(--hl)} table.diff{border-collapse:collapse;width:100%;font-family:var(--mono);font-size:12px;line-height:20px} table.diff td{padding:0 8px;vertical-align:top} table.diff td.ln{width:1%;min-width:44px;text-align:right;color:var(--fg3);user-select:none;white-space:nowrap} table.diff td.code{white-space:pre-wrap;word-break:break-all;width:100%} table.diff tr.add td{background:var(--add-bg)}table.diff tr.add td.ln{background:var(--add-ln)} table.diff tr.del td{background:var(--del-bg)}table.diff tr.del td.ln{background:var(--del-ln)} table.diff tr.hunk td{background:var(--hunk-bg);color:var(--fg2);padding-top:2px;padding-bottom:2px} table.diff tr.meta td{color:var(--fg3);font-style:italic} table.diff td.act{width:1%;padding:0 2px} table.diff .addc{visibility:hidden;border:0;background:var(--accent);color:#fff;border-radius:4px;width:18px;height:18px;line-height:16px;cursor:pointer;font-weight:700;padding:0} table.diff tr:hover .addc{visibility:visible} table.diff tr.thread td{background:var(--bg2);padding:8px 12px;font-family:var(--sans);font-size:14px;white-space:normal} /* Shiki tokens carry both GitHub themes as custom properties; untokened text keeps the site's color. */ .sh>span{color:var(--shiki-light);font-style:var(--shiki-light-font-style);font-weight:var(--shiki-light-font-weight);text-decoration:var(--shiki-light-text-decoration)} :root[data-theme=dark] .sh>span{color:var(--shiki-dark);font-style:var(--shiki-dark-font-style);font-weight:var(--shiki-dark-font-weight);text-decoration:var(--shiki-dark-text-decoration)} @media (prefers-color-scheme:dark){:root:not([data-theme=light]) .sh>span{color:var(--shiki-dark);font-style:var(--shiki-dark-font-style);font-weight:var(--shiki-dark-font-weight);text-decoration:var(--shiki-dark-text-decoration)}} .filehead{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--bg2);border-bottom:1px solid var(--border);cursor:pointer;position:sticky;top:52px;z-index:5;flex-wrap:wrap} details.file{border:1px solid var(--border);border-radius:var(--r);margin:0 0 14px;overflow:clip} details.file>summary{list-style:none}details.file>summary::-webkit-details-marker{display:none} details.file:not([open])>.filehead{border-bottom:0} .stat-add{color:var(--green);font-weight:600}.stat-del{color:var(--red);font-weight:600} .bar{display:inline-flex;gap:1px;vertical-align:middle}.bar i{width:8px;height:8px;border-radius:1px;background:var(--bg3)}.bar i.a{background:var(--green)}.bar i.d{background:var(--red)} .comment{border:1px solid var(--border);border-radius:var(--r);margin:0 0 16px;background:var(--bg)} .comment>.head{display:flex;gap:8px;align-items:center;padding:8px 14px;background:var(--bg2);border-bottom:1px solid var(--border);border-radius:var(--r) var(--r) 0 0;flex-wrap:wrap;font-size:13px} .comment>.body{padding:14px} .comment.intent{border-color:color-mix(in srgb,var(--accent) 45%,transparent)}.comment.intent>.head{background:var(--accent-soft)} .timeline{position:relative} .event{display:flex;gap:10px;align-items:center;padding:6px 0 6px 14px;margin:0 0 16px;color:var(--fg2);font-size:13px} .event .ic{display:inline-flex;width:28px;height:28px;border-radius:50%;align-items:center;justify-content:center;background:var(--bg3);flex:none} .event.approved .ic{background:var(--green-soft);color:var(--green)}.event.changes .ic{background:var(--red-soft);color:var(--red)} .linec{border-left:3px solid var(--border);padding:6px 10px;margin:8px 0;background:var(--bg2);border-radius:0 6px 6px 0} .linec .where{font-family:var(--mono);font-size:12px;color:var(--fg2)} .mergebox{border:1px solid var(--border);border-radius:var(--r);margin:0 0 16px;overflow:hidden} .mergebox>div{padding:12px 14px;border-top:1px solid var(--border2)}.mergebox>div:first-child{border-top:0} .mergebox.clean{border-color:color-mix(in srgb,var(--green) 50%,transparent)}.mergebox.blocked,.mergebox.conflicting{border-color:color-mix(in srgb,var(--amber) 55%,transparent)} .mergebox.merged{border-color:color-mix(in srgb,var(--purple) 50%,transparent)} .checks{list-style:none;margin:0;padding:0}.checks li{display:flex;gap:8px;align-items:center;padding:4px 0} .st{display:inline-flex;width:16px;height:16px;flex:none;align-items:center;justify-content:center} .st svg{width:16px;height:16px} .st.spin svg{animation:spin 1.1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}} .job{display:flex;align-items:center;gap:10px;padding:8px 14px;border-top:1px solid var(--border2);color:var(--fg)} .job:hover{background:var(--bg2);text-decoration:none}.job:first-of-type{border-top:0} .jobgroup{margin:0 0 16px} .failure{border:1px solid color-mix(in srgb,var(--red) 45%,transparent);background:var(--red-soft);border-radius:var(--r);padding:12px 14px;margin:0 0 16px} .failure pre{white-space:pre-wrap;margin:6px 0 0;color:var(--fg)} .log{background:#0d1014;color:#d5d9de;border-radius:var(--r);overflow:hidden;margin:0 0 16px;border:1px solid var(--border)} .log details{border-top:1px solid #1d2229}.log details:first-child{border-top:0} .log summary{display:flex;gap:10px;align-items:center;padding:8px 14px;cursor:pointer;list-style:none;color:#e6e8eb} .log summary::-webkit-details-marker{display:none}.log summary:hover{background:#151a20} .log summary .dur{margin-left:auto;color:#7f8792;font-size:12px} .log pre{margin:0;padding:6px 0 10px;overflow:auto;font-size:12px;line-height:19px;counter-reset:l} .log pre span{display:block;padding:0 14px 0 64px;position:relative;white-space:pre-wrap;word-break:break-all;min-height:19px} .log pre span::before{counter-increment:l;content:counter(l);position:absolute;left:0;width:48px;text-align:right;color:#59616c} .log pre span.grp{color:#8fb3ff;font-weight:600}.log pre span.err{color:#ff8c84}.log pre span.wrn{color:#e5c07b} .markdown{line-height:1.65;word-wrap:break-word} .markdown>*:first-child{margin-top:0}.markdown>*:last-child{margin-bottom:0} .markdown h1,.markdown h2{padding-bottom:6px;border-bottom:1px solid var(--border2);margin:22px 0 12px} .markdown h3,.markdown h4,.markdown h5,.markdown h6{margin:18px 0 8px} .markdown h1 .anchor,.markdown h2 .anchor,.markdown h3 .anchor,.markdown h4 .anchor,.markdown h5 .anchor,.markdown h6 .anchor{float:left;margin-left:-18px;padding-right:4px;opacity:0;color:var(--fg3)} .markdown :is(h1,h2,h3,h4,h5,h6):hover .anchor{opacity:1} .markdown p,.markdown ul,.markdown ol,.markdown blockquote,.markdown pre,.markdown .table-wrap{margin:0 0 14px} .markdown ul,.markdown ol{padding-left:2em}.markdown li+li{margin-top:3px}.markdown li.task{list-style:none;margin-left:-1.4em} .markdown code{background:var(--code-bg);padding:.15em .4em;border-radius:5px;font-size:85%} .markdown pre{background:var(--code-bg);padding:14px;border-radius:7px;overflow:auto;line-height:1.45;border:1px solid var(--border2)} .markdown pre code{background:none;padding:0;font-size:12.5px} .markdown blockquote{padding:0 1em;color:var(--fg2);border-left:3px solid var(--border)} .markdown img{max-width:100%}.markdown hr{height:2px;background:var(--border2);border:0} .markdown .markdown-alert{margin:0 0 14px;padding:8px 14px;border-left:3px solid var(--a);border-radius:0 6px 6px 0;background:var(--as)} .markdown .markdown-alert>:last-child{margin-bottom:0}.markdown .markdown-alert-title{font-weight:600;color:var(--a);margin:0 0 4px} .markdown-alert-note{--a:var(--blue);--as:var(--blue-soft)}.markdown-alert-tip{--a:var(--green);--as:var(--green-soft)}.markdown-alert-important{--a:var(--purple);--as:var(--purple-soft)} .markdown-alert-warning{--a:var(--amber);--as:var(--amber-soft)}.markdown-alert-caution{--a:var(--red);--as:var(--red-soft)} .markdown .table-wrap{overflow:auto}.markdown table{border-collapse:collapse} .markdown th,.markdown td{border:1px solid var(--border);padding:6px 12px}.markdown th{background:var(--bg2);font-weight:600} .readme{margin-top:16px}.readme>.body{padding:24px 32px} @media (max-width:700px){.readme>.body{padding:16px}.wrap{padding:0 12px}} dialog#palette{border:1px solid var(--border);border-radius:12px;padding:0;width:min(640px,94vw);background:var(--bg);color:var(--fg);box-shadow:var(--shadow);margin-top:12vh} dialog#palette::backdrop{background:rgba(10,12,16,.45)} #palette input{border:0;border-bottom:1px solid var(--border);border-radius:0;padding:14px 16px;font-size:15px;outline:none} #palette ul{list-style:none;margin:0;padding:6px;max-height:min(420px,60vh);overflow:auto} #palette li a{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;color:var(--fg)} #palette li a span{margin-left:auto;color:var(--fg3);font-size:12px} #palette li.sel a,#palette li a:hover{background:var(--accent-soft);text-decoration:none} #palette .foot{display:flex;gap:14px;padding:8px 14px;border-top:1px solid var(--border);font-size:12px;color:var(--fg3)} .hero{padding:72px 0 40px;text-align:center} .hero h1{font-size:44px;letter-spacing:-.03em;margin:0 0 14px} .hero p{font-size:18px;color:var(--fg2);max-width:640px;margin:0 auto 26px} .features{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:16px;margin:24px 0} .features .box{padding:18px}.features h3{margin:0 0 6px} /* Early access (web/early-access.tsx): the request form, its result pages and the admin list. */ .ea-eyebrow{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--link);background:var(--accent-soft);border-radius:999px;padding:3px 12px;margin:0 0 16px} a.ea-eyebrow:hover{text-decoration:none;filter:brightness(1.08)} .ea{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);grid-template-areas:"head card" "more card";column-gap:56px;align-items:start;max-width:1040px;margin:48px auto 24px} .ea-head{grid-area:head}.ea-more{grid-area:more}.ea-card{grid-area:card} .ea h1{font-size:36px;letter-spacing:-.025em;margin:0 0 12px} .ea-lede{font-size:16px;color:var(--fg2);margin:0 0 28px;max-width:520px} .ea-points{list-style:none;padding:0;margin:0 0 28px;display:grid;gap:16px} .ea-points li{display:flex;gap:12px;align-items:flex-start} .ea-points li>span:last-child{display:flex;flex-direction:column;gap:2px} .ea-points .ic{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:9px;background:var(--bg);border:1px solid var(--border);color:var(--fg)} .ea-steps{counter-reset:s;list-style:none;margin:0;display:grid;gap:10px;border-top:1px solid var(--border2);padding:20px 0 0} .ea-steps li{counter-increment:s;display:flex;gap:10px;align-items:center;color:var(--fg2)} .ea-steps li::before{content:counter(s);flex:none;display:grid;place-items:center;width:22px;height:22px;border-radius:999px;background:var(--bg3);color:var(--fg);font-size:12px;font-weight:600} .ea-card{border:0;box-shadow:var(--shadow)} .ea-card .body{padding:26px} .ea-card h2{margin:0 0 2px} .ea-card textarea,.ea-card input[type=email],.ea-card input[type=text]{width:100%} .ea-hp{position:absolute!important;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden} .ea-privacy{font-size:12px;color:var(--fg2);margin:14px 0 0} .ea-done{max-width:580px;margin:64px auto;text-align:center} .ea-done>p{font-size:15px} .ea-done .ic{display:inline-grid;place-items:center;width:60px;height:60px;border-radius:999px;background:var(--accent-soft);color:var(--link);margin:0 0 18px} .ea-done .ic svg{width:28px;height:28px} .ea-done form{margin-top:18px} .ea-av{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:999px;background:var(--accent-soft);color:var(--link);font-weight:600;font-size:14px} .ea-av.lg{width:48px;height:48px;font-size:20px} .ea-use{margin-top:6px;color:var(--fg);font-size:13px;white-space:pre-wrap;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden} .ea-actions{display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:flex-end} @media (max-width:900px){.ea{grid-template-columns:1fr;grid-template-areas:"head" "card" "more";row-gap:24px;margin-top:24px}.ea h1{font-size:28px}.ea-list>li{flex-wrap:wrap}.ea-actions{width:100%;justify-content:flex-start;padding-left:42px}} .stats{display:flex;gap:18px;flex-wrap:wrap;color:var(--fg2);font-size:13px} .stats b{color:var(--fg)} .tx{display:flex;flex-direction:column;gap:10px}.tx .markdown{margin:0} .tx-run{margin:8px 0 0;padding-top:8px;border-top:1px solid var(--border);font-size:13px;color:var(--muted)}.tx-run:first-child{border-top:0;padding-top:0;margin-top:0} .tx-note{padding-left:10px;border-left:2px solid var(--border)} .tx-result{padding:10px 12px;border:1px solid var(--border);border-radius:var(--r);background:var(--subtle,transparent)} .tx-tool summary{cursor:pointer;color:var(--muted)}.tx-tool[open] summary{margin-bottom:6px} .term{height:min(70vh,760px);min-height:320px;padding:8px;background:#111113;border:1px solid var(--border);border-radius:var(--r);overflow:hidden}.term .xterm{height:100%} .term-status[data-tone=ok]{color:var(--green)}.term-status[data-tone=warn]{color:var(--amber)} .tx-pre{margin:0;padding:8px 10px;background:#0d1014;color:#d5d9de;border-radius:var(--r);font-size:12px;white-space:pre-wrap;word-break:break-word;max-height:360px;overflow:auto} .tx-err{border-left:3px solid var(--red)} .today-sec>summary{list-style:none;cursor:pointer;user-select:none}.today-sec>summary::-webkit-details-marker{display:none} .today-sec>summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.today-sec:not([open])>summary{border-bottom:0} .today-sec>summary .tog{display:inline-flex;color:var(--fg2);transition:transform .15s}.today-sec:not([open])>summary .tog{transform:rotate(-90deg)} .today-sec>summary .count{font:600 12px/18px var(--sans);padding:0 7px;border-radius:999px;background:var(--bg-hover);color:var(--fg2)} .today-sec>summary .manage{margin-left:auto} @media (max-width:640px){.today-sec>summary .note{flex-basis:100%;order:9}.today-sec:not([open])>summary .note{display:none}} .today-more>summary{list-style:none;padding:8px 14px;border-top:1px solid var(--border2)}.today-more>summary::-webkit-details-marker{display:none} .today-more>summary .btn svg{width:12px;height:12px}.today-more[open]>summary{display:none} .today-more>.list>li:first-child{border-top:1px solid var(--border2)}.today-more>.fewer{padding:8px 14px;border-top:1px solid var(--border2)} .tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:0 0 16px} .tile{display:flex;flex-direction:column;gap:2px;border:1px solid var(--border);border-radius:var(--r);padding:12px 14px;background:var(--bg);color:var(--fg);text-decoration:none} .tile:hover{border-color:var(--accent);text-decoration:none} .tile .num{font-size:24px;font-weight:600;line-height:1.2} .tile .lbl{font-size:12px;color:var(--fg2)} .tile.purple .num{color:var(--purple)} .tile.red .num{color:var(--red)} .kv{display:grid;grid-template-columns:max-content 1fr;gap:6px 16px;font-size:13px}.kv dt{color:var(--fg2)}.kv dd{margin:0} table.tbl{width:100%;border-collapse:collapse;font-size:13px} table.tbl th{text-align:left;font-weight:600;color:var(--fg2);padding:8px 12px;border-bottom:1px solid var(--border);background:var(--bg2);white-space:nowrap} table.tbl td{padding:8px 12px;border-top:1px solid var(--border2);vertical-align:middle} table.tbl th.r,table.tbl td.r{text-align:right;font-variant-numeric:tabular-nums} .xscroll{overflow-x:auto} .secret{font-family:var(--mono);background:var(--amber-soft);border:1px solid color-mix(in srgb,var(--amber) 45%,transparent);border-radius:var(--r);padding:7px 12px;line-height:20px;min-height:36px;word-break:break-all} .connect-url{font-family:var(--mono);background:var(--bg2);border:1px solid var(--border);border-radius:var(--r);padding:7px 12px;line-height:20px;min-height:36px;word-break:break-all;font-size:13px}.connect-ai{border-bottom:1px solid var(--border2)} .pager{display:flex;gap:8px;justify-content:center;margin:16px 0} .sha{font-family:var(--mono);font-size:12px;padding:1px 6px;border-radius:5px;background:var(--bg3);color:var(--fg)} /* Buttons joined into one control (copy · sha · browse). */ .btngroup{display:inline-flex;flex:none}.btngroup>.btn{border-radius:0;margin-left:-1px}.btngroup>.btn:first-child{border-radius:var(--r-sm) 0 0 var(--r-sm);margin-left:0}.btngroup>.btn:last-child{border-radius:0 var(--r-sm) var(--r-sm) 0}.btngroup>.btn:hover{position:relative;z-index:1} .btn.mono{font-family:var(--mono)} a.sha:hover{text-decoration:none;background:var(--accent-soft);color:var(--accent)} .right{text-align:right}.mt{margin-top:16px}.mb{margin-bottom:16px}.m0{margin:0} form.inline{display:inline} .navbtn{background:none;border:0;color:var(--fg2);padding:6px 10px;border-radius:6px;font:inherit;cursor:pointer;white-space:nowrap}.navbtn:hover{background:var(--bg-hover);color:var(--fg)} .btn.block{display:flex;width:100%;justify-content:center} .authcard{max-width:440px;margin:56px auto}.authcard .body{padding:28px}.authcard h1{font-size:24px;margin:12px 0 8px} .usercode{font-family:var(--mono);font-size:18px;font-weight:600;letter-spacing:.12em;padding:2px 8px;border:1px solid var(--border);border-radius:var(--r);background:var(--bg2);white-space:nowrap} .usercode-input{font-family:var(--mono);font-size:20px;letter-spacing:.14em;text-transform:uppercase;text-align:center} .authmark{width:44px;height:44px;border-radius:var(--r);display:grid;place-items:center;background:color-mix(in srgb,var(--brand) 14%,transparent);color:var(--brand)}.authmark svg{width:22px;height:22px} .authfoot{margin-top:20px;padding-top:14px;border-top:1px solid var(--border)}.authfoot p{margin:0 0 6px} .kstack{display:flex;flex-direction:column;align-items:flex-start;gap:6px;margin:0 0 8px} .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)} .task-box{display:inline-block;width:14px;height:14px;margin:0 4px -2px 0;border-radius:4px;box-shadow:inset 0 0 0 1px var(--border);background:var(--bg)} .task-box.on{background:var(--fg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath fill='white' d='M232.49 80.49l-128 128a12 12 0 0 1-17 0l-56-56a12 12 0 1 1 17-17L96 183 215.51 63.51a12 12 0 0 1 17 17Z'/%3E%3C/svg%3E") center/10px no-repeat;box-shadow:none} @media (prefers-color-scheme:dark){:root:not([data-theme=light]) .task-box.on{filter:invert(1)}}:root[data-theme=dark] .task-box.on{filter:invert(1)} } @layer kumo-reset{.dfy-k,.dfy-k :not(svg,svg *){all:revert}} @layer islands{ .dfy-k{display:inline-block;vertical-align:middle;font:14px/1.5 var(--sans);color:var(--fg);text-align:left;font-weight:400} .dfy-k.block{display:block}.dfy-k.block .dfy-k-select{display:block} .dfy-k-select{display:inline-block} .dfy-k-portal{display:block} .dfy-k.block [data-kumo-part=trigger]{width:100%} .dfy-k-desc{display:block;color:var(--fg2);font-size:12px;font-weight:400}.dfy-k-lbl{display:block} .dfy-k-html .muted{color:var(--fg2)}.dfy-k-html .small{font-size:12px}.dfy-k-html .mono,.dfy-k-html code{font-family:var(--mono);font-size:12.5px} .dfy-k-html .ok{color:var(--green)}.dfy-k-html .bad{color:var(--red)} .dfy-k-html .lbl{display:inline-block;padding:0 8px;border-radius:999px;font-size:12px;font-weight:550;line-height:20px;background:color-mix(in srgb,var(--lc) 18%,transparent);color:color-mix(in srgb,var(--lc) 70%,var(--fg));border:1px solid color-mix(in srgb,var(--lc) 40%,transparent)} .dfy-k-html code{background:var(--code-bg);padding:1px 5px;border-radius:4px} .kf-select{display:inline-flex;align-items:center;justify-content:space-between;gap:8px;min-width:120px;height:36px;padding:0 12px;border-radius:8px;background:var(--bg);box-shadow:0 0 0 1px var(--border);color:var(--fg);white-space:nowrap} .kf-select.sm{height:26px;padding:0 8px;border-radius:6px;font-size:12px;min-width:90px}.kf-select.xs{height:20px;padding:0 6px;border-radius:4px;font-size:12px;min-width:70px} .dfy-k.block .kf-select{display:flex;width:100%} .kf-select svg{color:var(--fg3);flex:none}.kf-ph{color:var(--fg3)} .kf-check{display:inline-flex;align-items:flex-start;gap:8px} .kf-box,.kf-dot{width:16px;height:16px;margin-top:2px;flex:none;box-shadow:0 0 0 1px var(--border);background:var(--bg)} .kf-box{border-radius:4px}.kf-box.on{background:var(--fg);box-shadow:none} .kf-dot{border-radius:50%}.kf-dot.on{box-shadow:inset 0 0 0 5px var(--fg)} .kf-radio{display:flex;flex-direction:column;gap:8px}.kf-radio.horizontal{flex-direction:row;gap:16px;flex-wrap:wrap} .kf-desc{display:block;color:var(--fg2);font-size:12px} .theme-opt{display:flex;align-items:center;gap:8px} .theme-prev{display:inline-flex;flex-direction:column;justify-content:center;gap:2px;width:30px;height:20px;padding:0 5px;border-radius:4px;box-shadow:0 0 0 1px var(--border);flex:none} .theme-prev i{display:block;height:2px;border-radius:2px;background:#a1a1aa}.theme-prev i:first-child{width:55%;background:oklch(48.8% 0.243 264.376)}.theme-prev i:last-child{width:75%} .theme-prev.light{background:#fff}.theme-prev.light i:not(:first-child){background:#d4d4d8} .theme-prev.dark{background:#1c1c1e}.theme-prev.dark i:not(:first-child){background:#52525b} .theme-prev.auto{background:linear-gradient(135deg,#fff 50%,#1c1c1e 50%)} } /* Page changes: a cross-document view transition under 100 ms. The header, repository header, organization tabs and settings menu keep their place and swap instantly; only the page content fades. Browsers without support, and people who ask for reduced motion, just navigate. */ @media (prefers-reduced-motion:no-preference){ @view-transition{navigation:auto} header.top{view-transition-name:dfy-top} .repohead{view-transition-name:dfy-repohead} main.wrap{view-transition-name:dfy-main} .vt-tabs{view-transition-name:dfy-tabs} .vt-side{view-transition-name:dfy-side} ::view-transition-group(*){animation-duration:70ms;animation-timing-function:ease-out} ::view-transition-old(dfy-top),::view-transition-new(dfy-top),::view-transition-old(dfy-repohead),::view-transition-new(dfy-repohead), ::view-transition-old(dfy-tabs),::view-transition-new(dfy-tabs),::view-transition-old(dfy-side),::view-transition-new(dfy-side){animation:none} ::view-transition-old(root),::view-transition-old(dfy-main){animation:70ms ease-out both dfy-vt-out} ::view-transition-new(root),::view-transition-new(dfy-main){animation:70ms ease-out both dfy-vt-in} @keyframes dfy-vt-out{to{opacity:0}} @keyframes dfy-vt-in{from{opacity:0;transform:translateY(3px)}} } </style><link rel="alternate" type="text/markdown" href="/index.md" title="Diffinery (Markdown)"/></head><body><header class="top"><div class="wrap"><a class="brand" href="/" aria-label="Diffinery home"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><path d="M6 8.5v7M8.3 7.2c4 1 7.4 2.2 7.6 3.3M8.3 16.8c4-1 7.4-2.2 7.6-3.3"/></svg> <span>Diffinery</span></a><nav><a href="/features" class="nav-site">Product</a><a href="/compare" class="nav-site">Compare</a><a href="/docs" title="Documentation">Docs</a><a href="/login" class="btn primary sm">Sign in</a></nav></div></header><main class="wrap"><div class="mk"><style> .mk .hero h1{max-width:820px;margin-left:auto;margin-right:auto;font-size:48px;line-height:1.08} .mk .hero>p:first-of-type{max-width:720px} .mk-stats{list-style:none;margin:8px 0 8px;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px} .mk-stats li{border:1px solid var(--border);border-radius:var(--r);background:var(--bg);padding:16px} .mk-stats b{display:block;font-size:24px;letter-spacing:-.02em;margin-bottom:4px} .mk-stats span{color:var(--fg2);font-size:13.5px;line-height:1.45} .mk-sec{margin:56px 0 0} .mk-sec>h2,.mk-band h2,.mk-related h2{font-size:26px;letter-spacing:-.02em;margin:0 0 10px} .mk-wide{max-width:760px;color:var(--fg2);font-size:16px} .mk .features{grid-template-columns:repeat(3,minmax(0,1fr))} .mk-card{display:block;color:var(--fg)}a.mk-card:hover{border-color:var(--accent);text-decoration:none} .mk-card h3{display:flex;align-items:center;gap:8px}.mk-card h3 svg{flex:none;color:var(--accent)} .mk-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:32px;align-items:center} .mk-split>*{min-width:0} .mk .table-wrap{overflow:auto} .mk-split p,.mk-split li{color:var(--fg2);font-size:15px;line-height:1.65} .mk-code{margin:0;padding:18px 20px;background:var(--code-bg);border:1px solid var(--border);border-radius:var(--r);overflow:auto;font-size:13px;line-height:1.6} .mk-table{width:100%;border-collapse:collapse;font-size:14px} .mk-table th,.mk-table td{border-bottom:1px solid var(--border2);padding:10px 12px;text-align:left;vertical-align:top} .mk-table thead th{font-weight:600;border-bottom:1px solid var(--border)}.mk-table thead th:nth-child(2){color:var(--accent)} .mk-table tbody th{font-weight:500;color:var(--fg2)} .mk-faq .mk-q{border-top:1px solid var(--border2);padding:14px 0}.mk-faq h3{font-size:16px;margin:0 0 6px}.mk-faq p{margin:0;color:var(--fg2);line-height:1.65;max-width:860px} .mk-band{margin:56px 0 0;padding:36px 20px;text-align:center;border:1px solid var(--border);border-radius:var(--r);background:var(--bg2)} .mk-band p{margin:0 auto 14px;max-width:620px} .mk-page{max-width:880px;margin:0 auto} .mk-head{padding:28px 0 18px;border-bottom:1px solid var(--border2);margin-bottom:8px} .mk-head h1{font-size:36px;line-height:1.15;letter-spacing:-.025em;margin:8px 0 10px} .mk-crumbs{font-size:13px;min-height:18px} .mk-lead{font-size:18px;color:var(--fg2);margin:0 0 10px;line-height:1.55} .mk-meta{margin:0} .mk-body{font-size:15.5px;line-height:1.7} .mk-body h2{font-size:23px;margin-top:38px;scroll-margin-top:64px}.mk-body h3{font-size:17px;margin-top:26px;scroll-margin-top:64px} .mk-body table{font-size:14px;width:100%}.mk-body td code{white-space:nowrap} .mk-related{margin:40px 0 0} .mk-related ul{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px} .mk-related li{border:1px solid var(--border);border-radius:var(--r);padding:12px 14px;display:flex;flex-direction:column;gap:4px} @media (max-width:900px){.mk .features{grid-template-columns:repeat(2,minmax(0,1fr))}.mk-stats{grid-template-columns:repeat(2,minmax(0,1fr))}.mk-split{grid-template-columns:minmax(0,1fr)}} @media (max-width:600px){.mk .features{grid-template-columns:minmax(0,1fr)}.mk .hero{padding-top:40px}.mk .hero h1{font-size:32px}.mk-head h1{font-size:27px}.mk-stats{grid-template-columns:minmax(0,1fr)}.mk-sec>h2,.mk-band h2{font-size:22px}} </style><section class="hero"><a class="ea-eyebrow" href="/open-source"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M69.12,94.15,28.5,128l40.62,33.85a8,8,0,1,1-10.24,12.29l-48-40a8,8,0,0,1,0-12.29l48-40a8,8,0,0,1,10.24,12.3Zm176,27.7-48-40a8,8,0,1,0-10.24,12.3L227.5,128l-40.62,33.85a8,8,0,1,0,10.24,12.29l48-40a8,8,0,0,0,0-12.29ZM162.73,32.48a8,8,0,0,0-10.25,4.79l-64,176a8,8,0,0,0,4.79,10.26A8.14,8.14,0,0,0,96,224a8,8,0,0,0,7.52-5.27l64-176A8,8,0,0,0,162.73,32.48Z"></path></svg> Open source under Apache-2.0</a><h1>Code hosting and CI for the agentic era</h1><p>Diffinery is an open-source GitHub alternative for teams of people and AI agents. Git repositories, pull requests, GitHub Actions–compatible CI on fast runners, and agents with their own accounts and guardrails, running entirely on your own Cloudflare account.</p><p class="row" style="justify-content:center"><a class="btn primary" href="/docs/self-hosting">Deploy your own</a><a class="btn" href="https://diffinery.com/codician/diffinery">View the source</a><a class="btn" href="/docs">Read the docs</a></p><p class="muted small">Free, with nothing to buy: you run Diffinery on your own Cloudflare account. Source on <a href="https://diffinery.com/codician/diffinery">Diffinery</a> and <a href="https://github.com/codician-team/diffinery">GitHub</a>.</p></section><ul class="mk-stats" aria-label="Diffinery in numbers"><li><b>4 vCPU</b><span>per CI job by default. GitHub's standard runner for private repositories has 2.</span></li><li><b>3–5 s</b><span>from a job being queued to its first step.</span></li><li><b>Apache-2.0</b><span>Open source, with nothing to buy. You run it on your own Cloudflare account.</span></li><li><b>1 person</b><span>approves every agent pull request, enforced by the server.</span></li></ul><section class="mk-sec"><h2>Everything your team and its agents need, in one place</h2><div class="features"><a class="box mk-card" href="/features#git-hosting"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M208,24H72A32,32,0,0,0,40,56V224a8,8,0,0,0,8,8H192a8,8,0,0,0,0-16H56a16,16,0,0,1,16-16H208a8,8,0,0,0,8-8V32A8,8,0,0,0,208,24ZM120,40h48v72L148.79,97.6a8,8,0,0,0-9.6,0L120,112Zm80,144H72a31.82,31.82,0,0,0-16,4.29V56A16,16,0,0,1,72,40h32v88a8,8,0,0,0,12.8,6.4L144,114l27.21,20.4A8,8,0,0,0,176,136a8,8,0,0,0,8-8V40h16Z"></path></svg> Git hosting</h3><p class="muted m0">Clone, fetch and push over HTTPS with Git LFS. Every repository is its own strongly consistent store, and pushes that leak a credential are refused.</p></a><a class="box mk-card" href="/features#pull-requests-reviews-and-issues"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M104,64A32,32,0,1,0,64,95v66a32,32,0,1,0,16,0V95A32.06,32.06,0,0,0,104,64ZM56,64A16,16,0,1,1,72,80,16,16,0,0,1,56,64ZM88,192a16,16,0,1,1-16-16A16,16,0,0,1,88,192Zm120-31V110.63a23.85,23.85,0,0,0-7-17L163.31,56H192a8,8,0,0,0,0-16H144a8,8,0,0,0-8,8V96a8,8,0,0,0,16,0V67.31L189.66,105a8,8,0,0,1,2.34,5.66V161a32,32,0,1,0,16,0Zm-8,47a16,16,0,1,1,16-16A16,16,0,0,1,200,208Z"></path></svg> Pull requests with intent</h3><p class="muted m0">Reviews, required approvals and checks, auto-merge and a merge queue. Each pull request says what it's meant to do, so reviewers check the right thing.</p></a><a class="box mk-card" href="/features#actions-ci-that-runs-your-github-workflows"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm48.24-94.78-64-40A8,8,0,0,0,100,88v80a8,8,0,0,0,12.24,6.78l64-40a8,8,0,0,0,0-13.56ZM116,153.57V102.43L156.91,128Z"></path></svg> GitHub Actions–compatible CI</h3><p class="muted m0">The same triggers, expressions, matrices, reusable workflows, secrets, OIDC and Docker. Actions from GitHub run as they do there.</p></a><a class="box mk-card" href="/performance"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M215.79,118.17a8,8,0,0,0-5-5.66L153.18,90.9l14.66-73.33a8,8,0,0,0-13.69-7l-112,120a8,8,0,0,0,3,13l57.63,21.61L88.16,238.43a8,8,0,0,0,13.69,7l112-120A8,8,0,0,0,215.79,118.17ZM109.37,214l10.47-52.38a8,8,0,0,0-5-9.06L62,132.71l84.62-90.66L136.16,94.43a8,8,0,0,0,5,9.06l52.8,19.8Z"></path></svg> Fast, right-sized runners</h3><p class="muted m0">4 vCPUs and 12 GiB per job by default, started in seconds. Jobs that only wait move to smaller runners on their own, never at the cost of speed.</p></a><a class="box mk-card" href="/agents"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M200,48H136V16a8,8,0,0,0-16,0V48H56A32,32,0,0,0,24,80V192a32,32,0,0,0,32,32H200a32,32,0,0,0,32-32V80A32,32,0,0,0,200,48Zm16,144a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V80A16,16,0,0,1,56,64H200a16,16,0,0,1,16,16Zm-52-56H92a28,28,0,0,0,0,56h72a28,28,0,0,0,0-56Zm-24,16v24H116V152ZM80,164a12,12,0,0,1,12-12h8v24H92A12,12,0,0,1,80,164Zm84,12h-8V152h8a12,12,0,0,1,0,24ZM72,108a12,12,0,1,1,12,12A12,12,0,0,1,72,108Zm88,0a12,12,0,1,1,12,12A12,12,0,0,1,160,108Z"></path></svg> AI agents with guardrails</h3><p class="muted m0">Agents get their own accounts and tokens, an MCP server, sandboxes, tasks and reviews. They can't push to protected branches or reach your secrets.</p></a><a class="box mk-card" href="/security"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M208,40H48A16,16,0,0,0,32,56v56c0,52.72,25.52,84.67,46.93,102.19,23.06,18.86,46,25.26,47,25.53a8,8,0,0,0,4.2,0c1-.27,23.91-6.67,47-25.53C198.48,196.67,224,164.72,224,112V56A16,16,0,0,0,208,40Zm0,72c0,37.07-13.66,67.16-40.6,89.42A129.3,129.3,0,0,1,128,223.62a128.25,128.25,0,0,1-38.92-21.81C61.82,179.51,48,149.3,48,112l0-56,160,0ZM82.34,141.66a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35a8,8,0,0,1,11.32,11.32l-56,56a8,8,0,0,1-11.32,0Z"></path></svg> Secure by default</h3><p class="muted m0">Passkeys instead of passwords, invite-only sign-up, encrypted secrets, scoped job tokens and an append-only audit log.</p></a></div></section><section class="mk-sec mk-split"><div><h2>Your workflows, as they are</h2><p>Diffinery reads <code>.github/workflows</code> with the same triggers, expressions, matrices, reusable workflows, environments, secrets and OIDC as GitHub Actions. Common actions such as checkout, setup-node and cache are built into the runner, so they finish in seconds.</p><ul><li>Each job gets a fresh Ubuntu 24.04 container with 4 vCPUs and 12 GiB of memory.</li><li>Caches restore in parallel and extract while they download.</li><li>Self-hosted runners cover macOS, Windows, Arm and GPUs.</li></ul><p><a href="/performance">See the measurements</a> · <a href="/docs/actions/compatibility">Compatibility with GitHub Actions</a></p></div><pre class="mk-code" aria-label="A GitHub Actions workflow that runs on Diffinery unchanged"><code>name: CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest # 4 vCPU, 12 GiB on Diffinery steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 22, cache: pnpm } - run: pnpm install --frozen-lockfile - run: pnpm test</code></pre></section><section class="mk-sec"><h2>Built for AI coding agents</h2><p class="mk-wide">Claude Code, Codex and other agents work through Git, the GitHub CLI, the REST API or the built-in MCP server, as accounts of their own. The server keeps a person in charge of what lands.</p><div class="features"><div class="box mk-card"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M200,48H136V16a8,8,0,0,0-16,0V48H56A32,32,0,0,0,24,80V192a32,32,0,0,0,32,32H200a32,32,0,0,0,32-32V80A32,32,0,0,0,200,48Zm16,144a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V80A16,16,0,0,1,56,64H200a16,16,0,0,1,16,16Zm-52-56H92a28,28,0,0,0,0,56h72a28,28,0,0,0,0-56Zm-24,16v24H116V152ZM80,164a12,12,0,0,1,12-12h8v24H92A12,12,0,0,1,80,164Zm84,12h-8V152h8a12,12,0,0,1,0,24ZM72,108a12,12,0,1,1,12,12A12,12,0,0,1,72,108Zm88,0a12,12,0,1,1,12,12A12,12,0,0,1,160,108Z"></path></svg> Agent accounts</h3><p class="muted m0">Their own logins and tokens, owned by a person or organization, with every commit stamped with who they act for.</p></div><div class="box mk-card"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M208,40H48A16,16,0,0,0,32,56v56c0,52.72,25.52,84.67,46.93,102.19,23.06,18.86,46,25.26,47,25.53a8,8,0,0,0,4.2,0c1-.27,23.91-6.67,47-25.53C198.48,196.67,224,164.72,224,112V56A16,16,0,0,0,208,40Zm0,72c0,37.07-13.66,67.16-40.6,89.42A129.3,129.3,0,0,1,128,223.62a128.25,128.25,0,0,1-38.92-21.81C61.82,179.51,48,149.3,48,112l0-56,160,0ZM82.34,141.66a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35a8,8,0,0,1,11.32,11.32l-56,56a8,8,0,0,1-11.32,0Z"></path></svg> Guardrails</h3><p class="muted m0">No pushes to protected branches, a person's approval on every agent pull request, and no secrets for agent-written code.</p></div><div class="box mk-card"><h3><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256" aria-hidden="true" focusable="false"><path d="M69.12,94.15,28.5,128l40.62,33.85a8,8,0,1,1-10.24,12.29l-48-40a8,8,0,0,1,0-12.29l48-40a8,8,0,0,1,10.24,12.3Zm176,27.7-48-40a8,8,0,1,0-10.24,12.3L227.5,128l-40.62,33.85a8,8,0,1,0,10.24,12.29l48-40a8,8,0,0,0,0-12.29ZM162.73,32.48a8,8,0,0,0-10.25,4.79l-64,176a8,8,0,0,0,4.79,10.26A8.14,8.14,0,0,0,96,224a8,8,0,0,0,7.52-5.27l64-176A8,8,0,0,0,162.73,32.48Z"></path></svg> MCP, sandboxes and tasks</h3><p class="muted m0">One URL connects any MCP app. Agents get sandboxes to build and test in, and tasks turn a goal into a pull request.</p></div></div><p><a href="/agents">Diffinery for AI agents</a> · <a href="/docs/connect">Connect Claude, Claude Code or Codex</a></p></section><section class="mk-sec"><h2>How Diffinery compares</h2><div class="table-wrap"><table class="mk-table"><thead><tr><th></th><th scope="col">Diffinery</th><th scope="col">GitHub</th><th scope="col">GitHub with a runner service</th></tr></thead><tbody><tr><th scope="row">Git hosting, pull requests, issues</th><td>Yes</td><td>Yes</td><td>Yes, on GitHub</td></tr><tr><th scope="row">Runs GitHub Actions workflows</th><td>Yes, as they are</td><td>Yes</td><td>Yes, with a new runs-on label</td></tr><tr><th scope="row">Default Linux runner, private repositories</th><td>4 vCPU, 12 GiB</td><td>2 vCPU, 8 GB</td><td>Your choice of size, billed by the vendor</td></tr><tr><th scope="row">Guardrails for AI agents</th><td>Built in for every agent account</td><td>Rulesets and permissions you configure</td><td>Rulesets and permissions you configure</td></tr><tr><th scope="row">Built-in MCP server and agent sandboxes</th><td>Yes</td><td>MCP server, Codespaces</td><td>GitHub's</td></tr><tr><th scope="row">Hosted macOS and Windows runners</th><td>No (self-hosted)</td><td>Yes</td><td>Depends on the vendor</td></tr><tr><th scope="row">Open source</th><td>Yes, Apache-2.0</td><td>No</td><td>No</td></tr><tr><th scope="row">Who runs it</th><td>You, on your own Cloudflare account</td><td>GitHub</td><td>GitHub and the runner vendor</td></tr></tbody></table></div><p class="muted small">Runner services include Blacksmith and Depot. GitHub's runner sizes are from its documentation, checked October 25, 2026. Read the full comparisons with <a href="/compare/github">GitHub</a>, <a href="/compare/gitlab">GitLab</a>, <a href="/compare/blacksmith">Blacksmith</a> and <a href="/compare/depot">Depot</a>.</p></section><section class="mk-sec mk-faq" id="faq"><h2>Frequently asked questions</h2><div class="mk-q"><h3>What is Diffinery?</h3><p>Diffinery is a git forge and CI platform for teams of people and AI agents. It hosts Git repositories, pull requests, issues and releases, runs GitHub Actions workflows on its own hosted runners, and gives AI agents their own accounts, tokens and server-enforced guardrails. It runs entirely on Cloudflare, and it's open source under the Apache License 2.0: you deploy it to your own Cloudflare account.</p></div><div class="mk-q"><h3>Is Diffinery an alternative to GitHub?</h3><p>Yes, for teams whose work fits it: Diffinery replaces GitHub's code hosting, pull requests and GitHub Actions in one platform. It doesn't have GitHub's hosted macOS and Windows runners, forks, app marketplace, Codespaces, Pages or Discussions. See <a href="/compare/github">Diffinery vs GitHub</a>.</p></div><div class="mk-q"><h3>Do my GitHub Actions workflows run on Diffinery?</h3><p>Most run without changes. Diffinery reads <code>.github/workflows/*.yml</code> with the same syntax, triggers, expressions and actions. Hosted runners are Linux x64; macOS, Windows and Arm jobs need a self-hosted runner. Every difference is listed in <a href="/docs/actions/compatibility">Compatibility with GitHub Actions</a>.</p></div><div class="mk-q"><h3>Is Diffinery built on Cloudflare?</h3><p>Yes, entirely, and as far as we know it's the only open-source project where Git hosting, pull requests with reviews and GitHub Actions–compatible CI, marketplace actions included, all run on Cloudflare (checked October 25, 2026). One Cloudflare Worker serves the site, the API, Git and the MCP server; each repository is its own Durable Object, with large objects in R2 and accounts in D1; Workflows and Queues drive CI runs, webhooks and email; and every CI job runs in a Cloudflare Container that exists only while the job runs. There are no servers to manage. See <a href="/built-on-cloudflare">Built on Cloudflare</a>.</p></div><div class="mk-q"><h3>How is Diffinery different from Blacksmith or Depot?</h3><p>Blacksmith sells faster runners for GitHub Actions, and Depot sells runners, its own CI engine and container builds. With either, your code and pull requests usually stay on GitHub and jobs run on their machines. Diffinery replaces GitHub and GitHub Actions together, with fast runners built in, as one open-source platform you run on your own Cloudflare account. See <a href="/compare/blacksmith">Diffinery vs Blacksmith</a> and <a href="/compare/depot">Diffinery vs Depot</a>.</p></div><div class="mk-q"><h3>How does Diffinery work with Claude Code, Codex and other AI agents?</h3><p>Agents connect over MCP at <code>/mcp</code> on your instance with a browser sign-in, or use Git, the GitHub CLI and the REST API with an agent token. Each agent is an account of its own: it can't push to protected branches, its pull requests need a person's approval, and runs of its code get no secrets. See <a href="/agents">Diffinery for AI agents</a>.</p></div><div class="mk-q"><h3>How do I move from GitHub?</h3><p>Diffinery's importer copies a repository or a whole organization from GitHub on the server, with history, issues, pull requests, reviews, releases and branch protection, keeping their numbers. Then you enter your secrets' values and push. See <a href="/docs/migrate-from-github">Migrate from GitHub</a>.</p></div><div class="mk-q"><h3>Is Diffinery open source?</h3><p>Yes, under the Apache License 2.0, with no paid edition and nothing sold. The source code is at <a href="https://diffinery.com/codician/diffinery" rel="nofollow noopener noreferrer">diffinery.com/codician/diffinery</a> and mirrored to <a href="https://github.com/codician-team/diffinery" rel="nofollow noopener noreferrer">github.com/codician-team/diffinery</a>. See <a href="/open-source">Open source</a>.</p></div><div class="mk-q"><h3>How do I start using Diffinery, and what does it cost?</h3><p>Deploy your own instance to your Cloudflare account and domain with one command, <code>scripts/setup.sh</code>, then sign in as its first administrator and invite your team. See <a href="/docs/self-hosting/deploy">Deploy your own Diffinery</a>. Diffinery is free; you pay Cloudflare for what your instance uses, on the Workers Paid plan (a minimum of $5 USD per month per account, plus usage; <a href="https://developers.cloudflare.com/workers/platform/pricing/" rel="nofollow noopener noreferrer">Cloudflare's pricing</a>, checked October 25, 2026). There's no hosted service to sign up for: diffinery.com is the project's own instance.</p></div></section><section class="mk-band"><h2>Run Diffinery on your own Cloudflare account</h2><p class="muted">Open source under Apache-2.0. Your workflows, your editor and gh keep working, your agents get guardrails, and you pay Cloudflare only for what you use.</p><p class="row" style="justify-content:center"><a class="btn primary" href="/docs/self-hosting">Deploy your own</a><a class="btn" href="https://diffinery.com/codician/diffinery">View the source</a><a class="btn" href="/docs">Read the docs</a></p></section></div></main><footer class="site-foot"><div class="wrap foot-main"><div class="foot-brand"><a class="brand" href="/" aria-label="Diffinery home"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><path d="M6 8.5v7M8.3 7.2c4 1 7.4 2.2 7.6 3.3M8.3 16.8c4-1 7.4-2.2 7.6-3.3"/></svg> <span>Diffinery</span></a><p><strong>Code hosting and CI for the agentic era.</strong> Open-source repositories, pull requests and GitHub Actions–compatible CI for teams of people and AI agents, on your own Cloudflare account.</p><a href="/docs/self-hosting" class="btn sm">Deploy your own</a></div><nav aria-label="Product"><h2>Product</h2><a href="/features">Features</a><a href="/agents">For AI agents</a><a href="/performance">Performance</a><a href="/security">Security</a><a href="/built-on-cloudflare">Built on Cloudflare</a><a href="/open-source">Open source</a><a href="/docs/migrate-from-github">Migrate from GitHub</a></nav><nav aria-label="Compare"><h2>Compare</h2><a href="/compare">All comparisons</a><a href="/compare/github">vs GitHub</a><a href="/compare/gitlab">vs GitLab</a><a href="/compare/blacksmith">vs Blacksmith</a><a href="/compare/depot">vs Depot</a></nav><nav aria-label="Resources"><h2>Resources</h2><a href="/docs">Docs</a><a href="/docs/self-hosting">Self-hosting</a><a href="/docs/guides">Guides</a><a href="/docs/connect">Connect AI apps</a><a href="/llms.txt">llms.txt</a><a href="/status">Status</a><a href="/docs/security/disclosure">Report a vulnerability</a></nav><nav aria-label="Company"><h2>Company</h2><a href="/about">About</a><a href="/faq">FAQ</a><a href="/blog">Blog</a><a href="https://diffinery.com/codician/diffinery">Source code</a><a href="https://github.com/codician-team/diffinery">GitHub mirror</a></nav></div><div class="wrap"><div class="foot-bar"><span>© 2026 Diffinery</span><a href="/built-on-cloudflare">Runs entirely on Cloudflare</a></div></div></footer><script nonce="tnwt9WYAuXTpg2S54jPo3g">(()=>{ const d=document,b=d.body,$=(s,r=d)=>r.querySelector(s),$$=(s,r=d)=>[...r.querySelectorAll(s)]; const repo=b.dataset.repo||'',ref=b.dataset.ref||''; const enc=p=>p.split('/').map(encodeURIComponent).join('/'); // Fields that want the browser's time zone (the morning digest's "this browser" choice). $$('input[data-browser-tz]').forEach(i=>{try{i.value=Intl.DateTimeFormat().resolvedOptions().timeZone||''}catch(_){}}); // Today's sections (agentic/web.tsx): remember which are folded away, open one a link points at, fold "Show N more" back. const todaySecs=$$('details[data-today-sec]'); const saveTodaySecs=()=>{d.cookie='today_collapsed='+todaySecs.filter(x=>!x.open).map(x=>x.dataset.todaySec).join('.')+';path=/;max-age=31536000;samesite=lax'+(location.protocol==='https:'?';secure':'')}; todaySecs.forEach(x=>x.addEventListener('toggle',saveTodaySecs)); const openTodaySec=()=>{const x=location.hash&&todaySecs.find(s=>'#'+s.id===location.hash);if(x&&!x.open)x.open=true}; openTodaySec();window.addEventListener('hashchange',openTodaySec); $$('.today-more>.fewer').forEach(x=>{x.hidden=false}); d.addEventListener('click',e=>{ const fewer=e.target.closest('[data-show-fewer]'); if(fewer){const m=fewer.closest('details');m.open=false;const s=$('summary',m);s.focus({preventScroll:true});s.scrollIntoView({block:'nearest'});return} const toSec=e.target.closest('a[href^="#"]');if(toSec){const x=todaySecs.find(s=>'#'+s.id===toSec.getAttribute('href'));if(x)x.open=true} const c=e.target.closest('[data-copy]'); if(c){e.preventDefault();const v=c.dataset.copy;(navigator.clipboard?navigator.clipboard.writeText(v):Promise.reject()).then(()=>{const o=c.innerHTML;if(c.dataset.copyIcon)c.innerHTML="<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 256 256\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z\"></path></svg>";else c.textContent='Copied';setTimeout(()=>{c.innerHTML=o},1200)}).catch(()=>{window.prompt('Copy:',v)});return} const p=e.target.closest('[data-palette]');if(p){e.preventDefault();openPalette();return} const a=e.target.closest('[data-comment-line]');if(a){e.preventDefault();lineComment(a);return} const x=e.target.closest('[data-cancel-line]');if(x){e.preventDefault();const tr=x.closest('tr');tr&&tr.remove()} if(!e.target.closest('details.menu'))$$('details.menu[open]').forEach(m=>m.removeAttribute('open')); }); d.addEventListener('submit',e=>{const f=e.target;if(f.dataset.passkey){e.preventDefault();passkey(f);return} if(f.dataset.confirm&&!confirm(f.dataset.confirm)){e.preventDefault();return} if(f.dataset.match){const i=f.querySelector('[name=confirm]');if(i&&i.value!==f.dataset.match){e.preventDefault();alert('Type '+f.dataset.match+' to confirm.');return}} $$('button[type=submit],button:not([type])',f).forEach(x=>setTimeout(()=>{x.disabled=true},0));},true); // Passkeys (WebAuthn): forms with data-passkey="login" or "register" const b2u=buf=>{let s='';new Uint8Array(buf).forEach(x=>{s+=String.fromCharCode(x)});return btoa(s).replaceAll('+','-').replaceAll('/','_').replaceAll('=','')}; const u2b=s=>{s=s.replaceAll('-','+').replaceAll('_','/');while(s.length%4)s+='=';const bin=atob(s);const out=new Uint8Array(bin.length);for(let i=0;i<bin.length;i++)out[i]=bin.charCodeAt(i);return out.buffer}; async function pkPost(url,body){const r=await fetch(url,{method:'POST',credentials:'same-origin',headers:{'content-type':'application/json'},body:JSON.stringify(body)}); let j={};try{j=await r.json()}catch(_){}if(!r.ok&&j.confirm){location.assign(j.confirm);await new Promise(()=>{})}if(!r.ok)throw new Error(j.message||('Request failed ('+r.status+')'));return j} async function passkey(f){const mode=f.dataset.passkey,msg=$('[data-passkey-msg]',f)||$('[data-passkey-msg]'),btns=$$('button',f); const show=t=>{if(msg){msg.textContent=t;msg.hidden=!t}else if(t)alert(t)}; if(!window.PublicKeyCredential||!navigator.credentials){show('This browser does not support passkeys. Try a current version of Chrome, Safari, Edge or Firefox.');return} show('');btns.forEach(x=>{x.disabled=true}); const data={};new FormData(f).forEach((v,k)=>{if(typeof v==='string')data[k]=v});data.next=f.dataset.next||'/'; try{const o=await pkPost('/auth/passkey/'+mode+'/options',data);o.challenge=u2b(o.challenge);let cred,res; if(mode==='login'){(o.allowCredentials||[]).forEach(c=>{c.id=u2b(c.id)});cred=await navigator.credentials.get({publicKey:o});const r=cred.response; res={authenticatorData:b2u(r.authenticatorData),clientDataJSON:b2u(r.clientDataJSON),signature:b2u(r.signature)};if(r.userHandle)res.userHandle=b2u(r.userHandle)} else{o.user.id=u2b(o.user.id);(o.excludeCredentials||[]).forEach(c=>{c.id=u2b(c.id)});cred=await navigator.credentials.create({publicKey:o});const r=cred.response; res={attestationObject:b2u(r.attestationObject),clientDataJSON:b2u(r.clientDataJSON),transports:r.getTransports?r.getTransports():[]}} const v=await pkPost('/auth/passkey/'+mode+'/verify',Object.assign({},data,{response:{id:cred.id,rawId:b2u(cred.rawId),type:cred.type,response:res,clientExtensionResults:cred.getClientExtensionResults(),authenticatorAttachment:cred.authenticatorAttachment||undefined}})); location.assign(v.redirect||'/')} catch(e){btns.forEach(x=>{x.disabled=false}); show(e&&e.name==='NotAllowedError'?'The passkey prompt was closed or timed out. Try again when you are ready.':e&&e.name==='InvalidStateError'?'This device already has a passkey for this account.':(e&&e.message)||String(e))}} function lineComment(btn){ const tpl=$('#line-comment-tpl');if(!tpl)return; const tr=btn.closest('tr');const next=tr.nextElementSibling; if(next&&next.classList.contains('newc')){next.querySelector('textarea').focus();return} const row=d.createElement('tr');row.className='thread newc';const td=d.createElement('td');td.colSpan=tr.children.length; td.append(tpl.content.cloneNode(true));row.append(td);tr.after(row); row.querySelector('[name=path]').value=btn.dataset.path;row.querySelector('[name=line]').value=btn.dataset.commentLine; row.querySelector('[name=side]').value=btn.dataset.side||'RIGHT';row.querySelector('.where').textContent=btn.dataset.path+':'+btn.dataset.commentLine; row.querySelector('textarea').focus(); } // Profile pictures: preview the centred square, then upload it at most 512 px wide (the server makes the small WebPs). // Files this browser cannot decode (HEIC in Chrome, say) go up as they are; the server's answer comes back as the flash message. let webpOk=null; async function squareBlob(file){const bmp=await createImageBitmap(file);const side=Math.min(bmp.width,bmp.height),out=Math.min(512,side); const cv=d.createElement('canvas');cv.width=cv.height=out;const ctx=cv.getContext('2d');ctx.imageSmoothingQuality='high'; ctx.drawImage(bmp,(bmp.width-side)/2,(bmp.height-side)/2,side,side,0,0,out,out);if(bmp.close)bmp.close(); if(webpOk===null){const t=d.createElement('canvas');t.width=t.height=1;webpOk=t.toDataURL('image/webp').startsWith('data:image/webp')} return new Promise((ok,no)=>cv.toBlob(x=>x?ok(x):no(new Error('encode failed')),webpOk?'image/webp':'image/png',0.92))} $$('form[data-avatar]').forEach(f=>{const inp=$('input[type=file]',f),st=$('[data-avatar-status]',f),box=f.closest('.avpick')||d,img=$('[data-avatar-preview] img',box); if(!inp)return;let blob=null,url='';const orig=img&&img.getAttribute('src');const say=t=>{if(st)st.textContent=t}; inp.addEventListener('change',async()=>{blob=null;if(url){URL.revokeObjectURL(url);url=''}const file=inp.files&&inp.files[0]; if(!file){if(img&&orig)img.src=orig;say('');return} try{blob=await squareBlob(file);url=URL.createObjectURL(blob);if(img){img.loading='eager';img.src=url}say('Preview. Save to use this picture.')} catch(_){blob=null;if(img&&orig)img.src=orig;say('No preview for this file; it will be checked when you save.')}}); f.addEventListener('submit',async e=>{const file=inp.files&&inp.files[0];if(e.defaultPrevented||!file)return;e.preventDefault(); const fd=new FormData(f);if(blob)fd.set(inp.name,blob,blob.type==='image/webp'?'avatar.webp':'avatar.png'); say('Uploading…');$$('button',f).forEach(x=>{x.disabled=true}); // The answer is a redirect that sets the flash message; follow it by reloading the page. try{await fetch(f.action,{method:'POST',body:fd,credentials:'same-origin',redirect:'manual'})}catch(_){} location.reload()})}); // Palette const dlg=$('#palette'),inp=dlg&&$('input',dlg),ul=dlg&&$('ul',dlg);let items=null,shown=[],sel=0,loading=false; function base(){const a=[['Dashboard','/'],['New repository','/new'],['Notifications','/notifications'],['Settings','/settings'],['Tokens','/settings/tokens'],['Agents','/settings/agents']].map(([t,u])=>({t,u,k:'Go to'})); if(repo){const r='/'+repo;[['Code',''],['Issues','/issues'],['New issue','/issues/new'],['Pull requests','/pulls'],['Actions','/actions'],['Branches','/branches'],['Tags','/tags'],['Commits','/commits/'+enc(ref||'HEAD')],['Compare','/compare'],['Settings','/settings']].forEach(([t,p])=>a.unshift({t:repo+' › '+t,u:r+p,k:'Repository'}))} return a} async function load(){if(items||loading)return;loading=true;items=base();draw(); try{const r=await fetch('/-/palette.json'+(repo?'?repo='+encodeURIComponent(repo)+'&ref='+encodeURIComponent(ref):''),{credentials:'same-origin'}); if(r.ok){const j=await r.json();(j.repos||[]).forEach(x=>items.push({t:x,u:'/'+x,k:'Repository'}));(j.files||[]).forEach(f=>items.push({t:f,u:'/'+repo+'/blob/'+enc(j.ref||ref||'HEAD')+'/'+enc(f),k:'File'}));draw()}}catch(_){}} function score(q,s){if(!q)return 1;let i=0,sc=0,last=-2;const lo=s.toLowerCase();const at=lo.indexOf(q);if(at>=0)return 1000-at-(s.length/100); for(const ch of q){const k=lo.indexOf(ch,i);if(k<0)return -1;sc+=k===last+1?5:1;if(k===0||'/ -_.'.includes(lo[k-1]))sc+=3;last=k;i=k+1}return sc-(s.length/100)} function draw(){if(!ul)return;const q=inp.value.trim().toLowerCase();let list=(items||[]).map(x=>[score(q,x.t),x]).filter(a=>a[0]>=0).sort((a,b)=>b[0]-a[0]).slice(0,60).map(a=>a[1]); const m=/^#?(\d+)$/.exec(q);if(m&&repo)list.unshift({t:'Go to #'+m[1],u:'/'+repo+'/issues/'+m[1],k:'Issue / PR'}); shown=list;if(sel>=shown.length)sel=Math.max(0,shown.length-1); ul.replaceChildren(...shown.map((x,i)=>{const li=d.createElement('li');if(i===sel)li.className='sel';const a=d.createElement('a');a.href=x.u;a.textContent=x.t;const k=d.createElement('span');k.textContent=x.k;a.append(k);li.append(a);return li})); const s=$('li.sel',ul);s&&s.scrollIntoView({block:'nearest'})} function openPalette(){if(!dlg)return;if(!dlg.open)dlg.showModal();inp.value='';sel=0;load();draw();inp.focus()} if(dlg){inp.addEventListener('input',()=>{sel=0;draw()}); inp.addEventListener('keydown',e=>{if(e.key==='ArrowDown'){e.preventDefault();sel=Math.min(sel+1,shown.length-1);draw()}else if(e.key==='ArrowUp'){e.preventDefault();sel=Math.max(sel-1,0);draw()}else if(e.key==='Enter'){e.preventDefault();const x=shown[sel];if(x)location.href=x.u}}); dlg.addEventListener('click',e=>{if(e.target===dlg)dlg.close()})} // Shortcuts let g=0; d.addEventListener('keydown',e=>{ if((e.metaKey||e.ctrlKey)&&!e.altKey&&e.key.toLowerCase()==='k'){e.preventDefault();openPalette();return} const t=e.target;if(t&&t.closest&&t.closest('input,textarea,select,[contenteditable],dialog,.dfy-k,[role=listbox]'))return; if(e.metaKey||e.ctrlKey||e.altKey)return; if(g&&Date.now()-g<1500){g=0;const m={c:'',i:'/issues',p:'/pulls',a:'/actions',s:'/settings'}[e.key];if(repo&&m!==undefined){e.preventDefault();location.href='/'+repo+m}else if(e.key==='d'){location.href='/'}else if(e.key==='n'){location.href='/notifications'}return} if(e.key==='g'){g=Date.now();return} if(e.key==='t'&&repo){e.preventDefault();openPalette();return} if(e.key==='/'){const s=$('input[type=search]');if(s){e.preventDefault();s.focus()}} }); // Live updates const live=b.dataset.live,mode=b.dataset.liveMode||'reload'; if(live&&repo&&'WebSocket' in window){let ws,tries=0,timer=null,lastSeq=Number(b.dataset.lastSeq||'-1'),opened=false,planned=false; function connect(){ws=new WebSocket((location.protocol==='https:'?'wss://':'ws://')+location.host+'/'+repo+'/live?topics='+encodeURIComponent(live)); ws.onopen=()=>{if(opened){if(mode!=='log')refresh();else if(!planned)location.reload()}opened=true;planned=false;tries=0}; ws.onmessage=e=>{if(e.data==='pong')return;let m;try{m=JSON.parse(e.data)}catch(_){return}handle(m)}; ws.onclose=e=>{planned=e.code===4001;setTimeout(connect,planned?0:Math.min(30000,1000*Math.pow(2,tries++)))}} setInterval(()=>{if(ws&&ws.readyState===1)ws.send('ping')},25000); function handle(m){const a=m.data&&m.data.action; if(mode==='log'){if(!String(m.topic).startsWith('job:'))return; if(a==='logs'){append(m.data.lines||[]);return} if(a==='step'&&m.data.step){stepState(m.data.step);return} if(a==='completed'||a==='restarted'){setTimeout(()=>location.reload(),700)}return} clearTimeout(timer);timer=setTimeout(refresh,350)} async function refresh(){const frags=$$('[data-fragment]');if(!frags.length){location.reload();return} try{const r=await fetch(location.href,{credentials:'same-origin'});if(!r.ok)return;const doc=new DOMParser().parseFromString(await r.text(),'text/html'); const kp=d.getElementById('dfy-k-portal');if(kp&&kp.childElementCount){setTimeout(refresh,1500);return}for(const f of frags){if(f.contains(d.activeElement)&&d.activeElement!==b)continue;const n=doc.querySelector('[data-fragment="'+f.dataset.fragment+'"]');if(n)f.replaceWith(d.importNode(n,true))}}catch(_){}} function clean(s){return s.replace(/\x1b\[[0-9;?]*[A-Za-z]/g,'')} function section(step){let s=$('.log [data-step="'+step+'"]');if(!s){const log=$('.log');if(!log)return null;s=d.createElement('details');s.open=true;s.dataset.step=step; const sm=d.createElement('summary');sm.innerHTML='<span class="st spin run"></span>';sm.append(step<0?'Set up job':'Step '+(step+1));s.append(sm,d.createElement('pre'));log.append(s)} return $('pre',s)} function append(lines){const follow=(innerHeight+scrollY)>=d.body.scrollHeight-80; for(const l of lines){if(l.seq<=lastSeq)continue;lastSeq=l.seq;const pre=section(l.step);if(!pre)continue;const sp=d.createElement('span');const t=clean(l.text); if(t.startsWith('::group::')){sp.className='grp';sp.textContent='\u25be '+t.slice(9)}else if(/^##\[error\]|^::error/.test(t)){sp.className='err';sp.textContent=t}else if(/^::warning/.test(t)){sp.className='wrn';sp.textContent=t}else sp.textContent=t; pre.append(sp);const det=pre.parentElement;if(det&&!det.open)det.open=true} if(follow)scrollTo(0,d.body.scrollHeight)} function stepState(s){if(!$('.log [data-step="'+s.index+'"]'))section(s.index);const sec=$('.log [data-step="'+s.index+'"]');if(!sec)return;const sm=$('summary',sec);if(!sm)return;const icon=$('.st',sm); if(s.status==='completed'&&icon){icon.className='st '+(s.conclusion==='success'?'ok':s.conclusion==='failure'?'bad':'faint');icon.textContent=s.conclusion==='success'?'\u2713':s.conclusion==='failure'?'\u2715':'\u2212'} if(s.name){const label=[...sm.childNodes].find(n=>n.nodeType===3);if(label)label.textContent=s.name}} connect()} })();</script></body></html> operator: 'match' stack: |- TestContext.<anonymous> (file:///workspace/diffinery/apps/diffinery/test/e2e/passkeys.test.mjs:589:10) process.processTicksAndRejections (node:internal/process/task_queues:105:5) async Test.run (node:internal/test_runner/test:1054:7) async Test.processPendingSubtests (node:internal/test_runner/test:744:7) ...# Subtest: registry: the OCI distribution APIok 46 - registry: the OCI distribution API --- duration_ms: 10984.080965 type: 'test' ...# Subtest: registry: token scopes, the packages API and repository linksok 47 - registry: token scopes, the packages API and repository links --- duration_ms: 646.97477 type: 'test' ...# Subtest: registry: organization packages follow ghcr.io's permissionsok 48 - registry: organization packages follow ghcr.io's permissions --- duration_ms: 1049.061192 type: 'test' ...# Subtest: registry: an organization's package linked to a private repository follows that repository's accessok 49 - registry: an organization's package linked to a private repository follows that repository's access --- duration_ms: 358.646804 type: 'test' ...# Subtest: registry: a workflow's GITHUB_TOKEN follows the packages permissionok 50 - registry: a workflow's GITHUB_TOKEN follows the packages permission --- duration_ms: 1792.789693 type: 'test' ...# Subtest: registry: docker login, push and pullok 51 - registry: docker login, push and pull --- duration_ms: 31935.572562 type: 'test' ...# Subtest: a web terminal: only its opener attaches, the sandbox API can't reach it, and End takes it awayok 52 - a web terminal: only its opener attaches, the sandbox API can't reach it, and End takes it away --- duration_ms: 11211.544368 type: 'test' ...# Subtest: a kill switch ends web terminals and refuses new ones until it's liftedok 53 - a kill switch ends web terminals and refuses new ones until it's lifted --- duration_ms: 3525.982777 type: 'test' ...# Subtest: a task in my terminal: only on my click, with the CLI signed in there, in a checkout of its ownok 54 - a task in my terminal: only on my click, with the CLI signed in there, in a checkout of its own --- duration_ms: 12092.892928 type: 'test' ...1..54# tests 54# suites 0# pass 53# fail 1# cancelled 0# skipped 0# todo 0# duration_ms 154816.277506##[error]Process completed with exit code 1.
Post Run pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b10s
Pruning is unnecessary.Post Run actions/checkout@v40s
Removing persisted credentials