From 9c4960be506a29a71a721fe873f2653cecb9e8ed Mon Sep 17 00:00:00 2001 From: badcuban <108198679+badcuban@users.noreply.github.com> Date: Mon, 10 Aug 2026 14:52:52 -0400 Subject: [PATCH] Ship a Docker self-host image and fix what testing it exposed The article-of-record audience runs orchestrators on VPSes and homelabs; Threadlines could already serve them headless but had no packaged way to do it. docker/Dockerfile builds a service appliance from the published npm package: Claude Code and Codex CLIs baked in, tini for agent process trees, non-root user, home volume for data and provider credentials, /workspace for repos, healthcheck, and auto-bootstrap disabled (a service must not mint a project from its own working directory). docker/README.md is the two-command operator guide. Two fixes fell out of the cold-user verification: - THREADLINES_ADVERTISED_HOST: startup URLs advertised the container's internal address, which no client can reach. An operator-set host now wins over interface resolution. - effect PubSub patch: every abrupt websocket disconnect logged "Failed to publish disconnected-session auth update" with a TypeError from inside effect's PubSub - an interrupted poller leaves an undefined hole in the pollers list and the publish path dereferences it. The patch skips holes. Reproduced deterministically (pair, open app, kill the browser context), clean after; upstream report worth filing. --- apps/server/src/bin.test.ts | 1 + apps/server/src/cli/config.ts | 8 ++ apps/server/src/cli/marketingStudioSeed.ts | 1 + apps/server/src/config.ts | 7 ++ .../Layers/ServerEnvironment.test.ts | 1 + apps/server/src/server.test.ts | 1 + apps/server/src/serverRuntimeStartup.ts | 4 +- apps/server/src/usage/UsageService.test.ts | 1 + docker/Dockerfile | 67 ++++++++++ docker/README.md | 91 ++++++++++++++ patches/effect@4.0.0-beta.98.patch | 16 +++ pnpm-lock.yaml | 117 +++++++++--------- 12 files changed, 256 insertions(+), 59 deletions(-) create mode 100644 docker/Dockerfile create mode 100644 docker/README.md diff --git a/apps/server/src/bin.test.ts b/apps/server/src/bin.test.ts index 5a3f77d19..1964ab94a 100644 --- a/apps/server/src/bin.test.ts +++ b/apps/server/src/bin.test.ts @@ -67,6 +67,7 @@ const makeCliTestServerConfig = (baseDir: string) => mode: "web", port: 0, host: "127.0.0.1", + advertisedHost: undefined, cwd: process.cwd(), baseDir, ...derivedPaths, diff --git a/apps/server/src/cli/config.ts b/apps/server/src/cli/config.ts index ea7aa12e9..3d6e58ec4 100644 --- a/apps/server/src/cli/config.ts +++ b/apps/server/src/cli/config.ts @@ -200,6 +200,13 @@ const EnvServerConfig = Config.all({ Config.string("BADCODE_HOST"), Config.string("T3CODE_HOST"), ), + // The hostname startup URLs advertise, when the bind address is not the + // reachable one -- a container binds 0.0.0.0 and its interfaces are + // internal, so only the operator knows the address clients can reach. + advertisedHost: Config.string("THREADLINES_ADVERTISED_HOST").pipe( + Config.option, + Config.map(Option.getOrUndefined), + ), threadlinesHome: aliasedConfigOption( Config.string("THREADLINES_HOME"), Config.string("BADCODE_HOME"), @@ -485,6 +492,7 @@ export const resolveServerConfig = ( ...derivedPaths, serverTracePath, host, + advertisedHost: env.advertisedHost, staticDir, devUrl, noBrowser, diff --git a/apps/server/src/cli/marketingStudioSeed.ts b/apps/server/src/cli/marketingStudioSeed.ts index aa8c9266c..1aa2386f1 100644 --- a/apps/server/src/cli/marketingStudioSeed.ts +++ b/apps/server/src/cli/marketingStudioSeed.ts @@ -144,6 +144,7 @@ const makeServerConfig = (input: MarketingStudioSeedInput): ServerConfigShape => mode: "desktop", port: 0, host: undefined, + advertisedHost: undefined, cwd: input.cwd, baseDir: input.baseDir, staticDir: undefined, diff --git a/apps/server/src/config.ts b/apps/server/src/config.ts index cc793ac28..77e8c8caa 100644 --- a/apps/server/src/config.ts +++ b/apps/server/src/config.ts @@ -63,6 +63,12 @@ export interface ServerConfigShape extends ServerDerivedPaths { readonly mode: RuntimeMode; readonly port: number; readonly host: string | undefined; + /** + * The hostname startup URLs advertise when the bind address is not the + * reachable one. A container binds 0.0.0.0 and its interfaces are internal, + * so only the operator knows what clients can actually reach. + */ + readonly advertisedHost: string | undefined; readonly cwd: string; readonly baseDir: string; readonly staticDir: string | undefined; @@ -194,6 +200,7 @@ export class ServerConfig extends Context.Service Devices). + +ARG THREADLINES_VERSION=latest + +# node-pty compiles natively on install, so the install happens in a stage +# with a toolchain and only the result ships. +FROM node:22-bookworm AS build +ARG THREADLINES_VERSION +RUN npm install -g --prefix /opt/threadlines "@threadlines/server@${THREADLINES_VERSION}" + +FROM node:22-bookworm-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + git \ + openssh-client \ + tini \ + && rm -rf /var/lib/apt/lists/* + +# The coding agent CLIs the server orchestrates. Their credentials land in +# the home volume, so sign-ins survive container replacement. +RUN npm install -g @anthropic-ai/claude-code @openai/codex + +COPY --from=build /opt/threadlines /opt/threadlines +RUN ln -s /opt/threadlines/bin/threadlines /usr/local/bin/threadlines + +# Reuse uid/gid 1000 (the image's `node` user) so named volumes and typical +# bind mounts agree on ownership. +RUN userdel -r node \ + && useradd --create-home --uid 1000 --user-group threadlines \ + && mkdir -p /workspace \ + && chown threadlines:threadlines /workspace + +USER threadlines +WORKDIR /workspace + +# Bind-mounted repos rarely share the container user's uid; without this git +# refuses them as "dubious ownership". /workspace is the operator's own code. +RUN git config --global safe.directory "*" + +ENV THREADLINES_HOME=/home/threadlines/.threadlines \ + THREADLINES_HOST=0.0.0.0 \ + THREADLINES_PORT=3773 \ + THREADLINES_NO_BROWSER=1 \ + # A service must not mint a project from its own working directory the way + # a `npx` launch does; operators add projects from /workspace deliberately. + THREADLINES_AUTO_BOOTSTRAP_PROJECT_FROM_CWD=false + +EXPOSE 3773 + +# Agent sessions spawn deep process trees; tini reaps what they leave behind. +ENTRYPOINT ["tini", "--", "threadlines"] + +HEALTHCHECK --interval=30s --timeout=5s --start-period=30s \ + CMD curl -fsS "http://127.0.0.1:${THREADLINES_PORT}/api/auth/session" || exit 1 diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..7927d0196 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,91 @@ +# Threadlines on a server + +Run Threadlines on a machine that is always on: a VPS, a home server, or a +spare computer. Your coding agents keep working when your laptop is closed, +and your phone or any browser connects to them from anywhere. + +## Quick start + +```bash +docker run -d --name threadlines --restart unless-stopped \ + -p 3773:3773 \ + -v threadlines-home:/home/threadlines \ + -v /path/to/your/repos:/workspace \ + ghcr.io/threadlines/threadlines:latest +``` + +Then: + +```bash +docker logs threadlines +``` + +The log prints a one-time link. Open it in a browser to unlock the web app. +From there, Settings -> Devices mints QR codes for pairing your phone. + +That is the whole install. + +## What the pieces mean + +- `--restart unless-stopped` makes Docker bring Threadlines back after a + crash or a server reboot. Nothing to babysit. +- `threadlines-home` is a named volume holding everything that must survive: + your threads, settings, device pairings, and the Claude/Codex sign-ins. + Containers are disposable; this volume is not. +- `/workspace` is where your repositories live. Mount the folder that holds + them and add projects from `/workspace/...` inside the app. +- Port `3773` serves both the web app and the phone connection. + +If clients will reach the server at a known address, tell startup links about +it with `-e THREADLINES_ADVERTISED_HOST=your-server.example.com` so the URL +in `docker logs` is directly clickable. + +## Signing in to the agents + +The Claude Code and Codex CLIs ship inside the image. Sign in once from the +web app (Settings -> Providers); the credentials land in the home volume and +survive container updates. For Claude on a headless server, the +"Advanced: headless chat token" flow in provider settings avoids needing a +browser on the server itself. + +## Updating + +```bash +docker pull ghcr.io/threadlines/threadlines:latest +docker rm -f threadlines +# re-run the same docker run command +``` + +Your data lives in the volume, so this is safe. Pin a version tag +(for example `ghcr.io/threadlines/threadlines:0.3.3`) if you prefer +updates on your own schedule. + +## Reaching it from outside your network + +The safest defaults, in order of effort: + +- **Tailscale or a VPN**: install it on the server and your devices, then use + the server's private address. Nothing is exposed to the internet. +- **A reverse proxy with HTTPS** (Caddy, nginx, Traefik) in front of port + 3773, if you want a public address. Threadlines requires pairing before any + data is served, but public endpoints deserve TLS. + +Avoid exposing port 3773 to the open internet without one of the above. + +## docker-compose + +```yaml +services: + threadlines: + image: ghcr.io/threadlines/threadlines:latest + container_name: threadlines + restart: unless-stopped + ports: + - "3773:3773" + volumes: + - threadlines-home:/home/threadlines + - /path/to/your/repos:/workspace + +volumes: + threadlines-home: +``` diff --git a/patches/effect@4.0.0-beta.98.patch b/patches/effect@4.0.0-beta.98.patch index eb393cfd7..ca73f53b6 100644 --- a/patches/effect@4.0.0-beta.98.patch +++ b/patches/effect@4.0.0-beta.98.patch @@ -1,3 +1,19 @@ +diff --git a/dist/PubSub.js b/dist/PubSub.js +index 5f294e781fcedc57902bf53d20cab83184fe358b..72d3b1f36b84e54a22321ab756401ad144e7c62b 100644 +--- a/dist/PubSub.js ++++ b/dist/PubSub.js +@@ -2049,6 +2049,11 @@ const strategyCompletePollersUnsafe = (strategy, pubsub, subscribers, subscripti + let keepPolling = true; + while (keepPolling && !subscription.isEmpty()) { + const poller = MutableList.take(pollers); ++ // An interrupted poller leaves an undefined hole in the list; completing ++ // it would dereference undefined. Skip holes and keep draining. ++ if (poller === undefined || poller === null) { ++ continue; ++ } + if (poller === MutableList.Empty) { + removeSubscribers(subscribers, subscription, pollers); + if (pollers.length === 0) { diff --git a/dist/unstable/rpc/RpcClient.d.ts b/dist/unstable/rpc/RpcClient.d.ts index a70061a638faabdd663eca25cb79585fec06e03c..1af40759e2d51d1c1d2da86bd00a43fc71cfff3a 100644 --- a/dist/unstable/rpc/RpcClient.d.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b7cb03180..0168536b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,7 +78,7 @@ patchedDependencies: hash: 954a7d16cd35f4b31756829c2e8a16c3f3fe0b89d8d69fbfe8d79b9a322f8275 path: patches/brace-expansion@5.0.9.patch effect@4.0.0-beta.98: - hash: 181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2 + hash: d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933 path: patches/effect@4.0.0-beta.98.patch lexical@0.47.0: hash: 4b8dd229acb72970dcf7536933ce8ac8689aeec7d653398adddb203d56f71780 @@ -111,7 +111,7 @@ importers: dependencies: '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@threadlines/contracts': specifier: workspace:* version: link:../../packages/contracts @@ -126,7 +126,7 @@ importers: version: link:../../packages/tailscale effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) electron: specifier: 43.1.0 version: 43.1.0 @@ -136,7 +136,7 @@ importers: devDependencies: '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) '@types/node': specifier: ^24.10.13 version: 24.13.3 @@ -216,16 +216,16 @@ importers: version: 0.115.0(zod@4.4.3) '@effect/platform-bun': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=9fc1610289fc4eec0a69d930d8a359b7a4b1055920b831ba4bf91223be7a0e04)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2)) + version: 4.0.0-beta.98(patch_hash=9fc1610289fc4eec0a69d930d8a359b7a4b1055920b831ba4bf91223be7a0e04)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933)) '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@effect/platform-node-shared': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2)) + version: 4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933)) '@effect/sql-sqlite-bun': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2)) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933)) '@opencode-ai/sdk': specifier: ^1.18.15 version: 1.18.15 @@ -234,14 +234,14 @@ importers: version: 1.3.0-beta.9(@shikijs/themes@4.4.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) node-pty: specifier: ^1.1.0 version: 1.1.0 devDependencies: '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) '@threadlines/contracts': specifier: workspace:* version: link:../../packages/contracts @@ -298,7 +298,7 @@ importers: version: 3.2.2(react@19.2.8) '@effect/atom-react': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(react@19.2.8)(scheduler@0.27.0) + version: 4.0.0-beta.98(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(react@19.2.8)(scheduler@0.27.0) '@fontsource-variable/cascadia-mono': specifier: ^5.3.0 version: 5.3.0 @@ -343,7 +343,7 @@ importers: version: 0.7.1 effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) lexical: specifier: ^0.47.0 version: 0.47.0(patch_hash=4b8dd229acb72970dcf7536933ce8ac8689aeec7d653398adddb203d56f71780)(typescript@7.0.2) @@ -425,20 +425,20 @@ importers: dependencies: '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@oxlint/plugins': specifier: ^1.77.0 version: 1.77.0 effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) devDependencies: '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) oxlint: specifier: ^1.77.0 - version: 1.77.0(vite-plus@0.2.4(@types/node@24.13.3)(@vitest/browser-playwright@4.1.10(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.62.1)(vitest@4.1.10))(esbuild@0.28.2)(jiti@2.7.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(typescript@7.0.2)(yaml@2.9.0)) + version: 1.77.0(oxlint-tsgolint@0.24.0)(vite-plus@0.2.4(@types/node@24.13.3)(@vitest/browser-playwright@4.1.10(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.62.1)(vitest@4.1.10))(esbuild@0.28.2)(jiti@2.7.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(typescript@7.0.2)(yaml@2.9.0)) typescript: specifier: 'catalog:' version: 7.0.2 @@ -462,7 +462,7 @@ importers: version: link:../shared effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) devDependencies: typescript: specifier: 'catalog:' @@ -481,11 +481,11 @@ importers: dependencies: effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) devDependencies: '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) typescript: specifier: 'catalog:' version: 7.0.2 @@ -503,17 +503,17 @@ importers: dependencies: effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) devDependencies: '@effect/openapi-generator': specifier: 'catalog:' - version: 4.0.0-beta.98(@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1))(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2)) + version: 4.0.0-beta.98(@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1))(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933)) '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) '@types/node': specifier: ^24.10.13 version: 24.13.3 @@ -534,17 +534,17 @@ importers: dependencies: effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) devDependencies: '@effect/openapi-generator': specifier: 'catalog:' - version: 4.0.0-beta.98(@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1))(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2)) + version: 4.0.0-beta.98(@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1))(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933)) '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) '@types/node': specifier: ^24.10.13 version: 24.13.3 @@ -568,17 +568,17 @@ importers: version: link:../contracts effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) yaml: specifier: ^2.9.0 version: 2.9.0 devDependencies: '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) '@types/node': specifier: ^24.10.13 version: 24.13.3 @@ -605,14 +605,14 @@ importers: version: link:../shared effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) devDependencies: '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) '@types/node': specifier: ^24.10.13 version: 24.13.3 @@ -633,14 +633,14 @@ importers: dependencies: '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) devDependencies: '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) '@types/node': specifier: ^24.10.13 version: 24.13.3 @@ -667,7 +667,7 @@ importers: version: 0.115.0(zod@4.4.3) '@effect/platform-node': specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) + version: 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) '@github/copilot-sdk': specifier: 'catalog:' version: 1.0.9 @@ -679,14 +679,14 @@ importers: version: link:../packages/shared effect: specifier: 4.0.0-beta.98 - version: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + version: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) yaml: specifier: ^2.9.0 version: 2.9.0 devDependencies: '@effect/vitest': specifier: 4.0.0-beta.97 - version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10) + version: 4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10) typescript: specifier: 'catalog:' version: 7.0.2 @@ -6874,41 +6874,41 @@ snapshots: react: 19.2.8 tslib: 2.8.1 - '@effect/atom-react@4.0.0-beta.98(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(react@19.2.8)(scheduler@0.27.0)': + '@effect/atom-react@4.0.0-beta.98(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(react@19.2.8)(scheduler@0.27.0)': dependencies: - effect: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + effect: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) react: 19.2.8 scheduler: 0.27.0 - '@effect/openapi-generator@4.0.0-beta.98(@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1))(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))': + '@effect/openapi-generator@4.0.0-beta.98(@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1))(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))': dependencies: - '@effect/platform-node': 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1) - effect: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + '@effect/platform-node': 4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1) + effect: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) swagger2openapi: 7.0.8 transitivePeerDependencies: - encoding - '@effect/platform-bun@4.0.0-beta.98(patch_hash=9fc1610289fc4eec0a69d930d8a359b7a4b1055920b831ba4bf91223be7a0e04)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))': + '@effect/platform-bun@4.0.0-beta.98(patch_hash=9fc1610289fc4eec0a69d930d8a359b7a4b1055920b831ba4bf91223be7a0e04)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))': dependencies: - '@effect/platform-node-shared': 4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2)) - effect: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + '@effect/platform-node-shared': 4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933)) + effect: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform-node-shared@4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))': + '@effect/platform-node-shared@4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))': dependencies: '@types/ws': 8.18.1 - effect: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + effect: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) ws: 8.21.0 transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(ioredis@5.11.1)': + '@effect/platform-node@4.0.0-beta.98(patch_hash=0e9f397f8e2ec9aef8e8d4f212b219732c48e5980d32035adad5764f3c56dc19)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(ioredis@5.11.1)': dependencies: - '@effect/platform-node-shared': 4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2)) - effect: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + '@effect/platform-node-shared': 4.0.0-beta.98(patch_hash=32a956569b355a7617af71fb5384e5ad2e40a302999506093492facea434779c)(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933)) + effect: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) ioredis: 5.11.1 mime: 4.1.0 undici: 8.10.0 @@ -6916,9 +6916,9 @@ snapshots: - bufferutil - utf-8-validate - '@effect/sql-sqlite-bun@4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))': + '@effect/sql-sqlite-bun@4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))': dependencies: - effect: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + effect: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) '@effect/tsgo-darwin-arm64@0.13.2': optional: true @@ -6951,9 +6951,9 @@ snapshots: '@effect/tsgo-win32-arm64': 0.13.2 '@effect/tsgo-win32-x64': 0.13.2 - '@effect/vitest@4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2))(vitest@4.1.10)': + '@effect/vitest@4.0.0-beta.97(effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933))(vitest@4.1.10)': dependencies: - effect: 4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2) + effect: 4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933) vitest: 4.1.10(@types/node@24.13.3)(@vitest/browser-playwright@4.1.10(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.62.1)(vitest@4.1.10))(@vitest/browser-preview@4.1.10)(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2)) '@electron-internal/extract-zip@1.0.4': {} @@ -9556,7 +9556,7 @@ snapshots: ee-first@1.1.1: {} - effect@4.0.0-beta.98(patch_hash=181986b14edb53e2f3c82527e8e5a9f7675db32427ed6940ee3da64e2f5968e2): + effect@4.0.0-beta.98(patch_hash=d3f9d7cfbb82a1137d9f5034d2d491aebcfb6386c6e26886eada7c5671c4d933): dependencies: '@standard-schema/spec': 1.1.0 fast-check: 4.9.0 @@ -11163,7 +11163,7 @@ snapshots: oxlint-tsgolint: 0.24.0 vite-plus: 0.2.4(@types/node@24.13.3)(@vitest/browser-playwright@4.1.10(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.62.1)(vitest@4.1.10))(esbuild@0.28.2)(jiti@2.7.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(typescript@7.0.2)(yaml@2.9.0) - oxlint@1.77.0(vite-plus@0.2.4(@types/node@24.13.3)(@vitest/browser-playwright@4.1.10(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.62.1)(vitest@4.1.10))(esbuild@0.28.2)(jiti@2.7.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(typescript@7.0.2)(yaml@2.9.0)): + oxlint@1.77.0(oxlint-tsgolint@0.24.0)(vite-plus@0.2.4(@types/node@24.13.3)(@vitest/browser-playwright@4.1.10(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.62.1)(vitest@4.1.10))(esbuild@0.28.2)(jiti@2.7.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(typescript@7.0.2)(yaml@2.9.0)): optionalDependencies: '@oxlint/binding-android-arm-eabi': 1.77.0 '@oxlint/binding-android-arm64': 1.77.0 @@ -11184,6 +11184,7 @@ snapshots: '@oxlint/binding-win32-arm64-msvc': 1.77.0 '@oxlint/binding-win32-ia32-msvc': 1.77.0 '@oxlint/binding-win32-x64-msvc': 1.77.0 + oxlint-tsgolint: 0.24.0 vite-plus: 0.2.4(@types/node@24.13.3)(@vitest/browser-playwright@4.1.10(@voidzero-dev/vite-plus-core@0.2.4(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.0))(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(playwright@1.62.1)(vitest@4.1.10))(esbuild@0.28.2)(jiti@2.7.0)(msw@2.15.0(@types/node@24.13.3)(typescript@7.0.2))(typescript@7.0.2)(yaml@2.9.0) p-cancelable@2.1.1: {}