From d2a3ed1da7a8fdee49a8ba20b2abddb9d36a1e46 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 16 Jul 2026 11:28:40 -0700 Subject: [PATCH 01/17] feat!: Ship the CLI as a Bun standalone binary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users previously needed a Node.js runtime to run the CLI, and every release shipped transpiled JS through a single npm package. Compiling with Bun produces one self-contained binary per platform, so the CLI runs with no runtime prerequisite and distributes directly through GitHub Releases. A compiled binary cannot discover package assets on disk at runtime, so integrations, bundled skills, and the Agent SDK executable move to generated manifests: the first two are embedded statically, while the Agent SDK is downloaded on first agent use and verified against a sha256 pinned at build time. Every release binary is smoke tested on native hardware for all five targets (including the new `workos internal verify-assets` command) before the draft release publishes, so a broken binary can never become `latest`. npm remains a secondary channel: a thin launcher package plus one platform package per binary (the esbuild pattern) preserves `npm install -g workos` and `npx workos`. BREAKING CHANGE: The npm package no longer exports a library API — `main`/`exports` are gone and it only provides the `workos` binary. Development now requires Bun >= 1.3.0 instead of Node >= 22.11. --- .github/workflows/ci.yml | 72 +- .github/workflows/release-please.yml | 1 - .github/workflows/release.yml | 177 +- .gitignore | 3 + .npmignore | 11 - .oxfmtrc.json | 2 +- CLAUDE.md | 27 +- DEVELOPMENT.md | 91 +- README.md | 59 +- bun.lock | 1072 ++++ package.json | 56 +- pnpm-lock.yaml | 5117 ----------------- release-please-config.json | 4 +- scripts/build.ts | 58 + scripts/craft-pre-release.sh | 10 - scripts/gen-agent-sdk-manifest.ts | 50 + scripts/gen-integration-manifest.ts | 40 + scripts/gen-npm-packages.ts | 160 + scripts/gen-skills-manifest.ts | 62 + scripts/smoke-test.ts | 2 +- src/bin-command-telemetry.integration.spec.ts | 16 +- src/bin.ts | 45 +- src/cli.config.ts | 2 - src/commands/api/catalog.spec.ts | 8 +- src/commands/api/catalog.ts | 13 +- src/commands/install-skill.spec.ts | 41 +- src/commands/install-skill.ts | 73 +- src/commands/internal-verify-assets.spec.ts | 30 + src/commands/internal-verify-assets.ts | 105 + src/commands/list-skills.spec.ts | 22 + src/commands/list-skills.ts | 12 +- src/commands/uninstall-skill.spec.ts | 22 + src/commands/uninstall-skill.ts | 17 +- src/doctor/checks/runtime.ts | 9 +- src/doctor/checks/skills-fix.spec.ts | 4 +- src/doctor/output.ts | 3 +- src/doctor/types.ts | 3 +- src/integrations/_manifest.ts | 36 + src/integrations/dotnet/index.ts | 2 +- src/integrations/elixir/index.ts | 2 +- src/integrations/go/index.ts | 2 +- src/integrations/no-skill-tool.spec.ts | 12 +- src/integrations/python/index.ts | 2 +- src/integrations/ruby/index.ts | 2 +- src/lib/adapters/cli-adapter.spec.ts | 6 +- src/lib/agent-interface.spec.ts | 2 +- src/lib/agent-interface.ts | 45 +- src/lib/agent-runner.ts | 2 +- src/lib/agent-sdk-assets.spec.ts | 63 + src/lib/agent-sdk-assets.ts | 208 + src/lib/registry.spec.ts | 33 + src/lib/registry.ts | 63 +- src/lib/settings.ts | 1 - src/lib/skills-assets.spec.ts | 42 + src/lib/skills-assets.ts | 151 + src/lib/validation/validator.ts | 44 +- src/lib/version-check.spec.ts | 49 +- src/lib/version-check.ts | 27 +- src/utils/analytics.spec.ts | 6 +- src/utils/analytics.ts | 2 +- src/utils/box.ts | 2 +- src/utils/command-invocation.spec.ts | 6 +- src/utils/command-invocation.ts | 15 +- src/utils/command-telemetry.ts | 2 +- src/utils/recovery-hints.spec.ts | 4 +- src/utils/telemetry-types.ts | 7 +- tests/evals/README.md | 34 +- tests/evals/__tests__/agent-executor.spec.ts | 2 +- tests/evals/agent-executor.ts | 8 +- tests/evals/cli.ts | 22 +- tests/evals/commands/history.ts | 4 +- tests/evals/fixture-manager.ts | 4 +- tests/evals/graders/build-grader.ts | 4 +- tests/evals/log-commands.ts | 8 +- tests/fixtures/README.md | 2 +- .../nextjs/typescript-strict/README.md | 2 +- .../react-router/typescript-strict/README.md | 2 +- .../react/typescript-strict/README.md | 2 +- .../typescript-strict/README.md | 2 +- types/assets.d.ts | 4 + vitest.config.ts | 17 + 81 files changed, 2863 insertions(+), 5591 deletions(-) delete mode 100644 .npmignore create mode 100644 bun.lock delete mode 100644 pnpm-lock.yaml create mode 100644 scripts/build.ts delete mode 100644 scripts/craft-pre-release.sh create mode 100644 scripts/gen-agent-sdk-manifest.ts create mode 100644 scripts/gen-integration-manifest.ts create mode 100644 scripts/gen-npm-packages.ts create mode 100644 scripts/gen-skills-manifest.ts create mode 100644 src/commands/internal-verify-assets.spec.ts create mode 100644 src/commands/internal-verify-assets.ts create mode 100644 src/integrations/_manifest.ts create mode 100644 src/lib/agent-sdk-assets.spec.ts create mode 100644 src/lib/agent-sdk-assets.ts create mode 100644 src/lib/registry.spec.ts create mode 100644 src/lib/skills-assets.spec.ts create mode 100644 src/lib/skills-assets.ts create mode 100644 types/assets.d.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b93b6621..6b12cdb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,35 +7,73 @@ on: jobs: ci: - name: Node ${{ matrix.node }} + name: Bun runs-on: ubuntu-latest - strategy: - matrix: - node: [20, 22, 24] steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 7.0.0 - - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # 6.0.9 - - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # 6.4.0 + - uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # 2.0.2 with: - node-version: ${{ matrix.node }} - cache: pnpm + bun-version: 1.3.14 - name: Install - run: pnpm install + run: bun install --frozen-lockfile - name: Lint - run: pnpm lint + run: bun run lint - name: Format - run: pnpm format:check + run: bun run format:check - name: Typecheck - run: pnpm typecheck - - - name: Build - run: pnpm build + run: bun run typecheck - name: Test - run: pnpm test + run: bun run test + + - name: Check committed integration manifest is fresh + run: git diff --exit-code src/integrations/_manifest.ts + + # Compile the same baseline variant that release.yml ships for linux-x64, + # not the host-default "modern" build — they embed different Bun runtimes. + - name: Build standalone binary + env: + WORKOS_BUILD_TARGET: bun-linux-x64-baseline + run: bun run build + + # Core commands must work standalone: no Bun, no Node.js, no + # node_modules, and no network. + - name: Smoke test without Bun, Node.js, node_modules, or network + run: >- + docker run --rm --network none + --volume "${PWD}/dist/workos:/workos:ro" + --env HOME=/tmp/home + debian:bookworm-slim + sh -eu -c + '/workos --help >/dev/null; + /workos auth status --json; + /workos api ls users --json >/dev/null; + /workos skills list --json >/dev/null' + + # `internal verify-assets` performs the first-run download of the pinned + # Agent SDK executable (checksum-verified) and spawns it, so a broken + # download path fails every PR here instead of on a user's first + # `workos install`. Needs network; still no Bun/Node/node_modules. + - name: Smoke test agent runtime first-run download + run: >- + docker run --rm + --volume "${PWD}/dist/workos:/workos:ro" + --env HOME=/tmp/home + debian:bookworm-slim + sh -eu -c + '/workos internal verify-assets --json' + + # Prove the npm thin-shim launcher resolves and spawns the platform + # binary — the same wiring `npx workos` uses after publish. + - name: Smoke test npm launcher packages + env: + WORKOS_NPM_ALLOW_MISSING: '1' + run: | + cp dist/workos dist/workos-linux-x64 + bun run ./scripts/gen-npm-packages.ts + NODE_PATH=dist/npm node dist/npm/workos/bin/workos.js --version diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index e8cc43e3..0b40bb08 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -8,7 +8,6 @@ on: permissions: contents: write pull-requests: write - id-token: write jobs: release-please: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 348c4e8e..70afa281 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,36 +1,185 @@ name: Release +# Release flow: release-please creates a DRAFT release (with its tag pushed +# up front via force-tag-creation), then this workflow cross-compiles every +# target, smoke tests each binary on real hardware for its platform, and only +# publishes the draft once all of them pass. Users never see a release whose +# binaries are missing or broken; on any failure the draft stays invisible and +# the previous release remains `latest`. + on: workflow_call: inputs: tag_name: description: Release tag name (e.g., v0.12.0-beta.1) type: string - default: '' + required: true + # Manual escape hatch: re-run the build/smoke/publish for an existing + # draft release tag if a previous run failed. + workflow_dispatch: + inputs: + tag_name: + description: Release tag name (e.g., v0.12.0-beta.1) + type: string + required: true + +concurrency: + group: release-${{ inputs.tag_name }} + +permissions: + contents: read jobs: + build: + name: Build ${{ matrix.target }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - target: bun-darwin-arm64 + asset: workos-darwin-arm64 + - target: bun-darwin-x64-baseline + asset: workos-darwin-x64 + - target: bun-linux-x64-baseline + asset: workos-linux-x64 + - target: bun-linux-arm64 + asset: workos-linux-arm64 + - target: bun-windows-x64-baseline + asset: workos-windows-x64.exe + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 7.0.0 + with: + ref: ${{ inputs.tag_name }} + + - uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # 2.0.2 + with: + bun-version: 1.3.14 + + - name: Install all target-specific dependencies + run: bun install --frozen-lockfile --os="*" --cpu="*" + + # prebuild regenerates the manifests with the same WORKOS_BUILD_TARGET, + # so the pinned Agent SDK download metadata (version, URL, checksum) + # matches the compile target. + - name: Build standalone binary + env: + WORKOS_BUILD_TARGET: ${{ matrix.target }} + WORKOS_BUILD_OUTFILE: ./dist/${{ matrix.asset }} + run: bun run build + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # 7.0.1 + with: + name: ${{ matrix.asset }} + path: dist/${{ matrix.asset }} + if-no-files-found: error + + smoke: + name: Smoke test ${{ matrix.asset }} + needs: build + strategy: + fail-fast: false + matrix: + include: + - asset: workos-darwin-arm64 + runner: macos-15 + - asset: workos-darwin-x64 + runner: macos-15-intel + - asset: workos-linux-x64 + runner: ubuntu-24.04 + - asset: workos-linux-arm64 + runner: ubuntu-24.04-arm + - asset: workos-windows-x64.exe + runner: windows-latest + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 8.0.1 + with: + name: ${{ matrix.asset }} + + # Diagnostics only — the hard gate is executing the binary below. Bun + # ad-hoc signs cross-compiled Mach-O binaries; a regression there (see + # oven-sh/bun#29120) makes the exec step SIGKILL on Apple Silicon. + - name: Inspect macOS code signature + if: startsWith(matrix.runner, 'macos') + run: codesign -dvvv "./${{ matrix.asset }}" || true + + # `internal verify-assets` extracts the embedded skills from the binary + # and performs the first-run download of the pinned Agent SDK executable + # (checksum-verified) and spawns it — proof this exact artifact works on + # real hardware for its platform. + - name: Run the binary + shell: bash + run: | + case "${{ matrix.asset }}" in + *.exe) ;; + *) chmod +x "./${{ matrix.asset }}" ;; + esac + "./${{ matrix.asset }}" --version + "./${{ matrix.asset }}" --help >/dev/null + "./${{ matrix.asset }}" internal verify-assets --json + publish: - name: Publish to npm + name: Publish release + needs: [build, smoke] + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 8.0.1 + with: + path: dist + merge-multiple: true + + # Assets attach to the draft first, so tag + release + assets go live + # atomically when the draft flips to published. `releases/latest` (and + # the CLI's update check) never advances early or to a partial release. + - name: Upload assets and publish the draft release + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + TAG_NAME: ${{ inputs.tag_name }} + run: | + test -n "$TAG_NAME" + gh release upload "$TAG_NAME" dist/* --clobber + gh release edit "$TAG_NAME" --draft=false + + # npm is a secondary channel: a thin `workos` launcher plus one + # @workos/cli-- package per binary (esbuild/swc/clerk + # pattern), preserving `npm install -g workos` / `npx workos`. Runs after + # the GitHub release publishes so npm never leads the primary channel; if + # it fails, re-run just this job. Auth is npm trusted publishing (OIDC) — + # same as the pre-binary release flow. + publish-npm: + name: Publish npm packages + needs: [smoke, publish] runs-on: ubuntu-latest permissions: contents: read id-token: write steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 7.0.0 + with: + ref: ${{ inputs.tag_name }} - - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # 6.0.9 + - uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # 2.0.2 + with: + bun-version: 1.3.14 - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # 6.4.0 with: node-version: 24 registry-url: 'https://registry.npmjs.org' - cache: pnpm - - name: Install - run: pnpm install + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 8.0.1 + with: + path: dist + merge-multiple: true - - name: Build - run: pnpm build + - name: Generate npm packages + env: + TAG_NAME: ${{ inputs.tag_name }} + run: WORKOS_NPM_VERSION="${TAG_NAME#v}" bun run ./scripts/gen-npm-packages.ts - name: Determine npm tag id: npm-tag @@ -38,19 +187,19 @@ jobs: TAG_NAME: ${{ inputs.tag_name }} run: | VERSION="${TAG_NAME#v}" - - if [[ -z "$VERSION" ]]; then - VERSION="$(node -p "require('./package.json').version")" - fi - if [[ "$VERSION" == *"-"* ]]; then echo "tag=beta" >> "$GITHUB_OUTPUT" else echo "tag=latest" >> "$GITHUB_OUTPUT" fi + # Platform packages publish before the launcher so the launcher's + # optionalDependencies are always resolvable once it is visible. - name: Publish run: | sed -i '/_authToken/d' "$NPM_CONFIG_USERCONFIG" unset NODE_AUTH_TOKEN - pnpm publish --tag ${{ steps.npm-tag.outputs.tag }} --access public --no-git-checks --provenance + for dir in dist/npm/@workos/cli-*; do + (cd "$dir" && npm publish --access public --provenance --tag ${{ steps.npm-tag.outputs.tag }}) + done + cd dist/npm/workos && npm publish --access public --provenance --tag ${{ steps.npm-tag.outputs.tag }} diff --git a/.gitignore b/.gitignore index c9639c7b..725c1b92 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ pnpm-debug.log dist/ coverage/ +.*.bun-build # .NET build output bin/ @@ -21,6 +22,8 @@ obj/ # Generated src/version.ts +src/generated/skills-manifest.ts +src/generated/agent-sdk-manifest.ts .eslintcache .vscode/launch.json diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 9ab60a11..00000000 --- a/.npmignore +++ /dev/null @@ -1,11 +0,0 @@ -assets -examples -docs -.idea -.vscode -.travis -.github -.craft.yml -.prettierrc -.eslintrc.js -tsconfig* diff --git a/.oxfmtrc.json b/.oxfmtrc.json index e0ae6d81..4216d142 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -6,5 +6,5 @@ "singleQuote": true, "printWidth": 120, "sortPackageJson": false, - "ignorePatterns": ["dist/", "node_modules/", "pnpm-lock.yaml", "CHANGELOG.md"] + "ignorePatterns": ["dist/", "node_modules/", "bun.lock", "CHANGELOG.md", ".claude/settings.local.json"] } diff --git a/CLAUDE.md b/CLAUDE.md index c3c5a033..ea143002 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,8 +19,8 @@ WorkOS CLI for installing AuthKit integrations and managing WorkOS resources (or ## Tech Constraints -- **pnpm** only -- Avoid Node-specific sync APIs (crypto, fs sync) unless necessary +- **Bun** only; the shipped CLI is a Bun-compiled standalone binary +- Runtime assets must be statically imported or materialized from the compiled binary. Exception: the Agent SDK `claude` executable is downloaded on first agent use — pinned by version + sha256 in the generated manifest — and cached under `~/.workos/cache/agent-sdk/` ## Commit Conventions @@ -29,18 +29,17 @@ WorkOS CLI for installing AuthKit integrations and managing WorkOS resources (or ## Commands ```bash -pnpm build # Build the project -pnpm dev # Dev mode (build + watch + link) -pnpm test # Run tests -pnpm typecheck # Type check +bun run build # Build the standalone binary +bun run dev # Run source in watch mode +bun run test # Run tests +bun run typecheck # Type check ``` ## Adding a New Framework -1. Create `src/{framework}/{framework}-installer-agent.ts` -2. Add to `Integration` enum in `lib/constants.ts` -3. Add detection logic in `lib/config.ts` -4. Wire up in `run.ts` switch statement +1. Create `src/integrations/{framework}/index.ts` exporting `config` and `run` +2. Run `bun run generate` to refresh `src/integrations/_manifest.ts` +3. Add or update detection and validation tests for the integration ## Adding a New Resource Command @@ -94,14 +93,14 @@ All commands automatically emit a `command` telemetry event with name, duration, **Don't:** - Use Node-specific sync APIs (crypto, fs sync) unless necessary -- Use npm or yarn -- pnpm only +- Add runtime filesystem discovery or import.meta.url-relative package asset reads - Skip JSON mode tests in spec files - Forget to wire up new frameworks in `src/run.ts` switch statement ## PR Checklist -- [ ] `pnpm build` passes -- [ ] `pnpm test` passes -- [ ] `pnpm typecheck` passes +- [ ] `bun run build` passes +- [ ] `bun run test` passes +- [ ] `bun run typecheck` passes - [ ] Conventional Commit message format used (`feat:`, `fix:`, `feat!:` for breaking) - [ ] New commands include JSON mode support and tests diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index bee7f991..bed04c51 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -47,17 +47,17 @@ src/ ```bash # Install dependencies -pnpm install +bun install # Build -pnpm build +bun run build ``` ## Development Workflow ```bash -# Build, link globally, and watch for changes -pnpm dev +# Run the TypeScript source in watch mode +bun run dev # Test installer in another project cd /path/to/test/nextjs-app @@ -73,20 +73,20 @@ workos user list ```bash # Build -pnpm build +bun run build # Clean and rebuild -pnpm clean && pnpm build +bun run clean && bun run build # Format code -pnpm format +bun run format # Check types -pnpm typecheck +bun run typecheck # Run tests -pnpm test -pnpm test:watch +bun run test +bun run test:watch ``` ## TypeScript Configuration @@ -127,14 +127,26 @@ The full backwards-compat matrix lives in `src/utils/mode-compatibility.spec.ts` ### Adding a New Framework -1. Create `src/your-framework/your-framework-installer-agent.ts` -2. Define `FrameworkConfig` with metadata, detection, environment, UI -3. Export `runYourFrameworkInstallerAgent(options)` function -4. Add to `Integration` enum in `lib/constants.ts` -5. Add detection logic to `lib/config.ts` -6. Wire up in `run.ts` +1. Create `src/integrations/your-framework/index.ts` +2. Export a `FrameworkConfig` as `config` and an installer function as `run` +3. Run `bun run generate` to refresh the static integration manifest +4. Add detection and validation coverage -See `nextjs/nextjs-installer-agent.ts` as reference. +See `src/integrations/nextjs/index.ts` as a reference. + +### Generated Manifests + +`bun run generate` produces **three** manifests (it runs automatically before +`build`, `test`, and `typecheck`, and after `bun install`): + +- `src/integrations/_manifest.ts` — static imports for every integration (committed; CI fails if it drifts from the directory listing) +- `src/generated/skills-manifest.ts` — embeds every file of the `@workos/skills` plugin tree into the binary (gitignored: contains absolute paths) +- `src/generated/agent-sdk-manifest.ts` — pins the target platform's native Claude Agent SDK `claude` executable: version, npm tarball URL, and sha256 (gitignored: target-specific). The executable is **not** embedded; a compiled binary downloads it on first agent use, verifies the checksum, and caches it under `~/.workos/cache/agent-sdk/` + +Set `WORKOS_BUILD_TARGET` (e.g. `bun-linux-x64-baseline`) to generate/build +for a non-host platform; the same value must be used for both `generate` and +the compile, which `bun run build` (via `scripts/build.ts` + the `prebuild` +hook) guarantees. ### Updating Integration Instructions @@ -181,11 +193,11 @@ export function redactCredentials(obj: any): any { Automated eval framework for testing installer skills across frameworks and project states. ```bash -pnpm eval # Run all scenarios -pnpm eval --framework=nextjs # Single framework -pnpm eval --quality # Include LLM quality grading -pnpm eval:history # List recent runs -pnpm eval:diff # Compare runs +bun run eval # Run all scenarios +bun run eval --framework=nextjs # Single framework +bun run eval --quality # Include LLM quality grading +bun run eval:history # List recent runs +bun run eval:diff # Compare runs ``` See [tests/evals/README.md](./tests/evals/README.md) for full documentation. @@ -204,6 +216,41 @@ workos --debug tail -f ~/.workos/logs/workos-{timestamp}.log ``` +## Releasing + +Releases are fully automated via release-please + GitHub Releases (there is no +npm publish; users download platform binaries): + +1. Merging to `main` updates the release-please PR; merging that PR creates a + **draft** GitHub release and pushes its tag immediately + (`force-tag-creation`). +2. `release.yml` cross-compiles all five platform binaries, smoke tests each + one **on native hardware** for its platform (including + `workos internal verify-assets`, which checks the keyring native binding + loaded, downloads the pinned Agent SDK executable, verifies its checksum, + and spawns it), attaches them to the draft, and only then publishes it. + `releases/latest` never points at a partial or untested release. +3. After the GitHub release publishes, `publish-npm` regenerates the npm + distribution (`scripts/gen-npm-packages.ts`): a thin `workos` launcher + package plus one `@workos/cli--` package per binary, + published via npm trusted publishing (OIDC). npm is a secondary channel — + it never leads GitHub Releases, and a failed npm publish is re-runnable in + isolation. + +Operational notes: + +- **A leg failed:** the release stays an invisible draft and the previous + release remains `latest`. Fix the problem, then either "Re-run failed jobs" + on the same run or trigger `release.yml` manually via `workflow_dispatch` + with the tag name. +- **Abandoning a draft:** delete BOTH the draft release and its tag, or + release-please will treat that version as shipped. +- **Bumping the pinned Bun version** (`ci.yml`, `release.yml`, + `packageManager`) is a smoke-gated event: Bun has shipped releases that + broke cross-compiled macOS code signatures (oven-sh/bun#29120 — binaries + SIGKILL on Apple Silicon). The native macOS smoke leg is the regression + gate; never bypass it. + ## Questions? See [README](./README.md) for user-facing docs. diff --git a/README.md b/README.md index e51003af..e5cf9b3f 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,41 @@ WorkOS CLI for installing AuthKit integrations and managing WorkOS resources. ## Installation +The CLI is distributed as a standalone executable from GitHub Releases. It does not require Node.js, Bun, or an npm installation. The first agent-driven command (e.g. `workos install`) performs a one-time, checksum-verified download of the Claude agent runtime (~230 MB, cached under `~/.workos`). + +macOS and Linux: + ```bash -# Run the installer directly with npx (recommended) -npx workos@latest install +case "$(uname -m)" in + arm64|aarch64) arch=arm64 ;; + x86_64) arch=x64 ;; + *) echo "Unsupported architecture: $(uname -m)"; exit 1 ;; +esac +case "$(uname -s)" in + Darwin) os=darwin ;; + Linux) os=linux ;; + *) echo "Unsupported operating system: $(uname -s)"; exit 1 ;; +esac +curl -fL "https://github.com/workos/cli/releases/latest/download/workos-${os}-${arch}" -o workos +chmod +x workos +sudo mv workos /usr/local/bin/workos +``` -# Or install globally -npm install -g workos -workos install +Windows (x64 PowerShell): + +```powershell +Invoke-WebRequest https://github.com/workos/cli/releases/latest/download/workos-windows-x64.exe -OutFile workos.exe ``` -`npx workos@latest install` is recommended because it bypasses stale global shims and older shell-resolved binaries. -If a global install reports `unknown command "install"`, run the npx command above or reinstall globally and clear your -shell command cache. +Move `workos.exe` to a directory on your `PATH`, then run `workos install`. + +npm (thin launcher that installs the same prebuilt binary for your platform): + +```bash +npm install -g workos +# or run without installing: +npx workos@latest install +``` ## Features @@ -104,7 +127,7 @@ When you run `workos install` without credentials, the CLI automatically provisi ```bash # Install with zero setup — environment provisioned automatically -npx workos@latest install +workos install # Check your environment workos env list @@ -456,13 +479,13 @@ workos install [options] ```bash # Interactive (recommended) -npx workos@latest install +workos install # Greenfield: scaffold a new Next.js app + AuthKit in an empty directory -mkdir my-app && cd my-app && npx workos@latest install +mkdir my-app && cd my-app && workos install # With visual dashboard (experimental) -npx workos@latest dashboard +workos dashboard # JSON output (explicit) workos org list --json --api-key sk_test_xxx @@ -579,13 +602,13 @@ The CLI uses WorkOS Connect OAuth device flow for authentication: ```bash # Login (opens browser for authentication) -npx workos@latest auth login +workos auth login # Check current auth status -npx workos@latest auth status +workos auth status # Logout (clears stored credentials) -npx workos@latest auth logout +workos auth logout ``` OAuth credentials are stored in the system keychain (with `~/.workos/credentials.json` fallback). Access tokens are not persisted long-term for security - users re-authenticate when tokens expire. @@ -634,14 +657,14 @@ See [DEVELOPMENT.md](./DEVELOPMENT.md) for development setup. Build: ```bash -pnpm build +bun run build ``` Run locally: ```bash -pnpm dev # Watch mode -./dist/bin.js --help +bun run dev # Watch mode +./dist/workos --help ``` ## License diff --git a/bun.lock b/bun.lock new file mode 100644 index 00000000..bd382c56 --- /dev/null +++ b/bun.lock @@ -0,0 +1,1072 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "workos", + "dependencies": { + "@anthropic-ai/claude-agent-sdk": "~0.3.0", + "@anthropic-ai/sdk": "^0.106.0", + "@clack/core": "^1.0.1", + "@clack/prompts": "1.6.0", + "@napi-rs/keyring": "^1.2.0", + "@workos-inc/node": "^8.7.0", + "@workos/emulate": "^0.1.0", + "@workos/migrations": "^2.4.0", + "@workos/openapi-spec": "^0.14.0", + "@workos/skills": "0.6.1", + "chalk": "^5.6.2", + "diff": "^8.0.3", + "fast-glob": "^3.3.3", + "ink": "^6.8.0", + "jsonc-parser": "^3.3.1", + "open": "^11.0.0", + "react": "^19.2.4", + "semver": "^7.7.4", + "uuid": "^13.0.0", + "xstate": "^5.28.0", + "yaml": "^2.8.2", + "yargs": "^18.0.0", + "zod": "^4.3.6", + }, + "devDependencies": { + "@statelyai/inspect": "^0.7.0", + "@types/node": "~22.20.0", + "@types/opn": "5.5.0", + "@types/react": "^19.2.14", + "@types/semver": "^7.7.1", + "@types/yargs": "^17.0.35", + "@vitest/coverage-v8": "^4.0.18", + "@vitest/ui": "^4.0.18", + "dotenv": "^17.3.1", + "oxfmt": "^0.56.0", + "oxlint": "^1.50.0", + "p-limit": "^7.3.0", + "react-devtools-core": "^7.0.1", + "typescript": "^5.9.3", + "vitest": "^4.0.18", + }, + }, + }, + "packages": { + "@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="], + + "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.211", "", { "optionalDependencies": { "@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.211", "@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.211", "@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.211", "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.211", "@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.211", "@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.211", "@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.211", "@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.211" }, "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-JhbLu6o1v2g9fjqkO+LDNPWrE0bgd9UeRQQ41JBGouAgows3KyPPYgU2WU0q7M2onuwQxR5plGDpas01F+oaUA=="], + + "@anthropic-ai/claude-agent-sdk-darwin-arm64": ["@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.211", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Iwhm4kfcs20LdXffZ2RGRjj+BFdUOrT/JjhGtICjlGlBPlrLkkkAiHtGzqO9K36v5B/kSIHwOw9CM836kYYPHQ=="], + + "@anthropic-ai/claude-agent-sdk-darwin-x64": ["@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.211", "", { "os": "darwin", "cpu": "x64" }, "sha512-sMBW1CLe2Hq4PwwvEbz9r8LxF84UErgB45TSf+iEa8M/EjYZCsXSoTRT0vKnN4TvrAN5mWoKgi39dkUxS9ybsA=="], + + "@anthropic-ai/claude-agent-sdk-linux-arm64": ["@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.211", "", { "os": "linux", "cpu": "arm64" }, "sha512-orZm8p+BzVRZ7I8c5yD43hEZ5TvBZ+UbKTZTlvID00Y8HSn3M3rNX3sW4RUvNGF2e0eNMaXKysPyEHPEj3kqpg=="], + + "@anthropic-ai/claude-agent-sdk-linux-arm64-musl": ["@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.211", "", { "os": "linux", "cpu": "arm64" }, "sha512-X1eg+lCwNH2VXyqLQR722dsDDtWPfUnz7OtnmPVoNMxcMexDlSLMMuvm5fNNi94kYT0pxmBdhIvudew145JuHg=="], + + "@anthropic-ai/claude-agent-sdk-linux-x64": ["@anthropic-ai/claude-agent-sdk-linux-x64@0.3.211", "", { "os": "linux", "cpu": "x64" }, "sha512-ohDS5EGKQvKiUUMtDNPjyWUDvaeIa+DlzUVjrZ8Y4hPtoWFpvOBtOFIYChJGpllwZ4YULS4H3gywVnLGB4do6Q=="], + + "@anthropic-ai/claude-agent-sdk-linux-x64-musl": ["@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.211", "", { "os": "linux", "cpu": "x64" }, "sha512-cR12YFMVGSj38074OYkkjgwhYeblgVRK3Uw7ZXw3ZTOevjQLASPajVruFuDRW07ixxTa1ZWxqI3kSsIl71RXYA=="], + + "@anthropic-ai/claude-agent-sdk-win32-arm64": ["@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.211", "", { "os": "win32", "cpu": "arm64" }, "sha512-AOIQRFO0YMDUCrG8W0NUWitBQQUB6fYdNW3SMcPPq3mXpYC/pCNURFyvRdrFm729xXkxDAP5OMLk9x2/IFrTmA=="], + + "@anthropic-ai/claude-agent-sdk-win32-x64": ["@anthropic-ai/claude-agent-sdk-win32-x64@0.3.211", "", { "os": "win32", "cpu": "x64" }, "sha512-pwzNuJg2xRBsv3kSSVVhgLdGAFxd5DqPkQX5ZLrT4uBZDJ+QM4xWKZyN8ZoFLLzNl+u0/4U83Q1ZQ0NdG/9JsQ=="], + + "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.106.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1", "standardwebhooks": "^1.0.0" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-ufwVvYNDBj2dzOGupBCTaNzBLxqcTnGOzI4z8Wouxlt+mT3J3HuOmatgCy1VmwCHOUueqZ41ERhm0O99OUcbWA=="], + + "@aws-sdk/client-cognito-identity-provider": ["@aws-sdk/client-cognito-identity-provider@3.1088.0", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/credential-provider-node": "^3.972.69", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/fetch-http-handler": "^5.6.6", "@smithy/node-http-handler": "^4.9.6", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-As1abE8taiU6BsN/xDJYmSnWRuCudo3FztQKSZbDzmA2sWD/t2kb84pl4lwKF+JZbeA8g46sXC1albpAIXpJpw=="], + + "@aws-sdk/core": ["@aws-sdk/core@3.975.3", "", { "dependencies": { "@aws-sdk/types": "^3.974.2", "@aws-sdk/xml-builder": "^3.972.36", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.29.4", "@smithy/signature-v4": "^5.6.5", "@smithy/types": "^4.16.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-7ur3kCKuvPLqlsZ2XlvnNBVQ7KkpSu6Y6dOTwSPHLrFpTEfZM8isLBJc4cgv96WB7GifeVM436mpycwxBd2vEA=="], + + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.59", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-Ny5e4Mfh3QPmiAc0AiUe+cbTXDlxkU3Rc+EpWOfyWeWEy6yp7Fa1KmfNeCc+1a8by9zQ9gtohmiQUkMPScF3ng=="], + + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.61", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/fetch-http-handler": "^5.6.6", "@smithy/node-http-handler": "^4.9.6", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-8jAjgStl5Ytq4+HF3X/9f+EmRinaRbGRRtQGktlPfBRVx73H+R1y48vIeXerQtYGFaUqkEp3fT6jP854rVO2yQ=="], + + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.3", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/credential-provider-env": "^3.972.59", "@aws-sdk/credential-provider-http": "^3.972.61", "@aws-sdk/credential-provider-login": "^3.972.65", "@aws-sdk/credential-provider-process": "^3.972.59", "@aws-sdk/credential-provider-sso": "^3.973.3", "@aws-sdk/credential-provider-web-identity": "^3.972.65", "@aws-sdk/nested-clients": "^3.997.33", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/credential-provider-imds": "^4.4.9", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-WpuqYX4gGkx++fCTSWE8+41JzkZVcrI50SH48Ml4CsG1pyuHKyMmpw/FixBHDrmjoQ553PmeCLa/fZIcst+WyA=="], + + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.65", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/nested-clients": "^3.997.33", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-xr9rgjYEdmC2Tpg2lwt9o+nOEaK9Qpd+dBjzrVCuWWyQfvhO91Ezu0Hh9ts2VUxOZxmS/k5T9msa34e4R1bnrQ=="], + + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.69", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.59", "@aws-sdk/credential-provider-http": "^3.972.61", "@aws-sdk/credential-provider-ini": "^3.973.3", "@aws-sdk/credential-provider-process": "^3.972.59", "@aws-sdk/credential-provider-sso": "^3.973.3", "@aws-sdk/credential-provider-web-identity": "^3.972.65", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/credential-provider-imds": "^4.4.9", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-wbJGGesd0Tl18bmUcbj1xJ+e7CpuRJ6PIpMywLFuUttGy615lua87cJ0EA8pFpY/QgPuUXbnupWBtSPJ9tyZhg=="], + + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.59", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-DlZF2/MhLlatDdlrIy3CUCpfdbLrKx+3SMjVo+WyHnPpwzkc/M3vwAHw4OVJf7DMvO+4vfRqSCMc/E9I1auN0g=="], + + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.3", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/nested-clients": "^3.997.33", "@aws-sdk/token-providers": "3.1088.0", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-hmdDHoy2G5Es2e8IgelNMYUuSQI6uCIAKZMJ2u2PdKDhxvbk1uWD/g4+R7R5c/tJfKEB1+KjjWiaoCr/S+ZTiQ=="], + + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.65", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/nested-clients": "^3.997.33", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-gHQb/Kt0chjk/JQDa/GJDqmAvEuVn8n7z10wK2h0LFM9TUDRkohgOO4aEF+s2sBLM0br7Cl5W6P7phgjrrJvLQ=="], + + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.33", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/signature-v4-multi-region": "^3.996.41", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/fetch-http-handler": "^5.6.6", "@smithy/node-http-handler": "^4.9.6", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-dVZOroI/r3/ENvqNGgjMPul+jjlz9GddfVusgTXlVjfZj5isibOxecLkGQbRPp8XOuX+RAfjXLFgPkD1JS5xrw=="], + + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.41", "", { "dependencies": { "@aws-sdk/types": "^3.974.2", "@smithy/signature-v4": "^5.6.5", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-QMUytg+FQMGouc8gHS00KoYih3+N6cqmVI/pQGOIo7Nr7OpQaiXjSYOuL+vsPZ1tymY4LAQ8MYcHJmws5LRxng=="], + + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1088.0", "", { "dependencies": { "@aws-sdk/core": "^3.975.3", "@aws-sdk/nested-clients": "^3.997.33", "@aws-sdk/types": "^3.974.2", "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-4ObatWt2qpJg5FBk4LOOKrTQYzaqeewAtdO3r9ZO8lH9YqLtpTzLyIdy0mJ+nVdfYOnqISkKNfmzP22bNDhwyw=="], + + "@aws-sdk/types": ["@aws-sdk/types@3.974.2", "", { "dependencies": { "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA=="], + + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.36", "", { "dependencies": { "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-RdGmS1GLrtaTOLE1ElSluMldNrpk9Emq6uYs8SS8iHlu5xTAmM9rRkM91o48+rIRryBtyO9t+uLYCoMG6jVMVA=="], + + "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.3.0", "", {}, "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], + + "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="], + + "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], + + "@bcoe/v8-coverage": ["@bcoe/v8-coverage@1.0.2", "", {}, "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA=="], + + "@clack/core": ["@clack/core@1.4.3", "", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ=="], + + "@clack/prompts": ["@clack/prompts@1.6.0", "", { "dependencies": { "@clack/core": "1.4.2", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-EYlRokl8szrP9Z25qT5aepMdBjzBvHF9ZEhzIiUBc9guz/T31EqRgvD0QSgZcpE93xiwrr+OkB4nz0BZyF6fSA=="], + + "@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], + + "@hono/node-server": ["@hono/node-server@1.19.14", "", { "peerDependencies": { "hono": "^4" } }, "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.29.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ=="], + + "@napi-rs/keyring": ["@napi-rs/keyring@1.3.0", "", { "optionalDependencies": { "@napi-rs/keyring-darwin-arm64": "1.3.0", "@napi-rs/keyring-darwin-x64": "1.3.0", "@napi-rs/keyring-freebsd-x64": "1.3.0", "@napi-rs/keyring-linux-arm-gnueabihf": "1.3.0", "@napi-rs/keyring-linux-arm64-gnu": "1.3.0", "@napi-rs/keyring-linux-arm64-musl": "1.3.0", "@napi-rs/keyring-linux-riscv64-gnu": "1.3.0", "@napi-rs/keyring-linux-x64-gnu": "1.3.0", "@napi-rs/keyring-linux-x64-musl": "1.3.0", "@napi-rs/keyring-win32-arm64-msvc": "1.3.0", "@napi-rs/keyring-win32-ia32-msvc": "1.3.0", "@napi-rs/keyring-win32-x64-msvc": "1.3.0" } }, "sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA=="], + + "@napi-rs/keyring-darwin-arm64": ["@napi-rs/keyring-darwin-arm64@1.3.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-pl76hJvdYUBn6I24bXiOBMA9nbDapo3I5B+f3OorjDU4dUMSypXeKbOVehJe8fhgTiH24flMyTS3aAIy43xegQ=="], + + "@napi-rs/keyring-darwin-x64": ["@napi-rs/keyring-darwin-x64@1.3.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-YcJtEV5LA3cvA4z3BurgxH5IhTsW1JfIvcAAcqcecwk06Si9F9NqkxbZVIfDwQ8oRHgaBmT3zZJnLAotCrVahw=="], + + "@napi-rs/keyring-freebsd-x64": ["@napi-rs/keyring-freebsd-x64@1.3.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-vlLf31TGhfRAaxLDBhg8b89ss0HHD/lyNmL5F3UjSaz5CUXElsJmKYq9fqA/B+cZKUEUcLHHGhF0I/CqcFdaVw=="], + + "@napi-rs/keyring-linux-arm-gnueabihf": ["@napi-rs/keyring-linux-arm-gnueabihf@1.3.0", "", { "os": "linux", "cpu": "arm" }, "sha512-KiWdMMu/Inz/bHHIAGrnF7r54FZDYXuHO6UFF/rhIrshUsxbMG1Rl9lEymNtqqsVo927G0VYcb02FzWQ3iBQRQ=="], + + "@napi-rs/keyring-linux-arm64-gnu": ["@napi-rs/keyring-linux-arm64-gnu@1.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-eyKGpY40lm9Jvs1aD294XRH4y7+TlJM0YVAryZeXA6TX0mb4gMkxVXwSQv7MCwgah7raeUd0dKUb4BPAYIgcMg=="], + + "@napi-rs/keyring-linux-arm64-musl": ["@napi-rs/keyring-linux-arm64-musl@1.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-iIK6JWHXAJqDrEyLY3TmswwloVyt2vj+04TZnew+uSJ9gnDO8EwRbp3/iw3LpWaXiDO7VomGO6y8I0Id8uBZSw=="], + + "@napi-rs/keyring-linux-riscv64-gnu": ["@napi-rs/keyring-linux-riscv64-gnu@1.3.0", "", { "os": "linux", "cpu": "none" }, "sha512-/PGqrwn6EwgtK6vccASSXJRfOSP4vN1F4ASsIQ+7MdrK6hNvAJ1FZPrIuD5gGGdxezo3F++To2Wq7DbuGIeuNQ=="], + + "@napi-rs/keyring-linux-x64-gnu": ["@napi-rs/keyring-linux-x64-gnu@1.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2PDK1WKWTu9lBGq9VvNEkSlQD3O7YwVpmnyN2M3cy4v7NJ/8gDMd9GXv3G+FVXN13uhp4gnnPBS+ScefmEeD2A=="], + + "@napi-rs/keyring-linux-x64-musl": ["@napi-rs/keyring-linux-x64-musl@1.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-oJ2HkX8YUo46QBkn0pG+HuIKQNqr523q6vBobCn+P95s4C4K6/kLBqHY/1bg5J4ap31DzsznhnFKcfBNBsjCnw=="], + + "@napi-rs/keyring-win32-arm64-msvc": ["@napi-rs/keyring-win32-arm64-msvc@1.3.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-tOd3c/uAaeoE4ycVlmAdSvygz0Zt3zdca6Y7gokBeIbaRDWpjDIUOpU3MvML59XAaqyuKGsVVu0F/DZb1lHPmw=="], + + "@napi-rs/keyring-win32-ia32-msvc": ["@napi-rs/keyring-win32-ia32-msvc@1.3.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-sPSqeAFZMGqP1R++M2JTza7GQJJ/TpCo6JU6Vcd4jnebvOaEDs9b7eipakU1PJdSvhpC2yXMCNRk9gXfrhuwHQ=="], + + "@napi-rs/keyring-win32-x64-msvc": ["@napi-rs/keyring-win32-x64-msvc@1.3.0", "", { "os": "win32", "cpu": "x64" }, "sha512-4DnCWXwDc0HRKwyRlG5y0VhKZW2tNRQfKKfyj6IX/KWfDNyq9hn4n+GL1auyDcOO/v8PwnhmYo2+rOOqCkvvOg=="], + + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], + + "@nodable/entities": ["@nodable/entities@2.2.0", "", {}, "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg=="], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@oxc-project/types": ["@oxc-project/types@0.139.0", "", {}, "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw=="], + + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.56.0", "", { "os": "android", "cpu": "arm" }, "sha512-CSCxi7ovYojgfdPOdUb9T508HKeAdDIKeRGg7x8IZwVJrWz9gVgX7MbUnFqtQAE4QvoNo07mj2JlwnOzJw4qqA=="], + + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.56.0", "", { "os": "android", "cpu": "arm64" }, "sha512-HYJFnd+PkDwf6S9ZPGzXXtjNqvRWFnnhdbWaouh4mi/SxU8wmDuzlMn3xo/wDTGnr4Q1VA7ZzOaE/D4biW0W6A=="], + + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.56.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-sftR/bEOr+t1gs+evwsHi/Xbq2FAPA2uU3VMr8n6ZU9PoK/IMSfnfu7+OEe/uy1+knhrFl4Wvy7Vkm3uo9mJ7g=="], + + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.56.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-z66SdjLqa3MUPKvTp3Mbb5nSjKSbnYxJGeB+Wx987s8T5hPcIRiBMfnJ6zcPgYtQn3x5xjvdzNVkXrSeYH6ZFg=="], + + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.56.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-t2tkrV1vtZyaItSQ71dTi2ZVKZEI39b/LqLT12V5KMfIeXK6N32TUC1jhOXKVQmhECq9j2ZXMQV3JeT1kh9Vmg=="], + + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-+gCy+Tp3RHeXQ9y/QrS76lXIpZkbziTyp6hIgjB2MssCwfMph3vG/GEfkhO34Rai1vhYIaUkvv8UT1BcDorJPw=="], + + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-0kKkVvQ2I+FJ2sxQyUu1zJ0yWP5kcWse/yVFnGQSFCXMwSSkfEaUGu0dW774O7nyy3jrcBGap7OSc8dZmU/CdA=="], + + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-npkA2siMbyWRh+wEhi1aTAx4RirukGcGNt8V4Ch86pG+xU9aurqS1MZOnKYMu03ISwat3rB6zkQx51SsB9obNw=="], + + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UekqOjGkV4/MkqreCV9SPIB2jlR3/HbXrmhV1rVXJZ9wfDXMyCMriLtq3tHqLY4PkbVWNtfcm1kMojJ26KLSJw=="], + + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.56.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-XSzveSpeZMD5XJpew5lRFVtNnT04xd3rJxENXmk7wkZzN9oWzv2aFJyoNDhOtoz69BYaS/fg4SYl+CfEZRpB0Q=="], + + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-EkQ0nJa7k7HDDIVuPF7WY+k4k+bzdclLYtyIXNt7/OqVghfNiMym6YGppFBgx1XRIHW6QylxBz5OogumPjPJbQ=="], + + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-dyjAGW8jKRge0ik6U/dgvQG0nVpA3iBlRskQTz5qJLvQWIrySxX5jpqzPetLBNIIZ231KA82fDdi1nLTk8ENCw=="], + + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.56.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-60ZGH3LtfqlW8X6vcLdSFY4lvCQYINurttYBKaALnHCDVAUCYJ1LsUgS6p1XOzVlzEDx3yNUZvDF1Lvt59zoZw=="], + + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-u1suj1tgJHK4ZqB7buCtdbNef2n8+d0lXTPJwLHNmtyK6p+DTpsaoDvmqhQrA56fgKYv4LuRxNtL8YooebKOew=="], + + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-aYGLvlQHt80y+qKEtfJY/Nm27G0125Lv+qyh9SJ4Cjc6lXnXjD+ndfhqQnbV24POpMi7rNRi0jvx/0d70FRpCQ=="], + + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.56.0", "", { "os": "none", "cpu": "arm64" }, "sha512-H/re/gO+7ysVc+kywHNuzY3C33EN9sQcZhg0kp1ZwOZl7y998ZE5mhnBiuGR/nYI0pqLL5xQfrHVUOJ/cIJsCA=="], + + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.56.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-6qLNXfXmtAs8jXDvYMkxk6Wec5SUJoew+ZX1uOZmqaR7ks0EJFbAohuOCELDyJMWyVlxotVG8Xf8m74Bfq0O2w=="], + + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.56.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UXEXuKphAe15bsob4AswNMArCw38XSmUIs3wk1s6e6MX9OWGW/IRWU95s1hZDiVg09STy1jHgyN2qkqbu1FT0w=="], + + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.56.0", "", { "os": "win32", "cpu": "x64" }, "sha512-HPyNDjky+NIOuaMvHZflR+kst3YWdUOH2JUQYkf99grqZ5mEBTQM6h9iGy501Z8Xt5xMScrwHOuVCOlqDrktRw=="], + + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.74.0", "", { "os": "android", "cpu": "arm" }, "sha512-+gHd12muVI9ZLBaWLPkHt3Fj7jihFjgQ1MGtBaRL8vWrWrI0P7dLUty/cHrHS0oqPYIRgQUJsPu2CExQuMcwNw=="], + + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.74.0", "", { "os": "android", "cpu": "arm64" }, "sha512-xjKdoMB+H+RCOByv/7l7nfIGW9mlOisqYdcyC75UqYuQecLpReAeEYUf2CNeDEI3KtmUgxpRw/+c63y4AeF/Bw=="], + + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.74.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iUK7wvc6sejMKsC+Pt67mntoF5weFcyEunhZfLJceU6gL419mexz5wBkSx/EnkFBExMLNtOi9fnDSc5xfK0IzQ=="], + + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.74.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ggKc/tn5SJ1u2yG2izC6VKODfYKV8MQ2AicJlNzOjuyrC29udvOef6/JzK2r32xqCnBDLFouR1VCkjzEI0/N9Q=="], + + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.74.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-u++dH/43jy9hTLbneaWlS0gla/Bp1JdwJ2zgevCl8nDFUh6qRCGMxcL0f0lb7By3A9p/LfFr+7cG4HU1hG856g=="], + + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.74.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Sj1zmtFDVTPeIbIz4ZfcXAbFHqCmKCXdCUlAJzvTF7I20NTH1RDpoF2PhkqNODutJzVhJYmm3oz0GwgY+tvE2g=="], + + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.74.0", "", { "os": "linux", "cpu": "arm" }, "sha512-//PKyQb/tQXcHArx2f7z+oVI/eMS2Jpv+edNuAtOrgIhWdGcpHxogveAxzmF2rpH1AIHp4Hq04RF/rgJdiICnQ=="], + + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.74.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-/k1Me+aX2tjuH10K62mLS0y8cLkJBHX6Ce0xPK+eWeel4bSdEGZ8dv4+hYMzg0GrSmjwy4yAYsDPeEeKBft/2w=="], + + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.74.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-3tFSjBxc5D8/zvjEuLvOqcA8ZXKD0+6NuaVO/edeamNc49MoAsbfaC9s1UiwODwgF6slGaF8yJA2TPkukd77tg=="], + + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.74.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9QggtPkSPXOCTu8Szis7auOK/sC7KdQaN+/TujP7YVVhzCAOhgdRfgv8uEz0r2tk5xdgus5rLYUrCDoZNtiRUw=="], + + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.74.0", "", { "os": "linux", "cpu": "none" }, "sha512-VM5VPUJ4DJIWiK+AZn8FScUqMr6OFrCAYybMYjEEi7W13ParI64MByiXTkKMqZpBmvQ9zxl9Ebq2VUOiZRJYUg=="], + + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.74.0", "", { "os": "linux", "cpu": "none" }, "sha512-SaDY1gh9rOA592J54g+gu5hkOFFQBZsMmIYHs+NRHG+Uq0OxtuuCXMWQ3vu1830Eugv5uMXyjG+bv2Z9y4IXjw=="], + + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.74.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-ZATQeHZCyr6MbDveg0obD5sxLHFOghtOdC5jwVwYlvFWqtFOxctgFEG6Ef/64hYvZrWyhyCckB10AelqLopeDA=="], + + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.74.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+aIvJyrdeD7LwCQ2WYLMUWNmnbeDRSPb40aBYtPjD9+PTqUwgJnk+HK5yLfSMeqXrMrDhE9uTmtt2y50tvjhHw=="], + + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.74.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XyktaR8lhK2qWiCK0Tk8oYD+/cgn+oHA6ddRnxSSXUKkkojkV78CmShZUxQF+yrBFs0SuW+JBOPG6hecyc/iZg=="], + + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.74.0", "", { "os": "none", "cpu": "arm64" }, "sha512-mzbjrPl4neaVUiJ1fUiEUxTGaSZBoiKtaoB6jmIpz9S+VOA2vDYmJpihQ82w6178V5jxziclTg8Cgj5yF6tTDg=="], + + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.74.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-vUAe9okpS2Oa5+lX67lqHMuNUvfkleRKwrUDJ/WJBsgmddvZ1mrsh2HVmuFDRzqFELhaJhFaCNOuR6a7L3rtIA=="], + + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.74.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-yyXXJyYYSXL4I8K8jAWjJs+J3fa9gH2JmEbo4f5adm+1tNC9itseicBNuwK7BDHvqQ5J534s+yDULu89vYL2ZQ=="], + + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.74.0", "", { "os": "win32", "cpu": "x64" }, "sha512-VTC9IYTIMrVUk/i6Ms1ohzzDKZFkWn0KU2OBbPBzgmVZ2V30165T/zK4LztTr0Xgp9fZ1qQZ1rsZAu/rEmySlA=="], + + "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], + + "@redocly/ajv": ["@redocly/ajv@8.18.3", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-l42u0of3hY98sN2A+M4qTX1O/KrpgGH32Hu9kP2GtHyD5Dfqq86PKFLe5dwaD8DEnNmlOlll2BAmeEtf0DaySg=="], + + "@redocly/config": ["@redocly/config@0.51.0", "", { "dependencies": { "json-schema-to-ts": "2.7.2" } }, "sha512-XoSkEN28ojqvF1fP8mhOlzHPowpr1/jkvbo3qXKIKXG8RqTiQkLCGTvYdMBjcagEheFFXAsaJKM/GMdoczd4Zg=="], + + "@redocly/openapi-core": ["@redocly/openapi-core@2.39.0", "", { "dependencies": { "@redocly/ajv": "^8.18.1", "@redocly/config": "^0.51.0", "ajv": "npm:@redocly/ajv@8.18.1", "ajv-formats": "^3.0.1", "colorette": "^1.2.0", "graphql": "^16.14.1", "js-levenshtein": "^1.1.6", "js-yaml": "^4.2.0", "picomatch": "^4.0.4", "pluralize": "^8.0.0", "yaml-ast-parser": "0.0.43" } }, "sha512-sACPZX1LUf/GLdZ7xyYV7dgZ73gRzi0TVgNXME5OGKVEHPeNv8z91v2KYhuJso8XJ+E5EVpwBU02UEkrKvSycA=="], + + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.5", "", { "os": "android", "cpu": "arm64" }, "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.5", "", { "os": "linux", "cpu": "arm" }, "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA=="], + + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg=="], + + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.5", "", { "os": "none", "cpu": "arm64" }, "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], + + "@smithy/core": ["@smithy/core@3.29.4", "", { "dependencies": { "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-G1GRglAabzEhqghJMBAd54FkRS7SAFGHEwbhcI9r+O+LIMuFsLyXkLZkCoFSgAglRu8s/URVXJB0hglq3ZipIg=="], + + "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.4.9", "", { "dependencies": { "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-2nfV4qRKiYeXU4zD2vvSCfg5dfp/BuhrM73vt7q9gzBhxs4rbPxXY21wo+kyI3bRmXcEGRnCLTaW8O437jzHIg=="], + + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.6.6", "", { "dependencies": { "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-NHLgAlORUFZjn5ZfhYuyyKMlXA1WLYOdGxEhyNxrPpbJzoacGbl0chn1lN2KiZ8mpNVk0tV5607CSYlYs/OFgw=="], + + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.9.6", "", { "dependencies": { "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-odd+HYx3OLcXRSEz0ZeF3JQdSYdK8QnRgA2N87cPW7coWIbKfRk7a9VQjfeWQLqnzrDLk23KMEn46p8N7M/JFg=="], + + "@smithy/signature-v4": ["@smithy/signature-v4@5.6.5", "", { "dependencies": { "@smithy/core": "^3.29.4", "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-MO5VEhwVl0BN7xVoVeNrZfiUFoQtqxUbgl6/RwOTlMMxCSjblG8twSrVTwz3J4w9WZxd2rBfBAUXjH77agspBg=="], + + "@smithy/types": ["@smithy/types@4.16.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg=="], + + "@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="], + + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + + "@statelyai/inspect": ["@statelyai/inspect@0.7.2", "", { "dependencies": { "fast-safe-stringify": "^2.1.1", "isomorphic-ws": "^5.0.0", "partysocket": "^0.0.25", "safe-stable-stringify": "^2.5.0", "superjson": "^1.13.3", "ws": "^8.20.0" }, "peerDependencies": { "xstate": "^5.5.1" } }, "sha512-axuXSEBsI8pQ89rP2DWq+kHLjABiXpe2qYDOo6+jVLJ+9NPOTjutMnmDd+XcJjn76d+RH6sfHa0XkFIYPUHDOw=="], + + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + + "@types/node": ["@types/node@22.20.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q=="], + + "@types/opn": ["@types/opn@5.5.0", "", { "dependencies": { "opn": "*" } }, "sha512-rfEmrSa/x0vArY1aFnVTBAmy6b2I0oNHONL59qR+vnsHfD5xacM40O4PSiVisERq/GmROjmS3Xo/ptp8fx823g=="], + + "@types/react": ["@types/react@19.2.17", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw=="], + + "@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="], + + "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="], + + "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.10", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.10", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.10", "vitest": "4.1.10" }, "optionalPeers": ["@vitest/browser"] }, "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g=="], + + "@vitest/expect": ["@vitest/expect@4.1.10", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.10", "@vitest/utils": "4.1.10", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" } }, "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA=="], + + "@vitest/mocker": ["@vitest/mocker@4.1.10", "", { "dependencies": { "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@4.1.10", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q=="], + + "@vitest/runner": ["@vitest/runner@4.1.10", "", { "dependencies": { "@vitest/utils": "4.1.10", "pathe": "^2.0.3" } }, "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg=="], + + "@vitest/snapshot": ["@vitest/snapshot@4.1.10", "", { "dependencies": { "@vitest/pretty-format": "4.1.10", "@vitest/utils": "4.1.10", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw=="], + + "@vitest/spy": ["@vitest/spy@4.1.10", "", {}, "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw=="], + + "@vitest/ui": ["@vitest/ui@4.1.10", "", { "dependencies": { "@vitest/utils": "4.1.10", "fflate": "^0.8.2", "flatted": "^3.4.2", "pathe": "^2.0.3", "sirv": "^3.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "vitest": "4.1.10" } }, "sha512-EOUqfXHTXtpSHsyLHH40ts3Ue+hRhSGwzwzMlK0dTEOLSDYyOXLyr5JDGmHQWhN2DYI30gw6dVx3cdgM9FZl+Q=="], + + "@vitest/utils": ["@vitest/utils@4.1.10", "", { "dependencies": { "@vitest/pretty-format": "4.1.10", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA=="], + + "@workos-inc/node": ["@workos-inc/node@8.13.0", "", { "dependencies": { "eventemitter3": "^5.0.4" } }, "sha512-NgQKHpwh8AbT4KvAsW91Y+4f4jja2IvFPQ5atcy5NUxUMVRgXzRFEee3erawfXrTmiCVqJjd9PljHySKBXmHKQ=="], + + "@workos/emulate": ["@workos/emulate@0.1.0", "", { "dependencies": { "@hono/node-server": "^1", "chalk": "^5.6.2", "hono": "^4", "yaml": "^2.8.2" }, "bin": { "workos-emulate": "dist/cli.js" } }, "sha512-0f4g99yh6Ozf7wfdVlcAktrkyq2ejmweanXFnn0KMfTYdsYO5/oDgBFw+MVLhx9CoslDp2ApPgdImMZTeJ1n6g=="], + + "@workos/migrations": ["@workos/migrations@2.5.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity-provider": "^3.1041.0", "@workos-inc/node": "^10.0.0", "chalk": "^5.6.2", "cli-progress": "^3.12.0", "commander": "^15.0.0", "csv-parse": "^6.2.1", "csv-stringify": "^6.4.5", "dotenv": "^17.4.2", "fast-xml-parser": "^5.7.2", "google-auth-library": "^10.6.2", "prompts": "^2.4.2" }, "bin": { "workos-migrate": "dist/index.js" } }, "sha512-2kBiKOf0djjQIThpi43POWy76Dkvx8fFtKvdKtMNiOk5rJqyjsX3Y3oU7JjSx+gZJTfW2YfdDXrQhPnWzdyiUw=="], + + "@workos/oagen": ["@workos/oagen@0.23.0", "", { "dependencies": { "@redocly/openapi-core": "^2.25.1", "commander": "^13.1.0", "dotenv": "^17.3.1", "tree-sitter": "^0.21.1", "tree-sitter-c-sharp": "0.23.1", "tree-sitter-elixir": "^0.3.5", "tree-sitter-go": "^0.23.4", "tree-sitter-kotlin": "github:fwcd/tree-sitter-kotlin#f66d2908542e93c0204c6c241f794afe4e9cd5d1", "tree-sitter-php": "^0.23.12", "tree-sitter-python": "^0.21.0", "tree-sitter-ruby": "^0.21.0", "tree-sitter-rust": "^0.21.0", "tree-sitter-typescript": "^0.23.2", "tsx": "^4.19.0", "typescript": "^6.0.0" }, "bin": { "oagen": "dist/cli/index.mjs" } }, "sha512-9eB6OnGr29VxPg/tBWKEI5B6C39v+lrqZpBZXbO5E2hEl+3hHUXAOrtGlMbZh4nLrXiwo16meDryEny1LDvjPw=="], + + "@workos/openapi-spec": ["@workos/openapi-spec@0.14.0", "", { "dependencies": { "@workos/oagen": "^0.23.0" } }, "sha512-mjh0K8RRWfo+sg9O6XWuNQ6PouzQzWzpMZKLn867fldfA7gDNNDR1d2Nqi/p6KRJBXLDEIfc8fdFb9HXJW/NcA=="], + + "@workos/skills": ["@workos/skills@0.6.1", "", { "dependencies": { "yaml": "^2.8.2" } }, "sha512-2YovBOFM1u3any7JVMIrwLOomSXT/Ndft1+QAl8YalDowWxXqBqiyebebZvm47jb6BI6rIR04svG2xI5c5rcjA=="], + + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "ajv": ["@redocly/ajv@8.18.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Ifm/pP/tul1qmAecpbVxCBluVE32rKfjf8gYXH4xI2gCv9mRWFhJMHzkPDM4TXlxwPQYIFegymlsy8lXz7optA=="], + + "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + + "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], + + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "anynum": ["anynum@1.0.1", "", {}, "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + + "ast-v8-to-istanbul": ["ast-v8-to-istanbul@1.0.5", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^10.0.0" } }, "sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA=="], + + "auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="], + + "body-parser": ["body-parser@2.3.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^2.0.0", "debug": "^4.4.3", "http-errors": "^2.0.1", "iconv-lite": "^0.7.2", "on-finished": "^2.4.1", "qs": "^6.15.2", "raw-body": "^3.0.2", "type-is": "^2.1.0" } }, "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw=="], + + "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], + + "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], + + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], + + "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], + + "cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="], + + "cli-progress": ["cli-progress@3.12.0", "", { "dependencies": { "string-width": "^4.2.3" } }, "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A=="], + + "cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="], + + "cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], + + "code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="], + + "colorette": ["colorette@1.4.0", "", {}, "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="], + + "commander": ["commander@15.0.0", "", {}, "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg=="], + + "content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], + + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="], + + "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], + + "copy-anything": ["copy-anything@3.0.5", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w=="], + + "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "csv-parse": ["csv-parse@6.2.1", "", {}, "sha512-LRLMV+UCyfMokp8Wb411duBf1gaBKJfOfBWU9eHMJ+b+cJYZsNu3AFmjJf3+yPGd59Exz1TsMjaSFyxnYB9+IQ=="], + + "csv-stringify": ["csv-stringify@6.8.1", "", {}, "sha512-tZ6X6TKQyQgCo5OptXcyAbfN1pwmoxEqELPQ7KFazNErx7kiVsDK8o+VYRXhfMl4N9vvOOLXuioquR2MeP847A=="], + + "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "default-browser": ["default-browser@5.5.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw=="], + + "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="], + + "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], + + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="], + + "dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], + + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-module-lexer": ["es-module-lexer@2.3.1", "", {}, "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA=="], + + "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], + + "es-toolkit": ["es-toolkit@1.49.0", "", {}, "sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g=="], + + "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "event-target-shim": ["event-target-shim@6.0.2", "", {}, "sha512-8q3LsZjRezbFZ2PN+uP+Q7pnHUMmAOziU2vA2OwoFaKIXxlxl38IylhSSgUorWu/rf4er67w0ikBqjBFk/pomA=="], + + "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + + "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], + + "eventsource-parser": ["eventsource-parser@3.1.0", "", {}, "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg=="], + + "expect-type": ["expect-type@1.4.0", "", {}, "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA=="], + + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + + "express-rate-limit": ["express-rate-limit@8.5.2", "", { "dependencies": { "ip-address": "^10.2.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="], + + "fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="], + + "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], + + "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], + + "fast-uri": ["fast-uri@3.1.3", "", {}, "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg=="], + + "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="], + + "fast-xml-builder": ["fast-xml-builder@1.3.0", "", { "dependencies": { "path-expression-matcher": "^1.6.2", "xml-naming": "^0.3.0" } }, "sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ=="], + + "fast-xml-parser": ["fast-xml-parser@5.10.0", "", { "dependencies": { "@nodable/entities": "^2.2.0", "fast-xml-builder": "^1.2.0", "is-unsafe": "^2.0.0", "path-expression-matcher": "^1.6.2", "strnum": "^2.4.1", "xml-naming": "^0.3.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-SLhnTEqE5QpJHq/6zl9bsmImEP2adv+y6Wy+cJa7nVTRzQh1OZfCe9k29M5xN74LWnu0xa1zrUrq3KnOKl92Fg=="], + + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], + + "fflate": ["fflate@0.8.3", "", {}, "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], + + "flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="], + + "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], + + "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "gaxios": ["gaxios@7.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2" } }, "sha512-CUVb4wcYe+771XevyH6HtGmXFAGGKkIC3kswAP8Z1JCe0j80JMaTPZH930DWFrvo0atjh18Arc0pEyUCWa5bfg=="], + + "gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "google-auth-library": ["google-auth-library@10.9.0", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.1.4", "gcp-metadata": "8.1.2", "google-logging-utils": "1.1.3", "jws": "^4.0.0" } }, "sha512-xtvUqvINPhTaBm7nXqlYPcrMHJPm1lCNdSovxnKKhTm+4JsvQ+KGVYJViLoH9Yxu8w+T0Qv5HubzYT9BLrppJg=="], + + "google-logging-utils": ["google-logging-utils@1.1.3", "", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "graphql": ["graphql@16.14.2", "", {}, "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], + + "hono": ["hono@4.12.30", "", {}, "sha512-emn+JoJjrN9YTpRDS5it/UI2SO9BAE37T6I3d963RxcZ81G9A4pr2SZTEiiaiKbzx+NKRg5BZ89fCL7gCJCUog=="], + + "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], + + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="], + + "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ink": ["ink@6.8.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.4", "ansi-escapes": "^7.3.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "scheduler": "^0.27.0", "signal-exit": "^3.0.7", "slice-ansi": "^8.0.0", "stack-utils": "^2.0.6", "string-width": "^8.1.1", "terminal-size": "^4.0.1", "type-fest": "^5.4.1", "widest-line": "^6.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": ">=6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA=="], + + "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], + + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + + "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="], + + "is-in-ssh": ["is-in-ssh@1.0.0", "", {}, "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw=="], + + "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], + + "is-unsafe": ["is-unsafe@2.0.0", "", {}, "sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA=="], + + "is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="], + + "is-wsl": ["is-wsl@1.1.0", "", {}, "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "isomorphic-ws": ["isomorphic-ws@5.0.0", "", { "peerDependencies": { "ws": "*" } }, "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw=="], + + "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], + + "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], + + "istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="], + + "jose": ["jose@6.2.3", "", {}, "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw=="], + + "js-levenshtein": ["js-levenshtein@1.1.6", "", {}, "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g=="], + + "js-tokens": ["js-tokens@10.0.0", "", {}, "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q=="], + + "js-yaml": ["js-yaml@4.3.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="], + + "json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="], + + "json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "ts-algebra": "^2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="], + + "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + + "jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="], + + "jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="], + + "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + + "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "magicast": ["magicast@0.5.3", "", { "dependencies": { "@babel/parser": "^7.29.3", "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw=="], + + "make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="], + + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "node-addon-api": ["node-addon-api@8.9.0", "", {}, "sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q=="], + + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], + + "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], + + "node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "obug": ["obug@2.1.3", "", {}, "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg=="], + + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="], + + "opn": ["opn@6.0.0", "", { "dependencies": { "is-wsl": "^1.1.0" } }, "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ=="], + + "oxfmt": ["oxfmt@0.56.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.56.0", "@oxfmt/binding-android-arm64": "0.56.0", "@oxfmt/binding-darwin-arm64": "0.56.0", "@oxfmt/binding-darwin-x64": "0.56.0", "@oxfmt/binding-freebsd-x64": "0.56.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.56.0", "@oxfmt/binding-linux-arm-musleabihf": "0.56.0", "@oxfmt/binding-linux-arm64-gnu": "0.56.0", "@oxfmt/binding-linux-arm64-musl": "0.56.0", "@oxfmt/binding-linux-ppc64-gnu": "0.56.0", "@oxfmt/binding-linux-riscv64-gnu": "0.56.0", "@oxfmt/binding-linux-riscv64-musl": "0.56.0", "@oxfmt/binding-linux-s390x-gnu": "0.56.0", "@oxfmt/binding-linux-x64-gnu": "0.56.0", "@oxfmt/binding-linux-x64-musl": "0.56.0", "@oxfmt/binding-openharmony-arm64": "0.56.0", "@oxfmt/binding-win32-arm64-msvc": "0.56.0", "@oxfmt/binding-win32-ia32-msvc": "0.56.0", "@oxfmt/binding-win32-x64-msvc": "0.56.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-9Dv0wV3zKiyvhjD7bRKaInKmHQ1sPx3RGOjQkGFJbbdQ16576yf8qhMSO9Q9cvHcs+1NpBsRTkuDDYFFPTJ6gw=="], + + "oxlint": ["oxlint@1.74.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.74.0", "@oxlint/binding-android-arm64": "1.74.0", "@oxlint/binding-darwin-arm64": "1.74.0", "@oxlint/binding-darwin-x64": "1.74.0", "@oxlint/binding-freebsd-x64": "1.74.0", "@oxlint/binding-linux-arm-gnueabihf": "1.74.0", "@oxlint/binding-linux-arm-musleabihf": "1.74.0", "@oxlint/binding-linux-arm64-gnu": "1.74.0", "@oxlint/binding-linux-arm64-musl": "1.74.0", "@oxlint/binding-linux-ppc64-gnu": "1.74.0", "@oxlint/binding-linux-riscv64-gnu": "1.74.0", "@oxlint/binding-linux-riscv64-musl": "1.74.0", "@oxlint/binding-linux-s390x-gnu": "1.74.0", "@oxlint/binding-linux-x64-gnu": "1.74.0", "@oxlint/binding-linux-x64-musl": "1.74.0", "@oxlint/binding-openharmony-arm64": "1.74.0", "@oxlint/binding-win32-arm64-msvc": "1.74.0", "@oxlint/binding-win32-ia32-msvc": "1.74.0", "@oxlint/binding-win32-x64-msvc": "1.74.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.24.0", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-odGl2s2x5IOJoj3A0v1k0PGBXVFBZeZ2+AK/+K2MJur7Ghi3bkyX5NuLUWHKqa4js1wjep3hJeuTQJOlr+4+dA=="], + + "p-limit": ["p-limit@7.3.0", "", { "dependencies": { "yocto-queue": "^1.2.1" } }, "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw=="], + + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "partysocket": ["partysocket@0.0.25", "", { "dependencies": { "event-target-shim": "^6.0.2" } }, "sha512-1oCGA65fydX/FgdnsiBh68buOvfxuteoZVSb3Paci2kRp/7lhF0HyA8EDb5X/O6FxId1e+usPTQNRuzFEvkJbQ=="], + + "patch-console": ["patch-console@2.0.0", "", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="], + + "path-expression-matcher": ["path-expression-matcher@1.6.2", "", {}, "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], + + "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], + + "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="], + + "postcss": ["postcss@8.5.19", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ=="], + + "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="], + + "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], + + "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + + "qs": ["qs@6.15.3", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "range-parser": ["range-parser@1.3.0", "", {}, "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw=="], + + "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], + + "react": ["react@19.2.7", "", {}, "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ=="], + + "react-devtools-core": ["react-devtools-core@7.0.1", "", { "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } }, "sha512-C3yNvRHaizlpiASzy7b9vbnBGLrhvdhl1CbdU6EnZgxPNbai60szdLtl+VL76UNOt5bOoVTOz5rNWZxgGt+Gsw=="], + + "react-reconciler": ["react-reconciler@0.33.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "rolldown": ["rolldown@1.1.5", "", { "dependencies": { "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.5", "@rolldown/binding-darwin-arm64": "1.1.5", "@rolldown/binding-darwin-x64": "1.1.5", "@rolldown/binding-freebsd-x64": "1.1.5", "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", "@rolldown/binding-linux-arm64-gnu": "1.1.5", "@rolldown/binding-linux-arm64-musl": "1.1.5", "@rolldown/binding-linux-ppc64-gnu": "1.1.5", "@rolldown/binding-linux-s390x-gnu": "1.1.5", "@rolldown/binding-linux-x64-gnu": "1.1.5", "@rolldown/binding-linux-x64-musl": "1.1.5", "@rolldown/binding-openharmony-arm64": "1.1.5", "@rolldown/binding-wasm32-wasi": "1.1.5", "@rolldown/binding-win32-arm64-msvc": "1.1.5", "@rolldown/binding-win32-x64-msvc": "1.1.5" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA=="], + + "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], + + "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + + "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], + + "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "shell-quote": ["shell-quote@1.10.0", "", {}, "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA=="], + + "side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="], + + "side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], + + "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], + + "slice-ansi": ["slice-ansi@8.0.0", "", { "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" } }, "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], + + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "standardwebhooks": ["standardwebhooks@1.0.0", "", { "dependencies": { "@stablelib/base64": "^1.0.0", "fast-sha256": "^1.3.0" } }, "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg=="], + + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + + "std-env": ["std-env@4.2.0", "", {}, "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw=="], + + "string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="], + + "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "strnum": ["strnum@2.4.1", "", { "dependencies": { "anynum": "^1.0.1" } }, "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg=="], + + "superjson": ["superjson@1.13.3", "", { "dependencies": { "copy-anything": "^3.0.2" } }, "sha512-mJiVjfd2vokfDxsQPOwJ/PtanO87LhpYY88ubI5dUB1Ab58Txbyje3+jpm+/83R/fevaq/107NNhtYBLuoTrFg=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], + + "terminal-size": ["terminal-size@4.0.1", "", {}, "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ=="], + + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], + + "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], + + "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], + + "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], + + "tree-sitter": ["tree-sitter@0.21.1", "", { "dependencies": { "node-addon-api": "^8.0.0", "node-gyp-build": "^4.8.0" } }, "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ=="], + + "tree-sitter-c-sharp": ["tree-sitter-c-sharp@0.23.1", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-9zZ4FlcTRWWfRf6f4PgGhG8saPls6qOOt75tDfX7un9vQZJmARjPrAC6yBNCX2T/VKcCjIDbgq0evFaB3iGhQw=="], + + "tree-sitter-elixir": ["tree-sitter-elixir@0.3.5", "", { "dependencies": { "node-addon-api": "^7.1.0", "node-gyp-build": "^4.8.0" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-xozQMvYK0aSolcQZAx2d84Xe/YMWFuRPYFlLVxO01bM2GITh5jyiIp0TqPCQa8754UzRAI7A83hZmfiYub5TZQ=="], + + "tree-sitter-go": ["tree-sitter-go@0.23.4", "", { "dependencies": { "node-addon-api": "^8.2.1", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-iQaHEs4yMa/hMo/ZCGqLfG61F0miinULU1fFh+GZreCRtKylFLtvn798ocCZjO2r/ungNZgAY1s1hPFyAwkc7w=="], + + "tree-sitter-javascript": ["tree-sitter-javascript@0.23.1", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-/bnhbrTD9frUYHQTiYnPcxyHORIw157ERBa6dqzaKxvR/x3PC4Yzd+D1pZIMS6zNg2v3a8BZ0oK7jHqsQo9fWA=="], + + "tree-sitter-kotlin": ["tree-sitter-kotlin@github:fwcd/tree-sitter-kotlin#f66d290", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "fwcd-tree-sitter-kotlin-f66d290", "sha512-uf5gcnILLfR+TP+qjX0KaOuQU7QOLCqb7bs/D/m5PrveehUnz6LOc9A/mrK+gU7ahDq7Hs+KECmPK/5Hf0QTfg=="], + + "tree-sitter-php": ["tree-sitter-php@0.23.12", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2" }, "peerDependencies": { "tree-sitter": "^0.21.1" }, "optionalPeers": ["tree-sitter"] }, "sha512-VwkBVOahhC2NYXK/Fuqq30NxuL/6c2hmbxEF4jrB7AyR5rLc7nT27mzF3qoi+pqx9Gy2AbXnGezF7h4MeM6YRA=="], + + "tree-sitter-python": ["tree-sitter-python@0.21.0", "", { "dependencies": { "node-addon-api": "^7.1.0", "node-gyp-build": "^4.8.0" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-IUKx7JcTVbByUx1iHGFS/QsIjx7pqwTMHL9bl/NGyhyyydbfNrpruo2C7W6V4KZrbkkCOlX8QVrCoGOFW5qecg=="], + + "tree-sitter-ruby": ["tree-sitter-ruby@0.21.0", "", { "dependencies": { "node-addon-api": "^8.0.0", "node-gyp-build": "^4.8.1" }, "peerDependencies": { "tree-sitter": "^0.21.0" } }, "sha512-UrMpF9CZxKbZ5UFuPdXDuraaaYSMMlAiuzTpQXwNm7y0D48ibc9stWU5D6vDyJD0qf5/R+3yKTYHdHkqibmLSQ=="], + + "tree-sitter-rust": ["tree-sitter-rust@0.21.0", "", { "dependencies": { "node-addon-api": "^7.1.0", "node-gyp-build": "^4.8.0" }, "peerDependencies": { "tree-sitter": "^0.21.1" } }, "sha512-unVr73YLn3VC4Qa/GF0Nk+Wom6UtI526p5kz9Rn2iZSqwIFedyCZ3e0fKCEmUJLIPGrTb/cIEdu3ZUNGzfZx7A=="], + + "tree-sitter-typescript": ["tree-sitter-typescript@0.23.2", "", { "dependencies": { "node-addon-api": "^8.2.2", "node-gyp-build": "^4.8.2", "tree-sitter-javascript": "^0.23.1" }, "peerDependencies": { "tree-sitter": "^0.21.0" }, "optionalPeers": ["tree-sitter"] }, "sha512-e04JUUKxTT53/x3Uq1zIL45DoYKVfHH4CZqwgZhPg5qYROl5nQjV+85ruFzFGZxu+QeFVbRTPDRnqL9UbU4VeA=="], + + "ts-algebra": ["ts-algebra@2.0.0", "", {}, "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "tsx": ["tsx@4.23.1", "", { "dependencies": { "esbuild": "~0.28.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ=="], + + "type-fest": ["type-fest@5.8.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA=="], + + "type-is": ["type-is@2.1.0", "", { "dependencies": { "content-type": "^2.0.0", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "uuid": ["uuid@13.0.2", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw=="], + + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "vite": ["vite@8.1.4", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", "postcss": "^8.5.16", "rolldown": "~1.1.4", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ=="], + + "vitest": ["vitest@4.1.10", "", { "dependencies": { "@vitest/expect": "4.1.10", "@vitest/mocker": "4.1.10", "@vitest/pretty-format": "4.1.10", "@vitest/runner": "4.1.10", "@vitest/snapshot": "4.1.10", "@vitest/spy": "4.1.10", "@vitest/utils": "4.1.10", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.1.0", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.10", "@vitest/browser-preview": "4.1.10", "@vitest/browser-webdriverio": "4.1.10", "@vitest/coverage-istanbul": "4.1.10", "@vitest/coverage-v8": "4.1.10", "@vitest/ui": "4.1.10", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "./vitest.mjs" } }, "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw=="], + + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + + "widest-line": ["widest-line@6.0.0", "", { "dependencies": { "string-width": "^8.1.0" } }, "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA=="], + + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "ws": ["ws@8.21.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="], + + "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="], + + "xml-naming": ["xml-naming@0.3.0", "", {}, "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ=="], + + "xstate": ["xstate@5.32.5", "", {}, "sha512-ULazi1oe6wGrXl0Frb6otSlkm5HLifbbVTkMk5kkSKqz4TkxJaVpnl6jOJwKeid3ORPxYyZQgNLUSYX9q65SIA=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + + "yaml-ast-parser": ["yaml-ast-parser@0.0.43", "", {}, "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A=="], + + "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], + + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], + + "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], + + "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="], + + "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + + "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], + + "@clack/prompts/@clack/core": ["@clack/core@1.4.2", "", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-0Ty/1Gfm+Kb07sXcuESjyKfwEhSy4Ns1AgeEisHb/bDY5fWme0tTeTkU14T1Gmcs17YIjB/teiDe4uaCghbYqQ=="], + + "@redocly/config/json-schema-to-ts": ["json-schema-to-ts@2.7.2", "", { "dependencies": { "@babel/runtime": "^7.18.3", "@types/json-schema": "^7.0.9", "ts-algebra": "^1.2.0" } }, "sha512-R1JfqKqbBR4qE8UyBR56Ms30LL62/nlhoz+1UkfI/VE7p54Awu919FZ6ZUPG8zIa3XB65usPJgr1ONVncUGSaQ=="], + + "@workos/migrations/@workos-inc/node": ["@workos-inc/node@10.7.0", "", {}, "sha512-rffa9znZuIv4yo+9JRxGOLTTSxh0XhOT6jlsktgqEi9MuB9V0VFHRzLd3bTpkq+J9sgrPZNGpvX4aWNfMqt5cQ=="], + + "@workos/oagen/commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], + + "@workos/oagen/typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "body-parser/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="], + + "cli-progress/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "cliui/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "react-devtools-core/ws": ["ws@7.5.12", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-1xGnbYN3zbog9CwuNDQULNRrTCLIn46/WmpR1f0w6PsCYQHkylZr5vkd6kfMZYV6pRnQkcPNRyiA8LsrNKyhpg=="], + + "tree-sitter-elixir/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "tree-sitter-python/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "tree-sitter-rust/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "type-is/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="], + + "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "wsl-utils/is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], + + "yargs/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "@redocly/config/json-schema-to-ts/ts-algebra": ["ts-algebra@1.2.2", "", {}, "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA=="], + + "cli-progress/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "cli-progress/string-width/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "cli-progress/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "cli-progress/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + } +} diff --git a/package.json b/package.json index 1a904b58..2f398f24 100644 --- a/package.json +++ b/package.json @@ -19,26 +19,7 @@ "sso" ], "bin": { - "workos": "dist/bin.js" - }, - "publishConfig": { - "access": "public" - }, - "files": [ - "dist", - "package.json", - "README.md" - ], - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "typescript": { - "definition": "dist/index.d.ts" - }, - "exports": { - ".": { - "import": "./dist/index.js", - "types": "./dist/index.d.ts" - } + "workos": "dist/workos" }, "dependencies": { "@anthropic-ai/claude-agent-sdk": "~0.3.0", @@ -78,35 +59,38 @@ "oxfmt": "^0.56.0", "oxlint": "^1.50.0", "p-limit": "^7.3.0", - "tsx": "^4.20.3", + "react-devtools-core": "^7.0.1", "typescript": "^5.9.3", "vitest": "^4.0.18" }, "engines": { - "node": ">=22.11" + "bun": ">=1.3.0" }, - "packageManager": "pnpm@10.34.4", + "packageManager": "bun@1.3.14", "scripts": { - "clean": "rm -rf ./dist", - "prebuild": "pnpm clean", - "build:watch": "pnpm tsc -w", - "build": "pnpm tsc", - "postbuild": "chmod +x ./dist/bin.js && cp -r scripts/** dist", + "clean": "bun -e \"await import('node:fs/promises').then((fs) => fs.rm('./dist', { recursive: true, force: true }))\"", + "generate": "bun run ./scripts/gen-integration-manifest.ts && bun run ./scripts/gen-skills-manifest.ts && bun run ./scripts/gen-agent-sdk-manifest.ts", + "postinstall": "bun run generate", + "prebuild": "bun run clean && bun run generate", + "build": "bun run ./scripts/build.ts", + "build:watch": "bun --watch ./dev.ts", "lint": "oxlint", "format": "oxfmt .", "format:check": "oxfmt --check .", - "try": "tsx dev.ts", - "dev": "pnpm build && pnpm link --global && pnpm build:watch", + "try": "bun run ./dev.ts", + "dev": "bun --watch ./dev.ts", + "pretest": "bun run generate", "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage", + "pretypecheck": "bun run generate", "typecheck": "tsc --noEmit", - "eval": "tsx tests/evals/index.ts", - "eval:history": "tsx tests/evals/index.ts history", - "eval:diff": "tsx tests/evals/index.ts diff", - "eval:prune": "tsx tests/evals/index.ts prune", - "eval:logs": "tsx tests/evals/index.ts logs", - "eval:show": "tsx tests/evals/index.ts show" + "eval": "bun run ./tests/evals/index.ts", + "eval:history": "bun run ./tests/evals/index.ts history", + "eval:diff": "bun run ./tests/evals/index.ts diff", + "eval:prune": "bun run ./tests/evals/index.ts prune", + "eval:logs": "bun run ./tests/evals/index.ts logs", + "eval:show": "bun run ./tests/evals/index.ts show" }, "author": "WorkOS", "license": "MIT" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 9f6f0bfc..00000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,5117 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@anthropic-ai/claude-agent-sdk': - specifier: ~0.3.0 - version: 0.3.201(@anthropic-ai/sdk@0.106.0(zod@4.4.3))(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) - '@anthropic-ai/sdk': - specifier: ^0.106.0 - version: 0.106.0(zod@4.4.3) - '@clack/core': - specifier: ^1.0.1 - version: 1.4.3 - '@clack/prompts': - specifier: 1.6.0 - version: 1.6.0 - '@napi-rs/keyring': - specifier: ^1.2.0 - version: 1.3.0 - '@workos-inc/node': - specifier: ^8.7.0 - version: 8.13.0 - '@workos/emulate': - specifier: ^0.1.0 - version: 0.1.0 - '@workos/migrations': - specifier: ^2.4.0 - version: 2.5.0 - '@workos/openapi-spec': - specifier: ^0.14.0 - version: 0.14.0 - '@workos/skills': - specifier: 0.6.1 - version: 0.6.1 - chalk: - specifier: ^5.6.2 - version: 5.6.2 - diff: - specifier: ^8.0.3 - version: 8.0.4 - fast-glob: - specifier: ^3.3.3 - version: 3.3.3 - ink: - specifier: ^6.8.0 - version: 6.8.0(@types/react@19.2.17)(react@19.2.7) - jsonc-parser: - specifier: ^3.3.1 - version: 3.3.1 - open: - specifier: ^11.0.0 - version: 11.0.0 - react: - specifier: ^19.2.4 - version: 19.2.7 - semver: - specifier: ^7.7.4 - version: 7.8.5 - uuid: - specifier: ^13.0.0 - version: 13.0.2 - xstate: - specifier: ^5.28.0 - version: 5.32.4 - yaml: - specifier: ^2.8.2 - version: 2.9.0 - yargs: - specifier: ^18.0.0 - version: 18.0.0 - zod: - specifier: ^4.3.6 - version: 4.4.3 - devDependencies: - '@statelyai/inspect': - specifier: ^0.7.0 - version: 0.7.2(xstate@5.32.4) - '@types/node': - specifier: ~22.20.0 - version: 22.20.0 - '@types/opn': - specifier: 5.5.0 - version: 5.5.0 - '@types/react': - specifier: ^19.2.14 - version: 19.2.17 - '@types/semver': - specifier: ^7.7.1 - version: 7.7.1 - '@types/yargs': - specifier: ^17.0.35 - version: 17.0.35 - '@vitest/coverage-v8': - specifier: ^4.0.18 - version: 4.1.10(vitest@4.1.10) - '@vitest/ui': - specifier: ^4.0.18 - version: 4.1.10(vitest@4.1.10) - dotenv: - specifier: ^17.3.1 - version: 17.4.2 - oxfmt: - specifier: ^0.56.0 - version: 0.56.0 - oxlint: - specifier: ^1.50.0 - version: 1.72.0 - p-limit: - specifier: ^7.3.0 - version: 7.3.0 - tsx: - specifier: ^4.20.3 - version: 4.23.0 - typescript: - specifier: ^5.9.3 - version: 5.9.3 - vitest: - specifier: ^4.0.18 - version: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(msw@2.10.4(@types/node@22.20.0)(typescript@5.9.3))(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0)) - -packages: - - '@alcalzone/ansi-tokenize@0.2.5': - resolution: {integrity: sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw==} - engines: {node: '>=18'} - - '@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.201': - resolution: {integrity: sha512-8Mcb3BDyKUGfJWFFTWwt+at37lbDH3ZwVtUNPWGG1toZ75RDCJry5U4kXRvQ2xokvJQlA0E+eNp6keWe5ZH22Q==} - cpu: [arm64] - os: [darwin] - - '@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.201': - resolution: {integrity: sha512-TFR2bu0+ml3RHoMrtsgD0qDK5Oknw8kYGBV7qpQHn+IWmE96gnHhogG1LpJwpHtni08XkJIjfWk1DdlsUYtRkQ==} - cpu: [x64] - os: [darwin] - - '@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.201': - resolution: {integrity: sha512-EiqbpfJIpChfkn+8Uj061Qjyw0eaRcOXtdrvVuHANyj8ZErVOr8HlH6op9PSeIUa9TX0m2+tNgKPQvOGseQckA==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.201': - resolution: {integrity: sha512-mShTo3MwF0gkN4dDw78wWJiB6aBDVRkl81cnApvoBofpdyUBYgm9Gw16CCjDTgelMKeBFqN6ErJpwjI3wbP00A==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.201': - resolution: {integrity: sha512-IbxnzO5UCbqbm2TnzCHkSyJorAFw2isdKdIsFCTxJJjSs3ZC+v3LC1QSUiVCx0qi+CV6w3MKx6mLI11mrvhbbQ==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.201': - resolution: {integrity: sha512-jrJBrRWrSuoFKIgjyqxHqmfd6Pb3Bs5Bvakg0knXCTC4fbUXGnC9Q6u7gdDwgXohUNP6/DD+s8U7bivvvVv0dg==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.201': - resolution: {integrity: sha512-UsoytRJ/037uHpb3ATrIoe+AgwTf+PwKuFLGjddHAV/11wERJs0hlrnSmcnp43kf0PFxoSNinngme96YYASmQg==} - cpu: [arm64] - os: [win32] - - '@anthropic-ai/claude-agent-sdk-win32-x64@0.3.201': - resolution: {integrity: sha512-PhalN/0cWcqDfbx7iwoLNR2gurjTiqhBk1G6K+NRScxEcQjWuu5xKXCcdbX8ePVpT+nbEMmFEFpn2y+8V8hIdA==} - cpu: [x64] - os: [win32] - - '@anthropic-ai/claude-agent-sdk@0.3.201': - resolution: {integrity: sha512-InT1XLmf2QpldWdtznKDWEoGJT4p+sXh24yxbeBQ++lMJCzMrI0W27MEmmmDWx0otpa+ubdHCF5YQ6oiNt7cmg==} - engines: {node: '>=18.0.0'} - peerDependencies: - '@anthropic-ai/sdk': '>=0.93.0' - '@modelcontextprotocol/sdk': ^1.29.0 - zod: ^4.0.0 - - '@anthropic-ai/sdk@0.106.0': - resolution: {integrity: sha512-ufwVvYNDBj2dzOGupBCTaNzBLxqcTnGOzI4z8Wouxlt+mT3J3HuOmatgCy1VmwCHOUueqZ41ERhm0O99OUcbWA==} - hasBin: true - peerDependencies: - zod: ^3.25.0 || ^4.0.0 - peerDependenciesMeta: - zod: - optional: true - - '@aws-sdk/client-cognito-identity-provider@3.1079.0': - resolution: {integrity: sha512-EISFwFAkHGPard4hsPxD+dGYoJFoGpWF2woa2meF0Gs6LiZ4RTeFsxDTQ0mGokBxHxt+iZ1bIlmA6zZlSDOdiQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/core@3.974.27': - resolution: {integrity: sha512-WRWEgIq6vx+NU6ot3VrRu4Jovj9MIObitSi6of/GV5THDDPccBhivCRNkWJutMM+m3GvdeI3l/UbGNcoOobxOA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-env@3.972.53': - resolution: {integrity: sha512-+KDA3uc/HZ1vIneGu5QMQb0gAXDYrm2vOE60+BJ7lS0YinMQ5i2oV4PR1A16XkF6K1IbSwjEHd1hQIIgMsK48w==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-http@3.972.55': - resolution: {integrity: sha512-1gBfkWY3RWeBlCoB9lIJjXMx45/54wxcgfzv6BY9otTmMrZPcNPi1v+MwZxxaCUg441NV3jsr1efnFNCXiW70g==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-ini@3.972.60': - resolution: {integrity: sha512-CV2md+PXvABwRjApWGhQ0wACy9WSFIhnUGrovLcjnjBCd/46TbuivLADtkF8IWNjtCQmQ+2IagSaxqBYqXBNAQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-login@3.972.59': - resolution: {integrity: sha512-JG4S9yyA1GFzJdJXqLKrUzZbyK+VDp2QIsJD7YOicJHAhqymfHpDJIok2dLnhOdVB0I37RjdC53uOwCMVS00gw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-node@3.972.62': - resolution: {integrity: sha512-S6Slq3Tx7bvFk5yc34XNADyZYTX2HUXvaFAnowGRQnhjBO8J/mP62Fn7lxvJwjaDyYm/7gh9h6HEHaltRyMFXw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-process@3.972.53': - resolution: {integrity: sha512-EhfH+MQlqOMCkXIVa8MMObPzAQqwTTtxA7KhEJiyPeuNVA8PLOOUpgK7nBrgaDaGiIDLN/9LpGdaHuDjomeRTw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-sso@3.972.59': - resolution: {integrity: sha512-h8793pOjcImx0SB+VcLONcaQQ57VAvKVuqyewQMRKqqH+CSXsG2dwOeLMUJPMxLdNvL7dXOM0ueTukyNUnu5mA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-web-identity@3.972.59': - resolution: {integrity: sha512-VoyO9+vl3XVmpZwn4obskrWIkrA/Jf3lSe1E3ZERlaN9u0D4YZ6+HywC3+L98QOXqZesEfedk67gRER8tK8+8w==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/nested-clients@3.997.27': - resolution: {integrity: sha512-A8PIePF9NIIOJ/4Lg1rl9xm/+QaKkHGetq+Z9wb5B+3Da31YYXRo8n7IDMh5C+HQI5eyEmjrwkGWVdYtnLtbXQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/signature-v4-multi-region@3.996.38': - resolution: {integrity: sha512-C379Sk+MiFZCfWZphKlMyLHKxV22OjoGM5KJjj5IJNJcOCWL4IGIpnEGzv1FQiRwhYXfq55SJMfxlqPE08JJ9g==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/token-providers@3.1079.0': - resolution: {integrity: sha512-cbietrLlHPhhmbnMPTuDS4Zj/KNGhY+3vVhn6dwjO6Dqzrwothzg2srtcY34T9mlICsTXn34avDoWLHSntP54A==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/types@3.973.15': - resolution: {integrity: sha512-IULn8uBV/SMtmOIANsm4WHXIOtVPBWfOWs3WGL0j/sI+KhaYehvOw0ET+9urnn8MBpiijuU/0JOpuwKOE451PQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/xml-builder@3.972.33': - resolution: {integrity: sha512-ezbwz9WpuLctm6o7P2t2naDhVVPI5jFGrVefVybhcKGjU57VIyT46pQVO0RI2RYkUdhdj2Z9uSIlAzGZE9NW9A==} - engines: {node: '>=20.0.0'} - - '@aws/lambda-invoke-store@0.3.0': - resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==} - engines: {node: '>=18.0.0'} - - '@babel/helper-string-parser@7.29.7': - resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.29.7': - resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.7': - resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/runtime@7.29.7': - resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.7': - resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} - engines: {node: '>=6.9.0'} - - '@bcoe/v8-coverage@1.0.2': - resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} - engines: {node: '>=18'} - - '@bundled-es-modules/cookie@2.0.1': - resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} - - '@bundled-es-modules/statuses@1.0.1': - resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} - - '@bundled-es-modules/tough-cookie@0.1.6': - resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} - - '@clack/core@1.4.2': - resolution: {integrity: sha512-0Ty/1Gfm+Kb07sXcuESjyKfwEhSy4Ns1AgeEisHb/bDY5fWme0tTeTkU14T1Gmcs17YIjB/teiDe4uaCghbYqQ==} - engines: {node: '>= 20.12.0'} - - '@clack/core@1.4.3': - resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} - engines: {node: '>= 20.12.0'} - - '@clack/prompts@1.6.0': - resolution: {integrity: sha512-EYlRokl8szrP9Z25qT5aepMdBjzBvHF9ZEhzIiUBc9guz/T31EqRgvD0QSgZcpE93xiwrr+OkB4nz0BZyF6fSA==} - engines: {node: '>= 20.12.0'} - - '@emnapi/core@1.11.1': - resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - - '@emnapi/runtime@1.11.1': - resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - - '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@hono/node-server@1.19.14': - resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} - engines: {node: '>=18.14.1'} - peerDependencies: - hono: ^4 - - '@inquirer/ansi@1.0.2': - resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} - engines: {node: '>=18'} - - '@inquirer/confirm@5.1.21': - resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@10.3.2': - resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@1.0.15': - resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} - engines: {node: '>=18'} - - '@inquirer/type@3.0.10': - resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@modelcontextprotocol/sdk@1.29.0': - resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} - engines: {node: '>=18'} - peerDependencies: - '@cfworker/json-schema': ^4.1.1 - zod: ^3.25 || ^4.0 - peerDependenciesMeta: - '@cfworker/json-schema': - optional: true - - '@mswjs/interceptors@0.39.8': - resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} - engines: {node: '>=18'} - - '@napi-rs/keyring-darwin-arm64@1.3.0': - resolution: {integrity: sha512-pl76hJvdYUBn6I24bXiOBMA9nbDapo3I5B+f3OorjDU4dUMSypXeKbOVehJe8fhgTiH24flMyTS3aAIy43xegQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@napi-rs/keyring-darwin-x64@1.3.0': - resolution: {integrity: sha512-YcJtEV5LA3cvA4z3BurgxH5IhTsW1JfIvcAAcqcecwk06Si9F9NqkxbZVIfDwQ8oRHgaBmT3zZJnLAotCrVahw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@napi-rs/keyring-freebsd-x64@1.3.0': - resolution: {integrity: sha512-vlLf31TGhfRAaxLDBhg8b89ss0HHD/lyNmL5F3UjSaz5CUXElsJmKYq9fqA/B+cZKUEUcLHHGhF0I/CqcFdaVw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [freebsd] - - '@napi-rs/keyring-linux-arm-gnueabihf@1.3.0': - resolution: {integrity: sha512-KiWdMMu/Inz/bHHIAGrnF7r54FZDYXuHO6UFF/rhIrshUsxbMG1Rl9lEymNtqqsVo927G0VYcb02FzWQ3iBQRQ==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@napi-rs/keyring-linux-arm64-gnu@1.3.0': - resolution: {integrity: sha512-eyKGpY40lm9Jvs1aD294XRH4y7+TlJM0YVAryZeXA6TX0mb4gMkxVXwSQv7MCwgah7raeUd0dKUb4BPAYIgcMg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@napi-rs/keyring-linux-arm64-musl@1.3.0': - resolution: {integrity: sha512-iIK6JWHXAJqDrEyLY3TmswwloVyt2vj+04TZnew+uSJ9gnDO8EwRbp3/iw3LpWaXiDO7VomGO6y8I0Id8uBZSw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@napi-rs/keyring-linux-riscv64-gnu@1.3.0': - resolution: {integrity: sha512-/PGqrwn6EwgtK6vccASSXJRfOSP4vN1F4ASsIQ+7MdrK6hNvAJ1FZPrIuD5gGGdxezo3F++To2Wq7DbuGIeuNQ==} - engines: {node: '>= 10'} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@napi-rs/keyring-linux-x64-gnu@1.3.0': - resolution: {integrity: sha512-2PDK1WKWTu9lBGq9VvNEkSlQD3O7YwVpmnyN2M3cy4v7NJ/8gDMd9GXv3G+FVXN13uhp4gnnPBS+ScefmEeD2A==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@napi-rs/keyring-linux-x64-musl@1.3.0': - resolution: {integrity: sha512-oJ2HkX8YUo46QBkn0pG+HuIKQNqr523q6vBobCn+P95s4C4K6/kLBqHY/1bg5J4ap31DzsznhnFKcfBNBsjCnw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@napi-rs/keyring-win32-arm64-msvc@1.3.0': - resolution: {integrity: sha512-tOd3c/uAaeoE4ycVlmAdSvygz0Zt3zdca6Y7gokBeIbaRDWpjDIUOpU3MvML59XAaqyuKGsVVu0F/DZb1lHPmw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@napi-rs/keyring-win32-ia32-msvc@1.3.0': - resolution: {integrity: sha512-sPSqeAFZMGqP1R++M2JTza7GQJJ/TpCo6JU6Vcd4jnebvOaEDs9b7eipakU1PJdSvhpC2yXMCNRk9gXfrhuwHQ==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@napi-rs/keyring-win32-x64-msvc@1.3.0': - resolution: {integrity: sha512-4DnCWXwDc0HRKwyRlG5y0VhKZW2tNRQfKKfyj6IX/KWfDNyq9hn4n+GL1auyDcOO/v8PwnhmYo2+rOOqCkvvOg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@napi-rs/keyring@1.3.0': - resolution: {integrity: sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA==} - engines: {node: '>= 10'} - - '@napi-rs/wasm-runtime@1.1.6': - resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} - peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 - - '@nodable/entities@2.2.0': - resolution: {integrity: sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} - engines: {node: '>=8.0.0'} - - '@oxc-project/types@0.138.0': - resolution: {integrity: sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA==} - - '@oxfmt/binding-android-arm-eabi@0.56.0': - resolution: {integrity: sha512-CSCxi7ovYojgfdPOdUb9T508HKeAdDIKeRGg7x8IZwVJrWz9gVgX7MbUnFqtQAE4QvoNo07mj2JlwnOzJw4qqA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxfmt/binding-android-arm64@0.56.0': - resolution: {integrity: sha512-HYJFnd+PkDwf6S9ZPGzXXtjNqvRWFnnhdbWaouh4mi/SxU8wmDuzlMn3xo/wDTGnr4Q1VA7ZzOaE/D4biW0W6A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxfmt/binding-darwin-arm64@0.56.0': - resolution: {integrity: sha512-sftR/bEOr+t1gs+evwsHi/Xbq2FAPA2uU3VMr8n6ZU9PoK/IMSfnfu7+OEe/uy1+knhrFl4Wvy7Vkm3uo9mJ7g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxfmt/binding-darwin-x64@0.56.0': - resolution: {integrity: sha512-z66SdjLqa3MUPKvTp3Mbb5nSjKSbnYxJGeB+Wx987s8T5hPcIRiBMfnJ6zcPgYtQn3x5xjvdzNVkXrSeYH6ZFg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxfmt/binding-freebsd-x64@0.56.0': - resolution: {integrity: sha512-t2tkrV1vtZyaItSQ71dTi2ZVKZEI39b/LqLT12V5KMfIeXK6N32TUC1jhOXKVQmhECq9j2ZXMQV3JeT1kh9Vmg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxfmt/binding-linux-arm-gnueabihf@0.56.0': - resolution: {integrity: sha512-+gCy+Tp3RHeXQ9y/QrS76lXIpZkbziTyp6hIgjB2MssCwfMph3vG/GEfkhO34Rai1vhYIaUkvv8UT1BcDorJPw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm-musleabihf@0.56.0': - resolution: {integrity: sha512-0kKkVvQ2I+FJ2sxQyUu1zJ0yWP5kcWse/yVFnGQSFCXMwSSkfEaUGu0dW774O7nyy3jrcBGap7OSc8dZmU/CdA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm64-gnu@0.56.0': - resolution: {integrity: sha512-npkA2siMbyWRh+wEhi1aTAx4RirukGcGNt8V4Ch86pG+xU9aurqS1MZOnKYMu03ISwat3rB6zkQx51SsB9obNw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-arm64-musl@0.56.0': - resolution: {integrity: sha512-UekqOjGkV4/MkqreCV9SPIB2jlR3/HbXrmhV1rVXJZ9wfDXMyCMriLtq3tHqLY4PkbVWNtfcm1kMojJ26KLSJw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxfmt/binding-linux-ppc64-gnu@0.56.0': - resolution: {integrity: sha512-XSzveSpeZMD5XJpew5lRFVtNnT04xd3rJxENXmk7wkZzN9oWzv2aFJyoNDhOtoz69BYaS/fg4SYl+CfEZRpB0Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-riscv64-gnu@0.56.0': - resolution: {integrity: sha512-EkQ0nJa7k7HDDIVuPF7WY+k4k+bzdclLYtyIXNt7/OqVghfNiMym6YGppFBgx1XRIHW6QylxBz5OogumPjPJbQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-riscv64-musl@0.56.0': - resolution: {integrity: sha512-dyjAGW8jKRge0ik6U/dgvQG0nVpA3iBlRskQTz5qJLvQWIrySxX5jpqzPetLBNIIZ231KA82fDdi1nLTk8ENCw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@oxfmt/binding-linux-s390x-gnu@0.56.0': - resolution: {integrity: sha512-60ZGH3LtfqlW8X6vcLdSFY4lvCQYINurttYBKaALnHCDVAUCYJ1LsUgS6p1XOzVlzEDx3yNUZvDF1Lvt59zoZw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-x64-gnu@0.56.0': - resolution: {integrity: sha512-u1suj1tgJHK4ZqB7buCtdbNef2n8+d0lXTPJwLHNmtyK6p+DTpsaoDvmqhQrA56fgKYv4LuRxNtL8YooebKOew==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-x64-musl@0.56.0': - resolution: {integrity: sha512-aYGLvlQHt80y+qKEtfJY/Nm27G0125Lv+qyh9SJ4Cjc6lXnXjD+ndfhqQnbV24POpMi7rNRi0jvx/0d70FRpCQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxfmt/binding-openharmony-arm64@0.56.0': - resolution: {integrity: sha512-H/re/gO+7ysVc+kywHNuzY3C33EN9sQcZhg0kp1ZwOZl7y998ZE5mhnBiuGR/nYI0pqLL5xQfrHVUOJ/cIJsCA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxfmt/binding-win32-arm64-msvc@0.56.0': - resolution: {integrity: sha512-6qLNXfXmtAs8jXDvYMkxk6Wec5SUJoew+ZX1uOZmqaR7ks0EJFbAohuOCELDyJMWyVlxotVG8Xf8m74Bfq0O2w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxfmt/binding-win32-ia32-msvc@0.56.0': - resolution: {integrity: sha512-UXEXuKphAe15bsob4AswNMArCw38XSmUIs3wk1s6e6MX9OWGW/IRWU95s1hZDiVg09STy1jHgyN2qkqbu1FT0w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxfmt/binding-win32-x64-msvc@0.56.0': - resolution: {integrity: sha512-HPyNDjky+NIOuaMvHZflR+kst3YWdUOH2JUQYkf99grqZ5mEBTQM6h9iGy501Z8Xt5xMScrwHOuVCOlqDrktRw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@oxlint/binding-android-arm-eabi@1.72.0': - resolution: {integrity: sha512-zhCmvn+1Mj3UchAc/90i99S0t7jJUsHmFVSPg4UWrjO8b8eaSGwscgO6QAUtvHBstkjQwBttQNswEnAF1mIQdA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxlint/binding-android-arm64@1.72.0': - resolution: {integrity: sha512-mtH+aY/ozv1eZoCUC2owjFAtyNBKHpJHygKeEu9zXXnQGW1Q2/qOpvx+I+Lf23+TvTz66F4iiXUbl2cGvoLPCQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxlint/binding-darwin-arm64@1.72.0': - resolution: {integrity: sha512-EvnajNPDtfknB3ZieeOOyDTwJn9QXDiwfnF4ZDQqART6RG6hjY4WigQcZdGoK2dkB3e1vrmEzN9aYbQCUkh/gQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxlint/binding-darwin-x64@1.72.0': - resolution: {integrity: sha512-ZkCdEa/G80A7vEHfeCDz/+L3m33DE73v32mDKhgOIgz8Uwf0DFcK7+uu6qC+7LEhmz5fpOe1osWKyjSNMydFIQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxlint/binding-freebsd-x64@1.72.0': - resolution: {integrity: sha512-NroXv2vh+sxVY1uya/rM5pjhx1hm8BzlYpx9q67QP0Xhw5MH2bf5GJylpvLEC+781p1Xli/317EoV9AlGwViag==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxlint/binding-linux-arm-gnueabihf@1.72.0': - resolution: {integrity: sha512-0NDywYgfj279Ou/BcQuCYSj7NJwBfmWn5qc5uGO/Ny7fUWmXyIpvawqX/8acQlWG6IXelJsJhj+JAy6sjsKj0A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm-musleabihf@1.72.0': - resolution: {integrity: sha512-4vpXB06h65Ezsy4hRyrGjGrfa1SkVPii09yaajiYhmVpgsFiLD+KNxIx/BNAY+XiO+i1yqp9HHdwqM8VTqa5XQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm64-gnu@1.72.0': - resolution: {integrity: sha512-immaN4g2ZGFiOkKrvRX9LvzZdd2GkQM5wR+UyzYyUuyhUTXGQ4HKUJH18xp4G8OfhCVaVAJfKZxwE1r8+4hhaQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-arm64-musl@1.72.0': - resolution: {integrity: sha512-JGHS9Mnr7iWyyLDxgCv1MhzVpAckgptg00F2gnxt/GD7lQ2SW1BRcxHqhSTaSdDpjWRrBkBxMMh4+Hn3aVtExg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxlint/binding-linux-ppc64-gnu@1.72.0': - resolution: {integrity: sha512-AOYgBZqxNshrg83P9v0RYv+m8s10Cqkj4/PxXFDhcS3k7FqsIG5+CxErshZCIN7G8iy4Y+VGfAsuEdar8AcbBg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-riscv64-gnu@1.72.0': - resolution: {integrity: sha512-QMybPS5ij3/vrKG67mqzHwW++91sYxK/PPUVi6SBtNCEzW4niS52fVBdXbQ6nou0wWbUPEpx8Sl/ZjtgE3clXA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-riscv64-musl@1.72.0': - resolution: {integrity: sha512-gOc3W7JV0PXRpIL7stUlLe3Wa9Gp0Kdlup87IT3gHDvPKck2xNgMIl/Gs2lldYY2lyXZDC4rWi3hmoLUobkgbQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@oxlint/binding-linux-s390x-gnu@1.72.0': - resolution: {integrity: sha512-rpGxph+FjjHcYI5q6uxB3Az+tnfmEnDbSA8+PK9ZE/VzyUAkvBOMeuY7ZQMhu5mpZH7YQDsTdW6Cx4kV/msc6w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-x64-gnu@1.72.0': - resolution: {integrity: sha512-WND+uhf/Ko13SLqQMWQUgsZuLvYYEvL0ZKgg0tgGYfLqxG7l8Ju123fHDMJyYSDl5E3bUbpFUuii/OvMreFQzw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-x64-musl@1.72.0': - resolution: {integrity: sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxlint/binding-openharmony-arm64@1.72.0': - resolution: {integrity: sha512-qkrsEn6NmgFKr7U/QnezQMb+q/vzAy0Dd9Y95gQGQTyjzDLN+HRZMuM5u70iyH4nBLCfKBzhjMsYCehKay2jyg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxlint/binding-win32-arm64-msvc@1.72.0': - resolution: {integrity: sha512-LWR6ZlFZph+KPjXv8opgZsXRDCdrdQe8VL8Cg9zxCoBS73h6znzZpydVgmdnwj8mB9AuSM5jxEgDJDpQkjboeg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxlint/binding-win32-ia32-msvc@1.72.0': - resolution: {integrity: sha512-yt6HEh7IsHvtjRWtmeZRX134eaXKHq5Gnqlf1xBJdJl1JtdoRUEJw3nAxpZoUDS860cX/foKbztO441anVBtVQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxlint/binding-win32-x64-msvc@1.72.0': - resolution: {integrity: sha512-b2eKFD2hX7tIwmo/cyH6TDq8vzWRZ2qNHrzoGntUTmq0h3zQh/uX3eTSHCwI8OB/ADQfJCRelLItK8BsxuucDA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - - '@redocly/ajv@8.18.1': - resolution: {integrity: sha512-Ifm/pP/tul1qmAecpbVxCBluVE32rKfjf8gYXH4xI2gCv9mRWFhJMHzkPDM4TXlxwPQYIFegymlsy8lXz7optA==} - - '@redocly/ajv@8.18.3': - resolution: {integrity: sha512-l42u0of3hY98sN2A+M4qTX1O/KrpgGH32Hu9kP2GtHyD5Dfqq86PKFLe5dwaD8DEnNmlOlll2BAmeEtf0DaySg==} - - '@redocly/config@0.50.1': - resolution: {integrity: sha512-TrdZUK50baxIjJB/y2ROOqfg35ex+GbkHPoJ40kXQXKMOjrfxfYQ9IliiaLqT5H/Y8qbajPrYQN2DLfvcMaHSw==} - - '@redocly/openapi-core@2.37.0': - resolution: {integrity: sha512-i+q5+3ciI+KjMpcPsec1XO7V3l83g/aX1kZRmuPhJQilKMY2cBDl9M3O9r8httDK9v+V19mF3iIGcjxlJcUlrg==} - engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} - - '@rolldown/binding-android-arm64@1.1.4': - resolution: {integrity: sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.1.4': - resolution: {integrity: sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.1.4': - resolution: {integrity: sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.1.4': - resolution: {integrity: sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.1.4': - resolution: {integrity: sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.1.4': - resolution: {integrity: sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-musl@1.1.4': - resolution: {integrity: sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-ppc64-gnu@1.1.4': - resolution: {integrity: sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-s390x-gnu@1.1.4': - resolution: {integrity: sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.1.4': - resolution: {integrity: sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-musl@1.1.4': - resolution: {integrity: sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-openharmony-arm64@1.1.4': - resolution: {integrity: sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.1.4': - resolution: {integrity: sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.1.4': - resolution: {integrity: sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.1.4': - resolution: {integrity: sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - - '@smithy/core@3.29.1': - resolution: {integrity: sha512-qoiY4nrk5OCu1+eIR1VB8l5DmON/oKiqrd5zZFAhXJXjJlLWQusKEW/SkBDAtGDcPaz86m9kfcE1lngU0GlM6A==} - engines: {node: '>=18.0.0'} - - '@smithy/credential-provider-imds@4.4.6': - resolution: {integrity: sha512-B2WQ/PV/H6Jeg3lrIq6bKUfa6Hy01mtK7CGs6lhjzHA6k4aagldH6T6eEjnzKl4HI0cJnAsxfJ19pgb5PV+CVQ==} - engines: {node: '>=18.0.0'} - - '@smithy/fetch-http-handler@5.6.3': - resolution: {integrity: sha512-CwCc/7SMTj45y97MUnDTbTaxvtAsiNNRm81z3abROIuMbMsC2Iy5EKfkkVdsKrz8WExQAAMx1EJapq+9j4fFTQ==} - engines: {node: '>=18.0.0'} - - '@smithy/node-http-handler@4.9.3': - resolution: {integrity: sha512-qZTa4gQFUo8RM02rk6q5UVTDLNrQ1oS20LsepBzqq1QBVc/EHJ03OOUADcqMZiXHArW+Y7+OGY0BpdTwZRq/Yg==} - engines: {node: '>=18.0.0'} - - '@smithy/signature-v4@5.6.2': - resolution: {integrity: sha512-QgHflghMoPxCJ9axiCVh8KZfbC9fuP6vkXXyK//E3cq7nLaSSyyLj0GAoqVWezYeDQmXIZhmlRvLE16jsqDK6g==} - engines: {node: '>=18.0.0'} - - '@smithy/types@4.15.1': - resolution: {integrity: sha512-x3L0XSACF6UYzKpa9biqiRMgvH5+wnFFew9Tm/grFYqgaupPwx/+ojDPpPJM8dZON3S9tjz5U+PQYsCBd1Mw5Q==} - engines: {node: '>=18.0.0'} - - '@stablelib/base64@1.0.1': - resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@statelyai/inspect@0.7.2': - resolution: {integrity: sha512-axuXSEBsI8pQ89rP2DWq+kHLjABiXpe2qYDOo6+jVLJ+9NPOTjutMnmDd+XcJjn76d+RH6sfHa0XkFIYPUHDOw==} - peerDependencies: - xstate: ^5.5.1 - - '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@22.20.0': - resolution: {integrity: sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==} - - '@types/opn@5.5.0': - resolution: {integrity: sha512-rfEmrSa/x0vArY1aFnVTBAmy6b2I0oNHONL59qR+vnsHfD5xacM40O4PSiVisERq/GmROjmS3Xo/ptp8fx823g==} - deprecated: This is a stub types definition. opn provides its own type definitions, so you do not need this installed. - - '@types/react@19.2.17': - resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} - - '@types/semver@7.7.1': - resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} - - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - - '@types/yargs@17.0.35': - resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - - '@vitest/coverage-v8@4.1.10': - resolution: {integrity: sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==} - peerDependencies: - '@vitest/browser': 4.1.10 - vitest: 4.1.10 - peerDependenciesMeta: - '@vitest/browser': - optional: true - - '@vitest/expect@4.1.10': - resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} - - '@vitest/mocker@4.1.10': - resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@4.1.10': - resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} - - '@vitest/runner@4.1.10': - resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} - - '@vitest/snapshot@4.1.10': - resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} - - '@vitest/spy@4.1.10': - resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} - - '@vitest/ui@4.1.10': - resolution: {integrity: sha512-EOUqfXHTXtpSHsyLHH40ts3Ue+hRhSGwzwzMlK0dTEOLSDYyOXLyr5JDGmHQWhN2DYI30gw6dVx3cdgM9FZl+Q==} - peerDependencies: - vitest: 4.1.10 - - '@vitest/utils@4.1.10': - resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} - - '@workos-inc/node@10.7.0': - resolution: {integrity: sha512-rffa9znZuIv4yo+9JRxGOLTTSxh0XhOT6jlsktgqEi9MuB9V0VFHRzLd3bTpkq+J9sgrPZNGpvX4aWNfMqt5cQ==} - engines: {node: '>=22.11.0'} - - '@workos-inc/node@8.13.0': - resolution: {integrity: sha512-NgQKHpwh8AbT4KvAsW91Y+4f4jja2IvFPQ5atcy5NUxUMVRgXzRFEee3erawfXrTmiCVqJjd9PljHySKBXmHKQ==} - engines: {node: '>=20.15.0'} - - '@workos/emulate@0.1.0': - resolution: {integrity: sha512-0f4g99yh6Ozf7wfdVlcAktrkyq2ejmweanXFnn0KMfTYdsYO5/oDgBFw+MVLhx9CoslDp2ApPgdImMZTeJ1n6g==} - engines: {node: '>=22.11'} - hasBin: true - - '@workos/migrations@2.5.0': - resolution: {integrity: sha512-2kBiKOf0djjQIThpi43POWy76Dkvx8fFtKvdKtMNiOk5rJqyjsX3Y3oU7JjSx+gZJTfW2YfdDXrQhPnWzdyiUw==} - engines: {node: '>=22.11.0'} - hasBin: true - - '@workos/oagen@0.23.0': - resolution: {integrity: sha512-9eB6OnGr29VxPg/tBWKEI5B6C39v+lrqZpBZXbO5E2hEl+3hHUXAOrtGlMbZh4nLrXiwo16meDryEny1LDvjPw==} - engines: {node: '>=24.10.0'} - hasBin: true - - '@workos/openapi-spec@0.14.0': - resolution: {integrity: sha512-mjh0K8RRWfo+sg9O6XWuNQ6PouzQzWzpMZKLn867fldfA7gDNNDR1d2Nqi/p6KRJBXLDEIfc8fdFb9HXJW/NcA==} - - '@workos/skills@0.6.1': - resolution: {integrity: sha512-2YovBOFM1u3any7JVMIrwLOomSXT/Ndft1+QAl8YalDowWxXqBqiyebebZvm47jb6BI6rIR04svG2xI5c5rcjA==} - - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - - ajv-formats@3.0.1: - resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv@8.20.0: - resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - - ansi-escapes@7.3.0: - resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} - engines: {node: '>=18'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} - - anynum@1.0.1: - resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - ast-v8-to-istanbul@1.0.4: - resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} - - auto-bind@5.0.1: - resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - bignumber.js@9.3.1: - resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} - - body-parser@2.3.0: - resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} - engines: {node: '>=18'} - - bowser@2.14.1: - resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - - bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} - engines: {node: '>=18'} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} - - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - cli-boxes@3.0.0: - resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} - engines: {node: '>=10'} - - cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cli-progress@3.12.0: - resolution: {integrity: sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==} - engines: {node: '>=4'} - - cli-truncate@5.1.1: - resolution: {integrity: sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==} - engines: {node: '>=20'} - - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - cliui@9.0.1: - resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} - engines: {node: '>=20'} - - code-excerpt@4.0.0: - resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - colorette@1.4.0: - resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} - - commander@13.1.0: - resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} - engines: {node: '>=18'} - - commander@15.0.0: - resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} - engines: {node: '>=22.12.0'} - - content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} - engines: {node: '>=18'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - content-type@2.0.0: - resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} - engines: {node: '>=18'} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - convert-to-spaces@2.0.1: - resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} - engines: {node: '>=12.13'} - - cors@2.8.6: - resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} - engines: {node: '>= 0.10'} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - csv-parse@6.2.1: - resolution: {integrity: sha512-LRLMV+UCyfMokp8Wb411duBf1gaBKJfOfBWU9eHMJ+b+cJYZsNu3AFmjJf3+yPGd59Exz1TsMjaSFyxnYB9+IQ==} - - csv-stringify@6.8.1: - resolution: {integrity: sha512-tZ6X6TKQyQgCo5OptXcyAbfN1pwmoxEqELPQ7KFazNErx7kiVsDK8o+VYRXhfMl4N9vvOOLXuioquR2MeP847A==} - - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - default-browser-id@5.0.1: - resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} - engines: {node: '>=18'} - - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} - engines: {node: '>=18'} - - define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - diff@8.0.4: - resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} - engines: {node: '>=0.3.1'} - - dotenv@17.4.2: - resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} - engines: {node: '>=12'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - environment@1.1.0: - resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} - engines: {node: '>=18'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@2.3.0: - resolution: {integrity: sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==} - - es-object-atoms@1.1.2: - resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} - engines: {node: '>= 0.4'} - - es-toolkit@1.44.0: - resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==} - - esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - event-target-shim@6.0.2: - resolution: {integrity: sha512-8q3LsZjRezbFZ2PN+uP+Q7pnHUMmAOziU2vA2OwoFaKIXxlxl38IylhSSgUorWu/rf4er67w0ikBqjBFk/pomA==} - engines: {node: '>=10.13.0'} - - eventemitter3@5.0.4: - resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} - - eventsource-parser@3.1.0: - resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} - engines: {node: '>=18.0.0'} - - eventsource@3.0.7: - resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} - engines: {node: '>=18.0.0'} - - expect-type@1.4.0: - resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} - engines: {node: '>=12.0.0'} - - express-rate-limit@8.5.2: - resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==} - engines: {node: '>= 16'} - peerDependencies: - express: '>= 4.11' - - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - - fast-sha256@1.3.0: - resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} - - fast-string-truncated-width@3.0.3: - resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} - - fast-string-width@3.0.2: - resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - - fast-uri@3.1.3: - resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==} - - fast-wrap-ansi@0.2.2: - resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} - - fast-xml-builder@1.2.1: - resolution: {integrity: sha512-tPb5TTWfgfVx5BNSi2xV0eLr89POeXXn0dXIsCJ9m1narrWxeIyx6je9d7Rce/3NyXLbvuQmLkxq+RuxMWejvw==} - - fast-xml-parser@5.9.3: - resolution: {integrity: sha512-brCNCeScma/kqa54J4PIDriSSSLssRkuYaUCpvHJulGc3HGI/xxKUCTDcYkAdqJsyb//ydpbxecjC3hB9+tb/g==} - hasBin: true - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - - fflate@0.8.3: - resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} - - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - gaxios@7.1.6: - resolution: {integrity: sha512-aIQ0QL8Or8vsUhHyXGA6AohOFRrAAiHhrvsAG6myzcSlfhxSXtnwXA/pRuQTilFgjhLe30swK5rg1d7E1f8Izw==} - engines: {node: '>=18'} - - gcp-metadata@8.1.2: - resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} - engines: {node: '>=18'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-east-asian-width@1.3.0: - resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} - engines: {node: '>=18'} - - get-east-asian-width@1.5.0: - resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} - engines: {node: '>=18'} - - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} - engines: {node: '>=18'} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - google-auth-library@10.9.0: - resolution: {integrity: sha512-xtvUqvINPhTaBm7nXqlYPcrMHJPm1lCNdSovxnKKhTm+4JsvQ+KGVYJViLoH9Yxu8w+T0Qv5HubzYT9BLrppJg==} - engines: {node: '>=18'} - - google-logging-utils@1.1.3: - resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} - engines: {node: '>=14'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graphql@16.14.2: - resolution: {integrity: sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - hasown@2.0.4: - resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} - engines: {node: '>= 0.4'} - - headers-polyfill@4.0.3: - resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} - - hono@4.12.28: - resolution: {integrity: sha512-YwUvVpSF7m1yOblFPrU3Hbo8XhPheBoiyfGuII6z19LnOr6JpDnyyp7LFNrfV56wS8tpvtBFGRISHN02pDdLOA==} - engines: {node: '>=16.9.0'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - - iconv-lite@0.7.3: - resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} - engines: {node: '>=0.10.0'} - - indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ink@6.8.0: - resolution: {integrity: sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA==} - engines: {node: '>=20'} - peerDependencies: - '@types/react': '>=19.0.0' - react: '>=19.0.0' - react-devtools-core: '>=6.1.2' - peerDependenciesMeta: - '@types/react': - optional: true - react-devtools-core: - optional: true - - ip-address@10.2.0: - resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} - engines: {node: '>= 12'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-fullwidth-code-point@5.0.0: - resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} - engines: {node: '>=18'} - - is-fullwidth-code-point@5.1.0: - resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} - engines: {node: '>=18'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-in-ci@2.0.0: - resolution: {integrity: sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==} - engines: {node: '>=20'} - hasBin: true - - is-in-ssh@1.0.0: - resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} - engines: {node: '>=20'} - - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - - is-unsafe@1.0.1: - resolution: {integrity: sha512-CLK2+VdgERgD96EYm5lUQssZYlRg2tkZnbsxZoacmSiRxiFJ4Nk4SzjCl+Ur+v3kXIY9dTIdb3IH22y1mZ56LA==} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - is-wsl@1.1.0: - resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} - engines: {node: '>=4'} - - is-wsl@3.1.1: - resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} - engines: {node: '>=16'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isomorphic-ws@5.0.0: - resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} - peerDependencies: - ws: '*' - - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - - jose@6.2.3: - resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} - - js-levenshtein@1.1.6: - resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} - engines: {node: '>=0.10.0'} - - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - - js-yaml@4.3.0: - resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} - hasBin: true - - json-bigint@1.0.0: - resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} - - json-schema-to-ts@2.7.2: - resolution: {integrity: sha512-R1JfqKqbBR4qE8UyBR56Ms30LL62/nlhoz+1UkfI/VE7p54Awu919FZ6ZUPG8zIa3XB65usPJgr1ONVncUGSaQ==} - engines: {node: '>=16'} - - json-schema-to-ts@3.1.1: - resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} - engines: {node: '>=16'} - - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - json-schema-typed@8.0.2: - resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} - - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - - jwa@2.0.1: - resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} - - jws@4.0.1: - resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - magicast@0.5.3: - resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - msw@2.10.4: - resolution: {integrity: sha512-6R1or/qyele7q3RyPwNuvc0IxO8L8/Aim6Sz5ncXEgcWUNxSKE+udriTOWHtpMwmfkLYlacA2y7TIx4cL5lgHA==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - typescript: '>= 4.8.x' - peerDependenciesMeta: - typescript: - optional: true - - mute-stream@2.0.0: - resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} - engines: {node: ^18.17.0 || >=20.5.0} - - nanoid@3.3.15: - resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - - node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - - node-addon-api@8.9.0: - resolution: {integrity: sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q==} - engines: {node: ^18 || ^20 || >= 21} - - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead - - node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} - hasBin: true - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - - obug@2.1.3: - resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} - engines: {node: '>=12.20.0'} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - open@11.0.0: - resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} - engines: {node: '>=20'} - - opn@6.0.0: - resolution: {integrity: sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==} - engines: {node: '>=8'} - deprecated: The package has been renamed to `open` - - outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - - oxfmt@0.56.0: - resolution: {integrity: sha512-9Dv0wV3zKiyvhjD7bRKaInKmHQ1sPx3RGOjQkGFJbbdQ16576yf8qhMSO9Q9cvHcs+1NpBsRTkuDDYFFPTJ6gw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - svelte: ^5.0.0 - vite-plus: '*' - peerDependenciesMeta: - svelte: - optional: true - vite-plus: - optional: true - - oxlint@1.72.0: - resolution: {integrity: sha512-1rhdZIP/EvoI91ABIwNU5Q8+bWf8mjrS5UzIOZld4d4bXxJvtlUhlQvaoTogIGin/qdErMOrwaIJvCSIAKTLhA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - oxlint-tsgolint: '>=0.22.1' - vite-plus: '*' - peerDependenciesMeta: - oxlint-tsgolint: - optional: true - vite-plus: - optional: true - - p-limit@7.3.0: - resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} - engines: {node: '>=20'} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - partysocket@0.0.25: - resolution: {integrity: sha512-1oCGA65fydX/FgdnsiBh68buOvfxuteoZVSb3Paci2kRp/7lhF0HyA8EDb5X/O6FxId1e+usPTQNRuzFEvkJbQ==} - - patch-console@2.0.0: - resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - path-expression-matcher@1.6.1: - resolution: {integrity: sha512-h7bxdzhHk8Knyc4Tj+jMaa7fEEoUJy7p1qtbVgkYg1Uhpe5Np5VuGXCRZnkZvU+Q42M1vStt0ifa3ueykRJPmQ==} - engines: {node: '>=14.0.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - - path-to-regexp@8.4.2: - resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} - - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - - picomatch@4.0.5: - resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} - engines: {node: '>=12'} - - pkce-challenge@5.0.1: - resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} - engines: {node: '>=16.20.0'} - - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - postcss@8.5.16: - resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} - engines: {node: ^10 || ^12 || >=14} - - powershell-utils@0.1.0: - resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} - engines: {node: '>=20'} - - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - qs@6.15.3: - resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} - engines: {node: '>=0.6'} - - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - range-parser@1.3.0: - resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} - engines: {node: '>= 0.6'} - - raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} - - react-reconciler@0.33.0: - resolution: {integrity: sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==} - engines: {node: '>=0.10.0'} - peerDependencies: - react: ^19.2.0 - - react@19.2.7: - resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} - engines: {node: '>=0.10.0'} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - - restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rolldown@1.1.4: - resolution: {integrity: sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - - run-applescript@7.1.0: - resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} - engines: {node: '>=18'} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - - semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} - engines: {node: '>=10'} - hasBin: true - - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.1: - resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} - engines: {node: '>= 0.4'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sirv@3.0.2: - resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} - engines: {node: '>=18'} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - slice-ansi@7.1.2: - resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} - engines: {node: '>=18'} - - slice-ansi@8.0.0: - resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} - engines: {node: '>=20'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - standardwebhooks@1.0.0: - resolution: {integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} - - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - string-width@8.2.0: - resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} - engines: {node: '>=20'} - - string-width@8.2.1: - resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} - engines: {node: '>=20'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} - - strnum@2.4.1: - resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==} - - superjson@1.13.3: - resolution: {integrity: sha512-mJiVjfd2vokfDxsQPOwJ/PtanO87LhpYY88ubI5dUB1Ab58Txbyje3+jpm+/83R/fevaq/107NNhtYBLuoTrFg==} - engines: {node: '>=10'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - - terminal-size@4.0.1: - resolution: {integrity: sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==} - engines: {node: '>=18'} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} - engines: {node: '>=18'} - - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} - - tinypool@2.1.0: - resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} - engines: {node: ^20.0.0 || >=22.0.0} - - tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} - engines: {node: '>=14.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} - engines: {node: '>=6'} - - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - - tree-sitter-c-sharp@0.23.1: - resolution: {integrity: sha512-9zZ4FlcTRWWfRf6f4PgGhG8saPls6qOOt75tDfX7un9vQZJmARjPrAC6yBNCX2T/VKcCjIDbgq0evFaB3iGhQw==} - peerDependencies: - tree-sitter: ^0.21.1 - peerDependenciesMeta: - tree-sitter: - optional: true - - tree-sitter-elixir@0.3.5: - resolution: {integrity: sha512-xozQMvYK0aSolcQZAx2d84Xe/YMWFuRPYFlLVxO01bM2GITh5jyiIp0TqPCQa8754UzRAI7A83hZmfiYub5TZQ==} - peerDependencies: - tree-sitter: ^0.21.0 - - tree-sitter-go@0.23.4: - resolution: {integrity: sha512-iQaHEs4yMa/hMo/ZCGqLfG61F0miinULU1fFh+GZreCRtKylFLtvn798ocCZjO2r/ungNZgAY1s1hPFyAwkc7w==} - peerDependencies: - tree-sitter: ^0.21.1 - peerDependenciesMeta: - tree-sitter: - optional: true - - tree-sitter-javascript@0.23.1: - resolution: {integrity: sha512-/bnhbrTD9frUYHQTiYnPcxyHORIw157ERBa6dqzaKxvR/x3PC4Yzd+D1pZIMS6zNg2v3a8BZ0oK7jHqsQo9fWA==} - peerDependencies: - tree-sitter: ^0.21.1 - peerDependenciesMeta: - tree-sitter: - optional: true - - tree-sitter-kotlin@https://codeload.github.com/fwcd/tree-sitter-kotlin/tar.gz/f66d2908542e93c0204c6c241f794afe4e9cd5d1: - resolution: {gitHosted: true, integrity: sha512-7pk1Tg/gXh+6hM4E0F2rPKeLyA/bNlYyqVu6T1Md/AV/vloakbvEZG0R4CYwUfVtgFAMZRbOtA8JBzX1SFatBA==, tarball: https://codeload.github.com/fwcd/tree-sitter-kotlin/tar.gz/f66d2908542e93c0204c6c241f794afe4e9cd5d1} - version: 0.4.0 - peerDependencies: - tree-sitter: ^0.21.1 - tree_sitter: '*' - peerDependenciesMeta: - tree_sitter: - optional: true - - tree-sitter-php@0.23.12: - resolution: {integrity: sha512-VwkBVOahhC2NYXK/Fuqq30NxuL/6c2hmbxEF4jrB7AyR5rLc7nT27mzF3qoi+pqx9Gy2AbXnGezF7h4MeM6YRA==} - peerDependencies: - tree-sitter: ^0.21.1 - peerDependenciesMeta: - tree-sitter: - optional: true - - tree-sitter-python@0.21.0: - resolution: {integrity: sha512-IUKx7JcTVbByUx1iHGFS/QsIjx7pqwTMHL9bl/NGyhyyydbfNrpruo2C7W6V4KZrbkkCOlX8QVrCoGOFW5qecg==} - peerDependencies: - tree-sitter: ^0.21.0 - tree_sitter: '*' - peerDependenciesMeta: - tree_sitter: - optional: true - - tree-sitter-ruby@0.21.0: - resolution: {integrity: sha512-UrMpF9CZxKbZ5UFuPdXDuraaaYSMMlAiuzTpQXwNm7y0D48ibc9stWU5D6vDyJD0qf5/R+3yKTYHdHkqibmLSQ==} - peerDependencies: - tree-sitter: ^0.21.0 - tree_sitter: '*' - peerDependenciesMeta: - tree_sitter: - optional: true - - tree-sitter-rust@0.21.0: - resolution: {integrity: sha512-unVr73YLn3VC4Qa/GF0Nk+Wom6UtI526p5kz9Rn2iZSqwIFedyCZ3e0fKCEmUJLIPGrTb/cIEdu3ZUNGzfZx7A==} - peerDependencies: - tree-sitter: ^0.21.1 - tree_sitter: '*' - peerDependenciesMeta: - tree_sitter: - optional: true - - tree-sitter-typescript@0.23.2: - resolution: {integrity: sha512-e04JUUKxTT53/x3Uq1zIL45DoYKVfHH4CZqwgZhPg5qYROl5nQjV+85ruFzFGZxu+QeFVbRTPDRnqL9UbU4VeA==} - peerDependencies: - tree-sitter: ^0.21.0 - peerDependenciesMeta: - tree-sitter: - optional: true - - tree-sitter@0.21.1: - resolution: {integrity: sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==} - - ts-algebra@1.2.2: - resolution: {integrity: sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA==} - - ts-algebra@2.0.0: - resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tsx@4.23.0: - resolution: {integrity: sha512-eUdUIaCr963q2h5u3+QwvYp0+eqPvn+egeqZUm0hwERCqqx1E3kK5ehbGCvqSE5MQAULr67ww0cA3jKc3YkM1w==} - engines: {node: '>=18.0.0'} - hasBin: true - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - type-fest@5.4.4: - resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==} - engines: {node: '>=20'} - - type-is@2.1.0: - resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} - engines: {node: '>= 18'} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - - uuid@13.0.2: - resolution: {integrity: sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw==} - hasBin: true - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - vite@8.1.3: - resolution: {integrity: sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.3.0 - esbuild: ^0.27.0 || ^0.28.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@4.1.10: - resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.10 - '@vitest/browser-preview': 4.1.10 - '@vitest/browser-webdriverio': 4.1.10 - '@vitest/coverage-istanbul': 4.1.10 - '@vitest/coverage-v8': 4.1.10 - '@vitest/ui': 4.1.10 - happy-dom: '*' - jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/browser-playwright': - optional: true - '@vitest/browser-preview': - optional: true - '@vitest/browser-webdriverio': - optional: true - '@vitest/coverage-istanbul': - optional: true - '@vitest/coverage-v8': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - - widest-line@6.0.0: - resolution: {integrity: sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA==} - engines: {node: '>=20'} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} - engines: {node: '>=18'} - - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - ws@8.21.0: - resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - wsl-utils@0.3.1: - resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} - engines: {node: '>=20'} - - xml-naming@0.1.0: - resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==} - engines: {node: '>=16.0.0'} - - xstate@5.32.4: - resolution: {integrity: sha512-E5WtDB8DBs2ZWliz2Ry9XfbSZTbBRcK/cwefBot04qQ/L5SLP16xpnTDU4/ZFXuXFhNxi7JP2RhuoGwBnM+S4A==} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yaml-ast-parser@0.0.43: - resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} - - yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} - hasBin: true - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs-parser@22.0.0: - resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - - yargs@17.7.3: - resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} - engines: {node: '>=12'} - - yargs@18.0.0: - resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - - yocto-queue@1.2.2: - resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} - engines: {node: '>=12.20'} - - yoctocolors-cjs@2.1.3: - resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} - engines: {node: '>=18'} - - yoga-layout@3.2.1: - resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} - - zod-to-json-schema@3.25.2: - resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} - peerDependencies: - zod: ^3.25.28 || ^4 - - zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} - -snapshots: - - '@alcalzone/ansi-tokenize@0.2.5': - dependencies: - ansi-styles: 6.2.3 - is-fullwidth-code-point: 5.1.0 - - '@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk-win32-x64@0.3.201': - optional: true - - '@anthropic-ai/claude-agent-sdk@0.3.201(@anthropic-ai/sdk@0.106.0(zod@4.4.3))(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)': - dependencies: - '@anthropic-ai/sdk': 0.106.0(zod@4.4.3) - '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) - zod: 4.4.3 - optionalDependencies: - '@anthropic-ai/claude-agent-sdk-darwin-arm64': 0.3.201 - '@anthropic-ai/claude-agent-sdk-darwin-x64': 0.3.201 - '@anthropic-ai/claude-agent-sdk-linux-arm64': 0.3.201 - '@anthropic-ai/claude-agent-sdk-linux-arm64-musl': 0.3.201 - '@anthropic-ai/claude-agent-sdk-linux-x64': 0.3.201 - '@anthropic-ai/claude-agent-sdk-linux-x64-musl': 0.3.201 - '@anthropic-ai/claude-agent-sdk-win32-arm64': 0.3.201 - '@anthropic-ai/claude-agent-sdk-win32-x64': 0.3.201 - - '@anthropic-ai/sdk@0.106.0(zod@4.4.3)': - dependencies: - json-schema-to-ts: 3.1.1 - standardwebhooks: 1.0.0 - optionalDependencies: - zod: 4.4.3 - - '@aws-sdk/client-cognito-identity-provider@3.1079.0': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/credential-provider-node': 3.972.62 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/fetch-http-handler': 5.6.3 - '@smithy/node-http-handler': 4.9.3 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/core@3.974.27': - dependencies: - '@aws-sdk/types': 3.973.15 - '@aws-sdk/xml-builder': 3.972.33 - '@aws/lambda-invoke-store': 0.3.0 - '@smithy/core': 3.29.1 - '@smithy/signature-v4': 5.6.2 - '@smithy/types': 4.15.1 - bowser: 2.14.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-env@3.972.53': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-http@3.972.55': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/fetch-http-handler': 5.6.3 - '@smithy/node-http-handler': 4.9.3 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-ini@3.972.60': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/credential-provider-env': 3.972.53 - '@aws-sdk/credential-provider-http': 3.972.55 - '@aws-sdk/credential-provider-login': 3.972.59 - '@aws-sdk/credential-provider-process': 3.972.53 - '@aws-sdk/credential-provider-sso': 3.972.59 - '@aws-sdk/credential-provider-web-identity': 3.972.59 - '@aws-sdk/nested-clients': 3.997.27 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/credential-provider-imds': 4.4.6 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-login@3.972.59': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/nested-clients': 3.997.27 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-node@3.972.62': - dependencies: - '@aws-sdk/credential-provider-env': 3.972.53 - '@aws-sdk/credential-provider-http': 3.972.55 - '@aws-sdk/credential-provider-ini': 3.972.60 - '@aws-sdk/credential-provider-process': 3.972.53 - '@aws-sdk/credential-provider-sso': 3.972.59 - '@aws-sdk/credential-provider-web-identity': 3.972.59 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/credential-provider-imds': 4.4.6 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-process@3.972.53': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-sso@3.972.59': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/nested-clients': 3.997.27 - '@aws-sdk/token-providers': 3.1079.0 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/credential-provider-web-identity@3.972.59': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/nested-clients': 3.997.27 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/nested-clients@3.997.27': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/signature-v4-multi-region': 3.996.38 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/fetch-http-handler': 5.6.3 - '@smithy/node-http-handler': 4.9.3 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/signature-v4-multi-region@3.996.38': - dependencies: - '@aws-sdk/types': 3.973.15 - '@smithy/signature-v4': 5.6.2 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/token-providers@3.1079.0': - dependencies: - '@aws-sdk/core': 3.974.27 - '@aws-sdk/nested-clients': 3.997.27 - '@aws-sdk/types': 3.973.15 - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/types@3.973.15': - dependencies: - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws-sdk/xml-builder@3.972.33': - dependencies: - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@aws/lambda-invoke-store@0.3.0': {} - - '@babel/helper-string-parser@7.29.7': {} - - '@babel/helper-validator-identifier@7.29.7': {} - - '@babel/parser@7.29.7': - dependencies: - '@babel/types': 7.29.7 - - '@babel/runtime@7.29.7': {} - - '@babel/types@7.29.7': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - - '@bcoe/v8-coverage@1.0.2': {} - - '@bundled-es-modules/cookie@2.0.1': - dependencies: - cookie: 0.7.2 - optional: true - - '@bundled-es-modules/statuses@1.0.1': - dependencies: - statuses: 2.0.2 - optional: true - - '@bundled-es-modules/tough-cookie@0.1.6': - dependencies: - '@types/tough-cookie': 4.0.5 - tough-cookie: 4.1.4 - optional: true - - '@clack/core@1.4.2': - dependencies: - fast-wrap-ansi: 0.2.2 - sisteransi: 1.0.5 - - '@clack/core@1.4.3': - dependencies: - fast-wrap-ansi: 0.2.2 - sisteransi: 1.0.5 - - '@clack/prompts@1.6.0': - dependencies: - '@clack/core': 1.4.2 - fast-string-width: 3.0.2 - fast-wrap-ansi: 0.2.2 - sisteransi: 1.0.5 - - '@emnapi/core@1.11.1': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.11.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.28.1': - optional: true - - '@esbuild/android-arm64@0.28.1': - optional: true - - '@esbuild/android-arm@0.28.1': - optional: true - - '@esbuild/android-x64@0.28.1': - optional: true - - '@esbuild/darwin-arm64@0.28.1': - optional: true - - '@esbuild/darwin-x64@0.28.1': - optional: true - - '@esbuild/freebsd-arm64@0.28.1': - optional: true - - '@esbuild/freebsd-x64@0.28.1': - optional: true - - '@esbuild/linux-arm64@0.28.1': - optional: true - - '@esbuild/linux-arm@0.28.1': - optional: true - - '@esbuild/linux-ia32@0.28.1': - optional: true - - '@esbuild/linux-loong64@0.28.1': - optional: true - - '@esbuild/linux-mips64el@0.28.1': - optional: true - - '@esbuild/linux-ppc64@0.28.1': - optional: true - - '@esbuild/linux-riscv64@0.28.1': - optional: true - - '@esbuild/linux-s390x@0.28.1': - optional: true - - '@esbuild/linux-x64@0.28.1': - optional: true - - '@esbuild/netbsd-arm64@0.28.1': - optional: true - - '@esbuild/netbsd-x64@0.28.1': - optional: true - - '@esbuild/openbsd-arm64@0.28.1': - optional: true - - '@esbuild/openbsd-x64@0.28.1': - optional: true - - '@esbuild/openharmony-arm64@0.28.1': - optional: true - - '@esbuild/sunos-x64@0.28.1': - optional: true - - '@esbuild/win32-arm64@0.28.1': - optional: true - - '@esbuild/win32-ia32@0.28.1': - optional: true - - '@esbuild/win32-x64@0.28.1': - optional: true - - '@hono/node-server@1.19.14(hono@4.12.28)': - dependencies: - hono: 4.12.28 - - '@inquirer/ansi@1.0.2': - optional: true - - '@inquirer/confirm@5.1.21(@types/node@22.20.0)': - dependencies: - '@inquirer/core': 10.3.2(@types/node@22.20.0) - '@inquirer/type': 3.0.10(@types/node@22.20.0) - optionalDependencies: - '@types/node': 22.20.0 - optional: true - - '@inquirer/core@10.3.2(@types/node@22.20.0)': - dependencies: - '@inquirer/ansi': 1.0.2 - '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.20.0) - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.20.0 - optional: true - - '@inquirer/figures@1.0.15': - optional: true - - '@inquirer/type@3.0.10(@types/node@22.20.0)': - optionalDependencies: - '@types/node': 22.20.0 - optional: true - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': - dependencies: - '@hono/node-server': 1.19.14(hono@4.12.28) - ajv: 8.20.0 - ajv-formats: 3.0.1(ajv@8.20.0) - content-type: 1.0.5 - cors: 2.8.6 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.1.0 - express: 5.2.1 - express-rate-limit: 8.5.2(express@5.2.1) - hono: 4.12.28 - jose: 6.2.3 - json-schema-typed: 8.0.2 - pkce-challenge: 5.0.1 - raw-body: 3.0.2 - zod: 4.4.3 - zod-to-json-schema: 3.25.2(zod@4.4.3) - transitivePeerDependencies: - - supports-color - - '@mswjs/interceptors@0.39.8': - dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 - optional: true - - '@napi-rs/keyring-darwin-arm64@1.3.0': - optional: true - - '@napi-rs/keyring-darwin-x64@1.3.0': - optional: true - - '@napi-rs/keyring-freebsd-x64@1.3.0': - optional: true - - '@napi-rs/keyring-linux-arm-gnueabihf@1.3.0': - optional: true - - '@napi-rs/keyring-linux-arm64-gnu@1.3.0': - optional: true - - '@napi-rs/keyring-linux-arm64-musl@1.3.0': - optional: true - - '@napi-rs/keyring-linux-riscv64-gnu@1.3.0': - optional: true - - '@napi-rs/keyring-linux-x64-gnu@1.3.0': - optional: true - - '@napi-rs/keyring-linux-x64-musl@1.3.0': - optional: true - - '@napi-rs/keyring-win32-arm64-msvc@1.3.0': - optional: true - - '@napi-rs/keyring-win32-ia32-msvc@1.3.0': - optional: true - - '@napi-rs/keyring-win32-x64-msvc@1.3.0': - optional: true - - '@napi-rs/keyring@1.3.0': - optionalDependencies: - '@napi-rs/keyring-darwin-arm64': 1.3.0 - '@napi-rs/keyring-darwin-x64': 1.3.0 - '@napi-rs/keyring-freebsd-x64': 1.3.0 - '@napi-rs/keyring-linux-arm-gnueabihf': 1.3.0 - '@napi-rs/keyring-linux-arm64-gnu': 1.3.0 - '@napi-rs/keyring-linux-arm64-musl': 1.3.0 - '@napi-rs/keyring-linux-riscv64-gnu': 1.3.0 - '@napi-rs/keyring-linux-x64-gnu': 1.3.0 - '@napi-rs/keyring-linux-x64-musl': 1.3.0 - '@napi-rs/keyring-win32-arm64-msvc': 1.3.0 - '@napi-rs/keyring-win32-ia32-msvc': 1.3.0 - '@napi-rs/keyring-win32-x64-msvc': 1.3.0 - - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@nodable/entities@2.2.0': {} - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - - '@open-draft/deferred-promise@2.2.0': - optional: true - - '@open-draft/logger@0.3.0': - dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - optional: true - - '@open-draft/until@2.1.0': - optional: true - - '@opentelemetry/api@1.9.0': - optional: true - - '@oxc-project/types@0.138.0': {} - - '@oxfmt/binding-android-arm-eabi@0.56.0': - optional: true - - '@oxfmt/binding-android-arm64@0.56.0': - optional: true - - '@oxfmt/binding-darwin-arm64@0.56.0': - optional: true - - '@oxfmt/binding-darwin-x64@0.56.0': - optional: true - - '@oxfmt/binding-freebsd-x64@0.56.0': - optional: true - - '@oxfmt/binding-linux-arm-gnueabihf@0.56.0': - optional: true - - '@oxfmt/binding-linux-arm-musleabihf@0.56.0': - optional: true - - '@oxfmt/binding-linux-arm64-gnu@0.56.0': - optional: true - - '@oxfmt/binding-linux-arm64-musl@0.56.0': - optional: true - - '@oxfmt/binding-linux-ppc64-gnu@0.56.0': - optional: true - - '@oxfmt/binding-linux-riscv64-gnu@0.56.0': - optional: true - - '@oxfmt/binding-linux-riscv64-musl@0.56.0': - optional: true - - '@oxfmt/binding-linux-s390x-gnu@0.56.0': - optional: true - - '@oxfmt/binding-linux-x64-gnu@0.56.0': - optional: true - - '@oxfmt/binding-linux-x64-musl@0.56.0': - optional: true - - '@oxfmt/binding-openharmony-arm64@0.56.0': - optional: true - - '@oxfmt/binding-win32-arm64-msvc@0.56.0': - optional: true - - '@oxfmt/binding-win32-ia32-msvc@0.56.0': - optional: true - - '@oxfmt/binding-win32-x64-msvc@0.56.0': - optional: true - - '@oxlint/binding-android-arm-eabi@1.72.0': - optional: true - - '@oxlint/binding-android-arm64@1.72.0': - optional: true - - '@oxlint/binding-darwin-arm64@1.72.0': - optional: true - - '@oxlint/binding-darwin-x64@1.72.0': - optional: true - - '@oxlint/binding-freebsd-x64@1.72.0': - optional: true - - '@oxlint/binding-linux-arm-gnueabihf@1.72.0': - optional: true - - '@oxlint/binding-linux-arm-musleabihf@1.72.0': - optional: true - - '@oxlint/binding-linux-arm64-gnu@1.72.0': - optional: true - - '@oxlint/binding-linux-arm64-musl@1.72.0': - optional: true - - '@oxlint/binding-linux-ppc64-gnu@1.72.0': - optional: true - - '@oxlint/binding-linux-riscv64-gnu@1.72.0': - optional: true - - '@oxlint/binding-linux-riscv64-musl@1.72.0': - optional: true - - '@oxlint/binding-linux-s390x-gnu@1.72.0': - optional: true - - '@oxlint/binding-linux-x64-gnu@1.72.0': - optional: true - - '@oxlint/binding-linux-x64-musl@1.72.0': - optional: true - - '@oxlint/binding-openharmony-arm64@1.72.0': - optional: true - - '@oxlint/binding-win32-arm64-msvc@1.72.0': - optional: true - - '@oxlint/binding-win32-ia32-msvc@1.72.0': - optional: true - - '@oxlint/binding-win32-x64-msvc@1.72.0': - optional: true - - '@polka/url@1.0.0-next.29': {} - - '@redocly/ajv@8.18.1': - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - '@redocly/ajv@8.18.3': - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - '@redocly/config@0.50.1': - dependencies: - json-schema-to-ts: 2.7.2 - - '@redocly/openapi-core@2.37.0': - dependencies: - '@redocly/ajv': 8.18.3 - '@redocly/config': 0.50.1 - ajv: '@redocly/ajv@8.18.1' - ajv-formats: 3.0.1(@redocly/ajv@8.18.1) - colorette: 1.4.0 - graphql: 16.14.2 - js-levenshtein: 1.1.6 - js-yaml: 4.3.0 - picomatch: 4.0.5 - pluralize: 8.0.0 - yaml-ast-parser: 0.0.43 - - '@rolldown/binding-android-arm64@1.1.4': - optional: true - - '@rolldown/binding-darwin-arm64@1.1.4': - optional: true - - '@rolldown/binding-darwin-x64@1.1.4': - optional: true - - '@rolldown/binding-freebsd-x64@1.1.4': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.1.4': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.1.4': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.1.4': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.1.4': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.1.4': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.1.4': - optional: true - - '@rolldown/binding-linux-x64-musl@1.1.4': - optional: true - - '@rolldown/binding-openharmony-arm64@1.1.4': - optional: true - - '@rolldown/binding-wasm32-wasi@1.1.4': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.1.4': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.1.4': - optional: true - - '@rolldown/pluginutils@1.0.1': {} - - '@smithy/core@3.29.1': - dependencies: - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@smithy/credential-provider-imds@4.4.6': - dependencies: - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@smithy/fetch-http-handler@5.6.3': - dependencies: - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@smithy/node-http-handler@4.9.3': - dependencies: - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@smithy/signature-v4@5.6.2': - dependencies: - '@smithy/core': 3.29.1 - '@smithy/types': 4.15.1 - tslib: 2.8.1 - - '@smithy/types@4.15.1': - dependencies: - tslib: 2.8.1 - - '@stablelib/base64@1.0.1': {} - - '@standard-schema/spec@1.1.0': {} - - '@statelyai/inspect@0.7.2(xstate@5.32.4)': - dependencies: - fast-safe-stringify: 2.1.1 - isomorphic-ws: 5.0.0(ws@8.21.0) - partysocket: 0.0.25 - safe-stable-stringify: 2.5.0 - superjson: 1.13.3 - ws: 8.21.0 - xstate: 5.32.4 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - '@tybys/wasm-util@0.10.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - - '@types/cookie@0.6.0': - optional: true - - '@types/deep-eql@4.0.2': {} - - '@types/estree@1.0.9': {} - - '@types/json-schema@7.0.15': {} - - '@types/node@22.20.0': - dependencies: - undici-types: 6.21.0 - - '@types/opn@5.5.0': - dependencies: - opn: 6.0.0 - - '@types/react@19.2.17': - dependencies: - csstype: 3.2.3 - - '@types/semver@7.7.1': {} - - '@types/statuses@2.0.6': - optional: true - - '@types/tough-cookie@4.0.5': - optional: true - - '@types/yargs-parser@21.0.3': {} - - '@types/yargs@17.0.35': - dependencies: - '@types/yargs-parser': 21.0.3 - - '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': - dependencies: - '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.10 - ast-v8-to-istanbul: 1.0.4 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 - magicast: 0.5.3 - obug: 2.1.3 - std-env: 4.1.0 - tinyrainbow: 3.1.0 - vitest: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(msw@2.10.4(@types/node@22.20.0)(typescript@5.9.3))(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0)) - - '@vitest/expect@4.1.10': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.10 - '@vitest/utils': 4.1.10 - chai: 6.2.2 - tinyrainbow: 3.1.0 - - '@vitest/mocker@4.1.10(msw@2.10.4(@types/node@22.20.0)(typescript@5.9.3))(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0))': - dependencies: - '@vitest/spy': 4.1.10 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - msw: 2.10.4(@types/node@22.20.0)(typescript@5.9.3) - vite: 8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0) - - '@vitest/pretty-format@4.1.10': - dependencies: - tinyrainbow: 3.1.0 - - '@vitest/runner@4.1.10': - dependencies: - '@vitest/utils': 4.1.10 - pathe: 2.0.3 - - '@vitest/snapshot@4.1.10': - dependencies: - '@vitest/pretty-format': 4.1.10 - '@vitest/utils': 4.1.10 - magic-string: 0.30.21 - pathe: 2.0.3 - - '@vitest/spy@4.1.10': {} - - '@vitest/ui@4.1.10(vitest@4.1.10)': - dependencies: - '@vitest/utils': 4.1.10 - fflate: 0.8.3 - flatted: 3.4.2 - pathe: 2.0.3 - sirv: 3.0.2 - tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vitest: 4.1.10(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(msw@2.10.4(@types/node@22.20.0)(typescript@5.9.3))(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0)) - - '@vitest/utils@4.1.10': - dependencies: - '@vitest/pretty-format': 4.1.10 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.0 - - '@workos-inc/node@10.7.0': {} - - '@workos-inc/node@8.13.0': - dependencies: - eventemitter3: 5.0.4 - - '@workos/emulate@0.1.0': - dependencies: - '@hono/node-server': 1.19.14(hono@4.12.28) - chalk: 5.6.2 - hono: 4.12.28 - yaml: 2.9.0 - - '@workos/migrations@2.5.0': - dependencies: - '@aws-sdk/client-cognito-identity-provider': 3.1079.0 - '@workos-inc/node': 10.7.0 - chalk: 5.6.2 - cli-progress: 3.12.0 - commander: 15.0.0 - csv-parse: 6.2.1 - csv-stringify: 6.8.1 - dotenv: 17.4.2 - fast-xml-parser: 5.9.3 - google-auth-library: 10.9.0 - prompts: 2.4.2 - transitivePeerDependencies: - - supports-color - - '@workos/oagen@0.23.0': - dependencies: - '@redocly/openapi-core': 2.37.0 - commander: 13.1.0 - dotenv: 17.4.2 - tree-sitter: 0.21.1 - tree-sitter-c-sharp: 0.23.1(tree-sitter@0.21.1) - tree-sitter-elixir: 0.3.5(tree-sitter@0.21.1) - tree-sitter-go: 0.23.4(tree-sitter@0.21.1) - tree-sitter-kotlin: https://codeload.github.com/fwcd/tree-sitter-kotlin/tar.gz/f66d2908542e93c0204c6c241f794afe4e9cd5d1(tree-sitter@0.21.1) - tree-sitter-php: 0.23.12(tree-sitter@0.21.1) - tree-sitter-python: 0.21.0(tree-sitter@0.21.1) - tree-sitter-ruby: 0.21.0(tree-sitter@0.21.1) - tree-sitter-rust: 0.21.0(tree-sitter@0.21.1) - tree-sitter-typescript: 0.23.2(tree-sitter@0.21.1) - tsx: 4.23.0 - typescript: 6.0.3 - transitivePeerDependencies: - - tree_sitter - - '@workos/openapi-spec@0.14.0': - dependencies: - '@workos/oagen': 0.23.0 - transitivePeerDependencies: - - tree_sitter - - '@workos/skills@0.6.1': - dependencies: - yaml: 2.9.0 - - accepts@2.0.0: - dependencies: - mime-types: 3.0.2 - negotiator: 1.0.0 - - agent-base@7.1.4: {} - - ajv-formats@3.0.1(@redocly/ajv@8.18.1): - optionalDependencies: - ajv: '@redocly/ajv@8.18.1' - - ajv-formats@3.0.1(ajv@8.20.0): - optionalDependencies: - ajv: 8.20.0 - - ajv@8.20.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ansi-escapes@7.3.0: - dependencies: - environment: 1.1.0 - - ansi-regex@5.0.1: {} - - ansi-regex@6.2.2: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - optional: true - - ansi-styles@6.2.1: {} - - ansi-styles@6.2.3: {} - - anynum@1.0.1: {} - - argparse@2.0.1: {} - - assertion-error@2.0.1: {} - - ast-v8-to-istanbul@1.0.4: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - estree-walker: 3.0.3 - js-tokens: 10.0.0 - - auto-bind@5.0.1: {} - - base64-js@1.5.1: {} - - bignumber.js@9.3.1: {} - - body-parser@2.3.0: - dependencies: - bytes: 3.1.2 - content-type: 2.0.0 - debug: 4.4.3 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - on-finished: 2.4.1 - qs: 6.15.3 - raw-body: 3.0.2 - type-is: 2.1.0 - transitivePeerDependencies: - - supports-color - - bowser@2.14.1: {} - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - buffer-equal-constant-time@1.0.1: {} - - bundle-name@4.1.0: - dependencies: - run-applescript: 7.1.0 - - bytes@3.1.2: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - chai@6.2.2: {} - - chalk@5.6.2: {} - - cli-boxes@3.0.0: {} - - cli-cursor@4.0.0: - dependencies: - restore-cursor: 4.0.0 - - cli-progress@3.12.0: - dependencies: - string-width: 4.2.3 - - cli-truncate@5.1.1: - dependencies: - slice-ansi: 7.1.2 - string-width: 8.2.1 - - cli-width@4.1.0: - optional: true - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - optional: true - - cliui@9.0.1: - dependencies: - string-width: 7.2.0 - strip-ansi: 7.2.0 - wrap-ansi: 9.0.2 - - code-excerpt@4.0.0: - dependencies: - convert-to-spaces: 2.0.1 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - optional: true - - color-name@1.1.4: - optional: true - - colorette@1.4.0: {} - - commander@13.1.0: {} - - commander@15.0.0: {} - - content-disposition@1.1.0: {} - - content-type@1.0.5: {} - - content-type@2.0.0: {} - - convert-source-map@2.0.0: {} - - convert-to-spaces@2.0.1: {} - - cookie-signature@1.2.2: {} - - cookie@0.7.2: {} - - copy-anything@3.0.5: - dependencies: - is-what: 4.1.16 - - cors@2.8.6: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - csstype@3.2.3: {} - - csv-parse@6.2.1: {} - - csv-stringify@6.8.1: {} - - data-uri-to-buffer@4.0.1: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - default-browser-id@5.0.1: {} - - default-browser@5.5.0: - dependencies: - bundle-name: 4.1.0 - default-browser-id: 5.0.1 - - define-lazy-prop@3.0.0: {} - - depd@2.0.0: {} - - detect-libc@2.1.2: {} - - diff@8.0.4: {} - - dotenv@17.4.2: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - ecdsa-sig-formatter@1.0.11: - dependencies: - safe-buffer: 5.2.1 - - ee-first@1.1.1: {} - - emoji-regex@10.6.0: {} - - emoji-regex@8.0.0: {} - - encodeurl@2.0.0: {} - - environment@1.1.0: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@2.3.0: {} - - es-object-atoms@1.1.2: - dependencies: - es-errors: 1.3.0 - - es-toolkit@1.44.0: {} - - esbuild@0.28.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 - - escalade@3.2.0: {} - - escape-html@1.0.3: {} - - escape-string-regexp@2.0.0: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.9 - - etag@1.8.1: {} - - event-target-shim@6.0.2: {} - - eventemitter3@5.0.4: {} - - eventsource-parser@3.1.0: {} - - eventsource@3.0.7: - dependencies: - eventsource-parser: 3.1.0 - - expect-type@1.4.0: {} - - express-rate-limit@8.5.2(express@5.2.1): - dependencies: - express: 5.2.1 - ip-address: 10.2.0 - - express@5.2.1: - dependencies: - accepts: 2.0.0 - body-parser: 2.3.0 - content-disposition: 1.1.0 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.3 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.1 - fresh: 2.0.0 - http-errors: 2.0.1 - merge-descriptors: 2.0.0 - mime-types: 3.0.2 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.15.3 - range-parser: 1.3.0 - router: 2.2.0 - send: 1.2.1 - serve-static: 2.2.1 - statuses: 2.0.2 - type-is: 2.1.0 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - extend@3.0.2: {} - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-safe-stringify@2.1.1: {} - - fast-sha256@1.3.0: {} - - fast-string-truncated-width@3.0.3: {} - - fast-string-width@3.0.2: - dependencies: - fast-string-truncated-width: 3.0.3 - - fast-uri@3.1.3: {} - - fast-wrap-ansi@0.2.2: - dependencies: - fast-string-width: 3.0.2 - - fast-xml-builder@1.2.1: - dependencies: - path-expression-matcher: 1.6.1 - xml-naming: 0.1.0 - - fast-xml-parser@5.9.3: - dependencies: - '@nodable/entities': 2.2.0 - fast-xml-builder: 1.2.1 - is-unsafe: 1.0.1 - path-expression-matcher: 1.6.1 - strnum: 2.4.1 - xml-naming: 0.1.0 - - fastq@1.20.1: - dependencies: - reusify: 1.1.0 - - fdir@6.5.0(picomatch@4.0.5): - optionalDependencies: - picomatch: 4.0.5 - - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 - - fflate@0.8.3: {} - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - finalhandler@2.1.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - flatted@3.4.2: {} - - formdata-polyfill@4.0.10: - dependencies: - fetch-blob: 3.2.0 - - forwarded@0.2.0: {} - - fresh@2.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - gaxios@7.1.6: - dependencies: - extend: 3.0.2 - https-proxy-agent: 7.0.6 - node-fetch: 3.3.2 - transitivePeerDependencies: - - supports-color - - gcp-metadata@8.1.2: - dependencies: - gaxios: 7.1.6 - google-logging-utils: 1.1.3 - json-bigint: 1.0.0 - transitivePeerDependencies: - - supports-color - - get-caller-file@2.0.5: {} - - get-east-asian-width@1.3.0: {} - - get-east-asian-width@1.5.0: {} - - get-east-asian-width@1.6.0: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.2 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.4 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.2 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - google-auth-library@10.9.0: - dependencies: - base64-js: 1.5.1 - ecdsa-sig-formatter: 1.0.11 - gaxios: 7.1.6 - gcp-metadata: 8.1.2 - google-logging-utils: 1.1.3 - jws: 4.0.1 - transitivePeerDependencies: - - supports-color - - google-logging-utils@1.1.3: {} - - gopd@1.2.0: {} - - graphql@16.14.2: {} - - has-flag@4.0.0: {} - - has-symbols@1.1.0: {} - - hasown@2.0.4: - dependencies: - function-bind: 1.1.2 - - headers-polyfill@4.0.3: - optional: true - - hono@4.12.28: {} - - html-escaper@2.0.2: {} - - http-errors@2.0.1: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 - - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - iconv-lite@0.7.3: - dependencies: - safer-buffer: 2.1.2 - - indent-string@5.0.0: {} - - inherits@2.0.4: {} - - ink@6.8.0(@types/react@19.2.17)(react@19.2.7): - dependencies: - '@alcalzone/ansi-tokenize': 0.2.5 - ansi-escapes: 7.3.0 - ansi-styles: 6.2.1 - auto-bind: 5.0.1 - chalk: 5.6.2 - cli-boxes: 3.0.0 - cli-cursor: 4.0.0 - cli-truncate: 5.1.1 - code-excerpt: 4.0.0 - es-toolkit: 1.44.0 - indent-string: 5.0.0 - is-in-ci: 2.0.0 - patch-console: 2.0.0 - react: 19.2.7 - react-reconciler: 0.33.0(react@19.2.7) - scheduler: 0.27.0 - signal-exit: 3.0.7 - slice-ansi: 8.0.0 - stack-utils: 2.0.6 - string-width: 8.2.0 - terminal-size: 4.0.1 - type-fest: 5.4.4 - widest-line: 6.0.0 - wrap-ansi: 9.0.0 - ws: 8.19.0 - yoga-layout: 3.2.1 - optionalDependencies: - '@types/react': 19.2.17 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - ip-address@10.2.0: {} - - ipaddr.js@1.9.1: {} - - is-docker@3.0.0: {} - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-fullwidth-code-point@5.0.0: - dependencies: - get-east-asian-width: 1.3.0 - - is-fullwidth-code-point@5.1.0: - dependencies: - get-east-asian-width: 1.6.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-in-ci@2.0.0: {} - - is-in-ssh@1.0.0: {} - - is-inside-container@1.0.0: - dependencies: - is-docker: 3.0.0 - - is-node-process@1.2.0: - optional: true - - is-number@7.0.0: {} - - is-promise@4.0.0: {} - - is-unsafe@1.0.1: {} - - is-what@4.1.16: {} - - is-wsl@1.1.0: {} - - is-wsl@3.1.1: - dependencies: - is-inside-container: 1.0.0 - - isexe@2.0.0: {} - - isomorphic-ws@5.0.0(ws@8.21.0): - dependencies: - ws: 8.21.0 - - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - - jose@6.2.3: {} - - js-levenshtein@1.1.6: {} - - js-tokens@10.0.0: {} - - js-yaml@4.3.0: - dependencies: - argparse: 2.0.1 - - json-bigint@1.0.0: - dependencies: - bignumber.js: 9.3.1 - - json-schema-to-ts@2.7.2: - dependencies: - '@babel/runtime': 7.29.7 - '@types/json-schema': 7.0.15 - ts-algebra: 1.2.2 - - json-schema-to-ts@3.1.1: - dependencies: - '@babel/runtime': 7.29.7 - ts-algebra: 2.0.0 - - json-schema-traverse@1.0.0: {} - - json-schema-typed@8.0.2: {} - - jsonc-parser@3.3.1: {} - - jwa@2.0.1: - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - - jws@4.0.1: - dependencies: - jwa: 2.0.1 - safe-buffer: 5.2.1 - - kleur@3.0.3: {} - - lightningcss-android-arm64@1.32.0: - optional: true - - lightningcss-darwin-arm64@1.32.0: - optional: true - - lightningcss-darwin-x64@1.32.0: - optional: true - - lightningcss-freebsd-x64@1.32.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - - lightningcss-linux-arm64-musl@1.32.0: - optional: true - - lightningcss-linux-x64-gnu@1.32.0: - optional: true - - lightningcss-linux-x64-musl@1.32.0: - optional: true - - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - - lightningcss-win32-x64-msvc@1.32.0: - optional: true - - lightningcss@1.32.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - magicast@0.5.3: - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - source-map-js: 1.2.1 - - make-dir@4.0.0: - dependencies: - semver: 7.8.5 - - math-intrinsics@1.1.0: {} - - media-typer@1.1.0: {} - - merge-descriptors@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.2 - - mime-db@1.54.0: {} - - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - - mimic-fn@2.1.0: {} - - mrmime@2.0.1: {} - - ms@2.1.3: {} - - msw@2.10.4(@types/node@22.20.0)(typescript@5.9.3): - dependencies: - '@bundled-es-modules/cookie': 2.0.1 - '@bundled-es-modules/statuses': 1.0.1 - '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.21(@types/node@22.20.0) - '@mswjs/interceptors': 0.39.8 - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/until': 2.1.0 - '@types/cookie': 0.6.0 - '@types/statuses': 2.0.6 - graphql: 16.14.2 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - strict-event-emitter: 0.5.1 - type-fest: 4.41.0 - yargs: 17.7.3 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - '@types/node' - optional: true - - mute-stream@2.0.0: - optional: true - - nanoid@3.3.15: {} - - negotiator@1.0.0: {} - - node-addon-api@7.1.1: {} - - node-addon-api@8.9.0: {} - - node-domexception@1.0.0: {} - - node-fetch@3.3.2: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-gyp-build@4.8.4: {} - - object-assign@4.1.1: {} - - object-inspect@1.13.4: {} - - obug@2.1.1: {} - - obug@2.1.3: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - open@11.0.0: - dependencies: - default-browser: 5.5.0 - define-lazy-prop: 3.0.0 - is-in-ssh: 1.0.0 - is-inside-container: 1.0.0 - powershell-utils: 0.1.0 - wsl-utils: 0.3.1 - - opn@6.0.0: - dependencies: - is-wsl: 1.1.0 - - outvariant@1.4.3: - optional: true - - oxfmt@0.56.0: - dependencies: - tinypool: 2.1.0 - optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.56.0 - '@oxfmt/binding-android-arm64': 0.56.0 - '@oxfmt/binding-darwin-arm64': 0.56.0 - '@oxfmt/binding-darwin-x64': 0.56.0 - '@oxfmt/binding-freebsd-x64': 0.56.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.56.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.56.0 - '@oxfmt/binding-linux-arm64-gnu': 0.56.0 - '@oxfmt/binding-linux-arm64-musl': 0.56.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.56.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.56.0 - '@oxfmt/binding-linux-riscv64-musl': 0.56.0 - '@oxfmt/binding-linux-s390x-gnu': 0.56.0 - '@oxfmt/binding-linux-x64-gnu': 0.56.0 - '@oxfmt/binding-linux-x64-musl': 0.56.0 - '@oxfmt/binding-openharmony-arm64': 0.56.0 - '@oxfmt/binding-win32-arm64-msvc': 0.56.0 - '@oxfmt/binding-win32-ia32-msvc': 0.56.0 - '@oxfmt/binding-win32-x64-msvc': 0.56.0 - - oxlint@1.72.0: - optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.72.0 - '@oxlint/binding-android-arm64': 1.72.0 - '@oxlint/binding-darwin-arm64': 1.72.0 - '@oxlint/binding-darwin-x64': 1.72.0 - '@oxlint/binding-freebsd-x64': 1.72.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.72.0 - '@oxlint/binding-linux-arm-musleabihf': 1.72.0 - '@oxlint/binding-linux-arm64-gnu': 1.72.0 - '@oxlint/binding-linux-arm64-musl': 1.72.0 - '@oxlint/binding-linux-ppc64-gnu': 1.72.0 - '@oxlint/binding-linux-riscv64-gnu': 1.72.0 - '@oxlint/binding-linux-riscv64-musl': 1.72.0 - '@oxlint/binding-linux-s390x-gnu': 1.72.0 - '@oxlint/binding-linux-x64-gnu': 1.72.0 - '@oxlint/binding-linux-x64-musl': 1.72.0 - '@oxlint/binding-openharmony-arm64': 1.72.0 - '@oxlint/binding-win32-arm64-msvc': 1.72.0 - '@oxlint/binding-win32-ia32-msvc': 1.72.0 - '@oxlint/binding-win32-x64-msvc': 1.72.0 - - p-limit@7.3.0: - dependencies: - yocto-queue: 1.2.2 - - parseurl@1.3.3: {} - - partysocket@0.0.25: - dependencies: - event-target-shim: 6.0.2 - - patch-console@2.0.0: {} - - path-expression-matcher@1.6.1: {} - - path-key@3.1.1: {} - - path-to-regexp@6.3.0: - optional: true - - path-to-regexp@8.4.2: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@2.3.2: {} - - picomatch@4.0.4: {} - - picomatch@4.0.5: {} - - pkce-challenge@5.0.1: {} - - pluralize@8.0.0: {} - - postcss@8.5.16: - dependencies: - nanoid: 3.3.15 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - powershell-utils@0.1.0: {} - - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - psl@1.15.0: - dependencies: - punycode: 2.3.1 - optional: true - - punycode@2.3.1: - optional: true - - qs@6.15.3: - dependencies: - es-define-property: 1.0.1 - side-channel: 1.1.1 - - querystringify@2.2.0: - optional: true - - queue-microtask@1.2.3: {} - - range-parser@1.3.0: {} - - raw-body@3.0.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - unpipe: 1.0.0 - - react-reconciler@0.33.0(react@19.2.7): - dependencies: - react: 19.2.7 - scheduler: 0.27.0 - - react@19.2.7: {} - - require-directory@2.1.1: - optional: true - - require-from-string@2.0.2: {} - - requires-port@1.0.0: - optional: true - - restore-cursor@4.0.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - reusify@1.1.0: {} - - rolldown@1.1.4: - dependencies: - '@oxc-project/types': 0.138.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.1.4 - '@rolldown/binding-darwin-arm64': 1.1.4 - '@rolldown/binding-darwin-x64': 1.1.4 - '@rolldown/binding-freebsd-x64': 1.1.4 - '@rolldown/binding-linux-arm-gnueabihf': 1.1.4 - '@rolldown/binding-linux-arm64-gnu': 1.1.4 - '@rolldown/binding-linux-arm64-musl': 1.1.4 - '@rolldown/binding-linux-ppc64-gnu': 1.1.4 - '@rolldown/binding-linux-s390x-gnu': 1.1.4 - '@rolldown/binding-linux-x64-gnu': 1.1.4 - '@rolldown/binding-linux-x64-musl': 1.1.4 - '@rolldown/binding-openharmony-arm64': 1.1.4 - '@rolldown/binding-wasm32-wasi': 1.1.4 - '@rolldown/binding-win32-arm64-msvc': 1.1.4 - '@rolldown/binding-win32-x64-msvc': 1.1.4 - - router@2.2.0: - dependencies: - debug: 4.4.3 - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.4.2 - transitivePeerDependencies: - - supports-color - - run-applescript@7.1.0: {} - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-buffer@5.2.1: {} - - safe-stable-stringify@2.5.0: {} - - safer-buffer@2.1.2: {} - - scheduler@0.27.0: {} - - semver@7.8.5: {} - - send@1.2.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.3.0 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - serve-static@2.2.1: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.1 - transitivePeerDependencies: - - supports-color - - setprototypeof@1.2.0: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - siginfo@2.0.0: {} - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: - optional: true - - sirv@3.0.2: - dependencies: - '@polka/url': 1.0.0-next.29 - mrmime: 2.0.1 - totalist: 3.0.1 - - sisteransi@1.0.5: {} - - slice-ansi@7.1.2: - dependencies: - ansi-styles: 6.2.3 - is-fullwidth-code-point: 5.0.0 - - slice-ansi@8.0.0: - dependencies: - ansi-styles: 6.2.3 - is-fullwidth-code-point: 5.1.0 - - source-map-js@1.2.1: {} - - stack-utils@2.0.6: - dependencies: - escape-string-regexp: 2.0.0 - - stackback@0.0.2: {} - - standardwebhooks@1.0.0: - dependencies: - '@stablelib/base64': 1.0.1 - fast-sha256: 1.3.0 - - statuses@2.0.2: {} - - std-env@4.1.0: {} - - strict-event-emitter@0.5.1: - optional: true - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@7.2.0: - dependencies: - emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 - strip-ansi: 7.2.0 - - string-width@8.2.0: - dependencies: - get-east-asian-width: 1.5.0 - strip-ansi: 7.2.0 - - string-width@8.2.1: - dependencies: - get-east-asian-width: 1.5.0 - strip-ansi: 7.2.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.2.0: - dependencies: - ansi-regex: 6.2.2 - - strnum@2.4.1: - dependencies: - anynum: 1.0.1 - - superjson@1.13.3: - dependencies: - copy-anything: 3.0.5 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - tagged-tag@1.0.0: {} - - terminal-size@4.0.1: {} - - tinybench@2.9.0: {} - - tinyexec@1.2.4: {} - - tinyglobby@0.2.17: - dependencies: - fdir: 6.5.0(picomatch@4.0.5) - picomatch: 4.0.5 - - tinypool@2.1.0: {} - - tinyrainbow@3.1.0: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - toidentifier@1.0.1: {} - - totalist@3.0.1: {} - - tough-cookie@4.1.4: - dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - optional: true - - tree-sitter-c-sharp@0.23.1(tree-sitter@0.21.1): - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - optionalDependencies: - tree-sitter: 0.21.1 - - tree-sitter-elixir@0.3.5(tree-sitter@0.21.1): - dependencies: - node-addon-api: 7.1.1 - node-gyp-build: 4.8.4 - tree-sitter: 0.21.1 - - tree-sitter-go@0.23.4(tree-sitter@0.21.1): - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - optionalDependencies: - tree-sitter: 0.21.1 - - tree-sitter-javascript@0.23.1(tree-sitter@0.21.1): - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - optionalDependencies: - tree-sitter: 0.21.1 - - tree-sitter-kotlin@https://codeload.github.com/fwcd/tree-sitter-kotlin/tar.gz/f66d2908542e93c0204c6c241f794afe4e9cd5d1(tree-sitter@0.21.1): - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - tree-sitter: 0.21.1 - - tree-sitter-php@0.23.12(tree-sitter@0.21.1): - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - optionalDependencies: - tree-sitter: 0.21.1 - - tree-sitter-python@0.21.0(tree-sitter@0.21.1): - dependencies: - node-addon-api: 7.1.1 - node-gyp-build: 4.8.4 - tree-sitter: 0.21.1 - - tree-sitter-ruby@0.21.0(tree-sitter@0.21.1): - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - tree-sitter: 0.21.1 - - tree-sitter-rust@0.21.0(tree-sitter@0.21.1): - dependencies: - node-addon-api: 7.1.1 - node-gyp-build: 4.8.4 - tree-sitter: 0.21.1 - - tree-sitter-typescript@0.23.2(tree-sitter@0.21.1): - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - tree-sitter-javascript: 0.23.1(tree-sitter@0.21.1) - optionalDependencies: - tree-sitter: 0.21.1 - - tree-sitter@0.21.1: - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - - ts-algebra@1.2.2: {} - - ts-algebra@2.0.0: {} - - tslib@2.8.1: {} - - tsx@4.23.0: - dependencies: - esbuild: 0.28.1 - optionalDependencies: - fsevents: 2.3.3 - - type-fest@4.41.0: - optional: true - - type-fest@5.4.4: - dependencies: - tagged-tag: 1.0.0 - - type-is@2.1.0: - dependencies: - content-type: 2.0.0 - media-typer: 1.1.0 - mime-types: 3.0.2 - - typescript@5.9.3: {} - - typescript@6.0.3: {} - - undici-types@6.21.0: {} - - universalify@0.2.0: - optional: true - - unpipe@1.0.0: {} - - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - optional: true - - uuid@13.0.2: {} - - vary@1.1.2: {} - - vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0): - dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.5 - postcss: 8.5.16 - rolldown: 1.1.4 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 22.20.0 - esbuild: 0.28.1 - fsevents: 2.3.3 - tsx: 4.23.0 - yaml: 2.9.0 - - vitest@4.1.10(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.10)(@vitest/ui@4.1.10)(msw@2.10.4(@types/node@22.20.0)(typescript@5.9.3))(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0)): - dependencies: - '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(msw@2.10.4(@types/node@22.20.0)(typescript@5.9.3))(vite@8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.10 - '@vitest/runner': 4.1.10 - '@vitest/snapshot': 4.1.10 - '@vitest/spy': 4.1.10 - '@vitest/utils': 4.1.10 - es-module-lexer: 2.3.0 - expect-type: 1.4.0 - magic-string: 0.30.21 - obug: 2.1.1 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vite: 8.1.3(@types/node@22.20.0)(esbuild@0.28.1)(tsx@4.23.0)(yaml@2.9.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@opentelemetry/api': 1.9.0 - '@types/node': 22.20.0 - '@vitest/coverage-v8': 4.1.10(vitest@4.1.10) - '@vitest/ui': 4.1.10(vitest@4.1.10) - transitivePeerDependencies: - - msw - - web-streams-polyfill@3.3.3: {} - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - widest-line@6.0.0: - dependencies: - string-width: 8.2.1 - - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - optional: true - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - optional: true - - wrap-ansi@9.0.0: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.2.0 - - wrap-ansi@9.0.2: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.2.0 - - wrappy@1.0.2: {} - - ws@8.19.0: {} - - ws@8.21.0: {} - - wsl-utils@0.3.1: - dependencies: - is-wsl: 3.1.1 - powershell-utils: 0.1.0 - - xml-naming@0.1.0: {} - - xstate@5.32.4: {} - - y18n@5.0.8: {} - - yaml-ast-parser@0.0.43: {} - - yaml@2.9.0: {} - - yargs-parser@21.1.1: - optional: true - - yargs-parser@22.0.0: {} - - yargs@17.7.3: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - optional: true - - yargs@18.0.0: - dependencies: - cliui: 9.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - string-width: 7.2.0 - y18n: 5.0.8 - yargs-parser: 22.0.0 - - yocto-queue@1.2.2: {} - - yoctocolors-cjs@2.1.3: - optional: true - - yoga-layout@3.2.1: {} - - zod-to-json-schema@3.25.2(zod@4.4.3): - dependencies: - zod: 4.4.3 - - zod@4.4.3: {} diff --git a/release-please-config.json b/release-please-config.json index 7dcb33a6..6a2f0e2a 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -6,7 +6,9 @@ "release-type": "node", "bump-minor-pre-major": true, "changelog-path": "CHANGELOG.md", - "versioning": "default" + "versioning": "default", + "draft": true, + "force-tag-creation": true } } } diff --git a/scripts/build.ts b/scripts/build.ts new file mode 100644 index 00000000..6a0c03d9 --- /dev/null +++ b/scripts/build.ts @@ -0,0 +1,58 @@ +// Single source of truth for compiling the standalone binary. Used by +// `bun run build` locally, ci.yml, and every release.yml matrix leg. +// +// WORKOS_BUILD_TARGET bun compile target (e.g. bun-linux-x64-baseline); +// defaults to the host. Must match the target passed to +// `bun run generate` so the pinned Agent SDK matches. +// WORKOS_BUILD_OUTFILE output path; defaults to ./dist/workos. +import { spawnSync } from 'node:child_process'; + +const target = process.env.WORKOS_BUILD_TARGET; +const outfile = process.env.WORKOS_BUILD_OUTFILE ?? './dist/workos'; + +// The keyring native binding for the compile target must be installed, or the +// compiled binary ships without OS keychain support and crashes at startup +// (config-store.ts imports @napi-rs/keyring statically). Fail the build fast +// instead — a missing binding means `bun install` ran without --os/--cpu +// wildcards for a cross-target build. `internal verify-assets` proves the +// binding actually loads at runtime on release smoke hardware. +const KEYRING_BINDINGS: Record = { + 'darwin-arm64': '@napi-rs/keyring-darwin-arm64', + 'darwin-x64': '@napi-rs/keyring-darwin-x64', + 'linux-x64': '@napi-rs/keyring-linux-x64-gnu', + 'linux-arm64': '@napi-rs/keyring-linux-arm64-gnu', + 'windows-x64': '@napi-rs/keyring-win32-x64-msvc', +}; + +const normalizedTarget = ( + target ?? `bun-${process.platform === 'win32' ? 'windows' : process.platform}-${process.arch}` +) + .replace(/^bun-/, '') + .replace(/-baseline$/, '') + .replace(/-modern$/, ''); +const keyringBinding = KEYRING_BINDINGS[normalizedTarget]; +if (!keyringBinding) { + throw new Error(`No keyring binding mapping for target ${normalizedTarget}; add it to KEYRING_BINDINGS`); +} +try { + import.meta.resolve(`${keyringBinding}/package.json`); +} catch { + throw new Error( + `${keyringBinding} is not installed, so the ${normalizedTarget} binary would ship without OS keychain support. ` + + `Run \`bun install --frozen-lockfile --os="*" --cpu="*"\` before cross-target builds.`, + ); +} + +const args = [ + 'build', + '--compile', + '--no-compile-autoload-dotenv', + '--no-compile-autoload-bunfig', + ...(target ? [`--target=${target}`] : []), + './src/bin.ts', + '--outfile', + outfile, +]; + +const result = spawnSync('bun', args, { stdio: 'inherit' }); +process.exit(result.status ?? 1); diff --git a/scripts/craft-pre-release.sh b/scripts/craft-pre-release.sh deleted file mode 100644 index c1d3e354..00000000 --- a/scripts/craft-pre-release.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -eux -# Move to the project root -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd $SCRIPT_DIR/.. -OLD_VERSION="${1}" -NEW_VERSION="${2}" - # Do not tag and commit changes made by "npm version" -export npm_config_git_tag_version=false -npm version "${NEW_VERSION}" diff --git a/scripts/gen-agent-sdk-manifest.ts b/scripts/gen-agent-sdk-manifest.ts new file mode 100644 index 00000000..ac73da52 --- /dev/null +++ b/scripts/gen-agent-sdk-manifest.ts @@ -0,0 +1,50 @@ +import { createHash } from 'node:crypto'; +import { mkdir, readFile } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const projectRoot = join(import.meta.dirname, '..'); +const manifestPath = join(projectRoot, 'src', 'generated', 'agent-sdk-manifest.ts'); +const requestedTarget = process.env.WORKOS_BUILD_TARGET ?? `bun-${process.platform}-${process.arch}`; +const normalizedTarget = requestedTarget + .replace(/^bun-/, '') + .replace(/-baseline$/, '') + .replace(/-modern$/, ''); +const [targetOs, targetArch] = normalizedTarget.split('-'); + +const packageOs = targetOs === 'windows' ? 'win32' : targetOs; +if (!packageOs || !targetArch || !['darwin', 'linux', 'win32'].includes(packageOs)) { + throw new Error(`Unsupported WorkOS binary target for the Agent SDK: ${requestedTarget}`); +} + +const packageName = `@anthropic-ai/claude-agent-sdk-${packageOs}-${targetArch}`; +const packageJsonPath = fileURLToPath(import.meta.resolve(`${packageName}/package.json`)); +const packageRoot = dirname(packageJsonPath); +const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8')) as { version?: unknown }; +const executableName = packageOs === 'win32' ? 'claude.exe' : 'claude'; +const executablePath = join(packageRoot, executableName); + +if (typeof packageJson.version !== 'string') { + throw new Error(`Could not determine the installed ${packageName} version`); +} + +const executable = await readFile(executablePath); +const executableSha256 = createHash('sha256').update(executable).digest('hex'); +const tarballBasename = packageName.split('/')[1]; +const tarballUrl = `https://registry.npmjs.org/${packageName}/-/${tarballBasename}-${packageJson.version}.tgz`; + +await mkdir(dirname(manifestPath), { recursive: true }); + +const manifest = `// Generated by scripts/gen-agent-sdk-manifest.ts. Do not edit manually. +// The native Agent SDK executable is NOT embedded in the compiled binary: it is +// downloaded on first agent use, pinned to this exact version and checksum. +export const AGENT_SDK_TARGET = ${JSON.stringify(`${packageOs}-${targetArch}`)}; +export const AGENT_SDK_VERSION = ${JSON.stringify(packageJson.version)}; +export const AGENT_SDK_PACKAGE = ${JSON.stringify(packageName)}; +export const AGENT_SDK_TARBALL_URL = ${JSON.stringify(tarballUrl)}; +export const AGENT_SDK_EXECUTABLE_NAME = ${JSON.stringify(executableName)}; +export const AGENT_SDK_EXECUTABLE_SIZE = ${executable.byteLength}; +export const AGENT_SDK_EXECUTABLE_SHA256 = ${JSON.stringify(executableSha256)}; +`; + +await Bun.write(manifestPath, manifest); diff --git a/scripts/gen-integration-manifest.ts b/scripts/gen-integration-manifest.ts new file mode 100644 index 00000000..e0064c74 --- /dev/null +++ b/scripts/gen-integration-manifest.ts @@ -0,0 +1,40 @@ +import { existsSync } from 'node:fs'; +import { readdir, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +const projectRoot = join(import.meta.dirname, '..'); +const integrationsDir = join(projectRoot, 'src', 'integrations'); +const manifestPath = join(integrationsDir, '_manifest.ts'); + +const entries = await readdir(integrationsDir, { withFileTypes: true }); +const integrationNames = entries + // A directory without an index.ts (scratch dir, editor artifact) must not + // produce a broken static import that fails the whole build. + .filter( + (entry) => + entry.isDirectory() && !entry.name.startsWith('_') && existsSync(join(integrationsDir, entry.name, 'index.ts')), + ) + .map((entry) => entry.name) + .sort(); + +const imports = integrationNames + .map((name, index) => `import * as integration${index} from './${name}/index.js';`) + .join('\n'); +const modules = integrationNames + .map((name, index) => { + const key = /^[A-Za-z_$][\w$]*$/.test(name) ? name : `'${name}'`; + return ` ${key}: integration${index},`; + }) + .join('\n'); + +const manifest = `// Generated by scripts/gen-integration-manifest.ts. Do not edit manually. +import type { IntegrationModule } from '../lib/registry.js'; + +${imports} + +export const integrationModules = { +${modules} +} satisfies Record; +`; + +await writeFile(manifestPath, manifest); diff --git a/scripts/gen-npm-packages.ts b/scripts/gen-npm-packages.ts new file mode 100644 index 00000000..517cd9b9 --- /dev/null +++ b/scripts/gen-npm-packages.ts @@ -0,0 +1,160 @@ +// Generates the npm distribution packages into dist/npm/ from already-built +// platform binaries in dist/ (release asset names). Layout follows the +// esbuild/swc/clerk thin-shim pattern: +// +// dist/npm/workos thin Node launcher; optionalDependencies +// pull in exactly one platform package +// dist/npm/@workos/cli-- the compiled binary for one platform +// +// WORKOS_NPM_VERSION version to stamp on every package; defaults to the +// repo package.json version. +// WORKOS_NPM_ALLOW_MISSING set to 1 to generate packages only for the +// binaries present in dist/ (local testing; the +// launcher's optionalDependencies are pruned to +// match). Release runs must not set this. +import { chmodSync, copyFileSync, existsSync, mkdirSync, rmSync } from 'node:fs'; +import { readFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +const projectRoot = join(import.meta.dirname, '..'); +const distDir = join(projectRoot, 'dist'); +const outDir = join(distDir, 'npm'); +const allowMissing = process.env.WORKOS_NPM_ALLOW_MISSING === '1'; + +const rootPackageJson = JSON.parse(await readFile(join(projectRoot, 'package.json'), 'utf8')) as { + version: string; + description?: string; + license?: string; + homepage?: string; +}; +const version = process.env.WORKOS_NPM_VERSION ?? rootPackageJson.version; +if (!/^\d+\.\d+\.\d+(-.+)?$/.test(version)) { + throw new Error(`Invalid npm version: ${version}`); +} + +const REPOSITORY = { type: 'git', url: 'git+https://github.com/workos/cli.git' }; +const LICENSE = 'MIT'; + +// Platform keys use process.platform/process.arch values so the launcher can +// build the package name from the running process; assets use release names. +const PLATFORMS = [ + { key: 'darwin-arm64', os: 'darwin', cpu: 'arm64', asset: 'workos-darwin-arm64', bin: 'workos' }, + { key: 'darwin-x64', os: 'darwin', cpu: 'x64', asset: 'workos-darwin-x64', bin: 'workos' }, + { key: 'linux-x64', os: 'linux', cpu: 'x64', asset: 'workos-linux-x64', bin: 'workos' }, + { key: 'linux-arm64', os: 'linux', cpu: 'arm64', asset: 'workos-linux-arm64', bin: 'workos' }, + { key: 'win32-x64', os: 'win32', cpu: 'x64', asset: 'workos-windows-x64.exe', bin: 'workos.exe' }, +]; + +const present = PLATFORMS.filter((platform) => existsSync(join(distDir, platform.asset))); +const missing = PLATFORMS.filter((platform) => !present.includes(platform)); +if (missing.length > 0 && !allowMissing) { + throw new Error(`Missing platform binaries in dist/: ${missing.map((p) => p.asset).join(', ')}`); +} +if (present.length === 0) { + throw new Error('No platform binaries found in dist/'); +} + +rmSync(outDir, { recursive: true, force: true }); + +const LAUNCHER = `#!/usr/bin/env node +'use strict'; +// Thin launcher: resolves the compiled workos binary for this platform from +// the matching @workos/cli-- optionalDependency and runs it. +const { spawnSync } = require('node:child_process'); + +const key = \`\${process.platform}-\${process.arch}\`; +const executable = process.platform === 'win32' ? 'workos.exe' : 'workos'; + +let binary; +try { + binary = require.resolve(\`@workos/cli-\${key}/bin/\${executable}\`); +} catch { + console.error(\`workos: no prebuilt binary for \${key}.\`); + console.error('Supported platforms: ${PLATFORMS.map((p) => p.key).join(', ')}.'); + console.error('If your platform is listed, reinstall with optional dependencies enabled'); + console.error('(npm install --include=optional), or download a binary directly:'); + console.error('https://github.com/workos/cli/releases/latest'); + process.exit(1); +} + +const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' }); +if (result.error) { + console.error(\`workos: failed to run \${binary}: \${result.error.message}\`); + process.exit(1); +} +if (result.signal) { + process.kill(process.pid, result.signal); +} +process.exit(result.status ?? 1); +`; + +for (const platform of present) { + const packageDir = join(outDir, '@workos', `cli-${platform.key}`); + mkdirSync(join(packageDir, 'bin'), { recursive: true }); + await writeFile( + join(packageDir, 'package.json'), + `${JSON.stringify( + { + name: `@workos/cli-${platform.key}`, + version, + description: `WorkOS CLI binary for ${platform.key}`, + repository: REPOSITORY, + license: LICENSE, + os: [platform.os], + cpu: [platform.cpu], + files: ['bin'], + }, + null, + 2, + )}\n`, + ); + const binPath = join(packageDir, 'bin', platform.bin); + copyFileSync(join(distDir, platform.asset), binPath); + chmodSync(binPath, 0o755); +} + +const launcherDir = join(outDir, 'workos'); +mkdirSync(join(launcherDir, 'bin'), { recursive: true }); +await writeFile( + join(launcherDir, 'package.json'), + `${JSON.stringify( + { + name: 'workos', + version, + description: rootPackageJson.description ?? 'WorkOS CLI', + repository: REPOSITORY, + license: LICENSE, + homepage: rootPackageJson.homepage ?? 'https://github.com/workos/cli', + bin: { workos: 'bin/workos.js' }, + files: ['bin'], + engines: { node: '>=18' }, + optionalDependencies: Object.fromEntries(present.map((p) => [`@workos/cli-${p.key}`, version])), + }, + null, + 2, + )}\n`, +); +await writeFile(join(launcherDir, 'bin', 'workos.js'), LAUNCHER); +chmodSync(join(launcherDir, 'bin', 'workos.js'), 0o755); +await writeFile( + join(launcherDir, 'README.md'), + [ + '# workos', + '', + 'Thin npm launcher for the WorkOS CLI. Installing this package pulls in the', + 'prebuilt binary for your platform via an optional dependency and runs it.', + '', + 'Standalone binaries are also available from', + '[GitHub Releases](https://github.com/workos/cli/releases/latest).', + '', + ].join('\n'), +); + +console.log(`Generated npm packages (v${version}) in ${outDir}:`); +console.log(` workos (launcher, ${present.length} optional platform deps)`); +for (const platform of present) { + console.log(` @workos/cli-${platform.key}`); +} +if (missing.length > 0) { + console.log(`Skipped missing binaries: ${missing.map((p) => p.asset).join(', ')}`); +} diff --git a/scripts/gen-skills-manifest.ts b/scripts/gen-skills-manifest.ts new file mode 100644 index 00000000..dee0ba63 --- /dev/null +++ b/scripts/gen-skills-manifest.ts @@ -0,0 +1,62 @@ +import { mkdir, readdir, readFile, stat } from 'node:fs/promises'; +import { dirname, join, relative, sep } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const projectRoot = join(import.meta.dirname, '..'); +const generatedDir = join(projectRoot, 'src', 'generated'); +const manifestPath = join(generatedDir, 'skills-manifest.ts'); +const packageEntry = fileURLToPath(import.meta.resolve('@workos/skills')); +const packageRoot = dirname(dirname(packageEntry)); +const pluginsDir = join(packageRoot, 'plugins'); +const packageJson = JSON.parse(await readFile(join(packageRoot, 'package.json'), 'utf8')) as { version?: unknown }; + +await mkdir(generatedDir, { recursive: true }); + +if (typeof packageJson.version !== 'string') { + throw new Error('Could not determine the installed @workos/skills version'); +} + +async function collectFiles(dir: string): Promise { + const entries = await readdir(dir, { withFileTypes: true }); + const files = await Promise.all( + entries.map(async (entry) => { + const path = join(dir, entry.name); + if (entry.isDirectory()) return collectFiles(path); + if (entry.isFile()) return [path]; + return []; + }), + ); + return files.flat(); +} + +const files = (await collectFiles(pluginsDir)).sort(); +const imports: string[] = []; +const assets: string[] = []; + +for (const [index, path] of files.entries()) { + const info = await stat(path); + const relPath = relative(pluginsDir, path).split(sep).join('/'); + // TypeScript does not model Bun's `file` import attribute, but Bun embeds + // each asset and replaces the import with its path in the standalone binary. + imports.push(`// @ts-expect-error Bun file imports support arbitrary asset extensions`); + imports.push(`import asset${index} from ${JSON.stringify(path)} with { type: 'file' };`); + assets.push( + ` { relPath: ${JSON.stringify(relPath)}, embedded: asset${index}, executable: ${Boolean(info.mode & 0o111)} },`, + ); +} + +const manifest = `// Generated by scripts/gen-skills-manifest.ts. Do not edit manually. +${imports.join('\n')} + +export const BUNDLED_SKILLS_VERSION = ${JSON.stringify(packageJson.version)}; + +export const skillsAssets: ReadonlyArray<{ + relPath: string; + embedded: string; + executable: boolean; +}> = [ +${assets.join('\n')} +]; +`; + +await Bun.write(manifestPath, manifest); diff --git a/scripts/smoke-test.ts b/scripts/smoke-test.ts index a203cbfa..dae77522 100644 --- a/scripts/smoke-test.ts +++ b/scripts/smoke-test.ts @@ -5,7 +5,7 @@ * to verify SDK method signatures are correct. * * Usage: - * WORKOS_API_KEY=sk_test_xxx pnpm tsx scripts/smoke-test.ts + * WORKOS_API_KEY=sk_test_xxx bun run scripts/smoke-test.ts */ import { writeFileSync, unlinkSync, existsSync } from 'node:fs'; diff --git a/src/bin-command-telemetry.integration.spec.ts b/src/bin-command-telemetry.integration.spec.ts index 3e288ce1..913bf100 100644 --- a/src/bin-command-telemetry.integration.spec.ts +++ b/src/bin-command-telemetry.integration.spec.ts @@ -25,7 +25,7 @@ import { fileURLToPath } from 'node:url'; * That captures the real event payload, independent of debug-log formatting. */ const binPath = fileURLToPath(new URL('./bin.ts', import.meta.url)); -const forceInsecureStorageImport = new URL('./test/force-insecure-storage.ts', import.meta.url).href; +const forceInsecureStorageImport = fileURLToPath(new URL('./test/force-insecure-storage.ts', import.meta.url)); const repoRoot = fileURLToPath(new URL('..', import.meta.url)); let sandboxTmp: string; @@ -68,15 +68,11 @@ function runCli(args: string[], envOverrides: NodeJS.ProcessEnv = {}) { ...envOverrides, }; - const result = spawnSync( - process.execPath, - ['--import', 'tsx', '--import', forceInsecureStorageImport, binPath, ...args], - { - cwd: repoRoot, - encoding: 'utf-8', - env, - }, - ); + const result = spawnSync('bun', ['--preload', forceInsecureStorageImport, binPath, ...args], { + cwd: repoRoot, + encoding: 'utf-8', + env, + }); const events: Array<{ type: string; attributes?: Record }> = []; const pendingDir = join(sandboxTmp, 'workos-cli-telemetry'); diff --git a/src/bin.ts b/src/bin.ts index d3bc88be..5fd268a8 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -1,33 +1,20 @@ -#!/usr/bin/env node +#!/usr/bin/env bun // Load .env.local for local development when --local flag is used if (process.argv.includes('--local') || process.env.WORKOS_DEV) { const { config } = await import('dotenv'); - // bin.ts compiles to dist/bin.js, so go up one level to find .env.local + const { existsSync } = await import('node:fs'); const { fileURLToPath } = await import('node:url'); - config({ path: fileURLToPath(new URL('../.env.local', import.meta.url)) }); + const envPath = fileURLToPath(new URL('../.env.local', import.meta.url)); + if (existsSync(envPath)) config({ path: envPath, quiet: true }); } -import { satisfies } from 'semver'; -import { red } from './utils/logging.js'; -import { getConfig, getVersion } from './lib/settings.js'; +import { getVersion } from './lib/settings.js'; import yargs from 'yargs'; -import { hideBin } from 'yargs/helpers'; import { ensureAuthenticated } from './lib/ensure-auth.js'; import { checkForUpdates } from './lib/version-check.js'; -const NODE_VERSION_RANGE = getConfig().nodeVersion; - -// Have to run this above the other imports because they are importing clack that -// has the problematic imports. -if (!satisfies(process.version, NODE_VERSION_RANGE)) { - red( - `WorkOS AuthKit installer requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`, - ); - process.exit(1); -} - import { InvalidInteractionModeError, isPromptAllowed, @@ -88,7 +75,9 @@ await loadDeviceId(); recoverPendingEvents(); // Resolve output mode early from raw argv (before yargs parses) -const rawArgs = hideBin(process.argv); +// Bun preserves the Node-style [runtime, entrypoint, ...args] argv shape in +// both source mode and standalone executables. +const rawArgs = process.argv.slice(2); const hasJsonFlag = rawArgs.includes('--json'); const baseOutputMode = resolveOutputMode(hasJsonFlag); setOutputMode(baseOutputMode); @@ -252,6 +241,7 @@ async function runCli(): Promise { const flags = extractUserFlags(rawArgs); const parser = yargs(rawArgs) + .scriptName('workos') .parserConfiguration({ 'populate--': true }) .exitProcess(false) .fail((msg, err) => { @@ -312,6 +302,7 @@ async function runCli(): Promise { 'claim', 'install', 'debug', + 'internal', 'dashboard', 'emulate', 'dev', @@ -340,6 +331,7 @@ async function runCli(): Promise { 'env', 'claim', 'debug', + 'internal', 'dashboard', 'emulate', 'dev', @@ -2658,6 +2650,19 @@ async function runCli(): Promise { ); return yargs.demandCommand(1, 'Run "workos debug " for debug tools.').strict(); }) + .command('internal', false, (yargs) => { + registerSubcommand( + yargs, + 'verify-assets', + 'Verify embedded assets (skills, Agent SDK) extract and run on this machine', + (y) => y, + async () => { + const { runVerifyAssets } = await import('./commands/internal-verify-assets.js'); + await runVerifyAssets(); + }, + ); + return yargs.demandCommand(1, 'Run "workos internal " for internal tools.').strict(); + }) .command( 'migrations', 'Migrate users from identity providers (Auth0, Cognito, Clerk, Firebase) to WorkOS', @@ -2699,7 +2704,7 @@ async function runCli(): Promise { async (argv) => { // Non-human modes: show help instead of prompting if (!isPromptAllowed()) { - yargs(rawArgs).showHelp(); + yargs(rawArgs).scriptName('workos').showHelp(); return; } diff --git a/src/cli.config.ts b/src/cli.config.ts index 9b1629b2..c40f00e0 100644 --- a/src/cli.config.ts +++ b/src/cli.config.ts @@ -25,8 +25,6 @@ export const config = { refreshThresholdMs: 60_000, }, - nodeVersion: '>=20.20', - logging: { debugMode: false, }, diff --git a/src/commands/api/catalog.spec.ts b/src/commands/api/catalog.spec.ts index 18709b53..9d415e3c 100644 --- a/src/commands/api/catalog.spec.ts +++ b/src/commands/api/catalog.spec.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { parseSpec, endpointsByTag, type EndpointInfo } from './catalog.js'; +import { parseSpec, loadCatalog, endpointsByTag, type EndpointInfo } from './catalog.js'; const SAMPLE_SPEC = ` openapi: 3.0.0 @@ -49,6 +49,12 @@ paths: `; describe('parseSpec', () => { + it('loads the bundled WorkOS specification', async () => { + const catalog = await loadCatalog(); + expect(catalog.endpoints.length).toBeGreaterThan(0); + expect(catalog.tags.length).toBeGreaterThan(0); + }); + it('returns endpoints for each method on a path', () => { const catalog = parseSpec(SAMPLE_SPEC); const ops = catalog.endpoints.filter((e) => e.path === '/organizations').map((e) => e.method); diff --git a/src/commands/api/catalog.ts b/src/commands/api/catalog.ts index c81dd577..52649531 100644 --- a/src/commands/api/catalog.ts +++ b/src/commands/api/catalog.ts @@ -1,6 +1,5 @@ import { parse as parseYaml } from 'yaml'; -import { createRequire } from 'node:module'; -import { readFile } from 'node:fs/promises'; +import openApiSpec from '@workos/openapi-spec/spec' with { type: 'text' }; export interface Param { name: string; @@ -115,16 +114,10 @@ export function parseSpec(yamlText: string): Catalog { let cachedCatalog: Promise | undefined; export function loadCatalog(): Promise { - // Cache the in-flight Promise (not just the resolved value) so concurrent - // callers reuse the same readFile/parse pass — see request.ts callers. + // Cache the in-flight Promise so concurrent callers reuse the same parse pass. if (cachedCatalog) return cachedCatalog; - cachedCatalog = (async () => { - const require = createRequire(import.meta.url); - const specPath = require.resolve('@workos/openapi-spec/spec'); - const yamlText = await readFile(specPath, 'utf-8'); - return parseSpec(yamlText); - })(); + cachedCatalog = Promise.resolve(parseSpec(openApiSpec)); return cachedCatalog; } diff --git a/src/commands/install-skill.spec.ts b/src/commands/install-skill.spec.ts index 98539ba9..56db4f62 100644 --- a/src/commands/install-skill.spec.ts +++ b/src/commands/install-skill.spec.ts @@ -19,8 +19,8 @@ vi.mock('os', async (importOriginal) => { return { ...actual, homedir: vi.fn(actual.homedir) }; }); -vi.mock('@workos/skills', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('../lib/skills-assets.js', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, getSkillsDir: vi.fn(actual.getSkillsDir) }; }); @@ -354,7 +354,7 @@ describe('install-skill', () => { describe('autoInstallSkills', () => { beforeEach(async () => { const { homedir } = await import('os'); - const { getSkillsDir } = await import('@workos/skills'); + const { getSkillsDir } = await import('../lib/skills-assets.js'); vi.mocked(homedir).mockReturnValue(homeDir); vi.mocked(getSkillsDir).mockReturnValue(skillsDir); }); @@ -386,34 +386,23 @@ describe('install-skill', () => { expect(result!.agents.sort()).toEqual(['Claude Code', 'Codex']); }); - it('writes a version marker per agent when the bundled version is resolvable', async () => { - // Plant a deterministic package layout so getBundledSkillsVersion finds - // a real version. The function walks up 3 dirnames from skillsDir to - // locate the package.json, so we mirror that layout here: - // /package.json ← version source - // /plugins/workos/skills ← skillsDir + it('writes the generated bundled version marker per agent', async () => { const { SKILL_VERSION_MARKER_FILENAME } = await import('./install-skill.js'); - const { getSkillsDir } = await import('@workos/skills'); + const { BUNDLED_SKILLS_VERSION } = await import('../lib/skills-assets.js'); - const packageRoot = join(testDir, 'pkg'); - mkdirSync(packageRoot); - writeFileSync(join(packageRoot, 'package.json'), JSON.stringify({ name: '@workos/skills', version: '9.9.9' })); - const deepSkillsDir = join(packageRoot, 'plugins/workos/skills'); - mkdirSync(deepSkillsDir, { recursive: true }); - mkdirSync(join(deepSkillsDir, 'skill-a')); - writeFileSync(join(deepSkillsDir, 'skill-a', 'SKILL.md'), '# Skill A'); - vi.mocked(getSkillsDir).mockReturnValue(deepSkillsDir); + mkdirSync(join(skillsDir, 'skill-a')); + writeFileSync(join(skillsDir, 'skill-a', 'SKILL.md'), '# Skill A'); mkdirSync(join(homeDir, '.claude')); const result = await autoInstallSkills(); expect(result).not.toBeNull(); - expect(result!.version).toBe('9.9.9'); + expect(result!.version).toBe(BUNDLED_SKILLS_VERSION); const marker = join(homeDir, '.claude/skills', SKILL_VERSION_MARKER_FILENAME); expect(existsSync(marker)).toBe(true); - expect(readFileSync(marker, 'utf8')).toBe('9.9.9'); + expect(readFileSync(marker, 'utf8')).toBe(BUNDLED_SKILLS_VERSION); }); it('returns null when no agents are detected', async () => { @@ -433,7 +422,7 @@ describe('install-skill', () => { it('swallows errors from discoverSkills and returns null', async () => { // Point to a nonexistent skills directory - const { getSkillsDir } = await import('@workos/skills'); + const { getSkillsDir } = await import('../lib/skills-assets.js'); vi.mocked(getSkillsDir).mockReturnValue('/nonexistent/path'); await expect(autoInstallSkills()).resolves.toBeNull(); @@ -479,7 +468,7 @@ describe('install-skill', () => { describe('refreshWorkOSSkills', () => { beforeEach(async () => { const { homedir } = await import('os'); - const { getSkillsDir } = await import('@workos/skills'); + const { getSkillsDir } = await import('../lib/skills-assets.js'); vi.mocked(homedir).mockReturnValue(homeDir); vi.mocked(getSkillsDir).mockReturnValue(skillsDir); }); @@ -508,12 +497,10 @@ describe('install-skill', () => { 'claude-code': '0.0.1', codex: null, }); - // After: in this fixture skillsDir isn't an npm package layout, so - // getBundledSkillsVersion returns null and no marker is rewritten. - // Therefore perAgentAfter must equal perAgentBefore for every agent. + const { BUNDLED_SKILLS_VERSION } = await import('../lib/skills-assets.js'); expect(result!.perAgentAfter).toMatchObject({ - 'claude-code': '0.0.1', - codex: null, + 'claude-code': BUNDLED_SKILLS_VERSION, + codex: BUNDLED_SKILLS_VERSION, }); }); diff --git a/src/commands/install-skill.ts b/src/commands/install-skill.ts index 6249ea22..b982446b 100644 --- a/src/commands/install-skill.ts +++ b/src/commands/install-skill.ts @@ -3,9 +3,11 @@ import { dirname, join } from 'path'; import { existsSync } from 'fs'; import { mkdir, mkdtemp, cp, rename, rm, readdir, readFile, stat, access, writeFile } from 'fs/promises'; import chalk from 'chalk'; -import { getSkillsDir as getSkillsPackageDir } from '@workos/skills'; +import { BUNDLED_SKILLS_VERSION, getSkillsDir as getSkillsPackageDir } from '../lib/skills-assets.js'; import { IS_WINDOWS } from '../utils/platform.js'; import { ExitCode, exitWithCode } from '../utils/exit-codes.js'; +import { exitWithError } from '../utils/output.js'; +import { logError } from '../utils/debug.js'; export const SKILL_VERSION_MARKER_FILENAME = '.workos-skill-version'; @@ -25,21 +27,10 @@ async function pathExists(p: string): Promise { } /** - * Read the bundled @workos/skills version by walking up from the skills - * directory to the package.json. The package's `exports` map doesn't expose - * package.json, so we resolve it by filesystem convention. - * Returns null if the version can't be determined — callers treat that as - * "no marker written" rather than failing the install. + * Read the @workos/skills version captured when the asset manifest was generated. */ -export async function getBundledSkillsVersion(skillsDir: string = getSkillsPackageDir()): Promise { - try { - // skillsDir = /plugins/workos/skills - const packageRoot = dirname(dirname(dirname(skillsDir))); - const pkgJson = JSON.parse(await readFile(join(packageRoot, 'package.json'), 'utf8')); - return typeof pkgJson.version === 'string' ? pkgJson.version : null; - } catch { - return null; - } +export async function getBundledSkillsVersion(): Promise { + return BUNDLED_SKILLS_VERSION; } export interface AgentConfig { @@ -88,6 +79,18 @@ export function getSkillsDir(): string { return getSkillsPackageDir(); } +/** + * Exit with the structured "corrupted installation" error. Shared by every + * command that materializes the embedded skills, so extraction failures get + * an actionable message instead of a raw stack trace. + */ +export function exitSkillsUnreadable(skillsDir?: string): never { + exitWithError({ + code: 'SKILLS_DIR_READ_FAILED', + message: `Could not read bundled skills${skillsDir ? ` at ${skillsDir}` : ''}. Your WorkOS CLI installation may be corrupted. Download a fresh binary from https://github.com/workos/cli/releases/latest.`, + }); +} + export async function discoverSkills(skillsDir: string): Promise { const entries = await readdir(skillsDir, { withFileTypes: true }); @@ -196,8 +199,16 @@ async function cleanupStaleOrphans(parent: string, skillName: string): Promise { const home = homedir(); const agents = createAgents(home); - const skillsDir = getSkillsDir(); - const skills = await discoverSkills(skillsDir); + + let skillsDir: string | undefined; + let skills: string[]; + try { + skillsDir = getSkillsDir(); + skills = await discoverSkills(skillsDir); + } catch (error) { + logError('Failed to read skills directory:', error); + exitSkillsUnreadable(skillsDir); + } const targetSkills = options.skill ? skills.filter((s) => options.skill!.includes(s)) : skills; @@ -249,13 +260,11 @@ export async function runInstallSkill(options: InstallSkillOptions): Promise(); - for (const r of successful) succeededAgents.add(r.agent); - for (const agent of succeededAgents) { - await writeAgentSkillMarker(agent, version); - } + const version = await getBundledSkillsVersion(); + const succeededAgents = new Set(); + for (const r of successful) succeededAgents.add(r.agent); + for (const agent of succeededAgents) { + await writeAgentSkillMarker(agent, version); } if (failed.length > 0) { @@ -331,7 +340,17 @@ async function writeAgentSkillMarker(agent: AgentConfig, version: string): Promi */ export async function refreshWorkOSSkills(opts: RefreshOptions = {}): Promise { const home = homedir(); - const skillsDir = getSkillsDir(); + + let skillsDir: string; + try { + skillsDir = getSkillsDir(); + } catch (error) { + // Best-effort hook: a failed embedded-assets extraction must not crash + // install/login flows. `doctor` reports the corruption separately. + logError('Failed to materialize bundled skills:', error); + return null; + } + const detected = opts.agents ?? detectAgents(createAgents(home)); const allSkills = await discoverSkills(skillsDir).catch(() => []); const skills = opts.skills ? allSkills.filter((s) => opts.skills!.includes(s)) : allSkills; @@ -339,7 +358,7 @@ export async function refreshWorkOSSkills(opts: RefreshOptions = {}): Promise = {}; const perAgentAfter: Record = {}; const succeededAgents: AgentConfig[] = []; @@ -362,7 +381,7 @@ export async function refreshWorkOSSkills(opts: RefreshOptions = {}): Promise { + // Exercises the real pipeline in source mode: skills materialize to a temp + // dir and the Agent SDK `claude` executable is spawned with --version. In + // the compiled binary the same code path additionally covers the first-run + // download + checksum verification (verified by the CI smoke test). + it('verifies embedded skills and the Agent SDK executable', async () => { + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + const { setOutputMode } = await import('../utils/output.js'); + setOutputMode('json'); + try { + await runVerifyAssets(); + + const lastLine = logSpy.mock.calls.at(-1)?.[0] as string; + const report = JSON.parse(lastLine); + expect(report.ok).toBe(true); + expect(report.skillCount).toBeGreaterThan(0); + expect(report.bundledSkillsVersion).toMatch(/^\d+\.\d+\.\d+/); + expect(report.agentSdkTarget).toBe(`${process.platform}-${process.arch}`); + expect(report.keyring).toMatch(/^native/); + expect(report.claudeVersion).toBeTruthy(); + expect(report.claudePath).not.toContain('$bunfs'); + } finally { + setOutputMode('human'); + logSpy.mockRestore(); + } + }, 120_000); +}); diff --git a/src/commands/internal-verify-assets.ts b/src/commands/internal-verify-assets.ts new file mode 100644 index 00000000..25387328 --- /dev/null +++ b/src/commands/internal-verify-assets.ts @@ -0,0 +1,105 @@ +import { spawnSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import chalk from 'chalk'; +import { AGENT_SDK_TARGET, AGENT_SDK_VERSION, ensureClaudeCodeExecutable } from '../lib/agent-sdk-assets.js'; +import { BUNDLED_SKILLS_VERSION, getSkillsDir } from '../lib/skills-assets.js'; +import { logError } from '../utils/debug.js'; +import { exitWithError, isJsonMode, outputJson } from '../utils/output.js'; +import { discoverSkills } from './install-skill.js'; + +// Generous timeout: on Windows the first spawn of a freshly-installed +// executable can stall behind a Defender scan. +const CLAUDE_SPAWN_TIMEOUT_MS = 120_000; + +/** + * CI/diagnostic command (hidden): prove that the runtime assets work on this + * machine — skills embedded in the compiled binary materialize and are + * readable, and the pinned Agent SDK `claude` executable resolves (first-run + * download + checksum verification from a compiled binary; node_modules in + * dev) and actually runs. Exits non-zero on the first failure so release + * pipelines can gate on it. Requires network access from a compiled binary + * unless the download is already cached. + */ +export async function runVerifyAssets(): Promise { + let skillsDir: string; + let skills: string[]; + try { + skillsDir = getSkillsDir(); + skills = await discoverSkills(skillsDir); + if (skills.length === 0) { + throw new Error(`no skills found under ${skillsDir}`); + } + // Read one SKILL.md end-to-end to prove the materialized content is usable. + readFileSync(join(skillsDir, skills[0], 'SKILL.md'), 'utf8'); + } catch (error) { + logError('Embedded skills verification failed:', error); + exitWithError({ + code: 'VERIFY_ASSETS_SKILLS_FAILED', + message: `Embedded skills failed to materialize: ${error instanceof Error ? error.message : String(error)}`, + }); + } + + // The keyring native binding is load-bearing: config-store.ts imports it + // statically, so a binary compiled without the target's .node binding + // crashes at startup instead of falling back to file storage. Constructing + // an Entry proves the binding embedded and loaded; a storage-layer error + // (e.g. headless CI with no secret service) still proves the binding works. + let keyring: 'native' | 'native-storage-unavailable'; + try { + const { Entry } = await import('@napi-rs/keyring'); + const entry = new Entry('workos-cli', 'verify-assets-probe'); + try { + entry.getPassword(); + keyring = 'native'; + } catch { + keyring = 'native-storage-unavailable'; + } + } catch (error) { + logError('Keyring binding verification failed:', error); + exitWithError({ + code: 'VERIFY_ASSETS_KEYRING_FAILED', + message: `Keyring native binding failed to load: ${error instanceof Error ? error.message : String(error)}`, + }); + } + + let claudePath: string; + let claudeVersion: string; + try { + claudePath = await ensureClaudeCodeExecutable(); + const result = spawnSync(claudePath, ['--version'], { encoding: 'utf8', timeout: CLAUDE_SPAWN_TIMEOUT_MS }); + if (result.error) throw result.error; + if (result.status !== 0 || !result.stdout.trim()) { + throw new Error(`claude --version exited with status ${result.status}: ${result.stderr?.trim() || 'no output'}`); + } + claudeVersion = result.stdout.trim(); + } catch (error) { + logError('Agent SDK verification failed:', error); + exitWithError({ + code: 'VERIFY_ASSETS_AGENT_SDK_FAILED', + message: `Agent SDK executable failed to resolve or run: ${error instanceof Error ? error.message : String(error)}`, + }); + } + + const report = { + ok: true, + skillsDir, + skillCount: skills.length, + bundledSkillsVersion: BUNDLED_SKILLS_VERSION, + keyring, + claudePath, + claudeVersion, + agentSdkTarget: AGENT_SDK_TARGET, + agentSdkVersion: AGENT_SDK_VERSION, + }; + + if (isJsonMode()) { + outputJson(report); + return; + } + + console.log(chalk.green('✓'), `Skills materialized: ${skills.length} skills at ${skillsDir}`); + console.log(chalk.green('✓'), `Keyring binding loaded (${keyring})`); + console.log(chalk.green('✓'), `Agent SDK ${AGENT_SDK_VERSION} (${AGENT_SDK_TARGET}) at ${claudePath}`); + console.log(chalk.green('✓'), `claude --version → ${claudeVersion} (pinned SDK ${AGENT_SDK_VERSION})`); +} diff --git a/src/commands/list-skills.spec.ts b/src/commands/list-skills.spec.ts index 1a9027be..2b2ccf21 100644 --- a/src/commands/list-skills.spec.ts +++ b/src/commands/list-skills.spec.ts @@ -61,6 +61,28 @@ describe('runListSkills', () => { return { runListSkills, resetMode: () => output.setOutputMode('human') }; } + it('exits with a structured error when skills materialization fails', async () => { + vi.resetModules(); + vi.doMock('./install-skill.js', async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + getSkillsDir: () => { + throw new Error('embedded asset extraction failed'); + }, + createAgents: () => ({ test: makeTestAgent() }), + detectAgents: () => [makeTestAgent()], + }; + }); + const { runListSkills } = await import('./list-skills.js'); + + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + await expect(runListSkills({})).rejects.toSatisfy((err) => err instanceof Error && err.name === 'CliExit'); + const output = errorSpy.mock.calls.map((c) => c.join(' ')).join('\n'); + expect(output).toContain('https://github.com/workos/cli/releases/latest'); + errorSpy.mockRestore(); + }); + it('lists available and installed skills', async () => { mkdirSync(join(skillsDir, 'skill-a'), { recursive: true }); writeFileSync(join(skillsDir, 'skill-a', 'SKILL.md'), '# A'); diff --git a/src/commands/list-skills.ts b/src/commands/list-skills.ts index 952a4993..da22afb4 100644 --- a/src/commands/list-skills.ts +++ b/src/commands/list-skills.ts @@ -1,8 +1,8 @@ import { homedir } from 'os'; import chalk from 'chalk'; import { logError } from '../utils/debug.js'; -import { exitWithError, isJsonMode, outputJson } from '../utils/output.js'; -import { createAgents, detectAgents, discoverSkills, getSkillsDir } from './install-skill.js'; +import { isJsonMode, outputJson } from '../utils/output.js'; +import { createAgents, detectAgents, discoverSkills, exitSkillsUnreadable, getSkillsDir } from './install-skill.js'; import { findInstalledSkills } from './uninstall-skill.js'; export interface ListSkillsOptions { @@ -12,17 +12,15 @@ export interface ListSkillsOptions { export async function runListSkills(options: ListSkillsOptions): Promise { const home = homedir(); const agents = createAgents(home); - const skillsDir = getSkillsDir(); + let skillsDir: string | undefined; let knownSkills: string[]; try { + skillsDir = getSkillsDir(); knownSkills = await discoverSkills(skillsDir); } catch (error) { logError('Failed to read skills directory:', error); - exitWithError({ - code: 'SKILLS_DIR_READ_FAILED', - message: `Could not read skills directory at ${skillsDir}. Your WorkOS CLI installation may be corrupted. Try reinstalling with \`npm install -g @workos-inc/cli\`.`, - }); + exitSkillsUnreadable(skillsDir); } const targetAgents = detectAgents(agents, options.agent); diff --git a/src/commands/uninstall-skill.spec.ts b/src/commands/uninstall-skill.spec.ts index cc698ecf..d8cc2c9d 100644 --- a/src/commands/uninstall-skill.spec.ts +++ b/src/commands/uninstall-skill.spec.ts @@ -200,6 +200,28 @@ describe('runUninstallSkill', () => { await expectCliExit(runUninstallSkill({ skill: ['nonexistent-skill'] })); }); + it('exits with a structured error when skills materialization fails', async () => { + vi.resetModules(); + vi.doMock('./install-skill.js', async (importOriginal) => { + const mod = await importOriginal(); + return { + ...mod, + getSkillsDir: () => { + throw new Error('embedded asset extraction failed'); + }, + createAgents: () => ({ test: makeTestAgent() }), + detectAgents: () => [makeTestAgent()], + }; + }); + const { runUninstallSkill } = await import('./uninstall-skill.js'); + + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + await expectCliExit(runUninstallSkill({})); + const output = errorSpy.mock.calls.map((c) => c.join(' ')).join('\n'); + expect(output).toContain('https://github.com/workos/cli/releases/latest'); + errorSpy.mockRestore(); + }); + it('does not uninstall all skills when --skill filter partially matches', async () => { // Set up known skills for (const name of ['skill-a', 'skill-b']) { diff --git a/src/commands/uninstall-skill.ts b/src/commands/uninstall-skill.ts index ac9fbd46..3b19ef10 100644 --- a/src/commands/uninstall-skill.ts +++ b/src/commands/uninstall-skill.ts @@ -5,7 +5,14 @@ import { join } from 'path'; import chalk from 'chalk'; import { logError, logInfo, logWarn } from '../utils/debug.js'; import { exitWithError, isJsonMode, outputJson } from '../utils/output.js'; -import { createAgents, detectAgents, discoverSkills, getSkillsDir, type AgentConfig } from './install-skill.js'; +import { + createAgents, + detectAgents, + discoverSkills, + exitSkillsUnreadable, + getSkillsDir, + type AgentConfig, +} from './install-skill.js'; import { ExitCode, exitWithCode } from '../utils/exit-codes.js'; export interface UninstallSkillOptions { @@ -35,17 +42,15 @@ export async function uninstallSkill( export async function runUninstallSkill(options: UninstallSkillOptions): Promise { const home = homedir(); const agents = createAgents(home); - const skillsDir = getSkillsDir(); + let skillsDir: string | undefined; let knownSkills: string[]; try { + skillsDir = getSkillsDir(); knownSkills = await discoverSkills(skillsDir); } catch (error) { logError('Failed to read skills directory:', error); - exitWithError({ - code: 'SKILLS_DIR_READ_FAILED', - message: `Could not read skills directory at ${skillsDir}. Your WorkOS CLI installation may be corrupted. Try reinstalling with \`npm install -g @workos-inc/cli\`.`, - }); + exitSkillsUnreadable(skillsDir); } const targetAgents = detectAgents(agents, options.agent); diff --git a/src/doctor/checks/runtime.ts b/src/doctor/checks/runtime.ts index 5cc5df20..e5380f55 100644 --- a/src/doctor/checks/runtime.ts +++ b/src/doctor/checks/runtime.ts @@ -3,7 +3,14 @@ import { execFileNoThrow } from '../../utils/exec-file.js'; import type { DoctorOptions, RuntimeInfo } from '../types.js'; export async function checkRuntime(options: DoctorOptions): Promise { - const nodeVersion = process.version; + // The CLI is a compiled Bun binary, so process.version is Bun's baked-in + // Node-compat constant — probe the host's actual Node.js instead, since + // this reports on the user's project environment. + let nodeVersion: string | null = null; + const nodeResult = await execFileNoThrow('node', ['--version']); + if (nodeResult.status === 0) { + nodeVersion = nodeResult.stdout.trim(); + } const managers = detectAllPackageManagers(options); const primaryManager = managers[0] ?? null; diff --git a/src/doctor/checks/skills-fix.spec.ts b/src/doctor/checks/skills-fix.spec.ts index edfb503d..9433d020 100644 --- a/src/doctor/checks/skills-fix.spec.ts +++ b/src/doctor/checks/skills-fix.spec.ts @@ -150,8 +150,8 @@ describe('--fix sibling protection (integration via real refreshWorkOSSkills)', it('only writes to skills on the FIXABLE_SKILLS allowlist; planted siblings are untouched', async () => { // Re-import after unmocking so we get the real impls. The real - // refreshWorkOSSkills resolves its skill source via @workos/skills's - // getSkillsDir(), so we cannot mock the source side here — the meaningful + // refreshWorkOSSkills resolves its source via the materialized embedded + // skills tree, so the meaningful // assertion is target-side: pre-existing sibling skill dirs at the agent's // target path must NOT be touched, regardless of what's in the bundled // source. The opts.skills allowlist is what scopes refresh. diff --git a/src/doctor/output.ts b/src/doctor/output.ts index 973b5820..faf911a4 100644 --- a/src/doctor/output.ts +++ b/src/doctor/output.ts @@ -27,7 +27,8 @@ export function formatReport(report: DoctorReport, options?: FormatOptions): voi console.log(` Language: ${report.language.name}`); } if (report.language.name === 'JavaScript/TypeScript' || report.language.name === 'Unknown') { - console.log(` Runtime: Node.js ${report.runtime.nodeVersion}`); + const runtime = report.runtime.nodeVersion ? `Node.js ${report.runtime.nodeVersion}` : 'Node.js not detected'; + console.log(` Runtime: ${runtime}`); } if (report.framework.name) { const variant = report.framework.variant ? ` (${report.framework.variant})` : ''; diff --git a/src/doctor/types.ts b/src/doctor/types.ts index 07654117..45d9e795 100644 --- a/src/doctor/types.ts +++ b/src/doctor/types.ts @@ -36,7 +36,8 @@ export interface FrameworkInfo { } export interface RuntimeInfo { - nodeVersion: string; + /** Host Node.js version (`node --version`), or null when not installed. */ + nodeVersion: string | null; packageManager: string | null; packageManagerVersion: string | null; } diff --git a/src/integrations/_manifest.ts b/src/integrations/_manifest.ts new file mode 100644 index 00000000..d7700dd7 --- /dev/null +++ b/src/integrations/_manifest.ts @@ -0,0 +1,36 @@ +// Generated by scripts/gen-integration-manifest.ts. Do not edit manually. +import type { IntegrationModule } from '../lib/registry.js'; + +import * as integration0 from './dotnet/index.js'; +import * as integration1 from './elixir/index.js'; +import * as integration2 from './go/index.js'; +import * as integration3 from './kotlin/index.js'; +import * as integration4 from './nextjs/index.js'; +import * as integration5 from './node/index.js'; +import * as integration6 from './php/index.js'; +import * as integration7 from './php-laravel/index.js'; +import * as integration8 from './python/index.js'; +import * as integration9 from './react/index.js'; +import * as integration10 from './react-router/index.js'; +import * as integration11 from './ruby/index.js'; +import * as integration12 from './sveltekit/index.js'; +import * as integration13 from './tanstack-start/index.js'; +import * as integration14 from './vanilla-js/index.js'; + +export const integrationModules = { + dotnet: integration0, + elixir: integration1, + go: integration2, + kotlin: integration3, + nextjs: integration4, + node: integration5, + php: integration6, + 'php-laravel': integration7, + python: integration8, + react: integration9, + 'react-router': integration10, + ruby: integration11, + sveltekit: integration12, + 'tanstack-start': integration13, + 'vanilla-js': integration14, +} satisfies Record; diff --git a/src/integrations/dotnet/index.ts b/src/integrations/dotnet/index.ts index d107c662..eedba6f9 100644 --- a/src/integrations/dotnet/index.ts +++ b/src/integrations/dotnet/index.ts @@ -18,7 +18,7 @@ import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js'; import { initializeAgent, runAgent } from '../../lib/agent-interface.js'; import { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js'; import { validateInstallation } from '../../lib/validation/index.js'; -import { getReference } from '@workos/skills'; +import { getReference } from '../../lib/skills-assets.js'; export const config: FrameworkConfig = { metadata: { diff --git a/src/integrations/elixir/index.ts b/src/integrations/elixir/index.ts index 36dd17a5..ac50b36e 100644 --- a/src/integrations/elixir/index.ts +++ b/src/integrations/elixir/index.ts @@ -8,7 +8,7 @@ import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js'; import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js'; import { initializeAgent, runAgent } from '../../lib/agent-interface.js'; import { writeEnvLocal } from '../../lib/env-writer.js'; -import { getReference } from '@workos/skills'; +import { getReference } from '../../lib/skills-assets.js'; export const config: FrameworkConfig = { metadata: { diff --git a/src/integrations/go/index.ts b/src/integrations/go/index.ts index c2fdf082..e36d8073 100644 --- a/src/integrations/go/index.ts +++ b/src/integrations/go/index.ts @@ -12,7 +12,7 @@ import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js'; import { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js'; import { validateInstallation } from '../../lib/validation/index.js'; import { parseEnvFile } from '../../utils/env-parser.js'; -import { getReference } from '@workos/skills'; +import { getReference } from '../../lib/skills-assets.js'; /** Default port for Go HTTP servers */ const GO_DEFAULT_PORT = 8080; diff --git a/src/integrations/no-skill-tool.spec.ts b/src/integrations/no-skill-tool.spec.ts index 19750d5f..efbd4022 100644 --- a/src/integrations/no-skill-tool.spec.ts +++ b/src/integrations/no-skill-tool.spec.ts @@ -6,7 +6,7 @@ const integrationsDir = join(import.meta.dirname, '.'); /** * Guard against regressions where integration prompts reference the Skill tool. - * All integrations should inject reference content from @workos/skills directly, + * All integrations should inject bundled @workos/skills reference content directly, * not tell the agent to invoke a skill. */ describe('no Skill tool references in integrations', () => { @@ -38,3 +38,13 @@ describe('allowedTools does not include Skill', () => { expect(match![1]).not.toContain("'Skill'"); }); }); + +describe('no MCP docs server', () => { + // Skills references (inlined into prompts) replaced the docs MCP server. + // Spawning it via `npx -y` also broke the compiled binary's self-containment + // (required node/npx on PATH). + it('agent-interface.ts should not spawn @workos/mcp-docs-server', () => { + const content = readFileSync(join(import.meta.dirname, '..', 'lib', 'agent-interface.ts'), 'utf-8'); + expect(content).not.toContain('mcp-docs-server'); + }); +}); diff --git a/src/integrations/python/index.ts b/src/integrations/python/index.ts index cf9af2c9..45267187 100644 --- a/src/integrations/python/index.ts +++ b/src/integrations/python/index.ts @@ -7,7 +7,7 @@ import { enableDebugLogs } from '../../utils/debug.js'; import { analytics } from '../../utils/analytics.js'; import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js'; import { parseEnvFile } from '../../utils/env-parser.js'; -import { getReference } from '@workos/skills'; +import { getReference } from '../../lib/skills-assets.js'; /** * Detect which Python package manager the project uses. diff --git a/src/integrations/ruby/index.ts b/src/integrations/ruby/index.ts index d259a6e6..21c53da6 100644 --- a/src/integrations/ruby/index.ts +++ b/src/integrations/ruby/index.ts @@ -8,7 +8,7 @@ import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js'; import { initializeAgent, runAgent } from '../../lib/agent-interface.js'; import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js'; import { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js'; -import { getReference } from '@workos/skills'; +import { getReference } from '../../lib/skills-assets.js'; export const config: FrameworkConfig = { metadata: { diff --git a/src/lib/adapters/cli-adapter.spec.ts b/src/lib/adapters/cli-adapter.spec.ts index f7af41f5..69c42d9a 100644 --- a/src/lib/adapters/cli-adapter.spec.ts +++ b/src/lib/adapters/cli-adapter.spec.ts @@ -245,7 +245,7 @@ describe('CLIAdapter', () => { consoleSpy.mockRestore(); }); - it('keeps npx in auth recovery hints when launched through npm exec', async () => { + it('uses the standalone binary in auth recovery hints', async () => { const originalNpmCommand = process.env.npm_command; process.env.npm_command = 'exec'; @@ -255,9 +255,7 @@ describe('CLIAdapter', () => { emitter.emit('error', { message: 'authentication failed', stack: undefined }); - expect(clack.default.log.info).toHaveBeenCalledWith( - 'Try running: npx workos@latest auth logout && npx workos@latest install', - ); + expect(clack.default.log.info).toHaveBeenCalledWith('Try running: workos auth logout && workos install'); } finally { if (originalNpmCommand === undefined) { delete process.env.npm_command; diff --git a/src/lib/agent-interface.spec.ts b/src/lib/agent-interface.spec.ts index bc8fc5ae..fcc0071b 100644 --- a/src/lib/agent-interface.spec.ts +++ b/src/lib/agent-interface.spec.ts @@ -133,10 +133,10 @@ function createMockSDKResponse(turns: Array<{ text?: string; error?: boolean; is function makeAgentConfig() { return { workingDirectory: '/tmp/test', - mcpServers: {}, model: 'test-model', allowedTools: [], sdkEnv: {}, + claudeExecutablePath: '/tmp/test/claude', }; } diff --git a/src/lib/agent-interface.ts b/src/lib/agent-interface.ts index d839e86b..5cdd58ab 100644 --- a/src/lib/agent-interface.ts +++ b/src/lib/agent-interface.ts @@ -4,7 +4,8 @@ */ import { dirname } from 'path'; -import { getSkillsDir as getSkillsPackageDir } from '@workos/skills'; +import { getSkillsDir as getSkillsPackageDir } from './skills-assets.js'; +import { ensureClaudeCodeExecutable } from './agent-sdk-assets.js'; import { debug, logInfo, logWarn, logError, initLogFile, getLogFilePath } from '../utils/debug.js'; import type { InstallerOptions } from '../utils/types.js'; import { analytics } from '../utils/analytics.js'; @@ -19,13 +20,7 @@ import type { InstallerEventEmitter } from './events.js'; import { startCredentialProxy, startClaimTokenProxy, type CredentialProxyHandle } from './credential-proxy.js'; import { getActiveEnvironment, isUnclaimedEnvironment } from './config-store.js'; import { getAuthkitDomain, getCliAuthClientId } from './settings.js'; -import type { - SDKMessage, - SDKUserMessage, - Options as AgentSDKOptions, - PermissionResult, - query as queryFn, -} from '@anthropic-ai/claude-agent-sdk'; +import type { SDKMessage, SDKUserMessage, PermissionResult, query as queryFn } from '@anthropic-ai/claude-agent-sdk'; // File content cache for computing edit diffs const fileContentCache = new Map(); @@ -97,10 +92,10 @@ export interface RetryConfig { */ export type AgentRunConfig = { workingDirectory: string; - mcpServers: AgentSDKOptions['mcpServers']; model: string; allowedTools: string[]; sdkEnv: Record; + claudeExecutablePath: string; }; /** @@ -489,18 +484,26 @@ export async function initializeAgent(config: AgentConfig, options: InstallerOpt analytics.setTag('api_mode', activeProxyHandle ? 'gateway-proxy' : 'gateway'); } - // Configure WorkOS MCP docs server for accessing WorkOS documentation + // First run from a compiled binary downloads the pinned agent runtime + // (~230MB, one-time, cached under ~/.workos); dev resolves node_modules. + let lastReportedPct = -1; + const claudeExecutablePath = await ensureClaudeCodeExecutable(({ receivedBytes, totalBytes }) => { + if (!totalBytes) return; + const pct = Math.floor((receivedBytes / totalBytes) * 100); + if (pct >= lastReportedPct + 25 || (lastReportedPct === -1 && pct === 0)) { + lastReportedPct = pct; + options.emitter?.emit('status', { + message: `Downloading Claude agent runtime (one-time, ${Math.round(totalBytes / 1024 / 1024)}MB): ${pct}%`, + }); + } + }); + const agentRunConfig: AgentRunConfig = { workingDirectory: config.workingDirectory, - mcpServers: { - workos: { - command: 'npx', - args: ['-y', '@workos/mcp-docs-server'], - }, - }, model: getConfig().model, allowedTools: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'WebFetch'], sdkEnv, + claudeExecutablePath, }; const configInfo = { workingDirectory: agentRunConfig.workingDirectory, authMode, useMcp: false }; @@ -645,7 +648,6 @@ export async function runAgent( model: agentConfig.model, cwd: agentConfig.workingDirectory, permissionMode: 'acceptEdits', - mcpServers: agentConfig.mcpServers, env: agentConfig.sdkEnv, canUseTool: (toolName, input) => { logInfo('canUseTool called:', { toolName, input }); @@ -656,6 +658,7 @@ export async function runAgent( tools: { type: 'preset', preset: 'claude_code' }, allowedTools: agentConfig.allowedTools, plugins: [{ type: 'local', path: pluginPath }], + pathToClaudeCodeExecutable: agentConfig.claudeExecutablePath, // Capture stderr from CLI subprocess for debugging stderr: (data: string) => { logInfo('CLI stderr:', data); @@ -904,7 +907,13 @@ function handleSDKMessage( const isResultError = (message as Record).is_error === true; if (isResultError) { - const resultText = typeof message.result === 'string' ? message.result : ''; + const resultRecord = message as unknown as Record; + const resultText = + typeof resultRecord.result === 'string' + ? resultRecord.result + : Array.isArray(resultRecord.errors) + ? resultRecord.errors.filter((error): error is string => typeof error === 'string').join('\n') + : ''; logError('Agent result marked as error:', resultText); // Detect rate limiting (429) — check before 5xx so it gets distinct messaging diff --git a/src/lib/agent-runner.ts b/src/lib/agent-runner.ts index dfdc6e85..5d259e2c 100644 --- a/src/lib/agent-runner.ts +++ b/src/lib/agent-runner.ts @@ -1,4 +1,4 @@ -import { getReference } from '@workos/skills'; +import { getReference } from './skills-assets.js'; import { SPINNER_MESSAGE, type FrameworkConfig } from './framework-config.js'; import { validateInstallation, quickCheckValidateAndFormat } from './validation/index.js'; import { diff --git a/src/lib/agent-sdk-assets.spec.ts b/src/lib/agent-sdk-assets.spec.ts new file mode 100644 index 00000000..7136a4ae --- /dev/null +++ b/src/lib/agent-sdk-assets.spec.ts @@ -0,0 +1,63 @@ +import { existsSync } from 'node:fs'; +import { gzipSync } from 'node:zlib'; +import { describe, expect, it } from 'vitest'; +import { AGENT_SDK_TARGET, AGENT_SDK_VERSION } from '../generated/agent-sdk-manifest.js'; +import { ensureClaudeCodeExecutable, extractTarEntry } from './agent-sdk-assets.js'; + +function tarHeader(name: string, size: number): Buffer { + const header = Buffer.alloc(512); + header.write(name, 0, 'utf8'); + header.write(`${size.toString(8).padStart(11, '0')}\0`, 124, 'utf8'); + header.write('0', 156, 'utf8'); // typeflag: regular file + header.write('ustar\0', 257, 'utf8'); + header.write('00', 263, 'utf8'); + header.fill(' ', 148, 156); // checksum field counts as spaces while summing + let sum = 0; + for (const byte of header) sum += byte; + header.write(`${sum.toString(8).padStart(6, '0')}\0 `, 148, 'utf8'); + return header; +} + +function makeTarball(entries: Array<[string, Buffer]>): Buffer { + const parts: Buffer[] = []; + for (const [name, content] of entries) { + parts.push(tarHeader(name, content.length), content, Buffer.alloc((512 - (content.length % 512)) % 512)); + } + parts.push(Buffer.alloc(1024)); // end-of-archive + return gzipSync(Buffer.concat(parts)); +} + +describe('ensureClaudeCodeExecutable', () => { + it('resolves the current platform executable from node_modules in source mode', async () => { + expect(AGENT_SDK_TARGET).toBe(`${process.platform}-${process.arch}`); + expect(AGENT_SDK_VERSION).toMatch(/^\d+\.\d+\.\d+/); + const path = await ensureClaudeCodeExecutable(); + expect(existsSync(path)).toBe(true); + expect(path).toContain('node_modules'); + }); +}); + +describe('extractTarEntry', () => { + it('extracts the named entry from a gzipped tarball', () => { + const content = Buffer.from('#!/bin/sh\necho claude\n'); + const tarball = makeTarball([ + ['package/package.json', Buffer.from('{}')], + ['package/claude', content], + ]); + expect(extractTarEntry(tarball, 'package/claude').equals(content)).toBe(true); + }); + + it('handles entries whose size is an exact block multiple', () => { + const content = Buffer.alloc(1024, 7); + const tarball = makeTarball([ + ['package/claude', content], + ['package/LICENSE.md', Buffer.from('license')], + ]); + expect(extractTarEntry(tarball, 'package/LICENSE.md').toString()).toBe('license'); + }); + + it('throws when the entry is missing', () => { + const tarball = makeTarball([['package/package.json', Buffer.from('{}')]]); + expect(() => extractTarEntry(tarball, 'package/claude')).toThrow(/not found/); + }); +}); diff --git a/src/lib/agent-sdk-assets.ts b/src/lib/agent-sdk-assets.ts new file mode 100644 index 00000000..4698821d --- /dev/null +++ b/src/lib/agent-sdk-assets.ts @@ -0,0 +1,208 @@ +import { createHash, randomUUID } from 'node:crypto'; +import { + chmodSync, + existsSync, + mkdirSync, + readdirSync, + readFileSync, + renameSync, + rmSync, + statSync, + writeFileSync, +} from 'node:fs'; +import { homedir } from 'node:os'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { gunzipSync } from 'node:zlib'; +import { + AGENT_SDK_EXECUTABLE_NAME, + AGENT_SDK_EXECUTABLE_SHA256, + AGENT_SDK_EXECUTABLE_SIZE, + AGENT_SDK_PACKAGE, + AGENT_SDK_TARBALL_URL, + AGENT_SDK_TARGET, + AGENT_SDK_VERSION, +} from '../generated/agent-sdk-manifest.js'; + +export { AGENT_SDK_TARGET, AGENT_SDK_VERSION } from '../generated/agent-sdk-manifest.js'; + +export type DownloadProgress = { + receivedBytes: number; + totalBytes: number | null; +}; + +let cachedExecutablePath: string | undefined; + +function runtimeTarget(): string { + return `${process.platform}-${process.arch}`; +} + +/** Running from a compiled binary: the module graph lives in Bun's virtual filesystem. */ +function isCompiledBinary(): boolean { + return import.meta.url.includes('$bunfs') || import.meta.url.includes('~BUN'); +} + +function agentSdkCacheRoot(): string { + return join(homedir(), '.workos', 'cache', 'agent-sdk'); +} + +function cacheKey(): string { + return `${AGENT_SDK_VERSION}-${AGENT_SDK_TARGET}`; +} + +function sha256Hex(data: Buffer): string { + return createHash('sha256').update(data).digest('hex'); +} + +/** Resolve the executable from node_modules when running from source (dev, tests, evals). */ +function resolveFromNodeModules(): string { + const packageJsonPath = fileURLToPath(import.meta.resolve(`${AGENT_SDK_PACKAGE}/package.json`)); + const path = join(dirname(packageJsonPath), AGENT_SDK_EXECUTABLE_NAME); + if (!existsSync(path)) { + throw new Error(`Agent SDK executable not found at ${path}; run \`bun install\``); + } + return path; +} + +/** + * Extract a single entry from a gzipped npm tarball. Exported for tests. + * + * Minimal ustar reader: npm tarballs are flat `package/…` archives well within + * ustar limits, so pax/GNU long-name extensions never apply to the entry we + * want — unknown entry types are skipped by the generic size-based walk. + */ +export function extractTarEntry(tarGz: Buffer, entryName: string): Buffer { + const raw = gunzipSync(tarGz); + let offset = 0; + while (offset + 512 <= raw.length) { + const header = raw.subarray(offset, offset + 512); + if (header.every((byte) => byte === 0)) break; + const name = header.subarray(0, 100).toString('utf8').replace(/\0.*$/s, ''); + const prefix = header.subarray(345, 500).toString('utf8').replace(/\0.*$/s, ''); + const fullName = prefix ? `${prefix}/${name}` : name; + const size = Number.parseInt(header.subarray(124, 136).toString('utf8').replace(/\0.*$/s, '').trim(), 8); + if (Number.isNaN(size) || size < 0) { + throw new Error(`Malformed tar header at offset ${offset}`); + } + const dataStart = offset + 512; + if (fullName === entryName) { + if (dataStart + size > raw.length) { + throw new Error(`Truncated tar entry ${entryName}`); + } + return Buffer.from(raw.subarray(dataStart, dataStart + size)); + } + offset = dataStart + Math.ceil(size / 512) * 512; + } + throw new Error(`Entry ${entryName} not found in tarball`); +} + +async function downloadTarball(onProgress?: (progress: DownloadProgress) => void): Promise { + const response = await fetch(AGENT_SDK_TARBALL_URL); + if (!response.ok || !response.body) { + throw new Error(`Download failed: HTTP ${response.status} from ${AGENT_SDK_TARBALL_URL}`); + } + const contentLength = Number(response.headers.get('content-length')); + const totalBytes = Number.isFinite(contentLength) && contentLength > 0 ? contentLength : null; + + const chunks: Uint8Array[] = []; + let receivedBytes = 0; + const reader = response.body.getReader(); + onProgress?.({ receivedBytes, totalBytes }); + for (;;) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); + receivedBytes += value.byteLength; + onProgress?.({ receivedBytes, totalBytes }); + } + return Buffer.concat(chunks); +} + +/** + * Best-effort reap of cache dirs for other CLI/SDK versions — each version + * keys its own `-` dir (~230MB), which would otherwise + * accumulate forever. Runs only after a successful download of the current + * version, so at most one stale sibling window per upgrade. + */ +function cleanupStaleCacheDirs(): void { + let entries: string[]; + try { + entries = readdirSync(agentSdkCacheRoot()); + } catch { + return; + } + for (const entry of entries) { + if (entry === cacheKey()) continue; + try { + rmSync(join(agentSdkCacheRoot(), entry), { recursive: true, force: true }); + } catch { + // In use or already gone — skip it. + } + } +} + +/** + * Return a spawnable path to the pinned Claude Agent SDK executable. + * + * Running from source: resolves it from node_modules. Running from the + * compiled binary: returns the cached download under ~/.workos/cache, or + * performs a one-time download of the exact pinned version from the npm + * registry, verifies its sha256 against the build-time manifest, and installs + * it atomically (write-to-temp + rename; a concurrent winner is accepted only + * if its bytes verify). + */ +export async function ensureClaudeCodeExecutable(onProgress?: (progress: DownloadProgress) => void): Promise { + if (cachedExecutablePath) return cachedExecutablePath; + + const target = runtimeTarget(); + if (target !== AGENT_SDK_TARGET) { + throw new Error(`Agent SDK target mismatch: binary was built for ${AGENT_SDK_TARGET}, running on ${target}`); + } + + if (!isCompiledBinary()) { + cachedExecutablePath = resolveFromNodeModules(); + return cachedExecutablePath; + } + + const finalPath = join(agentSdkCacheRoot(), cacheKey(), AGENT_SDK_EXECUTABLE_NAME); + if (existsSync(finalPath) && statSync(finalPath).size === AGENT_SDK_EXECUTABLE_SIZE) { + cachedExecutablePath = finalPath; + return finalPath; + } + + const tarball = await downloadTarball(onProgress); + const executable = extractTarEntry(tarball, `package/${AGENT_SDK_EXECUTABLE_NAME}`); + const digest = sha256Hex(executable); + if (digest !== AGENT_SDK_EXECUTABLE_SHA256) { + throw new Error( + `Agent SDK checksum mismatch for ${AGENT_SDK_PACKAGE}@${AGENT_SDK_VERSION}: ` + + `expected ${AGENT_SDK_EXECUTABLE_SHA256}, got ${digest}. Refusing to install it.`, + ); + } + + mkdirSync(dirname(finalPath), { recursive: true, mode: 0o700 }); + const temporary = `${finalPath}.tmp.${process.pid}.${randomUUID()}`; + try { + writeFileSync(temporary, executable, { mode: 0o755 }); + chmodSync(temporary, 0o755); + renameSync(temporary, finalPath); + } catch (error) { + // A concurrent process may have won the install race (or holds the file + // open on Windows). Accept its copy only if the bytes verify. + try { + if (existsSync(finalPath) && sha256Hex(readFileSync(finalPath)) === AGENT_SDK_EXECUTABLE_SHA256) { + rmSync(temporary, { force: true }); + cachedExecutablePath = finalPath; + return finalPath; + } + } catch { + // Fall through to the original failure. + } + rmSync(temporary, { force: true }); + throw error; + } + + cleanupStaleCacheDirs(); + cachedExecutablePath = finalPath; + return finalPath; +} diff --git a/src/lib/registry.spec.ts b/src/lib/registry.spec.ts new file mode 100644 index 00000000..3c92cf44 --- /dev/null +++ b/src/lib/registry.spec.ts @@ -0,0 +1,33 @@ +import { describe, expect, it } from 'vitest'; +import { buildRegistry } from './registry.js'; + +const EXPECTED_INTEGRATIONS = [ + 'dotnet', + 'elixir', + 'go', + 'kotlin', + 'nextjs', + 'node', + 'php', + 'php-laravel', + 'python', + 'react', + 'react-router', + 'ruby', + 'sveltekit', + 'tanstack-start', + 'vanilla-js', +]; + +describe('integration registry', () => { + it('contains every statically generated integration', async () => { + const registry = await buildRegistry(); + expect( + registry + .all() + .map((config) => config.metadata.integration) + .sort(), + ).toEqual(EXPECTED_INTEGRATIONS); + for (const name of EXPECTED_INTEGRATIONS) expect(registry.get(name)?.run).toBeTypeOf('function'); + }); +}); diff --git a/src/lib/registry.ts b/src/lib/registry.ts index 69900e35..12d3ab11 100644 --- a/src/lib/registry.ts +++ b/src/lib/registry.ts @@ -1,8 +1,6 @@ -import { readdirSync, existsSync } from 'node:fs'; -import { join, dirname } from 'node:path'; -import { fileURLToPath, pathToFileURL } from 'node:url'; import type { FrameworkConfig, Language } from './framework-config.js'; import type { InstallerOptions } from '../utils/types.js'; +import { integrationModules } from '../integrations/_manifest.js'; /** * Standard exports from an integration module. @@ -34,64 +32,29 @@ export interface IntegrationRegistry { } /** - * Build the integration registry by discovering all integration modules. - * Scans `src/integrations/` (or `dist/integrations/` at runtime) for directories - * with an index.js/index.ts file and dynamically imports them. + * Build the integration registry from the generated static manifest. + * Static imports allow Bun to include every integration in a compiled binary. */ export async function buildRegistry(): Promise { const modules = new Map(); - // Resolve the integrations directory relative to this file - // In dev: src/lib/registry.ts -> src/integrations/ - // In dist: dist/lib/registry.js -> dist/integrations/ - const __filename = fileURLToPath(import.meta.url); - const __dirname = dirname(__filename); - const integrationsDir = join(__dirname, '..', 'integrations'); - - if (!existsSync(integrationsDir)) { - throw new Error(`No integrations directory found at ${integrationsDir}. Is the build corrupt?`); - } - - const entries = readdirSync(integrationsDir, { withFileTypes: true }); - const dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name); - - if (dirs.length === 0) { + const entries = Object.entries(integrationModules); + if (entries.length === 0) { throw new Error('No integrations found. Is the build corrupt?'); } - for (const dir of dirs) { - // Skip directories starting with _ (convention for internal files like _manifest.ts) - if (dir.startsWith('_')) continue; - - const indexPath = join(integrationsDir, dir, 'index.js'); - const indexTsPath = join(integrationsDir, dir, 'index.ts'); - - if (!existsSync(indexPath) && !existsSync(indexTsPath)) { - // Skip directories without an index file (not an integration) + for (const [dir, mod] of entries) { + if (!mod.config || !mod.run) { + console.warn(`Integration ${dir} missing 'config' or 'run' export, skipping`); continue; } - try { - const mod = (await import(pathToFileURL(join(integrationsDir, dir, 'index.js')).href)) as IntegrationModule; - - if (!mod.config || !mod.run) { - console.warn(`Integration ${dir} missing 'config' or 'run' export, skipping`); - continue; - } - - const name = mod.config.metadata.integration; - - if (modules.has(name)) { - throw new Error(`Duplicate integration name: '${name}' (found in both existing and '${dir}/')`); - } - - modules.set(name, mod); - } catch (err) { - if (err instanceof Error && err.message.startsWith('Duplicate integration name')) { - throw err; // Re-throw duplicate name errors - } - console.warn(`Failed to load integration from ${dir}/: ${err}`); + const name = mod.config.metadata.integration; + if (modules.has(name)) { + throw new Error(`Duplicate integration name: '${name}' (found in both existing and '${dir}/')`); } + + modules.set(name, mod); } // Build sorted config array (by priority, descending) diff --git a/src/lib/settings.ts b/src/lib/settings.ts index 233a660c..9fd97c64 100644 --- a/src/lib/settings.ts +++ b/src/lib/settings.ts @@ -21,7 +21,6 @@ export interface InstallerConfig { proxy: { refreshThresholdMs: number; }; - nodeVersion: string; logging: { debugMode: boolean; }; diff --git a/src/lib/skills-assets.spec.ts b/src/lib/skills-assets.spec.ts new file mode 100644 index 00000000..4e94cfb0 --- /dev/null +++ b/src/lib/skills-assets.spec.ts @@ -0,0 +1,42 @@ +import { existsSync, mkdirSync, readFileSync, rmSync, utimesSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { describe, expect, it, vi } from 'vitest'; +import { BUNDLED_SKILLS_VERSION, getReference, getSkillsDir } from './skills-assets.js'; + +describe('embedded skills assets', () => { + it('materializes the complete plugin tree to a real directory', async () => { + const skillsDir = getSkillsDir(); + expect(skillsDir).toContain(`workos-skills-${BUNDLED_SKILLS_VERSION}`); + expect(existsSync(join(skillsDir, 'workos', 'SKILL.md'))).toBe(true); + expect(existsSync(join(skillsDir, 'workos-widgets', 'SKILL.md'))).toBe(true); + + const reference = await getReference('workos-authkit-base'); + expect(reference).toBe(readFileSync(join(skillsDir, 'workos', 'references', 'workos-authkit-base.md'), 'utf8')); + }); + + it('reaps stale extraction roots from other versions, keeping fresh ones', async () => { + const suffix = process.platform === 'win32' ? '' : `-${process.getuid?.() ?? 0}`; + const staleRoot = join(tmpdir(), `workos-skills-0.0.1-spec-stale${suffix}`); + const freshRoot = join(tmpdir(), `workos-skills-0.0.2-spec-fresh${suffix}`); + mkdirSync(staleRoot, { recursive: true }); + mkdirSync(freshRoot, { recursive: true }); + // Backdate past the 24h reap cutoff; the fresh root stays (it could + // belong to a concurrently running CLI of another version). + const twoDaysAgo = new Date(Date.now() - 48 * 60 * 60 * 1000); + utimesSync(staleRoot, twoDaysAgo, twoDaysAgo); + + try { + // Fresh module instance: materializeSkillsDir caches per module graph. + vi.resetModules(); + const fresh = await import('./skills-assets.js'); + fresh.getSkillsDir(); + + expect(existsSync(staleRoot)).toBe(false); + expect(existsSync(freshRoot)).toBe(true); + } finally { + rmSync(staleRoot, { recursive: true, force: true }); + rmSync(freshRoot, { recursive: true, force: true }); + } + }); +}); diff --git a/src/lib/skills-assets.ts b/src/lib/skills-assets.ts new file mode 100644 index 00000000..94f85297 --- /dev/null +++ b/src/lib/skills-assets.ts @@ -0,0 +1,151 @@ +import { randomUUID } from 'node:crypto'; +import { + chmodSync, + existsSync, + lstatSync, + mkdirSync, + readdirSync, + readFileSync, + renameSync, + rmSync, + writeFileSync, +} from 'node:fs'; +import { readFile } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { dirname, join } from 'node:path'; +import { BUNDLED_SKILLS_VERSION, skillsAssets } from '../generated/skills-manifest.js'; + +let cachedSkillsDir: string | undefined; + +// Only reap extraction roots older than this: a fresh one may belong to a +// concurrently running older/newer CLI mid-install. +const STALE_ROOT_MS = 24 * 60 * 60 * 1000; + +function extractionSuffix(): string { + return process.platform === 'win32' ? '' : `-${process.getuid?.() ?? 0}`; +} + +function safeExtractionRoot(): string { + const root = join(tmpdir(), `workos-skills-${BUNDLED_SKILLS_VERSION}${extractionSuffix()}`); + + mkdirSync(root, { recursive: true, mode: 0o700 }); + if (typeof process.getuid === 'function') { + const info = lstatSync(root); + if (!info.isDirectory()) { + throw new Error(`Skills temp path ${root} is not a directory; refusing to use it`); + } + const uid = process.getuid(); + if (info.uid !== uid) { + throw new Error(`Skills temp directory ${root} is owned by uid ${info.uid}, expected ${uid}`); + } + if ((info.mode & 0o777) !== 0o700) chmodSync(root, 0o700); + } + + return root; +} + +function materializeFile(target: string, embedded: string, mode: number): void { + const contents = readFileSync(embedded); + if (existsSync(target)) { + try { + if (readFileSync(target).equals(contents)) { + chmodSync(target, mode); + return; + } + } catch { + // Replace unreadable or incomplete files below. + } + } + + mkdirSync(dirname(target), { recursive: true, mode: 0o700 }); + const temporary = `${target}.tmp.${process.pid}.${randomUUID()}`; + try { + writeFileSync(temporary, contents, { mode }); + chmodSync(temporary, mode); + renameSync(temporary, target); + } catch (error) { + // A concurrent process may have won the extraction race. Only accept its + // output when it is byte-identical to the embedded asset. + if (existsSync(target)) { + try { + if (readFileSync(target).equals(contents)) { + rmSync(temporary, { force: true }); + chmodSync(target, mode); + return; + } + } catch { + // Re-throw the original extraction failure below. + } + } + rmSync(temporary, { force: true }); + throw error; + } +} + +/** + * Best-effort reap of extraction roots left behind by other CLI versions — + * each version keys its own `workos-skills-` tree, which would + * otherwise accumulate in tmp forever. Never interferes with the current run. + */ +function cleanupStaleExtractionRoots(currentRoot: string): void { + const suffix = extractionSuffix(); + let entries: string[]; + try { + entries = readdirSync(tmpdir()); + } catch { + return; + } + + const cutoff = Date.now() - STALE_ROOT_MS; + for (const entry of entries) { + if (!entry.startsWith('workos-skills-')) continue; + if (suffix && !entry.endsWith(suffix)) continue; + const path = join(tmpdir(), entry); + if (path === currentRoot) continue; + try { + if (lstatSync(path).mtimeMs < cutoff) { + rmSync(path, { recursive: true, force: true }); + } + } catch { + // Owned by someone else, already gone, or mid-removal — skip it. + } + } +} + +/** Extract the bundled plugin assets to a real directory and return its skills directory. */ +export function materializeSkillsDir(): string { + if (cachedSkillsDir) return cachedSkillsDir; + + const root = safeExtractionRoot(); + const pluginsRoot = join(root, 'plugins'); + for (const asset of skillsAssets) { + materializeFile(join(pluginsRoot, ...asset.relPath.split('/')), asset.embedded, asset.executable ? 0o755 : 0o644); + } + + cleanupStaleExtractionRoots(root); + + cachedSkillsDir = join(pluginsRoot, 'workos', 'skills'); + return cachedSkillsDir; +} + +export function getSkillsDir(): string { + return materializeSkillsDir(); +} + +export function getReferencePath(name: string): string { + return join(getSkillsDir(), 'workos', 'references', `${name}.md`); +} + +export async function getReference(name: string): Promise { + return readFile(getReferencePath(name), 'utf8'); +} + +export function getSkillPath(skillName: string): string { + return join(getSkillsDir(), skillName, 'SKILL.md'); +} + +export async function getSkill(skillName: string): Promise { + return readFile(getSkillPath(skillName), 'utf8'); +} + +export { BUNDLED_SKILLS_VERSION }; diff --git a/src/lib/validation/validator.ts b/src/lib/validation/validator.ts index 18146b7a..feb2cffd 100644 --- a/src/lib/validation/validator.ts +++ b/src/lib/validation/validator.ts @@ -4,6 +4,19 @@ import { join } from 'path'; import fg from 'fast-glob'; import type { ValidationResult, ValidationRules, ValidationIssue } from './types.js'; import { runBuildValidation } from './build-validator.js'; +import nextjsRules from './rules/nextjs.json' with { type: 'json' }; +import reactRouterRules from './rules/react-router.json' with { type: 'json' }; +import reactRules from './rules/react.json' with { type: 'json' }; +import tanstackStartRules from './rules/tanstack-start.json' with { type: 'json' }; +import vanillaJsRules from './rules/vanilla-js.json' with { type: 'json' }; + +const RULES_BY_FRAMEWORK: Readonly> = { + nextjs: nextjsRules as ValidationRules, + 'react-router': reactRouterRules as ValidationRules, + react: reactRules as ValidationRules, + 'tanstack-start': tanstackStartRules as ValidationRules, + 'vanilla-js': vanillaJsRules as ValidationRules, +}; export interface ValidateOptions { variant?: string; @@ -52,26 +65,21 @@ export async function validateInstallation( } async function loadRules(framework: string, variant?: string): Promise { - const rulesPath = new URL(`./rules/${framework}.json`, import.meta.url); - try { - const content = await readFile(rulesPath, 'utf-8'); - const rules = JSON.parse(content) as ValidationRules; - - // Merge variant rules if specified - if (variant && rules.variants?.[variant]) { - const variantRules = rules.variants[variant]; - return { - ...rules, - files: [...rules.files, ...(variantRules.files || [])], - packages: [...rules.packages, ...(variantRules.packages || [])], - envVars: [...rules.envVars, ...(variantRules.envVars || [])], - }; - } + const rules = RULES_BY_FRAMEWORK[framework]; + if (!rules) return null; - return rules; - } catch { - return null; // No rules for this framework yet + // Merge variant rules if specified + if (variant && rules.variants?.[variant]) { + const variantRules = rules.variants[variant]; + return { + ...rules, + files: [...rules.files, ...(variantRules.files || [])], + packages: [...rules.packages, ...(variantRules.packages || [])], + envVars: [...rules.envVars, ...(variantRules.envVars || [])], + }; } + + return rules; } export async function validatePackages(rules: ValidationRules, projectDir: string): Promise { diff --git a/src/lib/version-check.spec.ts b/src/lib/version-check.spec.ts index 5c1d6172..98bdda95 100644 --- a/src/lib/version-check.spec.ts +++ b/src/lib/version-check.spec.ts @@ -18,6 +18,14 @@ vi.mock('./settings.js', () => ({ const { checkForUpdates, _resetWarningState } = await import('./version-check.js'); const { yellow, dim } = await import('../utils/logging.js'); +// github.com/…/releases/latest answers with a redirect to the tag page. +function redirectTo(tag: string) { + return { + status: 302, + headers: new Headers({ location: `https://github.com/workos/cli/releases/tag/${tag}` }), + }; +} + describe('version-check', () => { beforeEach(() => { vi.clearAllMocks(); @@ -25,33 +33,24 @@ describe('version-check', () => { }); it('shows warning when outdated', async () => { - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ version: '0.4.0' }), - }); + mockFetch.mockResolvedValueOnce(redirectTo('v0.4.0')); await checkForUpdates(); expect(yellow).toHaveBeenCalledWith(expect.stringContaining('0.3.0 → 0.4.0')); - expect(dim).toHaveBeenCalledWith('Run: npx workos@latest'); + expect(dim).toHaveBeenCalledWith('Download: https://github.com/workos/cli/releases/latest'); }); it('no warning when up to date', async () => { - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ version: '0.3.0' }), - }); + mockFetch.mockResolvedValueOnce(redirectTo('v0.3.0')); await checkForUpdates(); expect(yellow).not.toHaveBeenCalled(); }); - it('no warning when ahead of npm', async () => { - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ version: '0.2.0' }), - }); + it('no warning when ahead of the latest release', async () => { + mockFetch.mockResolvedValueOnce(redirectTo('v0.2.0')); await checkForUpdates(); @@ -72,19 +71,17 @@ describe('version-check', () => { expect(yellow).not.toHaveBeenCalled(); }); - it('silently handles non-ok response', async () => { - mockFetch.mockResolvedValueOnce({ ok: false }); + it('silently handles a non-redirect response', async () => { + mockFetch.mockResolvedValueOnce({ status: 200, headers: new Headers() }); await expect(checkForUpdates()).resolves.toBeUndefined(); expect(yellow).not.toHaveBeenCalled(); }); - it('silently handles invalid JSON', async () => { + it('silently handles a redirect to an unexpected location', async () => { mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => { - throw new Error('Invalid JSON'); - }, + status: 302, + headers: new Headers({ location: 'https://github.com/workos/cli/releases' }), }); await expect(checkForUpdates()).resolves.toBeUndefined(); @@ -92,20 +89,14 @@ describe('version-check', () => { }); it('silently handles invalid semver', async () => { - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ version: 'not-valid-semver' }), - }); + mockFetch.mockResolvedValueOnce(redirectTo('not-valid-semver')); await expect(checkForUpdates()).resolves.toBeUndefined(); expect(yellow).not.toHaveBeenCalled(); }); it('only warns once', async () => { - mockFetch.mockResolvedValue({ - ok: true, - json: async () => ({ version: '0.4.0' }), - }); + mockFetch.mockResolvedValue(redirectTo('v0.4.0')); await checkForUpdates(); await checkForUpdates(); diff --git a/src/lib/version-check.ts b/src/lib/version-check.ts index 4fc9c4ea..540fa2c9 100644 --- a/src/lib/version-check.ts +++ b/src/lib/version-check.ts @@ -2,17 +2,17 @@ import { lt, valid } from 'semver'; import { yellow, dim } from '../utils/logging.js'; import { getVersion } from './settings.js'; -const NPM_REGISTRY_URL = 'https://registry.npmjs.org/workos/latest'; +// The web endpoint redirects to …/releases/tag/v{version} and, unlike +// api.github.com, is not subject to the anonymous 60-requests/hour/IP rate +// limit — users behind shared corporate NATs would otherwise silently stop +// seeing update notices. +const LATEST_RELEASE_URL = 'https://github.com/workos/cli/releases/latest'; const TIMEOUT_MS = 500; let hasWarned = false; -interface NpmPackageInfo { - version: string; -} - /** - * Check npm registry for latest version and warn if outdated. + * Check GitHub Releases for the latest binary version and warn if outdated. * Runs asynchronously, fails silently on any error. * Safe to call without awaiting (fire-and-forget). */ @@ -20,14 +20,19 @@ export async function checkForUpdates(): Promise { if (hasWarned) return; try { - const response = await fetch(NPM_REGISTRY_URL, { + const response = await fetch(LATEST_RELEASE_URL, { + method: 'HEAD', + redirect: 'manual', signal: AbortSignal.timeout(TIMEOUT_MS), }); - if (!response.ok) return; + // Expect a redirect to …/releases/tag/v{version}; anything else means no + // published release (or GitHub changed shape) — stay quiet. + const location = response.headers.get('location') ?? ''; + const match = /\/releases\/tag\/v?([^/?#]+)/.exec(location); + if (!match) return; - const data = (await response.json()) as NpmPackageInfo; - const latestVersion = data.version; + const latestVersion = decodeURIComponent(match[1]); const currentVersion = getVersion(); // Validate both versions are valid semver @@ -37,7 +42,7 @@ export async function checkForUpdates(): Promise { if (lt(currentVersion, latestVersion)) { hasWarned = true; yellow(`Update available: ${currentVersion} → ${latestVersion}`); - dim('Run: npx workos@latest'); + dim('Download: https://github.com/workos/cli/releases/latest'); console.log(); } } catch { diff --git a/src/utils/analytics.spec.ts b/src/utils/analytics.spec.ts index 44f682ee..039a638a 100644 --- a/src/utils/analytics.spec.ts +++ b/src/utils/analytics.spec.ts @@ -322,7 +322,7 @@ describe('Analytics', () => { const event = mockQueueEvent.mock.calls.find((c) => c[0].type === 'session.start')[0]; expect(event.attributes).toHaveProperty('env.os'); expect(event.attributes).toHaveProperty('env.os_version'); - expect(event.attributes).toHaveProperty('env.node_version'); + expect(event.attributes).toHaveProperty('env.runtime_version'); expect(event.attributes).toHaveProperty('env.shell'); expect(typeof event.attributes['env.ci']).toBe('boolean'); }); @@ -390,7 +390,7 @@ describe('Analytics', () => { const event = mockQueueEvent.mock.calls.find((c) => c[0].type === 'session.end')[0]; expect(event.attributes).toHaveProperty('env.os'); expect(event.attributes).toHaveProperty('env.os_version'); - expect(event.attributes).toHaveProperty('env.node_version'); + expect(event.attributes).toHaveProperty('env.runtime_version'); expect(event.attributes).toHaveProperty('env.shell'); expect(typeof event.attributes['env.ci']).toBe('boolean'); expect(event.attributes['installer.mode']).toBe('tui'); @@ -636,7 +636,7 @@ describe('Analytics', () => { 'crash.command': 'install', 'cli.version': '1.0.0', 'env.os': expect.any(String), - 'env.node_version': expect.any(String), + 'env.runtime_version': expect.any(String), }), }), ); diff --git a/src/utils/analytics.ts b/src/utils/analytics.ts index 070ee3a0..15a7bb5e 100644 --- a/src/utils/analytics.ts +++ b/src/utils/analytics.ts @@ -203,7 +203,7 @@ export class Analytics { 'auth.mode': this.authMode, 'env.os': process.platform, 'env.os_version': osVersion, - 'env.node_version': process.version, + 'env.runtime_version': process.versions.bun ? `bun-${process.versions.bun}` : `node-${process.versions.node}`, 'env.shell': basename(process.env.SHELL ?? process.env.COMSPEC ?? 'unknown'), 'env.ci': Boolean(process.env.CI || process.env.GITHUB_ACTIONS || process.env.BUILDKITE), ...(ciProvider ? { 'env.ci_provider': ciProvider } : {}), diff --git a/src/utils/box.ts b/src/utils/box.ts index 1b9cd093..676745ed 100644 --- a/src/utils/box.ts +++ b/src/utils/box.ts @@ -24,7 +24,7 @@ function terminalWidth(): number { * a long unbroken word) overflows its own line rather than being split mid-span. * Such an overflow can push the rendered box border past the terminal width; * acceptable at standard widths. Note that a colored command produced by - * `formatWorkOSCommand` can be long (e.g. `npx workos@latest telemetry opt-out`) + * `formatWorkOSCommand` can be long (e.g. `workos telemetry opt-out`) * and stays a single unbreakable token by design. * * Limitation: a colored span is grouped atomically only when it is a single SGR diff --git a/src/utils/command-invocation.spec.ts b/src/utils/command-invocation.spec.ts index cf5b665d..5e0b749d 100644 --- a/src/utils/command-invocation.spec.ts +++ b/src/utils/command-invocation.spec.ts @@ -6,12 +6,12 @@ describe('command invocation helpers', () => { expect(getWorkOSCommand({})).toBe('workos'); }); - it('uses npx workos@latest when launched by npm exec', () => { - expect(getWorkOSCommand({ npm_command: 'exec' })).toBe('npx workos@latest'); + it('uses the standalone binary name even when npm variables are present', () => { + expect(getWorkOSCommand({ npm_command: 'exec' })).toBe('workos'); }); it('formats commands with the detected invocation', () => { - expect(formatWorkOSCommand('auth login', { npm_command: 'exec' })).toBe('npx workos@latest auth login'); + expect(formatWorkOSCommand('auth login', { npm_command: 'exec' })).toBe('workos auth login'); }); it('quotes shell arguments that contain JSON or shell metacharacters', () => { diff --git a/src/utils/command-invocation.ts b/src/utils/command-invocation.ts index c1d0db33..83421b9d 100644 --- a/src/utils/command-invocation.ts +++ b/src/utils/command-invocation.ts @@ -1,17 +1,8 @@ /** - * Return the safest user-facing way to invoke this CLI. - * - * When the package is run through npm exec/npx, `workos ...` may resolve to an - * older global binary in the user's shell. Recovery hints should keep using npx. + * Return the user-facing executable name for the standalone binary. */ -export function getWorkOSCommand(env: NodeJS.ProcessEnv = process.env): string { - const npmCommand = env.npm_command; - const npmExecPath = env.npm_execpath ?? ''; - const npmUserAgent = env.npm_config_user_agent ?? ''; - - const launchedByNpmExec = npmCommand === 'exec' || npmExecPath.includes('npx-cli') || /\bnpx\//.test(npmUserAgent); - - return launchedByNpmExec ? 'npx workos@latest' : 'workos'; +export function getWorkOSCommand(_env: NodeJS.ProcessEnv = process.env): string { + return 'workos'; } export function formatWorkOSCommand(args: string, env: NodeJS.ProcessEnv = process.env): string { diff --git a/src/utils/command-telemetry.ts b/src/utils/command-telemetry.ts index b54f74ec..94610aa1 100644 --- a/src/utils/command-telemetry.ts +++ b/src/utils/command-telemetry.ts @@ -16,7 +16,7 @@ function topLevelCommands(): Set { return knownTopLevelCommands; } -export const SKIP_TELEMETRY_COMMANDS = new Set(['install', 'dashboard', 'root', 'telemetry']); +export const SKIP_TELEMETRY_COMMANDS = new Set(['install', 'dashboard', 'root', 'telemetry', 'internal']); export function resolveCanonicalName(parts: string[]): string { if (parts.length === 0) return 'root'; diff --git a/src/utils/recovery-hints.spec.ts b/src/utils/recovery-hints.spec.ts index fa199186..70b23097 100644 --- a/src/utils/recovery-hints.spec.ts +++ b/src/utils/recovery-hints.spec.ts @@ -33,12 +33,12 @@ describe('recovery-hints', () => { expect(recovery.hints[0].hostShellRequired).toBeUndefined(); }); - it('uses npx invocation when called via npm exec', () => { + it('uses the standalone binary when npm variables are present', () => { const recovery = authLoginRecovery({ mode: 'agent', env: { npm_command: 'exec' }, }); - expect(recovery.hints[0].command).toBe('npx workos@latest auth login'); + expect(recovery.hints[0].command).toBe('workos auth login'); }); }); diff --git a/src/utils/telemetry-types.ts b/src/utils/telemetry-types.ts index 4ea58839..c38e3296 100644 --- a/src/utils/telemetry-types.ts +++ b/src/utils/telemetry-types.ts @@ -24,7 +24,12 @@ export interface EnvFingerprint { 'auth.mode': AuthMode; 'env.os': string; 'env.os_version': string; - 'env.node_version': string; + /** + * The runtime the CLI itself executes on (`bun-x.y.z` in the compiled + * binary). Replaces `env.node_version`, which reported Bun's baked-in + * Node-compat constant — not anything about the user's machine. + */ + 'env.runtime_version': string; 'env.shell': string; 'env.ci': boolean; 'env.ci_provider'?: string; diff --git a/tests/evals/README.md b/tests/evals/README.md index c55c5165..b8593546 100644 --- a/tests/evals/README.md +++ b/tests/evals/README.md @@ -6,13 +6,13 @@ Automated evaluation framework for testing WorkOS AuthKit installer skills. ```bash # Run all evaluations -pnpm eval +bun run eval # Run specific framework -pnpm eval --framework=nextjs +bun run eval --framework=nextjs # Run with quality grading -pnpm eval --quality +bun run eval --quality ``` ## Success Criteria @@ -91,16 +91,16 @@ Every run tracks: ```bash # List recent runs -pnpm eval:history +bun run eval:history # Show more runs -pnpm eval:history --limit=20 +bun run eval:history --limit=20 # Compare two runs -pnpm eval:diff 2024-01-15T10-30-00 2024-01-16T14-45-00 +bun run eval:diff 2024-01-15T10-30-00 2024-01-16T14-45-00 # Use 'latest' as alias for most recent run -pnpm eval:diff latest 2024-01-15T10-30-00 +bun run eval:diff latest 2024-01-15T10-30-00 ``` The diff command shows: @@ -139,10 +139,10 @@ Prune old results: ```bash # Keep only 10 most recent (default) -pnpm eval:prune +bun run eval:prune # Keep specific number -pnpm eval:prune --keep=5 +bun run eval:prune --keep=5 ``` ## Adding a New Fixture @@ -159,8 +159,8 @@ pnpm eval:prune --keep=5 ```bash cd tests/fixtures/{framework}/{state} - pnpm install - pnpm build + bun install + bun run build ``` 4. Add scenario to `tests/evals/runner.ts` SCENARIOS array @@ -208,30 +208,30 @@ return { passed: checks.every((c) => c.passed), checks }; Use `--keep-on-fail` to preserve temp directory and inspect: ```bash -pnpm eval --framework=nextjs --keep-on-fail -cd /tmp/eval-nextjs-xxxxx && pnpm build +bun run eval --framework=nextjs --keep-on-fail +cd /tmp/eval-nextjs-xxxxx && bun run build ``` ### Flaky passes/failures -Increase retries: `pnpm eval --retry=3` +Increase retries: `bun run eval --retry=3` If consistently flaky, check if skill instructions are ambiguous. ### Pass rate regression -1. Run `pnpm eval:diff latest ` +1. Run `bun run eval:diff latest ` 2. Check "Likely Causes" section 3. Review skill file changes listed 4. If no skill changes, check for external factors (API changes, dependency updates) -### "pnpm install failed" +### "bun install failed" The fixture's dependencies may have version conflicts. Check: ```bash cd tests/fixtures/{framework}/{state} -pnpm install +bun install ``` ### High latency diff --git a/tests/evals/__tests__/agent-executor.spec.ts b/tests/evals/__tests__/agent-executor.spec.ts index 62f057da..08a67959 100644 --- a/tests/evals/__tests__/agent-executor.spec.ts +++ b/tests/evals/__tests__/agent-executor.spec.ts @@ -106,7 +106,7 @@ describe('AgentExecutor', () => { expect(agentRunConfig.model).toBe('test-model'); expect(agentRunConfig.allowedTools).toContain('Skill'); expect(agentRunConfig.allowedTools).toContain('Write'); - expect(agentRunConfig.mcpServers).toHaveProperty('workos'); + expect(agentRunConfig.mcpServers).toBeUndefined(); // Direct mode — no gateway URL expect(agentRunConfig.sdkEnv.ANTHROPIC_API_KEY).toBe('sk-ant-test'); expect(agentRunConfig.sdkEnv.ANTHROPIC_BASE_URL).toBeUndefined(); diff --git a/tests/evals/agent-executor.ts b/tests/evals/agent-executor.ts index 9af2451f..d0f4d52d 100644 --- a/tests/evals/agent-executor.ts +++ b/tests/evals/agent-executor.ts @@ -7,6 +7,7 @@ import { getConfig } from '../../src/lib/settings.js'; import { LatencyTracker } from './latency-tracker.js'; import { quickCheckValidateAndFormat } from '../../src/lib/validation/quick-checks.js'; import { runAgent, type AgentRunConfig, type RetryConfig } from '../../src/lib/agent-interface.js'; +import { ensureClaudeCodeExecutable } from '../../src/lib/agent-sdk-assets.js'; import type { InstallerOptions } from '../../src/utils/types.js'; import type { ToolCall, LatencyMetrics } from './types.js'; import type { SDKMessage } from '@anthropic-ai/claude-agent-sdk'; @@ -127,15 +128,10 @@ export class AgentExecutor { const agentRunConfig: AgentRunConfig = { workingDirectory: this.workDir, - mcpServers: { - workos: { - command: 'npx', - args: ['-y', '@workos/mcp-docs-server'], - }, - }, model: getConfig().model, allowedTools: ['Skill', 'Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'WebFetch'], sdkEnv, + claudeExecutablePath: await ensureClaudeCodeExecutable(), }; const installerOptions: InstallerOptions = { diff --git a/tests/evals/cli.ts b/tests/evals/cli.ts index e5d1082c..122a6f00 100644 --- a/tests/evals/cli.ts +++ b/tests/evals/cli.ts @@ -167,7 +167,7 @@ export function parseArgs(args: string[]): CliOptions { export function printHelp(): void { console.log(` -Usage: pnpm eval [command] [options] +Usage: bun run eval [command] [options] Commands: run (default) Run evaluations @@ -213,16 +213,16 @@ Options: --help, -h Show this help message Examples: - pnpm eval # Run all 10 scenarios - pnpm eval --framework=nextjs # Run only Next.js scenarios - pnpm eval --state=example # Run only example app scenarios - pnpm eval --framework=react --state=example-auth0 + bun run eval # Run all 10 scenarios + bun run eval --framework=nextjs # Run only Next.js scenarios + bun run eval --state=example # Run only example app scenarios + bun run eval --framework=react --state=example-auth0 # Run specific scenario - pnpm eval --debug # Verbose output, keep failed dirs - pnpm eval --retry=3 # More retry attempts - pnpm eval:history # List recent runs - pnpm eval:history --limit=20 # Show more runs - pnpm eval:diff # Compare two runs - pnpm eval:prune --keep=5 # Keep only 5 most recent runs + bun run eval --debug # Verbose output, keep failed dirs + bun run eval --retry=3 # More retry attempts + bun run eval:history # List recent runs + bun run eval:history --limit=20 # Show more runs + bun run eval:diff # Compare two runs + bun run eval:prune --keep=5 # Keep only 5 most recent runs `); } diff --git a/tests/evals/commands/history.ts b/tests/evals/commands/history.ts index 46c69091..fec6b890 100644 --- a/tests/evals/commands/history.ts +++ b/tests/evals/commands/history.ts @@ -10,7 +10,7 @@ export async function listHistory(limit: number = 10): Promise { try { files = await readdir(RESULTS_DIR); } catch { - console.log(chalk.yellow('No eval results found. Run `pnpm eval` first.')); + console.log(chalk.yellow('No eval results found. Run `bun run eval` first.')); return; } @@ -21,7 +21,7 @@ export async function listHistory(limit: number = 10): Promise { .slice(0, limit); if (runFiles.length === 0) { - console.log(chalk.yellow('No eval results found. Run `pnpm eval` first.')); + console.log(chalk.yellow('No eval results found. Run `bun run eval` first.')); return; } diff --git a/tests/evals/fixture-manager.ts b/tests/evals/fixture-manager.ts index 87add3f5..080e2bcf 100644 --- a/tests/evals/fixture-manager.ts +++ b/tests/evals/fixture-manager.ts @@ -63,8 +63,8 @@ export class FixtureManager { private async installDependencies(workDir: string): Promise { // JS projects if (existsSync(join(workDir, 'package.json'))) { - const result = await execFileNoThrow('pnpm', ['install'], { cwd: workDir }); - if (result.status !== 0) throw new Error(`pnpm install failed: ${result.stderr}`); + const result = await execFileNoThrow('bun', ['install'], { cwd: workDir }); + if (result.status !== 0) throw new Error(`bun install failed: ${result.stderr}`); return; } diff --git a/tests/evals/graders/build-grader.ts b/tests/evals/graders/build-grader.ts index eb5b2050..c73975bd 100644 --- a/tests/evals/graders/build-grader.ts +++ b/tests/evals/graders/build-grader.ts @@ -5,7 +5,7 @@ export class BuildGrader { constructor(protected workDir: string) {} async checkBuild(): Promise { - const result = await execFileNoThrow('pnpm', ['build'], { + const result = await execFileNoThrow('bun', ['run', 'build'], { cwd: this.workDir, timeout: 120000, // 2 minute timeout }); @@ -46,7 +46,7 @@ export class BuildGrader { } async checkTypecheck(): Promise { - const result = await execFileNoThrow('pnpm', ['tsc', '--noEmit'], { + const result = await execFileNoThrow('bun', ['run', 'tsc', '--noEmit'], { cwd: this.workDir, timeout: 60000, }); diff --git a/tests/evals/log-commands.ts b/tests/evals/log-commands.ts index 3292304c..1cf98db1 100644 --- a/tests/evals/log-commands.ts +++ b/tests/evals/log-commands.ts @@ -14,7 +14,7 @@ export async function listLogs(): Promise { .slice(0, 10); if (logFiles.length === 0) { - console.log('No eval log files found. Run `pnpm eval` first.'); + console.log('No eval log files found. Run `bun run eval` first.'); return; } @@ -24,10 +24,10 @@ export async function listLogs(): Promise { const size = Math.round(stat.size / 1024); console.log(` ${file} (${size}KB)`); } - console.log(`\nUse 'pnpm eval:show ' to view details.`); + console.log(`\nUse 'bun run eval:show ' to view details.`); } catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') { - console.log('No eval log files found. Run `pnpm eval` first.'); + console.log('No eval log files found. Run `bun run eval` first.'); } else { throw error; } @@ -68,7 +68,7 @@ export async function showLog(filename: string): Promise { } catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') { console.error(`Log file not found: ${filename}`); - console.error(`Use 'pnpm eval:logs' to list available files.`); + console.error(`Use 'bun run eval:logs' to list available files.`); process.exit(1); } else if (error instanceof SyntaxError) { console.error(`Invalid JSON in log file: ${filename}`); diff --git a/tests/fixtures/README.md b/tests/fixtures/README.md index 7f545509..7e3046ae 100644 --- a/tests/fixtures/README.md +++ b/tests/fixtures/README.md @@ -28,7 +28,7 @@ Every fixture must: ### Node.js (`node/`) - **Manifest**: `package.json` -- **Install**: `pnpm install` +- **Install**: `bun install` - **partial-install**: `@workos-inc/node` in package.json, WorkOS client initialized, login route incomplete (TODO), no callback route - **conflicting-auth**: `passport` + `passport-local` with working form-based auth, express-session configured diff --git a/tests/fixtures/nextjs/typescript-strict/README.md b/tests/fixtures/nextjs/typescript-strict/README.md index abffb2bc..bf207f7b 100644 --- a/tests/fixtures/nextjs/typescript-strict/README.md +++ b/tests/fixtures/nextjs/typescript-strict/README.md @@ -18,7 +18,7 @@ This fixture has the strictest TypeScript configuration possible. It tests wheth ## Success Criteria -- [ ] `pnpm build` passes with zero type errors +- [ ] `bun run build` passes with zero type errors - [ ] Generated middleware.ts has proper types - [ ] Generated callback route has proper types - [ ] No implicit any errors diff --git a/tests/fixtures/react-router/typescript-strict/README.md b/tests/fixtures/react-router/typescript-strict/README.md index 76223aa7..44d8408f 100644 --- a/tests/fixtures/react-router/typescript-strict/README.md +++ b/tests/fixtures/react-router/typescript-strict/README.md @@ -18,7 +18,7 @@ This fixture has the strictest TypeScript configuration. Tests whether agent gen ## Success Criteria -- [ ] `pnpm build` passes with zero type errors +- [ ] `bun run build` passes with zero type errors - [ ] Generated code has proper types - [ ] No implicit any errors diff --git a/tests/fixtures/react/typescript-strict/README.md b/tests/fixtures/react/typescript-strict/README.md index ca16ce54..241d228a 100644 --- a/tests/fixtures/react/typescript-strict/README.md +++ b/tests/fixtures/react/typescript-strict/README.md @@ -18,7 +18,7 @@ This fixture has the strictest TypeScript configuration. It tests whether the ag ## Success Criteria -- [ ] `pnpm build` passes with zero type errors +- [ ] `bun run build` passes with zero type errors - [ ] Generated code has proper types - [ ] No implicit any errors - [ ] No unused variable errors diff --git a/tests/fixtures/tanstack-start/typescript-strict/README.md b/tests/fixtures/tanstack-start/typescript-strict/README.md index 0228c15f..8b325ab2 100644 --- a/tests/fixtures/tanstack-start/typescript-strict/README.md +++ b/tests/fixtures/tanstack-start/typescript-strict/README.md @@ -18,7 +18,7 @@ This fixture has the strictest TypeScript configuration. Tests whether agent gen ## Success Criteria -- [ ] `pnpm build` passes with zero type errors +- [ ] `bun run build` passes with zero type errors - [ ] Generated code has proper types - [ ] No implicit any errors diff --git a/types/assets.d.ts b/types/assets.d.ts new file mode 100644 index 00000000..f7f8c48f --- /dev/null +++ b/types/assets.d.ts @@ -0,0 +1,4 @@ +declare module '@workos/openapi-spec/spec' { + const contents: string; + export default contents; +} diff --git a/vitest.config.ts b/vitest.config.ts index d99388f6..2bbdd1a1 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,6 +1,23 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ + plugins: [ + { + name: 'bun-import-attributes', + enforce: 'pre', + transform(code, id) { + if (id.includes('/src/generated/') && code.includes("with { type: 'file' }")) { + return code.replace(/import ([A-Za-z_$][\w$]*) from ("[^"]+") with \{ type: 'file' \};/g, 'const $1 = $2;'); + } + + if (code.includes("with { type: 'text' }")) { + return code.replace(/from ('[^']+') with \{ type: 'text' \}/g, (_match, specifier: string) => { + return `from ${specifier.slice(0, -1)}?raw'`; + }); + } + }, + }, + ], test: { globals: true, environment: 'node', From 01e6225ab975782337a56938a54ce056e0f26688 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Thu, 16 Jul 2026 11:35:26 -0700 Subject: [PATCH 02/17] feat: Add Linux musl and Windows arm64 binary targets The Bun standalone binaries only covered glibc Linux, so the CLI could not run on Alpine and other musl systems, and Windows ARM users were left running the x64 build under emulation. Runtime musl detection mirrors the napi-rs loaders so the npm launcher and the Agent SDK download both resolve the same target the binary was compiled for, and musl artifacts are smoke tested in real Alpine containers because no glibc host can prove they run. --- .github/workflows/release.yml | 40 +++++++++++++++++++++++--- DEVELOPMENT.md | 3 +- README.md | 10 +++++-- scripts/build.ts | 3 ++ scripts/gen-agent-sdk-manifest.ts | 8 ++++-- scripts/gen-npm-packages.ts | 40 ++++++++++++++++++++++---- src/commands/internal-verify-assets.ts | 12 ++++---- src/lib/agent-sdk-assets.ts | 19 +++++++++++- 8 files changed, 112 insertions(+), 23 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70afa281..d9da832e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,8 +45,14 @@ jobs: asset: workos-linux-x64 - target: bun-linux-arm64 asset: workos-linux-arm64 + - target: bun-linux-x64-musl-baseline + asset: workos-linux-x64-musl + - target: bun-linux-arm64-musl + asset: workos-linux-arm64-musl - target: bun-windows-x64-baseline asset: workos-windows-x64.exe + - target: bun-windows-arm64 + asset: workos-windows-arm64.exe steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 7.0.0 with: @@ -89,8 +95,18 @@ jobs: runner: ubuntu-24.04 - asset: workos-linux-arm64 runner: ubuntu-24.04-arm + # musl binaries smoke inside Alpine containers on matching-arch + # runners — real musl libc, native CPU, no glibc on the path. + - asset: workos-linux-x64-musl + runner: ubuntu-24.04 + musl: true + - asset: workos-linux-arm64-musl + runner: ubuntu-24.04-arm + musl: true - asset: workos-windows-x64.exe runner: windows-latest + - asset: workos-windows-arm64.exe + runner: windows-11-arm runs-on: ${{ matrix.runner }} steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 8.0.1 @@ -104,11 +120,13 @@ jobs: if: startsWith(matrix.runner, 'macos') run: codesign -dvvv "./${{ matrix.asset }}" || true - # `internal verify-assets` extracts the embedded skills from the binary - # and performs the first-run download of the pinned Agent SDK executable - # (checksum-verified) and spawns it — proof this exact artifact works on - # real hardware for its platform. + # `internal verify-assets` extracts the embedded skills from the binary, + # checks the keyring native binding loaded, and performs the first-run + # download of the pinned Agent SDK executable (checksum-verified) and + # spawns it — proof this exact artifact works on real hardware for its + # platform. - name: Run the binary + if: matrix.musl != true shell: bash run: | case "${{ matrix.asset }}" in @@ -119,6 +137,20 @@ jobs: "./${{ matrix.asset }}" --help >/dev/null "./${{ matrix.asset }}" internal verify-assets --json + # Bun musl builds dynamically link libstdc++/libgcc (same as Node's musl + # builds) — install them like real Alpine users must. + - name: Run the binary (Alpine container) + if: matrix.musl == true + run: | + chmod +x "./${{ matrix.asset }}" + docker run --rm \ + --volume "${PWD}/${{ matrix.asset }}:/workos:ro" \ + --env HOME=/tmp/home \ + alpine:3.22 \ + sh -eu -c 'apk add --no-cache libstdc++ libgcc >/dev/null; + /workos --version; /workos --help >/dev/null; + /workos internal verify-assets --json' + publish: name: Publish release needs: [build, smoke] diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index bed04c51..f1e66083 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -224,7 +224,8 @@ npm publish; users download platform binaries): 1. Merging to `main` updates the release-please PR; merging that PR creates a **draft** GitHub release and pushes its tag immediately (`force-tag-creation`). -2. `release.yml` cross-compiles all five platform binaries, smoke tests each +2. `release.yml` cross-compiles all eight platform binaries (macOS arm64/x64, + Linux glibc + musl on x64/arm64, Windows x64/arm64), smoke tests each one **on native hardware** for its platform (including `workos internal verify-assets`, which checks the keyring native binding loaded, downloads the pinned Agent SDK executable, verifies its checksum, diff --git a/README.md b/README.md index e5cf9b3f..5af34078 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,19 @@ case "$(uname -s)" in Linux) os=linux ;; *) echo "Unsupported operating system: $(uname -s)"; exit 1 ;; esac -curl -fL "https://github.com/workos/cli/releases/latest/download/workos-${os}-${arch}" -o workos +libc="" +if [ "$os" = "linux" ] && ldd --version 2>&1 | grep -qi musl; then libc="-musl"; fi +curl -fL "https://github.com/workos/cli/releases/latest/download/workos-${os}-${arch}${libc}" -o workos +# Alpine only: the musl build needs the C++ runtime: apk add libstdc++ libgcc chmod +x workos sudo mv workos /usr/local/bin/workos ``` -Windows (x64 PowerShell): +Windows (PowerShell): ```powershell -Invoke-WebRequest https://github.com/workos/cli/releases/latest/download/workos-windows-x64.exe -OutFile workos.exe +$arch = if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64') { 'arm64' } else { 'x64' } +Invoke-WebRequest "https://github.com/workos/cli/releases/latest/download/workos-windows-$arch.exe" -OutFile workos.exe ``` Move `workos.exe` to a directory on your `PATH`, then run `workos install`. diff --git a/scripts/build.ts b/scripts/build.ts index 6a0c03d9..d7400984 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -21,7 +21,10 @@ const KEYRING_BINDINGS: Record = { 'darwin-x64': '@napi-rs/keyring-darwin-x64', 'linux-x64': '@napi-rs/keyring-linux-x64-gnu', 'linux-arm64': '@napi-rs/keyring-linux-arm64-gnu', + 'linux-x64-musl': '@napi-rs/keyring-linux-x64-musl', + 'linux-arm64-musl': '@napi-rs/keyring-linux-arm64-musl', 'windows-x64': '@napi-rs/keyring-win32-x64-msvc', + 'windows-arm64': '@napi-rs/keyring-win32-arm64-msvc', }; const normalizedTarget = ( diff --git a/scripts/gen-agent-sdk-manifest.ts b/scripts/gen-agent-sdk-manifest.ts index ac73da52..25c74cf8 100644 --- a/scripts/gen-agent-sdk-manifest.ts +++ b/scripts/gen-agent-sdk-manifest.ts @@ -10,14 +10,16 @@ const normalizedTarget = requestedTarget .replace(/^bun-/, '') .replace(/-baseline$/, '') .replace(/-modern$/, ''); -const [targetOs, targetArch] = normalizedTarget.split('-'); +const isMusl = normalizedTarget.endsWith('-musl'); +const [targetOs, targetArch] = normalizedTarget.replace(/-musl$/, '').split('-'); const packageOs = targetOs === 'windows' ? 'win32' : targetOs; if (!packageOs || !targetArch || !['darwin', 'linux', 'win32'].includes(packageOs)) { throw new Error(`Unsupported WorkOS binary target for the Agent SDK: ${requestedTarget}`); } -const packageName = `@anthropic-ai/claude-agent-sdk-${packageOs}-${targetArch}`; +const packageTarget = `${packageOs}-${targetArch}${isMusl ? '-musl' : ''}`; +const packageName = `@anthropic-ai/claude-agent-sdk-${packageTarget}`; const packageJsonPath = fileURLToPath(import.meta.resolve(`${packageName}/package.json`)); const packageRoot = dirname(packageJsonPath); const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8')) as { version?: unknown }; @@ -38,7 +40,7 @@ await mkdir(dirname(manifestPath), { recursive: true }); const manifest = `// Generated by scripts/gen-agent-sdk-manifest.ts. Do not edit manually. // The native Agent SDK executable is NOT embedded in the compiled binary: it is // downloaded on first agent use, pinned to this exact version and checksum. -export const AGENT_SDK_TARGET = ${JSON.stringify(`${packageOs}-${targetArch}`)}; +export const AGENT_SDK_TARGET = ${JSON.stringify(packageTarget)}; export const AGENT_SDK_VERSION = ${JSON.stringify(packageJson.version)}; export const AGENT_SDK_PACKAGE = ${JSON.stringify(packageName)}; export const AGENT_SDK_TARBALL_URL = ${JSON.stringify(tarballUrl)}; diff --git a/scripts/gen-npm-packages.ts b/scripts/gen-npm-packages.ts index 517cd9b9..4c89e87f 100644 --- a/scripts/gen-npm-packages.ts +++ b/scripts/gen-npm-packages.ts @@ -35,14 +35,27 @@ if (!/^\d+\.\d+\.\d+(-.+)?$/.test(version)) { const REPOSITORY = { type: 'git', url: 'git+https://github.com/workos/cli.git' }; const LICENSE = 'MIT'; -// Platform keys use process.platform/process.arch values so the launcher can -// build the package name from the running process; assets use release names. -const PLATFORMS = [ +// Platform keys use process.platform/process.arch values (plus a -musl +// suffix) so the launcher can build the package name from the running +// process; assets use release names. The `libc` field keeps package managers +// that honor it (pnpm, yarn, npm ≥10.4) from installing the wrong linux +// flavor; the launcher's own musl detection covers the rest. +const PLATFORMS: Array<{ key: string; os: string; cpu: string; asset: string; bin: string; libc?: string[] }> = [ { key: 'darwin-arm64', os: 'darwin', cpu: 'arm64', asset: 'workos-darwin-arm64', bin: 'workos' }, { key: 'darwin-x64', os: 'darwin', cpu: 'x64', asset: 'workos-darwin-x64', bin: 'workos' }, - { key: 'linux-x64', os: 'linux', cpu: 'x64', asset: 'workos-linux-x64', bin: 'workos' }, - { key: 'linux-arm64', os: 'linux', cpu: 'arm64', asset: 'workos-linux-arm64', bin: 'workos' }, + { key: 'linux-x64', os: 'linux', cpu: 'x64', asset: 'workos-linux-x64', bin: 'workos', libc: ['glibc'] }, + { key: 'linux-arm64', os: 'linux', cpu: 'arm64', asset: 'workos-linux-arm64', bin: 'workos', libc: ['glibc'] }, + { key: 'linux-x64-musl', os: 'linux', cpu: 'x64', asset: 'workos-linux-x64-musl', bin: 'workos', libc: ['musl'] }, + { + key: 'linux-arm64-musl', + os: 'linux', + cpu: 'arm64', + asset: 'workos-linux-arm64-musl', + bin: 'workos', + libc: ['musl'], + }, { key: 'win32-x64', os: 'win32', cpu: 'x64', asset: 'workos-windows-x64.exe', bin: 'workos.exe' }, + { key: 'win32-arm64', os: 'win32', cpu: 'arm64', asset: 'workos-windows-arm64.exe', bin: 'workos.exe' }, ]; const present = PLATFORMS.filter((platform) => existsSync(join(distDir, platform.asset))); @@ -62,7 +75,21 @@ const LAUNCHER = `#!/usr/bin/env node // the matching @workos/cli-- optionalDependency and runs it. const { spawnSync } = require('node:child_process'); -const key = \`\${process.platform}-\${process.arch}\`; +// Same musl detection the napi-rs loaders use: Alpine's ldd is a musl script, +// and glibc processes report a glibcVersionRuntime header. +function isMusl() { + if (process.platform !== 'linux') return false; + try { + if (require('node:fs').readFileSync('/usr/bin/ldd', 'utf8').includes('musl')) return true; + } catch {} + try { + const report = process.report?.getReport(); + if (report?.header) return !report.header.glibcVersionRuntime; + } catch {} + return false; +} + +const key = \`\${process.platform}-\${process.arch}\${isMusl() ? '-musl' : ''}\`; const executable = process.platform === 'win32' ? 'workos.exe' : 'workos'; let binary; @@ -102,6 +129,7 @@ for (const platform of present) { license: LICENSE, os: [platform.os], cpu: [platform.cpu], + ...(platform.libc ? { libc: platform.libc } : {}), files: ['bin'], }, null, diff --git a/src/commands/internal-verify-assets.ts b/src/commands/internal-verify-assets.ts index 25387328..9cebe516 100644 --- a/src/commands/internal-verify-assets.ts +++ b/src/commands/internal-verify-assets.ts @@ -42,15 +42,17 @@ export async function runVerifyAssets(): Promise { // The keyring native binding is load-bearing: config-store.ts imports it // statically, so a binary compiled without the target's .node binding - // crashes at startup instead of falling back to file storage. Constructing - // an Entry proves the binding embedded and loaded; a storage-layer error - // (e.g. headless CI with no secret service) still proves the binding works. + // crashes at startup instead of falling back to file storage. The import is + // where the binding dlopens — success proves it embedded and loaded. Entry + // construction/reads exercise the OS storage layer, which is environmental + // (Docker seccomp blocks kernel keyutils; headless CI has no secret + // service) — a failure there still proves the binding and must not fail + // verification. let keyring: 'native' | 'native-storage-unavailable'; try { const { Entry } = await import('@napi-rs/keyring'); - const entry = new Entry('workos-cli', 'verify-assets-probe'); try { - entry.getPassword(); + new Entry('workos-cli', 'verify-assets-probe').getPassword(); keyring = 'native'; } catch { keyring = 'native-storage-unavailable'; diff --git a/src/lib/agent-sdk-assets.ts b/src/lib/agent-sdk-assets.ts index 4698821d..45d5c903 100644 --- a/src/lib/agent-sdk-assets.ts +++ b/src/lib/agent-sdk-assets.ts @@ -33,8 +33,25 @@ export type DownloadProgress = { let cachedExecutablePath: string | undefined; +/** Detect a musl libc runtime (Alpine etc.) the same way napi-rs loaders do. */ +function isMuslRuntime(): boolean { + if (process.platform !== 'linux') return false; + try { + if (readFileSync('/usr/bin/ldd', 'utf8').includes('musl')) return true; + } catch { + // No readable /usr/bin/ldd — fall through to the process report. + } + try { + const report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined; + if (report?.header) return !report.header.glibcVersionRuntime; + } catch { + // Report unavailable — assume glibc. + } + return false; +} + function runtimeTarget(): string { - return `${process.platform}-${process.arch}`; + return `${process.platform}-${process.arch}${isMuslRuntime() ? '-musl' : ''}`; } /** Running from a compiled binary: the module graph lives in Bun's virtual filesystem. */ From b6253e7b5897913fe0c2ef89f7cc3989219a2133 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 11:05:47 -0400 Subject: [PATCH 03/17] ci(release): Skip already-published npm packages on re-run A partial npm publish failure left the release permanently half-published: re-running the job hit npm's cannot-publish-over- existing-version error on the first already-live package and aborted before reaching the unpublished ones, including the launcher. Guarding each publish with `npm view` makes re-runs converge, so the job comment's "re-run just this job" recovery actually works. --- .github/workflows/release.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d9da832e..13168223 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -226,12 +226,22 @@ jobs: fi # Platform packages publish before the launcher so the launcher's - # optionalDependencies are always resolvable once it is visible. + # optionalDependencies are always resolvable once it is visible — the + # single glob list keeps that order (cli-* dirs before the workos dir). + # Each publish is skipped when that exact version is already on npm, so a + # partially-published release converges cleanly on a re-run of this job. - name: Publish + env: + TAG_NAME: ${{ inputs.tag_name }} run: | sed -i '/_authToken/d' "$NPM_CONFIG_USERCONFIG" unset NODE_AUTH_TOKEN - for dir in dist/npm/@workos/cli-*; do + VERSION="${TAG_NAME#v}" + for dir in dist/npm/@workos/cli-* dist/npm/workos; do + pkg=$(node -p "require('./$dir/package.json').name") + if npm view "$pkg@$VERSION" version >/dev/null 2>&1; then + echo "$pkg@$VERSION already published, skipping" + continue + fi (cd "$dir" && npm publish --access public --provenance --tag ${{ steps.npm-tag.outputs.tag }}) done - cd dist/npm/workos && npm publish --access public --provenance --tag ${{ steps.npm-tag.outputs.tag }} From 0a0ede40fbd851344e75791a92c45f7bdec3fcf8 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 11:05:50 -0400 Subject: [PATCH 04/17] fix(build): Detect musl for host-default build targets On Alpine, `bun install` (postinstall runs generate) pinned the glibc Agent SDK package while the runtime's musl detection demanded the musl one, so every dev agent use threw a target mismatch. The keyring-binding check in build.ts assumed glibc the same way. Both scripts now mirror the runtime's isMuslRuntime() when WORKOS_BUILD_TARGET is unset; explicit targets are unchanged. --- scripts/build.ts | 28 +++++++++++++++++++++++++--- scripts/gen-agent-sdk-manifest.ts | 24 +++++++++++++++++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/scripts/build.ts b/scripts/build.ts index d7400984..914da15a 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -6,10 +6,31 @@ // `bun run generate` so the pinned Agent SDK matches. // WORKOS_BUILD_OUTFILE output path; defaults to ./dist/workos. import { spawnSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; const target = process.env.WORKOS_BUILD_TARGET; const outfile = process.env.WORKOS_BUILD_OUTFILE ?? './dist/workos'; +// Same musl detection the runtime's isMuslRuntime() and the napi-rs loaders use: +// Alpine's ldd is a musl script, and glibc processes report a glibcVersionRuntime +// header. Without this, a host build on Alpine would resolve the glibc keyring +// binding instead of the musl one the compiled binary needs. +function isMuslHost(): boolean { + if (process.platform !== 'linux') return false; + try { + if (readFileSync('/usr/bin/ldd', 'utf8').includes('musl')) return true; + } catch { + // No readable /usr/bin/ldd — fall through to the process report. + } + try { + const report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined; + if (report?.header) return !report.header.glibcVersionRuntime; + } catch { + // Report unavailable — assume glibc. + } + return false; +} + // The keyring native binding for the compile target must be installed, or the // compiled binary ships without OS keychain support and crashes at startup // (config-store.ts imports @napi-rs/keyring statically). Fail the build fast @@ -27,9 +48,10 @@ const KEYRING_BINDINGS: Record = { 'windows-arm64': '@napi-rs/keyring-win32-arm64-msvc', }; -const normalizedTarget = ( - target ?? `bun-${process.platform === 'win32' ? 'windows' : process.platform}-${process.arch}` -) +const hostTarget = `bun-${process.platform === 'win32' ? 'windows' : process.platform}-${process.arch}${ + isMuslHost() ? '-musl' : '' +}`; +const normalizedTarget = (target ?? hostTarget) .replace(/^bun-/, '') .replace(/-baseline$/, '') .replace(/-modern$/, ''); diff --git a/scripts/gen-agent-sdk-manifest.ts b/scripts/gen-agent-sdk-manifest.ts index 25c74cf8..c7106e24 100644 --- a/scripts/gen-agent-sdk-manifest.ts +++ b/scripts/gen-agent-sdk-manifest.ts @@ -1,11 +1,33 @@ import { createHash } from 'node:crypto'; +import { readFileSync } from 'node:fs'; import { mkdir, readFile } from 'node:fs/promises'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; +// Same musl detection the runtime's isMuslRuntime() and the napi-rs loaders use: +// Alpine's ldd is a musl script, and glibc processes report a glibcVersionRuntime +// header. Without this, a `bun install` on Alpine (postinstall runs generate) +// would pin the glibc SDK package while the runtime demands the musl one. +function isMuslHost(): boolean { + if (process.platform !== 'linux') return false; + try { + if (readFileSync('/usr/bin/ldd', 'utf8').includes('musl')) return true; + } catch { + // No readable /usr/bin/ldd — fall through to the process report. + } + try { + const report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined; + if (report?.header) return !report.header.glibcVersionRuntime; + } catch { + // Report unavailable — assume glibc. + } + return false; +} + const projectRoot = join(import.meta.dirname, '..'); const manifestPath = join(projectRoot, 'src', 'generated', 'agent-sdk-manifest.ts'); -const requestedTarget = process.env.WORKOS_BUILD_TARGET ?? `bun-${process.platform}-${process.arch}`; +const hostTarget = `bun-${process.platform}-${process.arch}${isMuslHost() ? '-musl' : ''}`; +const requestedTarget = process.env.WORKOS_BUILD_TARGET ?? hostTarget; const normalizedTarget = requestedTarget .replace(/^bun-/, '') .replace(/-baseline$/, '') From 1a0abae1a6eb5587d14014454ba6e52c1d2611a5 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 11:05:50 -0400 Subject: [PATCH 05/17] fix: Abort stalled Agent SDK downloads and retry once The first-run download (~100MB from the npm registry) had no abort signal, so a stalled connection hung `workos install` forever mid-progress, and any transient network error failed the run outright. A stall timer that resets on each received chunk catches both connect hangs and mid-stream stalls without penalizing slow links, and a single retry absorbs transient failures. Checksum mismatches stay hard failures and are never retried. --- src/lib/agent-sdk-assets.spec.ts | 64 +++++++++++++++++++++++- src/lib/agent-sdk-assets.ts | 86 +++++++++++++++++++++++++------- 2 files changed, 130 insertions(+), 20 deletions(-) diff --git a/src/lib/agent-sdk-assets.spec.ts b/src/lib/agent-sdk-assets.spec.ts index 7136a4ae..507377f5 100644 --- a/src/lib/agent-sdk-assets.spec.ts +++ b/src/lib/agent-sdk-assets.spec.ts @@ -1,8 +1,8 @@ import { existsSync } from 'node:fs'; import { gzipSync } from 'node:zlib'; -import { describe, expect, it } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { AGENT_SDK_TARGET, AGENT_SDK_VERSION } from '../generated/agent-sdk-manifest.js'; -import { ensureClaudeCodeExecutable, extractTarEntry } from './agent-sdk-assets.js'; +import { downloadTarball, ensureClaudeCodeExecutable, extractTarEntry } from './agent-sdk-assets.js'; function tarHeader(name: string, size: number): Buffer { const header = Buffer.alloc(512); @@ -61,3 +61,63 @@ describe('extractTarEntry', () => { expect(() => extractTarEntry(tarball, 'package/claude')).toThrow(/not found/); }); }); + +describe('downloadTarball', () => { + afterEach(() => { + vi.unstubAllGlobals(); + }); + + function streamedResponse(body: Buffer): Response { + let sent = false; + return { + ok: true, + status: 200, + headers: { get: (name: string) => (name === 'content-length' ? String(body.length) : null) }, + body: { + getReader() { + return { + read: async () => + sent ? { done: true, value: undefined } : ((sent = true), { done: false, value: new Uint8Array(body) }), + }; + }, + }, + } as unknown as Response; + } + + it('retries once when the first attempt fails, then succeeds', async () => { + const tarball = makeTarball([['package/claude', Buffer.from('binary')]]); + const fetchMock = vi + .fn() + .mockRejectedValueOnce(new Error('connection reset')) + .mockResolvedValueOnce(streamedResponse(tarball)); + vi.stubGlobal('fetch', fetchMock); + + const result = await downloadTarball(); + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(result.equals(tarball)).toBe(true); + }); + + it('aborts a stalled download and reports it after retrying', async () => { + const fetchMock = vi.fn((_url: string, init?: { signal?: AbortSignal }) => + Promise.resolve({ + ok: true, + status: 200, + headers: { get: () => null }, + body: { + getReader() { + return { + read: () => + new Promise((_resolve, reject) => { + init?.signal?.addEventListener('abort', () => reject(new Error('aborted'))); + }), + }; + }, + }, + } as unknown as Response), + ); + vi.stubGlobal('fetch', fetchMock); + + await expect(downloadTarball(undefined, 20)).rejects.toThrow(/stalled/); + expect(fetchMock).toHaveBeenCalledTimes(2); + }); +}); diff --git a/src/lib/agent-sdk-assets.ts b/src/lib/agent-sdk-assets.ts index 45d5c903..80d8f76a 100644 --- a/src/lib/agent-sdk-assets.ts +++ b/src/lib/agent-sdk-assets.ts @@ -113,26 +113,76 @@ export function extractTarEntry(tarGz: Buffer, entryName: string): Buffer { throw new Error(`Entry ${entryName} not found in tarball`); } -async function downloadTarball(onProgress?: (progress: DownloadProgress) => void): Promise { - const response = await fetch(AGENT_SDK_TARBALL_URL); - if (!response.ok || !response.body) { - throw new Error(`Download failed: HTTP ${response.status} from ${AGENT_SDK_TARBALL_URL}`); - } - const contentLength = Number(response.headers.get('content-length')); - const totalBytes = Number.isFinite(contentLength) && contentLength > 0 ? contentLength : null; - - const chunks: Uint8Array[] = []; - let receivedBytes = 0; - const reader = response.body.getReader(); - onProgress?.({ receivedBytes, totalBytes }); - for (;;) { - const { done, value } = await reader.read(); - if (done) break; - chunks.push(value); - receivedBytes += value.byteLength; +/** Abort a download that goes this long without a data chunk, so a stalled connection can't hang forever. */ +const DOWNLOAD_STALL_TIMEOUT_MS = 30_000; + +async function downloadTarballOnce( + url: string, + onProgress: ((progress: DownloadProgress) => void) | undefined, + stallTimeoutMs: number, +): Promise { + const controller = new AbortController(); + let stalled = false; + let timer: ReturnType | undefined; + const armStallTimer = () => { + clearTimeout(timer); + timer = setTimeout(() => { + stalled = true; + controller.abort(); + }, stallTimeoutMs); + }; + + armStallTimer(); + try { + const response = await fetch(url, { signal: controller.signal }); + if (!response.ok || !response.body) { + throw new Error(`Download failed: HTTP ${response.status} from ${url}`); + } + const contentLength = Number(response.headers.get('content-length')); + const totalBytes = Number.isFinite(contentLength) && contentLength > 0 ? contentLength : null; + + const chunks: Uint8Array[] = []; + let receivedBytes = 0; + const reader = response.body.getReader(); onProgress?.({ receivedBytes, totalBytes }); + for (;;) { + const { done, value } = await reader.read(); + if (done) break; + armStallTimer(); + chunks.push(value); + receivedBytes += value.byteLength; + onProgress?.({ receivedBytes, totalBytes }); + } + return Buffer.concat(chunks); + } catch (error) { + if (stalled) { + throw new Error(`Download stalled: no data from ${url} for ${stallTimeoutMs / 1000}s`); + } + throw error; + } finally { + clearTimeout(timer); + } +} + +/** + * Download the pinned tarball, retrying once on any network, stall, or HTTP + * failure. Checksum verification stays in the caller and is never retried. + * Exported for tests. + */ +export async function downloadTarball( + onProgress?: (progress: DownloadProgress) => void, + stallTimeoutMs: number = DOWNLOAD_STALL_TIMEOUT_MS, +): Promise { + const url = AGENT_SDK_TARBALL_URL; + let lastError: unknown; + for (let attempt = 0; attempt < 2; attempt++) { + try { + return await downloadTarballOnce(url, onProgress, stallTimeoutMs); + } catch (error) { + lastError = error; + } } - return Buffer.concat(chunks); + throw lastError; } /** From 689d15f207d77d4042403a722f1d80f9f10473fc Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 11:05:50 -0400 Subject: [PATCH 06/17] fix: Re-verify the Agent SDK sha256 in verify-assets After the first install the cached executable is only revalidated by file size, so silent size-preserving corruption (disk fault, antivirus quarantine/restore) passed unnoticed until runtime. `internal verify-assets` is the diagnostic a user with a corrupted cache gets pointed at, so it now re-hashes the executable against the pinned manifest digest and fails with a distinct error code and a delete-the-cache remedy. --- src/commands/internal-verify-assets.spec.ts | 2 ++ src/commands/internal-verify-assets.ts | 37 ++++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/commands/internal-verify-assets.spec.ts b/src/commands/internal-verify-assets.spec.ts index 0bdefd26..4b119b86 100644 --- a/src/commands/internal-verify-assets.spec.ts +++ b/src/commands/internal-verify-assets.spec.ts @@ -1,4 +1,5 @@ import { describe, expect, it, vi } from 'vitest'; +import { AGENT_SDK_EXECUTABLE_SHA256 } from '../generated/agent-sdk-manifest.js'; import { runVerifyAssets } from './internal-verify-assets.js'; describe('runVerifyAssets', () => { @@ -22,6 +23,7 @@ describe('runVerifyAssets', () => { expect(report.keyring).toMatch(/^native/); expect(report.claudeVersion).toBeTruthy(); expect(report.claudePath).not.toContain('$bunfs'); + expect(report.claudeSha256).toBe(AGENT_SDK_EXECUTABLE_SHA256); } finally { setOutputMode('human'); logSpy.mockRestore(); diff --git a/src/commands/internal-verify-assets.ts b/src/commands/internal-verify-assets.ts index 9cebe516..a2308833 100644 --- a/src/commands/internal-verify-assets.ts +++ b/src/commands/internal-verify-assets.ts @@ -1,7 +1,9 @@ import { spawnSync } from 'node:child_process'; +import { createHash } from 'node:crypto'; import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import chalk from 'chalk'; +import { AGENT_SDK_EXECUTABLE_SHA256 } from '../generated/agent-sdk-manifest.js'; import { AGENT_SDK_TARGET, AGENT_SDK_VERSION, ensureClaudeCodeExecutable } from '../lib/agent-sdk-assets.js'; import { BUNDLED_SKILLS_VERSION, getSkillsDir } from '../lib/skills-assets.js'; import { logError } from '../utils/debug.js'; @@ -17,9 +19,12 @@ const CLAUDE_SPAWN_TIMEOUT_MS = 120_000; * machine — skills embedded in the compiled binary materialize and are * readable, and the pinned Agent SDK `claude` executable resolves (first-run * download + checksum verification from a compiled binary; node_modules in - * dev) and actually runs. Exits non-zero on the first failure so release - * pipelines can gate on it. Requires network access from a compiled binary - * unless the download is already cached. + * dev), matches the pinned manifest sha256, and actually runs. The cached + * executable is otherwise only revalidated by file size on subsequent runs, so + * this command re-hashes it to catch silent, size-preserving corruption (disk + * fault, antivirus quarantine/restore). Exits non-zero on the first failure so + * release pipelines can gate on it. Requires network access from a compiled + * binary unless the download is already cached. */ export async function runVerifyAssets(): Promise { let skillsDir: string; @@ -66,9 +71,31 @@ export async function runVerifyAssets(): Promise { } let claudePath: string; - let claudeVersion: string; try { claudePath = await ensureClaudeCodeExecutable(); + } catch (error) { + logError('Agent SDK verification failed:', error); + exitWithError({ + code: 'VERIFY_ASSETS_AGENT_SDK_FAILED', + message: `Agent SDK executable failed to resolve or run: ${error instanceof Error ? error.message : String(error)}`, + }); + } + + // Re-verify the cached executable's sha256 against the pinned manifest + // digest. After the first install the cache is only revalidated by file size, + // so silent corruption that preserves size (disk fault, antivirus + // quarantine/restore) would otherwise pass unnoticed until runtime. + const claudeSha256 = createHash('sha256').update(readFileSync(claudePath)).digest('hex'); + if (claudeSha256 !== AGENT_SDK_EXECUTABLE_SHA256) { + logError('Agent SDK checksum verification failed:', `expected ${AGENT_SDK_EXECUTABLE_SHA256}, got ${claudeSha256}`); + exitWithError({ + code: 'VERIFY_ASSETS_AGENT_SDK_CHECKSUM_FAILED', + message: `Agent SDK executable at ${claudePath} failed checksum verification: expected sha256 ${AGENT_SDK_EXECUTABLE_SHA256}, got ${claudeSha256}. Delete ~/.workos/cache/agent-sdk to force a re-download.`, + }); + } + + let claudeVersion: string; + try { const result = spawnSync(claudePath, ['--version'], { encoding: 'utf8', timeout: CLAUDE_SPAWN_TIMEOUT_MS }); if (result.error) throw result.error; if (result.status !== 0 || !result.stdout.trim()) { @@ -90,6 +117,7 @@ export async function runVerifyAssets(): Promise { bundledSkillsVersion: BUNDLED_SKILLS_VERSION, keyring, claudePath, + claudeSha256, claudeVersion, agentSdkTarget: AGENT_SDK_TARGET, agentSdkVersion: AGENT_SDK_VERSION, @@ -103,5 +131,6 @@ export async function runVerifyAssets(): Promise { console.log(chalk.green('✓'), `Skills materialized: ${skills.length} skills at ${skillsDir}`); console.log(chalk.green('✓'), `Keyring binding loaded (${keyring})`); console.log(chalk.green('✓'), `Agent SDK ${AGENT_SDK_VERSION} (${AGENT_SDK_TARGET}) at ${claudePath}`); + console.log(chalk.green('✓'), `Agent SDK checksum verified (sha256 ${claudeSha256})`); console.log(chalk.green('✓'), `claude --version → ${claudeVersion} (pinned SDK ${AGENT_SDK_VERSION})`); } From 134766bf96b7b739c771e7b6ecdfd9421a589236 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 11:05:50 -0400 Subject: [PATCH 07/17] test: Cover the skills extraction rename-race recovery The concurrent-extraction recovery in materializeFile (accept a winner's byte-identical copy, re-throw on divergence) had no coverage; only the happy path was exercised. A mocked renameSync that plants the winner's file before failing forces both branches and proves no temp files are orphaned either way. --- src/lib/skills-assets.spec.ts | 103 +++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/src/lib/skills-assets.spec.ts b/src/lib/skills-assets.spec.ts index 4e94cfb0..f76971b1 100644 --- a/src/lib/skills-assets.spec.ts +++ b/src/lib/skills-assets.spec.ts @@ -1,9 +1,28 @@ -import { existsSync, mkdirSync, readFileSync, rmSync, utimesSync } from 'node:fs'; +import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, utimesSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { describe, expect, it, vi } from 'vitest'; import { BUNDLED_SKILLS_VERSION, getReference, getSkillsDir } from './skills-assets.js'; +function extractionSuffix(): string { + return process.platform === 'win32' ? '' : `-${process.getuid?.() ?? 0}`; +} + +/** Recursively collect any leftover atomic-write temp files under a directory. */ +function tempFilesUnder(root: string): string[] { + if (!existsSync(root)) return []; + const found: string[] = []; + const walk = (dir: string): void => { + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const full = join(dir, entry.name); + if (entry.isDirectory()) walk(full); + else if (entry.name.includes('.tmp.')) found.push(full); + } + }; + walk(root); + return found; +} + describe('embedded skills assets', () => { it('materializes the complete plugin tree to a real directory', async () => { const skillsDir = getSkillsDir(); @@ -16,7 +35,7 @@ describe('embedded skills assets', () => { }); it('reaps stale extraction roots from other versions, keeping fresh ones', async () => { - const suffix = process.platform === 'win32' ? '' : `-${process.getuid?.() ?? 0}`; + const suffix = extractionSuffix(); const staleRoot = join(tmpdir(), `workos-skills-0.0.1-spec-stale${suffix}`); const freshRoot = join(tmpdir(), `workos-skills-0.0.2-spec-fresh${suffix}`); mkdirSync(staleRoot, { recursive: true }); @@ -40,3 +59,83 @@ describe('embedded skills assets', () => { } }); }); + +describe('materializeFile concurrent extraction race', () => { + // The extraction root is version-keyed and shared with the other tests and + // real CLI runs on this machine; each test wipes it first so materializeFile's + // identical-target pre-check can't short-circuit before the mocked rename runs. + const extractionRoot = join(tmpdir(), `workos-skills-${BUNDLED_SKILLS_VERSION}${extractionSuffix()}`); + + it('re-throws the rename failure when a concurrent winner wrote divergent bytes', async () => { + rmSync(extractionRoot, { recursive: true, force: true }); + + let raced = false; + try { + vi.resetModules(); + vi.doMock('node:fs', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + renameSync(oldPath: string, newPath: string): void { + // Simulate a concurrent winner for the first extracted asset only: + // publish DIVERGENT bytes at the target, then fail this rename. + if (!raced && newPath.includes('workos-skills-')) { + raced = true; + actual.writeFileSync(newPath, Buffer.from('divergent winner contents')); + throw Object.assign(new Error('EEXIST: file already exists, rename'), { code: 'EEXIST' }); + } + actual.renameSync(oldPath, newPath); + }, + }; + }); + + const mod = await import('./skills-assets.js'); + expect(() => mod.materializeSkillsDir()).toThrow(/EEXIST/); + expect(raced).toBe(true); + // The temp file for the raced asset must be cleaned up before re-throwing. + expect(tempFilesUnder(extractionRoot)).toEqual([]); + } finally { + vi.doUnmock('node:fs'); + vi.resetModules(); + } + }); + + it('accepts a byte-identical file written by a concurrent winner when rename fails', async () => { + rmSync(extractionRoot, { recursive: true, force: true }); + + let raced = false; + try { + vi.resetModules(); + vi.doMock('node:fs', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + renameSync(oldPath: string, newPath: string): void { + // Simulate a concurrent winner for the first extracted asset only: + // publish a BYTE-IDENTICAL copy at the target, then fail this rename. + // Later assets extract normally so materializeSkillsDir can finish. + if (!raced && newPath.includes('workos-skills-')) { + raced = true; + actual.writeFileSync(newPath, actual.readFileSync(oldPath)); + throw Object.assign(new Error('EEXIST: file already exists, rename'), { code: 'EEXIST' }); + } + actual.renameSync(oldPath, newPath); + }, + }; + }); + + const mod = await import('./skills-assets.js'); + const skillsDir = mod.materializeSkillsDir(); + + expect(raced).toBe(true); + // Recovery accepted the winner's copy and the rest of the tree extracted. + expect(existsSync(join(skillsDir, 'workos', 'SKILL.md'))).toBe(true); + expect(existsSync(join(skillsDir, 'workos-widgets', 'SKILL.md'))).toBe(true); + // The temp file for the raced asset must be removed, not orphaned. + expect(tempFilesUnder(extractionRoot)).toEqual([]); + } finally { + vi.doUnmock('node:fs'); + vi.resetModules(); + } + }); +}); From 37070d3cf34e99eb5cae364d51c0de0bb025ef60 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 11:05:50 -0400 Subject: [PATCH 08/17] docs: Explain the react-devtools-core devDependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing in src/ imports it, so it reads as removable — but ink's devtools.js statically imports it and `bun build --compile` cannot prove the DEV-gated branch dead, so removing the dep fails the compile. `--external` compiles but crashes the binary on every command. Documenting the measured ~742 KiB cost and the failed alternatives keeps a well-meaning cleanup from breaking the build. --- DEVELOPMENT.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index f1e66083..46fd5732 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -148,6 +148,22 @@ for a non-host platform; the same value must be used for both `generate` and the compile, which `bun run build` (via `scripts/build.ts` + the `prebuild` hook) guarantees. +### Why `react-devtools-core` is a devDependency + +Nothing in `src/` imports `react-devtools-core`, but it is required to +**build**, not to run. The dashboard TUI (`src/dashboard/`) uses `ink`, whose +reconciler does a runtime-gated `await import('./devtools.js')` that only fires +when `DEV=true`; `devtools.js` then _statically_ imports `react-devtools-core`. +`bun build --compile` follows that static import at bundle time and cannot prove +the `DEV` branch is dead, so removing the devDependency fails the compile with +`error: Could not resolve: "react-devtools-core"` (do not "clean it up"). As a +result it is also bundled into every shipped binary, costing ~742 KiB +(measured: 72,512,032 → 71,752,480 bytes when excluded). Do **not** try to trim +it with `--external react-devtools-core`: that compiles, but bun resolves the +external eagerly and the standalone binary then crashes on _every_ command +(even `--version`) with `Cannot find package 'react-devtools-core'`. The ~742 KiB +is the price of keeping the compile green and the dev-mode fallback graceful. + ### Updating Integration Instructions The installer prompt in `agent-runner.ts` tells Claude to: From 74b2baa17d85f60dd8a7264bf498e6bf5abcbfbf Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 13:30:13 -0400 Subject: [PATCH 09/17] test: Smoke test the npm distribution against a local registry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only npm-channel check was running the launcher script directly with NODE_PATH, which bypasses everything that can actually break for users: registry fetch, optionalDependencies platform selection, npx cache and bin linking, and the launcher's no-binary error path. A manual dress rehearsal against a local registry surfaced real gaps the shortcut can't see (npm nests global deps inside the package; a brew-installed `workos` shadows bare `npx workos` unless the prefix and PATH are isolated). Codifying it makes `npx workos` a gated guarantee: every PR runs it, and the release pipeline runs it after generating the real packages — so a packaging regression fails before anything touches npmjs.org. The registry has no uplinks, proving the install is self-contained. --- .github/workflows/ci.yml | 11 +- .github/workflows/release.yml | 7 + DEVELOPMENT.md | 15 ++ scripts/npm-dist-smoke.ts | 277 ++++++++++++++++++++++++++++++++++ 4 files changed, 306 insertions(+), 4 deletions(-) create mode 100644 scripts/npm-dist-smoke.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b12cdb1..eeb9813f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,12 +68,15 @@ jobs: sh -eu -c '/workos internal verify-assets --json' - # Prove the npm thin-shim launcher resolves and spawns the platform - # binary — the same wiring `npx workos` uses after publish. - - name: Smoke test npm launcher packages + # Publish the generated packages to a throwaway local registry and run + # the real user flows — `npx workos`, `npm install -g workos`, platform + # selection, and the launcher's no-binary error path — from a hermetic + # environment. This exercises the npm machinery the in-repo launcher + # check can't (registry fetch, optionalDependencies, npx cache/bin). + - name: Smoke test npm distribution against a local registry env: WORKOS_NPM_ALLOW_MISSING: '1' run: | cp dist/workos dist/workos-linux-x64 bun run ./scripts/gen-npm-packages.ts - NODE_PATH=dist/npm node dist/npm/workos/bin/workos.js --version + bun run ./scripts/npm-dist-smoke.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 13168223..910554f0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -213,6 +213,13 @@ jobs: TAG_NAME: ${{ inputs.tag_name }} run: WORKOS_NPM_VERSION="${TAG_NAME#v}" bun run ./scripts/gen-npm-packages.ts + # Pre-publish gate: publish all generated packages to a throwaway local + # registry and drive the real `npx workos` / `npm install -g workos` + # flows (linux-x64 binary executes on this runner). A packaging + # regression fails here instead of after touching npmjs.org. + - name: Smoke test npm distribution against a local registry + run: bun run ./scripts/npm-dist-smoke.ts + - name: Determine npm tag id: npm-tag env: diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 46fd5732..1910d893 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -204,6 +204,21 @@ export function redactCredentials(obj: any): any { - Environment variables - UI components +**Smoke testing the npm distribution:** + +`scripts/npm-dist-smoke.ts` publishes the generated npm packages to a +throwaway local registry (Verdaccio) and drives the real user flows — +`npx workos`, `npm install -g workos`, platform selection, and the +launcher's no-binary error path — from a hermetic environment (fresh +HOME/cache/prefix, sanitized PATH, no uplinks so nothing can leak to the +real registry). CI runs it on every PR and the release pipeline runs it as a +pre-publish gate. Locally: + +```bash +bun run build +bun run ./scripts/npm-dist-smoke.ts # generates a host-only dist/npm if absent +``` + ## Evaluations Automated eval framework for testing installer skills across frameworks and project states. diff --git a/scripts/npm-dist-smoke.ts b/scripts/npm-dist-smoke.ts new file mode 100644 index 00000000..3ba25c24 --- /dev/null +++ b/scripts/npm-dist-smoke.ts @@ -0,0 +1,277 @@ +// End-to-end smoke test for the npm distribution channel: publishes the +// generated packages from dist/npm/ to a throwaway local registry (Verdaccio) +// and drives the exact flows users run — `npx workos`, `npm install -g workos` +// — from a hermetic environment (fresh HOME, cache, and npm prefix; sanitized +// PATH). This covers what the in-repo launcher check cannot: real registry +// fetch, optionalDependencies platform selection, npx cache + bin linking, +// and the launcher's no-binary error path. +// +// The registry has NO uplinks, so any fetch beyond our own packages fails +// loudly — proving the install is self-contained. +// +// Prerequisites: dist/npm/ generated (bun run build + gen-npm-packages.ts); +// if absent but dist/workos exists, this script generates a host-only set. +// Requires node/npm/npx on PATH. Skipped on Windows (CI covers unix). +import { spawn, spawnSync, type ChildProcess } from 'node:child_process'; +import { + copyFileSync, + existsSync, + mkdirSync, + mkdtempSync, + readdirSync, + readFileSync, + rmSync, + symlinkSync, + writeFileSync, +} from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; + +if (process.platform === 'win32') { + console.log('npm-dist-smoke: skipped on Windows (covered by unix CI)'); + process.exit(0); +} + +const projectRoot = join(import.meta.dirname, '..'); +const npmDir = join(projectRoot, 'dist', 'npm'); + +function isMuslHost(): boolean { + if (process.platform !== 'linux') return false; + try { + if (readFileSync('/usr/bin/ldd', 'utf8').includes('musl')) return true; + } catch { + // No readable /usr/bin/ldd — fall through to the process report. + } + try { + const report = process.report?.getReport() as { header?: { glibcVersionRuntime?: string } } | undefined; + if (report?.header) return !report.header.glibcVersionRuntime; + } catch { + // Report unavailable — assume glibc. + } + return false; +} + +const hostKey = `${process.platform}-${process.arch}${isMuslHost() ? '-musl' : ''}`; +const hostAsset = `workos-${process.platform}-${process.arch}${isMuslHost() ? '-musl' : ''}`; + +// Convenience for local runs: generate a host-only package set from the +// compiled binary when dist/npm is absent. +if (!existsSync(join(npmDir, 'workos'))) { + const binary = join(projectRoot, 'dist', 'workos'); + if (!existsSync(binary)) { + console.error('npm-dist-smoke: dist/workos not found — run `bun run build` first'); + process.exit(1); + } + copyFileSync(binary, join(projectRoot, 'dist', hostAsset)); + const gen = spawnSync('bun', ['run', join(projectRoot, 'scripts', 'gen-npm-packages.ts')], { + stdio: 'inherit', + env: { ...process.env, WORKOS_NPM_ALLOW_MISSING: '1' }, + }); + if (gen.status !== 0) process.exit(gen.status ?? 1); +} + +const version = (JSON.parse(readFileSync(join(npmDir, 'workos', 'package.json'), 'utf8')) as { version: string }) + .version; +const platformPackageDirs = readdirSync(join(npmDir, '@workos')).map((name) => join(npmDir, '@workos', name)); +if (!existsSync(join(npmDir, '@workos', `cli-${hostKey}`))) { + console.error(`npm-dist-smoke: no package for this host (@workos/cli-${hostKey}) in dist/npm`); + process.exit(1); +} + +const root = mkdtempSync(join(tmpdir(), 'workos-npm-smoke-')); +const port = Number(process.env.WORKOS_SMOKE_REGISTRY_PORT) || 41000 + Math.floor(Math.random() * 8000); +const registry = `http://localhost:${port}`; +let verdaccio: ChildProcess | undefined; +let failed = false; + +function check(label: string, ok: boolean, detail?: string): void { + console.log(`${ok ? '✓' : '✗'} ${label}${detail ? ` — ${detail}` : ''}`); + if (!ok) failed = true; +} + +async function waitForRegistry(deadlineMs: number): Promise { + const deadline = Date.now() + deadlineMs; + while (Date.now() < deadline) { + try { + const response = await fetch(`${registry}/-/ping`, { signal: AbortSignal.timeout(2_000) }); + if (response.ok) return true; + } catch { + // Not up yet. + } + await new Promise((resolve) => setTimeout(resolve, 500)); + } + return false; +} + +try { + // A registry someone else is already running on this port would swallow our + // publishes — require the port to be free before we start our own. + if (await waitForRegistry(1)) { + console.error(`npm-dist-smoke: something is already listening on ${registry}; set WORKOS_SMOKE_REGISTRY_PORT`); + process.exit(1); + } + + writeFileSync( + join(root, 'verdaccio.yaml'), + [ + `storage: ${join(root, 'storage')}`, + 'auth:', + ' htpasswd:', + ` file: ${join(root, 'htpasswd')}`, + 'packages:', + " 'workos':", + ' access: $all', + ' publish: $authenticated', + " '@workos/*':", + ' access: $all', + ' publish: $authenticated', + // No '**' rule and no uplinks: anything beyond our packages 404s. + 'max_body_size: 300mb', + 'log: { type: stdout, format: pretty, level: warn }', + ].join('\n'), + ); + + verdaccio = spawn('bun', ['x', 'verdaccio@6', '--config', join(root, 'verdaccio.yaml'), '--listen', String(port)], { + stdio: ['ignore', 'ignore', 'inherit'], + }); + // First run may download verdaccio through bunx; allow for a cold cache. + if (!(await waitForRegistry(120_000))) { + console.error('npm-dist-smoke: local registry did not come up within 120s'); + process.exit(1); + } + + const userResponse = await fetch(`${registry}/-/user/org.couchdb.user:smoke`, { + method: 'PUT', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ name: 'smoke', password: 'smoke-test-password' }), + }); + const { token } = (await userResponse.json()) as { token?: string }; + if (!token) { + console.error('npm-dist-smoke: could not obtain a publish token from the local registry'); + process.exit(1); + } + const npmrc = join(root, 'npmrc'); + writeFileSync(npmrc, `//localhost:${port}/:_authToken=${token}\n`); + + // Platform packages before the launcher — same order as the release flow. + for (const dir of [...platformPackageDirs, join(npmDir, 'workos')]) { + const publish = spawnSync('npm', ['publish', '--registry', registry, '--access', 'public', '--userconfig', npmrc], { + cwd: dir, + encoding: 'utf8', + }); + check( + `publish ${dir.slice(npmDir.length + 1)}`, + publish.status === 0, + publish.status === 0 ? undefined : publish.stderr.trim().split('\n').at(-1), + ); + } + if (failed) process.exit(1); + + // Hermetic client environment. npx consults npm's global prefix bin and + // PATH for an existing `workos` before fetching (a brew-installed workos + // CLI hijacks it otherwise), so both are redirected to temp dirs that only + // contain node/npm/npx. + const home = join(root, 'home'); + const shimBin = join(root, 'shim-bin'); + mkdirSync(home, { recursive: true }); + mkdirSync(shimBin, { recursive: true }); + for (const tool of ['node', 'npm', 'npx']) { + const found = Bun.which(tool); + if (!found) { + console.error(`npm-dist-smoke: ${tool} not found on PATH`); + process.exit(1); + } + symlinkSync(found, join(shimBin, tool)); + } + + function clientEnv(prefix: string): Record { + return { + PATH: `${shimBin}:/usr/bin:/bin`, + HOME: home, + TMPDIR: join(root, 'tmp'), + npm_config_registry: registry, + npm_config_cache: join(root, 'npm-cache'), + npm_config_prefix: prefix, + npm_config_audit: 'false', + npm_config_fund: 'false', + npm_config_update_notifier: 'false', + WORKOS_TELEMETRY: 'false', + }; + } + + mkdirSync(join(root, 'tmp'), { recursive: true }); + const npxPrefix = join(root, 'npx-prefix'); + mkdirSync(npxPrefix, { recursive: true }); + + function run(args: string[], prefix: string): ReturnType> { + return spawnSync(args[0], args.slice(1), { cwd: home, encoding: 'utf8', env: clientEnv(prefix) }); + } + + const bareNpx = run(['npx', '--yes', 'workos', '--version'], npxPrefix); + check('npx workos --version', bareNpx.stdout.trim() === version, bareNpx.stdout.trim() || bareNpx.stderr.trim()); + + const pinnedNpx = run(['npx', '--yes', `workos@${version}`, '--version'], npxPrefix); + check(`npx workos@${version} --version`, pinnedNpx.stdout.trim() === version); + + const jsonRun = run(['npx', '--yes', 'workos', 'skills', 'list', '--json'], npxPrefix); + let jsonOk = false; + try { + JSON.parse(jsonRun.stdout.trim()); + jsonOk = jsonRun.status === 0; + } catch { + // Not JSON — fails below. + } + check( + 'npx workos skills list --json emits valid JSON', + jsonOk, + jsonOk ? undefined : jsonRun.stderr.trim().slice(0, 200), + ); + + const globalPrefix = join(root, 'global-prefix'); + mkdirSync(globalPrefix, { recursive: true }); + const globalInstall = run(['npm', 'install', '-g', 'workos'], globalPrefix); + check( + 'npm install -g workos', + globalInstall.status === 0, + globalInstall.status === 0 ? undefined : globalInstall.stderr.trim().split('\n').at(-1), + ); + const globalRun = run([join(globalPrefix, 'bin', 'workos'), '--version'], globalPrefix); + check('globally installed workos --version', globalRun.stdout.trim() === version); + + // npm nests a global package's deps inside it (lib/node_modules/workos/ + // node_modules/); newer versions may hoist to the prefix root — accept both. + const globalScopeDirs = [ + join(globalPrefix, 'lib', 'node_modules', '@workos'), + join(globalPrefix, 'lib', 'node_modules', 'workos', 'node_modules', '@workos'), + ]; + const installedPlatformPackages = globalScopeDirs.flatMap((dir) => (existsSync(dir) ? readdirSync(dir) : [])); + check( + `platform selection installed @workos/cli-${hostKey}`, + installedPlatformPackages.includes(`cli-${hostKey}`), + installedPlatformPackages.join(', ') || 'none installed', + ); + if (installedPlatformPackages.length > 1) { + // npm < 10.4 ignores the libc field and installs both linux flavors; the + // launcher still picks the right one, so this is informational only. + console.log(` note: ${installedPlatformPackages.length} platform packages installed (old npm ignores libc)`); + } + + // Simulate an unsupported platform deterministically: remove the installed + // platform package(s) and rerun the launcher — it must fail with the + // actionable "no prebuilt binary" message, not a raw resolution crash. + for (const dir of globalScopeDirs) rmSync(dir, { recursive: true, force: true }); + const errorRun = run([join(globalPrefix, 'bin', 'workos'), '--version'], globalPrefix); + check( + 'launcher fails helpfully when no platform binary is present', + errorRun.status === 1 && /no prebuilt binary/.test(errorRun.stderr), + `exit ${errorRun.status}`, + ); + + if (failed) process.exit(1); + console.log( + `\nnpm distribution smoke test passed: ${platformPackageDirs.length} platform package(s) + launcher v${version} (npx, pinned npx, JSON subcommand, global install, platform selection, no-binary error path)`, + ); +} finally { + verdaccio?.kill(); + rmSync(root, { recursive: true, force: true }); +} From ac363bdd930e7182e872c2ae1c61f83fe1e95c24 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 13:56:25 -0400 Subject: [PATCH 10/17] test: Smoke the command contract on every release binary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The smoke gates proved the binary starts (--version, --help, verify-assets) but nothing executed real subcommands and asserted the non-TTY contract that agents and CI pipelines script against: exit codes (0 success, 1 error, 4 auth required), structured JSON errors on stderr, and JSON output. Seven of the eight platform binaries never ran a user-facing command before shipping. command-smoke.sh is POSIX sh so the same checks run inside the --network none debian container on PRs, inside the Alpine containers for musl, under Git Bash on the Windows runners, and directly on the mac/linux legs — every release binary now executes the contract on native hardware before the draft release publishes. It sandboxes HOME/USERPROFILE and uses --insecure-storage so host auth state can never leak in, keeping the exit-4 assertion deterministic. --- .github/workflows/ci.yml | 14 +++--- .github/workflows/release.yml | 11 ++++- DEVELOPMENT.md | 13 +++++ scripts/command-smoke.sh | 93 +++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 scripts/command-smoke.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eeb9813f..ecddd6cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,19 +41,17 @@ jobs: WORKOS_BUILD_TARGET: bun-linux-x64-baseline run: bun run build - # Core commands must work standalone: no Bun, no Node.js, no - # node_modules, and no network. - - name: Smoke test without Bun, Node.js, node_modules, or network + # The full command contract (exit codes, structured JSON errors, JSON + # output — see scripts/command-smoke.sh) must hold standalone: no Bun, + # no Node.js, no node_modules, and no network. + - name: Smoke test command contract without Bun, Node.js, or network run: >- docker run --rm --network none --volume "${PWD}/dist/workos:/workos:ro" + --volume "${PWD}/scripts/command-smoke.sh:/command-smoke.sh:ro" --env HOME=/tmp/home debian:bookworm-slim - sh -eu -c - '/workos --help >/dev/null; - /workos auth status --json; - /workos api ls users --json >/dev/null; - /workos skills list --json >/dev/null' + sh /command-smoke.sh /workos # `internal verify-assets` performs the first-run download of the pinned # Agent SDK executable (checksum-verified) and spawns it, so a broken diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 910554f0..4a230f60 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -109,6 +109,12 @@ jobs: runner: windows-11-arm runs-on: ${{ matrix.runner }} steps: + # Checked out so the command-contract smoke script matches the tag + # whose binaries are under test. + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 7.0.0 + with: + ref: ${{ inputs.tag_name }} + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 8.0.1 with: name: ${{ matrix.asset }} @@ -136,6 +142,7 @@ jobs: "./${{ matrix.asset }}" --version "./${{ matrix.asset }}" --help >/dev/null "./${{ matrix.asset }}" internal verify-assets --json + sh ./scripts/command-smoke.sh "./${{ matrix.asset }}" # Bun musl builds dynamically link libstdc++/libgcc (same as Node's musl # builds) — install them like real Alpine users must. @@ -145,11 +152,13 @@ jobs: chmod +x "./${{ matrix.asset }}" docker run --rm \ --volume "${PWD}/${{ matrix.asset }}:/workos:ro" \ + --volume "${PWD}/scripts/command-smoke.sh:/command-smoke.sh:ro" \ --env HOME=/tmp/home \ alpine:3.22 \ sh -eu -c 'apk add --no-cache libstdc++ libgcc >/dev/null; /workos --version; /workos --help >/dev/null; - /workos internal verify-assets --json' + /workos internal verify-assets --json; + sh /command-smoke.sh /workos' publish: name: Publish release diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 1910d893..0c9353d2 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -219,6 +219,19 @@ bun run build bun run ./scripts/npm-dist-smoke.ts # generates a host-only dist/npm if absent ``` +**Smoke testing the command contract:** + +`scripts/command-smoke.sh` executes real commands against a compiled binary +and asserts the non-TTY contract: exit codes (0 success, 1 error, 4 auth +required), structured JSON errors on stderr, and JSON output. It is +offline-safe — CI runs it in a `--network none` container, and the release +pipeline runs it against every platform binary on native hardware. Locally: + +```bash +bun run build +sh scripts/command-smoke.sh ./dist/workos +``` + ## Evaluations Automated eval framework for testing installer skills across frameworks and project states. diff --git a/scripts/command-smoke.sh b/scripts/command-smoke.sh new file mode 100644 index 00000000..fa48f288 --- /dev/null +++ b/scripts/command-smoke.sh @@ -0,0 +1,93 @@ +#!/bin/sh +# Command-contract smoke for a compiled workos binary. +# +# Asserts the non-TTY contract documented in CLAUDE.md against real command +# executions: exit codes (0 success, 1 error, 4 auth required), structured +# JSON errors on stderr, and JSON output on stdout. Everything here is +# offline-safe — CI runs it inside a --network none container, and release +# smoke runs it on native hardware for every platform binary. Exit code 2 +# (cancelled) needs an interactive session and is covered by unit tests. +# +# POSIX sh only: this runs in debian-slim and Alpine containers (no bash) +# and under Git Bash on the Windows runners. +# +# Usage: sh command-smoke.sh /path/to/workos +set -u + +BIN="$1" +fails=0 + +pass() { echo " ok: $1"; } +fail() { + echo "FAIL: $1" + fails=$((fails + 1)) +} + +# Sandbox the config/home so host auth state can never leak in; the Windows +# binary reads USERPROFILE, which needs a Windows-style path under Git Bash. +SANDBOX=$(mktemp -d) +if command -v cygpath >/dev/null 2>&1; then + USERPROFILE=$(cygpath -w "$SANDBOX") +else + USERPROFILE="$SANDBOX" +fi +export USERPROFILE +export HOME="$SANDBOX" +export WORKOS_TELEMETRY=false +trap 'rm -rf "$SANDBOX"' EXIT + +out=$("$BIN" --version 2>/dev/null) +code=$? +if [ "$code" -eq 0 ] && [ -n "$out" ]; then pass "--version prints a version ($out)"; else fail "--version (exit $code)"; fi + +"$BIN" --help >/dev/null 2>&1 +code=$? +if [ "$code" -eq 0 ]; then pass "--help exits 0"; else fail "--help (exit $code)"; fi + +out=$("$BIN" auth status --json --insecure-storage 2>/dev/null) +code=$? +case "$out" in + *'"authenticated"'*) json_ok=1 ;; + *) json_ok=0 ;; +esac +if [ "$code" -eq 0 ] && [ "$json_ok" -eq 1 ]; then pass "auth status --json reports state, exit 0"; else fail "auth status --json (exit $code): $out"; fi + +out=$("$BIN" skills list --json 2>/dev/null) +code=$? +case "$out" in + '['* | '{'*) json_ok=1 ;; + *) json_ok=0 ;; +esac +if [ "$code" -eq 0 ] && [ "$json_ok" -eq 1 ]; then pass "skills list --json emits JSON, exit 0"; else fail "skills list --json (exit $code)"; fi + +out=$("$BIN" api ls users --json 2>/dev/null) +code=$? +case "$out" in + *'"data"'*) json_ok=1 ;; + *) json_ok=0 ;; +esac +if [ "$code" -eq 0 ] && [ "$json_ok" -eq 1 ]; then pass "api ls users --json lists endpoints from the embedded spec, exit 0"; else fail "api ls users --json (exit $code)"; fi + +# Auth-required commands must exit 4 with a structured JSON error on stderr — +# the contract agents and CI pipelines depend on (gh CLI convention). +err=$("$BIN" organization list --json --insecure-storage 2>&1 >/dev/null) +code=$? +case "$err" in + *'"error"'*'"code"'*) json_ok=1 ;; + *) json_ok=0 ;; +esac +if [ "$code" -eq 4 ] && [ "$json_ok" -eq 1 ]; then pass "unauthenticated organization list exits 4 with structured error"; else fail "organization list contract (exit $code, want 4): $err"; fi + +err=$("$BIN" definitely-not-a-command 2>&1 >/dev/null) +code=$? +case "$err" in + *'"error"'*) json_ok=1 ;; + *) json_ok=0 ;; +esac +if [ "$code" -eq 1 ] && [ "$json_ok" -eq 1 ]; then pass "unknown command exits 1 with structured error"; else fail "unknown command contract (exit $code, want 1): $err"; fi + +if [ "$fails" -gt 0 ]; then + echo "command-smoke: $fails check(s) failed" + exit 1 +fi +echo "command-smoke: all checks passed" From d59f91fc07ce39b85bdb3667f39fa5592460db8a Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 14:12:28 -0400 Subject: [PATCH 11/17] test: Add authenticated command smoke against staging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The smoke gates covered offline behavior only — no shipped binary ever executed a command that talks to the WorkOS API before release. With a dedicated staging-environment key the contract smoke now also runs an authenticated section: organization list plus a create → get → delete round-trip, exercising key resolution, real HTTP, and JSON output on the write path. The key is withheld from the offline checks so the exit-4 assertion stays deterministic, a cleanup trap deletes the round-trip org even when a mid-flight check fails, and the CI step skips itself when the WORKOS_SMOKE_API_KEY secret is absent — fork PRs receive no secrets, so this cannot fail there. --- .github/workflows/ci.yml | 14 ++++++++ DEVELOPMENT.md | 5 +++ scripts/command-smoke.sh | 71 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecddd6cc..1c1d42d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,6 +66,20 @@ jobs: sh -eu -c '/workos internal verify-assets --json' + # Authenticated command execution against a real WorkOS staging + # environment: list plus a create → get → delete round-trip. The secret + # is a dedicated staging-environment API key; fork PRs receive no + # secrets, so this skips there instead of failing. + - name: Smoke test authenticated commands + env: + WORKOS_API_KEY: ${{ secrets.WORKOS_SMOKE_API_KEY }} + run: | + if [ -z "$WORKOS_API_KEY" ]; then + echo "Skipped: WORKOS_SMOKE_API_KEY secret not available (fork PR or not yet configured)" + exit 0 + fi + sh scripts/command-smoke.sh ./dist/workos + # Publish the generated packages to a throwaway local registry and run # the real user flows — `npx workos`, `npm install -g workos`, platform # selection, and the launcher's no-binary error path — from a hermetic diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 0c9353d2..33ddd406 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -232,6 +232,11 @@ bun run build sh scripts/command-smoke.sh ./dist/workos ``` +With `WORKOS_API_KEY` set to a staging-environment key, it also runs an +authenticated section (organization list + create → get → delete round-trip). +CI provides this via the `WORKOS_SMOKE_API_KEY` repository secret; fork PRs +receive no secrets and skip it. + ## Evaluations Automated eval framework for testing installer skills across frameworks and project states. diff --git a/scripts/command-smoke.sh b/scripts/command-smoke.sh index fa48f288..a744f754 100644 --- a/scripts/command-smoke.sh +++ b/scripts/command-smoke.sh @@ -11,7 +11,13 @@ # POSIX sh only: this runs in debian-slim and Alpine containers (no bash) # and under Git Bash on the Windows runners. # -# Usage: sh command-smoke.sh /path/to/workos +# When WORKOS_API_KEY is provided, an authenticated section also runs: list +# plus a create → get → delete round-trip against that environment. CI passes +# a dedicated staging-environment key; fork PRs receive no secrets and skip +# it. The offline contract checks always run with the key withheld, so the +# exit-4 assertion stays deterministic. +# +# Usage: [WORKOS_API_KEY=sk_...] sh command-smoke.sh /path/to/workos set -u BIN="$1" @@ -34,7 +40,23 @@ fi export USERPROFILE export HOME="$SANDBOX" export WORKOS_TELEMETRY=false -trap 'rm -rf "$SANDBOX"' EXIT + +# Withhold the key from the offline contract checks; the authenticated +# section reinjects it per command. +SMOKE_API_KEY="${WORKOS_API_KEY:-}" +unset WORKOS_API_KEY + +ORG_ID="" +org_deleted=1 +cleanup() { + # Never orphan the round-trip organization in the shared staging + # environment, even when a check between create and delete fails. + if [ -n "$ORG_ID" ] && [ "$org_deleted" -eq 0 ]; then + WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization delete "$ORG_ID" --insecure-storage >/dev/null 2>&1 || true + fi + rm -rf "$SANDBOX" +} +trap cleanup EXIT out=$("$BIN" --version 2>/dev/null) code=$? @@ -86,6 +108,51 @@ case "$err" in esac if [ "$code" -eq 1 ] && [ "$json_ok" -eq 1 ]; then pass "unknown command exits 1 with structured error"; else fail "unknown command contract (exit $code, want 1): $err"; fi +# ---- Authenticated commands (opt-in via WORKOS_API_KEY) ---- +if [ -n "$SMOKE_API_KEY" ]; then + out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization list --json --insecure-storage 2>/dev/null) + code=$? + case "$out" in + *'"data"'*) json_ok=1 ;; + *) json_ok=0 ;; + esac + if [ "$code" -eq 0 ] && [ "$json_ok" -eq 1 ]; then pass "authenticated organization list exits 0 with data"; else fail "authenticated organization list (exit $code)"; fi + + ORG_NAME="cli-smoke-$$-$(date +%s)" + out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization create "$ORG_NAME" --json --insecure-storage 2>/dev/null) + code=$? + # Org ids are org_; the closing-quote anchor keeps nested + # org_domain_* ids from matching. + ORG_ID=$(printf '%s' "$out" | sed -n 's/.*"id":"\(org_[A-Za-z0-9]*\)".*/\1/p') + if [ "$code" -eq 0 ] && [ -n "$ORG_ID" ]; then + org_deleted=0 + pass "organization create returns an id ($ORG_ID)" + else + fail "organization create (exit $code): $out" + fi + + if [ -n "$ORG_ID" ]; then + out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization get "$ORG_ID" --json --insecure-storage 2>/dev/null) + code=$? + case "$out" in + *"$ORG_NAME"*) json_ok=1 ;; + *) json_ok=0 ;; + esac + if [ "$code" -eq 0 ] && [ "$json_ok" -eq 1 ]; then pass "organization get returns the created organization"; else fail "organization get (exit $code)"; fi + + WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization delete "$ORG_ID" --json --insecure-storage >/dev/null 2>&1 + code=$? + if [ "$code" -eq 0 ]; then + org_deleted=1 + pass "organization delete cleans up" + else + fail "organization delete (exit $code) — cleanup trap will retry" + fi + fi +else + echo " (authenticated checks skipped: WORKOS_API_KEY not set)" +fi + if [ "$fails" -gt 0 ]; then echo "command-smoke: $fails check(s) failed" exit 1 From f9ccfd0818da9a36d9d0ef71eeb62f0473ec5dca Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 14:51:21 -0400 Subject: [PATCH 12/17] test: Surface API errors in the authenticated smoke and allow a staging API URL The authenticated section discarded stderr, so a CI failure showed exit codes with no cause. The CLI's structured errors are key-free by design (keys are masked in all output), so printing them is safe and turns a blind failure into a diagnosis. WORKOS_SMOKE_API_URL lets the smoke key target a non-default API host, guarded so an unset secret cannot inject an empty WORKOS_API_URL. --- .github/workflows/ci.yml | 6 ++++++ scripts/command-smoke.sh | 13 ++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c1d42d0..e6d3e236 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,11 +73,17 @@ jobs: - name: Smoke test authenticated commands env: WORKOS_API_KEY: ${{ secrets.WORKOS_SMOKE_API_KEY }} + # Optional: set when the smoke key belongs to a non-default API host + # (e.g. an internal staging deployment). + WORKOS_SMOKE_API_URL: ${{ secrets.WORKOS_SMOKE_API_URL }} run: | if [ -z "$WORKOS_API_KEY" ]; then echo "Skipped: WORKOS_SMOKE_API_KEY secret not available (fork PR or not yet configured)" exit 0 fi + if [ -n "$WORKOS_SMOKE_API_URL" ]; then + export WORKOS_API_URL="$WORKOS_SMOKE_API_URL" + fi sh scripts/command-smoke.sh ./dist/workos # Publish the generated packages to a throwaway local registry and run diff --git a/scripts/command-smoke.sh b/scripts/command-smoke.sh index a744f754..0f5cb640 100644 --- a/scripts/command-smoke.sh +++ b/scripts/command-smoke.sh @@ -110,16 +110,19 @@ if [ "$code" -eq 1 ] && [ "$json_ok" -eq 1 ]; then pass "unknown command exits 1 # ---- Authenticated commands (opt-in via WORKOS_API_KEY) ---- if [ -n "$SMOKE_API_KEY" ]; then - out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization list --json --insecure-storage 2>/dev/null) + # On failure, surface the CLI's structured stderr error — it never + # contains key material (keys are masked in all output). + err_file="$SANDBOX/stderr" + out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization list --json --insecure-storage 2>"$err_file") code=$? case "$out" in *'"data"'*) json_ok=1 ;; *) json_ok=0 ;; esac - if [ "$code" -eq 0 ] && [ "$json_ok" -eq 1 ]; then pass "authenticated organization list exits 0 with data"; else fail "authenticated organization list (exit $code)"; fi + if [ "$code" -eq 0 ] && [ "$json_ok" -eq 1 ]; then pass "authenticated organization list exits 0 with data"; else fail "authenticated organization list (exit $code): $(cat "$err_file")"; fi ORG_NAME="cli-smoke-$$-$(date +%s)" - out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization create "$ORG_NAME" --json --insecure-storage 2>/dev/null) + out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization create "$ORG_NAME" --json --insecure-storage 2>"$err_file") code=$? # Org ids are org_; the closing-quote anchor keeps nested # org_domain_* ids from matching. @@ -128,11 +131,11 @@ if [ -n "$SMOKE_API_KEY" ]; then org_deleted=0 pass "organization create returns an id ($ORG_ID)" else - fail "organization create (exit $code): $out" + fail "organization create (exit $code): $out $(cat "$err_file")" fi if [ -n "$ORG_ID" ]; then - out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization get "$ORG_ID" --json --insecure-storage 2>/dev/null) + out=$(WORKOS_API_KEY="$SMOKE_API_KEY" "$BIN" organization get "$ORG_ID" --json --insecure-storage 2>"$err_file") code=$? case "$out" in *"$ORG_NAME"*) json_ok=1 ;; From 3166781dffe171578cc626069948c84d820f512e Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 17:46:14 -0400 Subject: [PATCH 13/17] fix: Treat malformed stored credentials as logged out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A keyring or file blob missing the required token fields — left by a partial write or an older schema — was returned as-is by getCredentials(). Consumers assume accessToken/expiresAt/userId exist, so `new Date(undefined).toISOString()` threw on every authenticated command AND on auth status, bricking the CLI until the entry was deleted by hand. Found on a real machine while smoke testing this branch: the entry held only the staging sub-object. The bug predates the Bun migration (main has the same code), but the binary upgrade makes stale keyring entries a mainstream path, so validate required fields at both read sites and degrade to "not logged in — run workos auth login", which also overwrites the bad entry on the next login. Malformed file blobs are no longer migrated into the keyring either. --- src/lib/credential-store.spec.ts | 26 ++++++++++++++++++++++++++ src/lib/credential-store.ts | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/lib/credential-store.spec.ts b/src/lib/credential-store.spec.ts index cff20764..c7b6b9c2 100644 --- a/src/lib/credential-store.spec.ts +++ b/src/lib/credential-store.spec.ts @@ -164,6 +164,32 @@ describe('credential-store', () => { }); }); + describe('malformed stored credentials read as logged out', () => { + // A partial write or older schema can leave a blob without the required + // token fields; returning it would crash every authenticated command + // (new Date(undefined).toISOString() throws), bricking the CLI. + it('keyring blob missing required fields returns null', () => { + mockKeyring.set( + 'workos-cli:credentials', + JSON.stringify({ staging: { clientId: 'client_x', apiKey: 'sk_x', fetchedAt: Date.now() } }), + ); + expect(getCredentials()).toBeNull(); + expect(hasCredentials()).toBe(false); + }); + + it('keyring blob with non-numeric expiresAt returns null', () => { + mockKeyring.set('workos-cli:credentials', JSON.stringify({ ...validCreds, expiresAt: 'not-a-timestamp' })); + expect(getCredentials()).toBeNull(); + }); + + it('malformed file blob returns null and is not migrated to keyring', () => { + mkdirSync(installerDir, { recursive: true }); + writeFileSync(credentialsFile, JSON.stringify({ userId: 'user_abc' })); + expect(getCredentials()).toBeNull(); + expect(mockKeyring.has('workos-cli:credentials')).toBe(false); + }); + }); + describe('file fallback (keyring unavailable)', () => { beforeEach(() => { keyringAvailable = false; diff --git a/src/lib/credential-store.ts b/src/lib/credential-store.ts index af4dd5e6..ca68490c 100644 --- a/src/lib/credential-store.ts +++ b/src/lib/credential-store.ts @@ -28,6 +28,24 @@ export interface Credentials { refreshToken?: string; } +/** + * A stored blob missing required fields (partial write, older schema) must + * read as logged-out: consumers assume accessToken/expiresAt/userId exist, + * and an invalid object otherwise crashes every authenticated command — + * `new Date(undefined).toISOString()` throws — bricking the CLI until the + * entry is manually deleted. + */ +function isValidCredentials(value: unknown): value is Credentials { + const creds = value as Credentials | null; + return ( + typeof creds === 'object' && + creds !== null && + typeof creds.accessToken === 'string' && + Number.isFinite(creds.expiresAt) && + typeof creds.userId === 'string' + ); +} + const SERVICE_NAME = 'workos-cli'; const ACCOUNT_NAME = 'credentials'; @@ -57,7 +75,12 @@ function readFromFile(): Credentials | null { const filePath = getCredentialsPath(); try { const content = fs.readFileSync(filePath, 'utf-8'); - return JSON.parse(content); + const parsed: unknown = JSON.parse(content); + if (!isValidCredentials(parsed)) { + logWarn('[credential-store] file: stored credentials are missing required fields; treating as logged out'); + return null; + } + return parsed; } catch (error) { observeHostFailure('home-fs', error, { operation: 'read', @@ -117,7 +140,12 @@ function readFromKeyring(): Credentials | null { logWarn('[credential-store] keyring: entry exists but data is null/empty'); return null; } - return JSON.parse(data); + const parsed: unknown = JSON.parse(data); + if (!isValidCredentials(parsed)) { + logWarn('[credential-store] keyring: stored credentials are missing required fields; treating as logged out'); + return null; + } + return parsed; } catch (error) { const msg = error instanceof Error ? error.message : String(error); logWarn(`[credential-store] keyring read failed: ${msg}`); From 054ba88846ce1f47945e65b428b0f5771fb624fa Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 18:26:35 -0400 Subject: [PATCH 14/17] fix: Report declined installs honestly to machine consumers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the version gate refused an install (Next.js < 15.3, React Router < 6), the integration returned an empty summary, which the runAgent wrapper mapped to success:true — so agents and CI scripting `workos install --json` saw "Successfully installed WorkOS AuthKit!" with exit 0 while nothing was installed. Found by running the compiled binary against the bundled Next.js 14 fixture. Gates now throw InstallDeclinedError, which rides the machine's existing error path: exit 1, a structured stderr error and NDJSON error/complete events carrying unsupported_framework_version, while the human flow keeps its friendly guidance (adapters recognize the decline code and skip the generic failure styling and AI-service message rewrites). --- src/commands/install.spec.ts | 26 +++++++++++ src/commands/install.ts | 10 ++++ src/integrations/nextjs/index.ts | 10 ++-- src/integrations/react-router/index.ts | 10 ++-- src/integrations/version-gate.spec.ts | 56 +++++++++++++++++++++++ src/lib/adapters/cli-adapter.ts | 9 +++- src/lib/adapters/headless-adapter.spec.ts | 19 ++++++++ src/lib/adapters/headless-adapter.ts | 9 ++-- src/lib/events.ts | 3 +- src/lib/installer-core.ts | 12 ++++- src/lib/installer-errors.ts | 16 +++++++ 11 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 src/integrations/version-gate.spec.ts create mode 100644 src/lib/installer-errors.ts diff --git a/src/commands/install.spec.ts b/src/commands/install.spec.ts index b686bd90..2aebadbc 100644 --- a/src/commands/install.spec.ts +++ b/src/commands/install.spec.ts @@ -132,6 +132,32 @@ describe('handleInstall', () => { expect(autoInstallSkills).toHaveBeenCalledOnce(); }); + describe('declined installs (e.g. unsupported framework version)', () => { + it('carries the structured decline code in JSON mode and exits non-zero', async () => { + const { InstallDeclinedError } = await import('../lib/installer-errors.js'); + vi.mocked(runInstaller).mockRejectedValue(new InstallDeclinedError('Next.js 14 is unsupported')); + vi.mocked(isJsonMode).mockReturnValue(true); + + await expect(handleInstall({ _: ['install'], $0: 'workos' } as any)).rejects.toThrow(CliExit); + + expect(exitWithError).toHaveBeenCalledWith({ + code: 'unsupported_framework_version', + message: 'Next.js 14 is unsupported', + }); + }); + + it('exits non-zero without extra output in human mode (guidance already printed)', async () => { + const { InstallDeclinedError } = await import('../lib/installer-errors.js'); + vi.mocked(runInstaller).mockRejectedValue(new InstallDeclinedError('Next.js 14 is unsupported')); + vi.mocked(isJsonMode).mockReturnValue(false); + + await expect(handleInstall({ _: ['install'], $0: 'workos' } as any)).rejects.toThrow(CliExit); + + expect(exitWithError).not.toHaveBeenCalled(); + expect(clack.log.info).not.toHaveBeenCalled(); + }); + }); + describe('CI-mode required-arg validation', () => { it('WORKOS_MODE=ci requires --api-key (validation triggered without the --ci flag)', async () => { vi.mocked(runInstaller).mockResolvedValue(undefined as any); diff --git a/src/commands/install.ts b/src/commands/install.ts index 8e4eb75f..dfeba801 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -6,6 +6,7 @@ import { ExitCode, exitWithCode } from '../utils/exit-codes.js'; import { isCiMode } from '../utils/interaction-mode.js'; import type { ArgumentsCamelCase } from 'yargs'; import { autoInstallSkills } from './install-skill.js'; +import { InstallDeclinedError } from '../lib/installer-errors.js'; import { maybeOfferMcpInstall } from '../lib/mcp-notice.js'; /** @@ -44,6 +45,15 @@ export async function handleInstall(argv: ArgumentsCamelCase): Pr // (human/TTY-only, decline-respecting) and best-effort — never fails install. await maybeOfferMcpInstall({ entryPoint: 'install-flow' }); } catch (err) { + if (err instanceof InstallDeclinedError) { + // The integration already printed actionable guidance; exit non-zero + // so scripts don't proceed as if AuthKit were installed. + if (isJsonMode()) { + exitWithError({ code: err.code, message: err.message }); + } + exitWithCode(ExitCode.GENERAL_ERROR); + } + const { getLogFilePath } = await import('../utils/debug.js'); const logPath = getLogFilePath(); diff --git a/src/integrations/nextjs/index.ts b/src/integrations/nextjs/index.ts index d7d9179e..d4cf5ee8 100644 --- a/src/integrations/nextjs/index.ts +++ b/src/integrations/nextjs/index.ts @@ -4,6 +4,7 @@ import type { InstallerOptions } from '../../utils/types.js'; import { enableDebugLogs } from '../../utils/debug.js'; import { getPackageVersion } from '../../utils/package-json.js'; import { getPackageDotJson } from '../../utils/clack-utils.js'; +import { InstallDeclinedError } from '../../lib/installer-errors.js'; import clack from '../../utils/clack.js'; import chalk from 'chalk'; import * as semver from 'semver'; @@ -96,12 +97,13 @@ export async function run(options: InstallerOptions): Promise { if (coercedVersion && semver.lt(coercedVersion, MINIMUM_NEXTJS_VERSION)) { const docsUrl = config.metadata.unsupportedVersionDocsUrl ?? config.metadata.docsUrl; - clack.log.warn( - `Sorry: the installer can't help you with Next.js ${nextVersion}. Upgrade to Next.js ${MINIMUM_NEXTJS_VERSION} or later, or check out the manual setup guide.`, - ); + const message = `Sorry: the installer can't help you with Next.js ${nextVersion}. Upgrade to Next.js ${MINIMUM_NEXTJS_VERSION} or later, or check out the manual setup guide.`; + clack.log.warn(message); clack.log.info(`Setup Next.js manually: ${chalk.cyan(docsUrl)}`); clack.outro('WorkOS AuthKit installer will see you next time!'); - return ''; + // Returning normally here used to surface as "Successfully installed" + // with exit 0 — machine consumers must see a decline, not a success. + throw new InstallDeclinedError(message); } } diff --git a/src/integrations/react-router/index.ts b/src/integrations/react-router/index.ts index 6423e3a6..af8e84b4 100644 --- a/src/integrations/react-router/index.ts +++ b/src/integrations/react-router/index.ts @@ -4,6 +4,7 @@ import type { InstallerOptions } from '../../utils/types.js'; import { enableDebugLogs } from '../../utils/debug.js'; import { getPackageVersion } from '../../utils/package-json.js'; import { getPackageDotJson } from '../../utils/clack-utils.js'; +import { InstallDeclinedError } from '../../lib/installer-errors.js'; import clack from '../../utils/clack.js'; import chalk from 'chalk'; import * as semver from 'semver'; @@ -99,12 +100,13 @@ export async function run(options: InstallerOptions): Promise { if (coercedVersion && semver.lt(coercedVersion, MINIMUM_REACT_ROUTER_VERSION)) { const docsUrl = config.metadata.unsupportedVersionDocsUrl ?? config.metadata.docsUrl; - clack.log.warn( - `Sorry: the installer can't help you with React Router ${reactRouterVersion}. Upgrade to React Router ${MINIMUM_REACT_ROUTER_VERSION} or later, or check out the manual setup guide.`, - ); + const message = `Sorry: the installer can't help you with React Router ${reactRouterVersion}. Upgrade to React Router ${MINIMUM_REACT_ROUTER_VERSION} or later, or check out the manual setup guide.`; + clack.log.warn(message); clack.log.info(`Setup React Router manually: ${chalk.cyan(docsUrl)}`); clack.outro('WorkOS AuthKit installer will see you next time!'); - return ''; + // Returning normally here used to surface as "Successfully installed" + // with exit 0 — machine consumers must see a decline, not a success. + throw new InstallDeclinedError(message); } } diff --git a/src/integrations/version-gate.spec.ts b/src/integrations/version-gate.spec.ts new file mode 100644 index 00000000..9ef632d4 --- /dev/null +++ b/src/integrations/version-gate.spec.ts @@ -0,0 +1,56 @@ +import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import type { InstallerOptions } from '../utils/types.js'; +import { InstallDeclinedError } from '../lib/installer-errors.js'; + +vi.mock('../utils/clack.js', () => ({ + default: { + log: { warn: vi.fn(), info: vi.fn(), error: vi.fn() }, + outro: vi.fn(), + }, +})); + +vi.mock('../lib/agent-runner.js', () => ({ + runAgentInstaller: vi.fn(async () => 'agent summary'), +})); + +const { run: runNextjs } = await import('./nextjs/index.js'); +const { run: runReactRouter } = await import('./react-router/index.js'); + +// A declined install must throw (not return a summary): a normal return used +// to surface as "Successfully installed" with exit 0 to machine consumers. +describe('unsupported framework versions decline the install', () => { + let dir: string; + + beforeEach(() => { + dir = mkdtempSync(join(tmpdir(), 'version-gate-')); + }); + + afterEach(() => { + rmSync(dir, { recursive: true, force: true }); + }); + + function options(): InstallerOptions { + return { installDir: dir } as InstallerOptions; + } + + it('nextjs below the minimum throws InstallDeclinedError', async () => { + writeFileSync(join(dir, 'package.json'), JSON.stringify({ dependencies: { next: '^14.2.0' } })); + await expect(runNextjs(options())).rejects.toMatchObject({ + name: 'InstallDeclinedError', + code: 'unsupported_framework_version', + }); + }); + + it('react-router below the minimum throws InstallDeclinedError', async () => { + writeFileSync(join(dir, 'package.json'), JSON.stringify({ dependencies: { 'react-router': '^5.3.0' } })); + await expect(runReactRouter(options())).rejects.toBeInstanceOf(InstallDeclinedError); + }); + + it('a supported nextjs version proceeds to the agent runner', async () => { + writeFileSync(join(dir, 'package.json'), JSON.stringify({ dependencies: { next: '^15.3.0' } })); + await expect(runNextjs(options())).resolves.toBe('agent summary'); + }); +}); diff --git a/src/lib/adapters/cli-adapter.ts b/src/lib/adapters/cli-adapter.ts index 935b41c3..523fd3f6 100644 --- a/src/lib/adapters/cli-adapter.ts +++ b/src/lib/adapters/cli-adapter.ts @@ -449,7 +449,14 @@ export class CLIAdapter implements InstallerAdapter { } }; - private handleError = ({ message, stack }: InstallerEvents['error']): void => { + private handleError = ({ message, stack, code }: InstallerEvents['error']): void => { + // A structured decline (e.g. unsupported framework version) already + // printed its guidance via the integration — don't restyle it as a + // generic failure. + if (code) { + this.stopSpinner('Installation skipped'); + return; + } this.stopSpinner('Error'); // Rewrite raw API/SDK errors into user-friendly messages diff --git a/src/lib/adapters/headless-adapter.spec.ts b/src/lib/adapters/headless-adapter.spec.ts index ec1c2e6f..d2596519 100644 --- a/src/lib/adapters/headless-adapter.spec.ts +++ b/src/lib/adapters/headless-adapter.spec.ts @@ -455,6 +455,25 @@ describe('HeadlessAdapter', () => { }); await adapter.stop(); }); + + it('passes a structured decline code through without rewriting the message', async () => { + const adapter = createAdapter(); + await adapter.start(); + + // "internal_error"-style pattern words in the message must not trigger + // the AI-service rewrites when the emitter supplied a code. + emitter.emit('error', { + message: 'Sorry: the installer cannot help with this framework version.', + code: 'unsupported_framework_version', + }); + + expect(mockWriteNDJSON).toHaveBeenCalledWith({ + type: 'error', + code: 'unsupported_framework_version', + message: 'Sorry: the installer cannot help with this framework version.', + }); + await adapter.stop(); + }); }); describe('staging events', () => { diff --git a/src/lib/adapters/headless-adapter.ts b/src/lib/adapters/headless-adapter.ts index fe07c3dd..0de00ffd 100644 --- a/src/lib/adapters/headless-adapter.ts +++ b/src/lib/adapters/headless-adapter.ts @@ -411,17 +411,20 @@ export class HeadlessAdapter implements InstallerAdapter { }); }; - private handleError = ({ message, stack }: InstallerEvents['error']): void => { + private handleError = ({ message, stack, code: declineCode }: InstallerEvents['error']): void => { const isServiceError = /\b50[0-9]\b/.test(message) || /server_error|internal_error|overloaded|service.*unavailable/i.test(message); const isRateLimit = /\b429\b/.test(message) || /rate.limit/i.test(message); const isNetworkError = /ECONNREFUSED|ETIMEDOUT|ENOTFOUND|fetch failed/i.test(message); const isProcessExit = /process exited with code/i.test(message); - let code = 'installer_error'; + let code = declineCode ?? 'installer_error'; let displayMessage = message; - if (isServiceError) { + if (declineCode) { + // A structured decline (e.g. unsupported framework version) is already + // user-facing — don't rewrite it as an AI-service failure. + } else if (isServiceError) { code = 'service_unavailable'; displayMessage = 'The AI service is temporarily unavailable. Please try again in a few minutes.'; } else if (isRateLimit) { diff --git a/src/lib/events.ts b/src/lib/events.ts index 86358e17..bb28d476 100644 --- a/src/lib/events.ts +++ b/src/lib/events.ts @@ -39,7 +39,8 @@ export interface InstallerEvents { 'credentials:request': { requiresApiKey: boolean }; 'credentials:response': { apiKey: string; clientId: string }; complete: { success: boolean; summary?: string; completion?: CompletionData }; - error: { message: string; stack?: string }; + /** `code` is set for structured declines (e.g. unsupported framework version); absent for unexpected failures. */ + error: { message: string; stack?: string; code?: string }; 'state:enter': { state: string }; 'state:exit': { state: string }; diff --git a/src/lib/installer-core.ts b/src/lib/installer-core.ts index 59d97d34..948ac27f 100644 --- a/src/lib/installer-core.ts +++ b/src/lib/installer-core.ts @@ -16,6 +16,7 @@ import type { InstallerOptions } from '../utils/types.js'; import type { CompletionData } from './events.js'; import type { DeviceAuthResult, DeviceAuthResponse } from './device-auth.js'; import type { StagingCredentials } from './staging-api.js'; +import { InstallDeclinedError } from './installer-errors.js'; import { getManualPrInstructions } from './post-install.js'; import { hasGhCli } from '../utils/git-utils.js'; import { formatWorkOSCommand } from '../utils/command-invocation.js'; @@ -234,8 +235,15 @@ export const installerMachine = setup({ }, emitError: ({ context }) => { const message = context.error?.message ?? 'An unexpected error occurred'; - context.emitter.emit('error', { message, stack: context.error?.stack }); - context.emitter.emit('complete', { success: false }); + // Declines carry a structured code so machine consumers can tell "we + // refused to install" apart from unexpected failures. + const declineCode = context.error instanceof InstallDeclinedError ? context.error.code : undefined; + context.emitter.emit('error', { + message, + stack: context.error?.stack, + ...(declineCode ? { code: declineCode } : {}), + }); + context.emitter.emit('complete', { success: false, ...(declineCode ? { summary: message } : {}) }); }, // Post-install actions assignChangedFiles: assign({ diff --git a/src/lib/installer-errors.ts b/src/lib/installer-errors.ts new file mode 100644 index 00000000..c71e4273 --- /dev/null +++ b/src/lib/installer-errors.ts @@ -0,0 +1,16 @@ +/** + * A deliberate, user-facing refusal to install (e.g. unsupported framework + * version). Routed through the installer's error path so machine consumers + * get a non-zero exit with a structured code, while adapters and the install + * command recognize it as a decline: the integration has already printed + * actionable guidance, so no generic failure output is layered on top. + */ +export class InstallDeclinedError extends Error { + readonly code: string; + + constructor(message: string, code = 'unsupported_framework_version') { + super(message); + this.name = 'InstallDeclinedError'; + this.code = code; + } +} From 6618f4caca3a8e31c8fdcbf3d41dd039c5c63547 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Mon, 20 Jul 2026 18:26:36 -0400 Subject: [PATCH 15/17] test: Bump the Next.js fixture above the installer minimum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The typescript-strict fixture pinned Next.js ^14.2.0 while the installer's own version gate requires >= 15.3.0, so the bundled fixture could never exercise the agent path — every eval or manual run against it hit the gate instead. Next 15 pairs with React 19, whose types drop the global JSX namespace, so the annotations move to ReactElement. Verified with tsc --noEmit and next build. --- .../nextjs/typescript-strict/app/about/page.tsx | 4 +++- .../nextjs/typescript-strict/app/dashboard/page.tsx | 4 +++- tests/fixtures/nextjs/typescript-strict/app/layout.tsx | 4 ++-- tests/fixtures/nextjs/typescript-strict/app/page.tsx | 4 +++- tests/fixtures/nextjs/typescript-strict/package.json | 10 +++++----- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/fixtures/nextjs/typescript-strict/app/about/page.tsx b/tests/fixtures/nextjs/typescript-strict/app/about/page.tsx index 8c5a9cf9..da666360 100644 --- a/tests/fixtures/nextjs/typescript-strict/app/about/page.tsx +++ b/tests/fixtures/nextjs/typescript-strict/app/about/page.tsx @@ -1,4 +1,6 @@ -export default function About(): JSX.Element { +import type { ReactElement } from 'react'; + +export default function About(): ReactElement { return (

About

diff --git a/tests/fixtures/nextjs/typescript-strict/app/dashboard/page.tsx b/tests/fixtures/nextjs/typescript-strict/app/dashboard/page.tsx index a0765233..c8d6b631 100644 --- a/tests/fixtures/nextjs/typescript-strict/app/dashboard/page.tsx +++ b/tests/fixtures/nextjs/typescript-strict/app/dashboard/page.tsx @@ -1,4 +1,6 @@ -export default function Dashboard(): JSX.Element { +import type { ReactElement } from 'react'; + +export default function Dashboard(): ReactElement { return (

Dashboard

diff --git a/tests/fixtures/nextjs/typescript-strict/app/layout.tsx b/tests/fixtures/nextjs/typescript-strict/app/layout.tsx index 8ddc7296..1a039f76 100644 --- a/tests/fixtures/nextjs/typescript-strict/app/layout.tsx +++ b/tests/fixtures/nextjs/typescript-strict/app/layout.tsx @@ -1,11 +1,11 @@ import Link from 'next/link'; -import type { ReactNode } from 'react'; +import type { ReactElement, ReactNode } from 'react'; interface RootLayoutProps { children: ReactNode; } -export default function RootLayout({ children }: RootLayoutProps): JSX.Element { +export default function RootLayout({ children }: RootLayoutProps): ReactElement { return ( diff --git a/tests/fixtures/nextjs/typescript-strict/app/page.tsx b/tests/fixtures/nextjs/typescript-strict/app/page.tsx index 4d9dda50..59358a09 100644 --- a/tests/fixtures/nextjs/typescript-strict/app/page.tsx +++ b/tests/fixtures/nextjs/typescript-strict/app/page.tsx @@ -1,4 +1,6 @@ -export default function Home(): JSX.Element { +import type { ReactElement } from 'react'; + +export default function Home(): ReactElement { return (

Home

diff --git a/tests/fixtures/nextjs/typescript-strict/package.json b/tests/fixtures/nextjs/typescript-strict/package.json index 2899353c..21fdf406 100644 --- a/tests/fixtures/nextjs/typescript-strict/package.json +++ b/tests/fixtures/nextjs/typescript-strict/package.json @@ -8,14 +8,14 @@ "start": "next start" }, "dependencies": { - "next": "^14.2.0", - "react": "^18.3.0", - "react-dom": "^18.3.0" + "next": "^15.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" }, "devDependencies": { "@types/node": "^20.0.0", - "@types/react": "^18.3.0", - "@types/react-dom": "^18.3.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "typescript": "^5.4.0" } } From 7e21e24ea38d8794df503d794a25c979d702b55a Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 21 Jul 2026 17:38:56 -0400 Subject: [PATCH 16/17] fix: Validate stored blobs in hasCredentials The recent malformed-credentials fix made getCredentials() return null for a blob missing required token fields, but hasCredentials() still reported true from a bare file/entry probe. A caller that gated on hasCredentials() alone would treat a malformed blob as logged-in and then hit the very null the fix was meant to prevent. Validating at both read sites keeps the two functions from ever disagreeing, without triggering getCredentials()'s keyring migration as a side effect of a boolean check. --- src/lib/credential-store.spec.ts | 11 +++++++++++ src/lib/credential-store.ts | 8 ++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lib/credential-store.spec.ts b/src/lib/credential-store.spec.ts index c7b6b9c2..dac61d03 100644 --- a/src/lib/credential-store.spec.ts +++ b/src/lib/credential-store.spec.ts @@ -186,8 +186,19 @@ describe('credential-store', () => { mkdirSync(installerDir, { recursive: true }); writeFileSync(credentialsFile, JSON.stringify({ userId: 'user_abc' })); expect(getCredentials()).toBeNull(); + // hasCredentials must agree with getCredentials — a present-but-malformed + // file is logged-out, not "has credentials". + expect(hasCredentials()).toBe(false); expect(mockKeyring.has('workos-cli:credentials')).toBe(false); }); + + it('malformed file blob reads as logged out under --insecure-storage too', () => { + setInsecureStorage(true); + mkdirSync(installerDir, { recursive: true }); + writeFileSync(credentialsFile, JSON.stringify({ userId: 'user_abc' })); + expect(getCredentials()).toBeNull(); + expect(hasCredentials()).toBe(false); + }); }); describe('file fallback (keyring unavailable)', () => { diff --git a/src/lib/credential-store.ts b/src/lib/credential-store.ts index ca68490c..ed32d849 100644 --- a/src/lib/credential-store.ts +++ b/src/lib/credential-store.ts @@ -203,10 +203,14 @@ function showFallbackWarning(): void { } export function hasCredentials(): boolean { + // Validate rather than just probing for a file/entry: a malformed blob must + // read as logged-out here too, so this never disagrees with getCredentials(). + // (readFrom* both run isValidCredentials; avoids getCredentials()'s keyring + // migration side effect.) if (forceInsecureStorage) { - return fileExists(); + return readFromFile() !== null; } - return readFromKeyring() !== null || fileExists(); + return readFromKeyring() !== null || readFromFile() !== null; } export function getCredentials(): Credentials | null { From 740251b87e4fb1e89c275f4a70d476cafa12c132 Mon Sep 17 00:00:00 2001 From: "Garen J. Torikian" Date: Tue, 21 Jul 2026 17:39:01 -0400 Subject: [PATCH 17/17] fix: Harden the Agent SDK first-run download Three robustness gaps surfaced while reviewing the first-run download path: - The stale-cache reap deleted every sibling version dir unconditionally, so an upgrade run could remove the executable out from under a concurrently running other-version CLI. A 24h staleness guard (matching the skills reaper) leaves fresh dirs alone. - gunzip ran unbounded before the sha256 gate, so a compromised or corrupt registry response could expand a gzip bomb in memory before verification had a chance to reject it. Capping output at the pinned executable size plus headroom bounds it. - A retry restarted the byte count at zero, which froze the progress readout until it re-passed the previous peak. An onRetry hook resets the throttle and tells the user it is retrying. --- src/lib/agent-interface.ts | 28 +++++++++++++++-------- src/lib/agent-sdk-assets.spec.ts | 22 ++++++++++++++++++ src/lib/agent-sdk-assets.ts | 39 ++++++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/lib/agent-interface.ts b/src/lib/agent-interface.ts index 44510f0f..3d49bc65 100644 --- a/src/lib/agent-interface.ts +++ b/src/lib/agent-interface.ts @@ -487,16 +487,24 @@ export async function initializeAgent(config: AgentConfig, options: InstallerOpt // First run from a compiled binary downloads the pinned agent runtime // (~230MB, one-time, cached under ~/.workos); dev resolves node_modules. let lastReportedPct = -1; - const claudeExecutablePath = await ensureClaudeCodeExecutable(({ receivedBytes, totalBytes }) => { - if (!totalBytes) return; - const pct = Math.floor((receivedBytes / totalBytes) * 100); - if (pct >= lastReportedPct + 25 || (lastReportedPct === -1 && pct === 0)) { - lastReportedPct = pct; - options.emitter?.emit('status', { - message: `Downloading Claude agent runtime (one-time, ${Math.round(totalBytes / 1024 / 1024)}MB): ${pct}%`, - }); - } - }); + const claudeExecutablePath = await ensureClaudeCodeExecutable( + ({ receivedBytes, totalBytes }) => { + if (!totalBytes) return; + const pct = Math.floor((receivedBytes / totalBytes) * 100); + if (pct >= lastReportedPct + 25 || (lastReportedPct === -1 && pct === 0)) { + lastReportedPct = pct; + options.emitter?.emit('status', { + message: `Downloading Claude agent runtime (one-time, ${Math.round(totalBytes / 1024 / 1024)}MB): ${pct}%`, + }); + } + }, + () => { + // The retry restarts the byte count at 0; reset the throttle so the + // fresh attempt's progress isn't suppressed until it re-passes the peak. + lastReportedPct = -1; + options.emitter?.emit('status', { message: 'Download interrupted; retrying…' }); + }, + ); const agentRunConfig: AgentRunConfig = { workingDirectory: config.workingDirectory, diff --git a/src/lib/agent-sdk-assets.spec.ts b/src/lib/agent-sdk-assets.spec.ts index 507377f5..beb2c8be 100644 --- a/src/lib/agent-sdk-assets.spec.ts +++ b/src/lib/agent-sdk-assets.spec.ts @@ -97,6 +97,28 @@ describe('downloadTarball', () => { expect(result.equals(tarball)).toBe(true); }); + it('fires onRetry once before the second attempt', async () => { + const tarball = makeTarball([['package/claude', Buffer.from('binary')]]); + const fetchMock = vi + .fn() + .mockRejectedValueOnce(new Error('connection reset')) + .mockResolvedValueOnce(streamedResponse(tarball)); + vi.stubGlobal('fetch', fetchMock); + const onRetry = vi.fn(); + + await downloadTarball(undefined, undefined, onRetry); + expect(onRetry).toHaveBeenCalledTimes(1); + }); + + it('does not fire onRetry when the first attempt succeeds', async () => { + const tarball = makeTarball([['package/claude', Buffer.from('binary')]]); + vi.stubGlobal('fetch', vi.fn().mockResolvedValueOnce(streamedResponse(tarball))); + const onRetry = vi.fn(); + + await downloadTarball(undefined, undefined, onRetry); + expect(onRetry).not.toHaveBeenCalled(); + }); + it('aborts a stalled download and reports it after retrying', async () => { const fetchMock = vi.fn((_url: string, init?: { signal?: AbortSignal }) => Promise.resolve({ diff --git a/src/lib/agent-sdk-assets.ts b/src/lib/agent-sdk-assets.ts index 80d8f76a..465f0e27 100644 --- a/src/lib/agent-sdk-assets.ts +++ b/src/lib/agent-sdk-assets.ts @@ -81,6 +81,12 @@ function resolveFromNodeModules(): string { return path; } +// The uncompressed tarball is the pinned executable plus a handful of small +// metadata files. Cap gunzip output generously above that so a compromised or +// corrupted response can't expand a gzip bomb in memory before the sha256 gate +// (which runs only after decompression) gets a chance to reject it. +const MAX_TARBALL_UNCOMPRESSED_BYTES = AGENT_SDK_EXECUTABLE_SIZE + 64 * 1024 * 1024; + /** * Extract a single entry from a gzipped npm tarball. Exported for tests. * @@ -89,7 +95,7 @@ function resolveFromNodeModules(): string { * want — unknown entry types are skipped by the generic size-based walk. */ export function extractTarEntry(tarGz: Buffer, entryName: string): Buffer { - const raw = gunzipSync(tarGz); + const raw = gunzipSync(tarGz, { maxOutputLength: MAX_TARBALL_UNCOMPRESSED_BYTES }); let offset = 0; while (offset + 512 <= raw.length) { const header = raw.subarray(offset, offset + 512); @@ -167,11 +173,14 @@ async function downloadTarballOnce( /** * Download the pinned tarball, retrying once on any network, stall, or HTTP * failure. Checksum verification stays in the caller and is never retried. + * `onRetry` fires before the second attempt (the retry restarts the byte + * count, so callers driving a progress bar use it to reset their throttle). * Exported for tests. */ export async function downloadTarball( onProgress?: (progress: DownloadProgress) => void, stallTimeoutMs: number = DOWNLOAD_STALL_TIMEOUT_MS, + onRetry?: () => void, ): Promise { const url = AGENT_SDK_TARBALL_URL; let lastError: unknown; @@ -180,30 +189,43 @@ export async function downloadTarball( return await downloadTarballOnce(url, onProgress, stallTimeoutMs); } catch (error) { lastError = error; + if (attempt === 0) onRetry?.(); } } throw lastError; } +// Only reap cache dirs untouched for this long. A newer sibling may belong to +// a concurrently running other-version CLI (mid-download, or spawned from that +// dir mid-agent-run), so leaving fresh dirs alone avoids yanking an executable +// out from under it — mirrors the skills reaper's staleness guard. +const STALE_CACHE_MS = 24 * 60 * 60 * 1000; + /** * Best-effort reap of cache dirs for other CLI/SDK versions — each version * keys its own `-` dir (~230MB), which would otherwise * accumulate forever. Runs only after a successful download of the current - * version, so at most one stale sibling window per upgrade. + * version, and skips any sibling touched within STALE_CACHE_MS so a concurrent + * run's dir is never removed. */ function cleanupStaleCacheDirs(): void { + const root = agentSdkCacheRoot(); let entries: string[]; try { - entries = readdirSync(agentSdkCacheRoot()); + entries = readdirSync(root); } catch { return; } + const cutoff = Date.now() - STALE_CACHE_MS; for (const entry of entries) { if (entry === cacheKey()) continue; + const path = join(root, entry); try { - rmSync(join(agentSdkCacheRoot(), entry), { recursive: true, force: true }); + // Fresh dir — may be in use by a concurrent run; leave it for a later reap. + if (statSync(path).mtimeMs >= cutoff) continue; + rmSync(path, { recursive: true, force: true }); } catch { - // In use or already gone — skip it. + // In use, already gone, or unreadable — skip it. } } } @@ -218,7 +240,10 @@ function cleanupStaleCacheDirs(): void { * it atomically (write-to-temp + rename; a concurrent winner is accepted only * if its bytes verify). */ -export async function ensureClaudeCodeExecutable(onProgress?: (progress: DownloadProgress) => void): Promise { +export async function ensureClaudeCodeExecutable( + onProgress?: (progress: DownloadProgress) => void, + onRetry?: () => void, +): Promise { if (cachedExecutablePath) return cachedExecutablePath; const target = runtimeTarget(); @@ -237,7 +262,7 @@ export async function ensureClaudeCodeExecutable(onProgress?: (progress: Downloa return finalPath; } - const tarball = await downloadTarball(onProgress); + const tarball = await downloadTarball(onProgress, undefined, onRetry); const executable = extractTarEntry(tarball, `package/${AGENT_SDK_EXECUTABLE_NAME}`); const digest = sha256Hex(executable); if (digest !== AGENT_SDK_EXECUTABLE_SHA256) {