From dabc2ff4111748546529b5606848293230f04a63 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Tue, 16 Jun 2026 14:55:37 +0800 Subject: [PATCH 01/12] feat: migrate to pnpm --- .agents/skills/dsh-code-review/SKILL.md | 2 +- .github/workflows/ci.yml | 20 +- .gitignore | 4 +- .yarnrc.yml | 1 - AGENTS.md | 42 +- README.md | 8 +- docs/adr/0007-quality-gates.md | 2 +- docs/adr/0008-tsdown-over-dumble.md | 6 +- docs/adr/0014-doc-sync-enforcement.md | 2 +- docs/cookbook/adding-a-package.md | 10 +- docs/cookbook/adding-a-vendored-package.md | 8 +- docs/cookbook/adding-an-llm-adapter.md | 2 +- docs/cookbook/extension-cookbook.md | 2 +- docs/development.md | 68 +- docs/rfc/007-supply-chain-and-vendor-drift.md | 2 +- docs/rfc/010-acp-agent-client-protocol.md | 2 +- docs/rfc/012-optional-code-mode.md | 2 +- examples/README.md | 4 +- examples/coding-agent/README.md | 4 +- examples/echo-agent/README.md | 2 +- lefthook.yml | 10 +- package.json | 8 +- packages/AGENTS.md | 2 +- packages/agent-loop/package.json | 12 +- packages/agent/package.json | 4 +- packages/bash-local/package.json | 2 +- packages/invariants/package.json | 6 +- packages/llm-deepseek/README.md | 2 +- packages/llm-deepseek/package.json | 2 +- packages/llm-pi-ai/README.md | 2 +- packages/llm-pi-ai/package.json | 4 +- packages/session/package.json | 2 +- packages/system-prompt/package.json | 2 +- packages/tool-bash/package.json | 16 +- packages/tools/package.json | 6 +- pnpm-lock.yaml | 4440 +++++++++++++++ pnpm-workspace.yaml | 13 + scripts/check-workspace-constraints.ts | 97 + scripts/doc-typecheck.ts | 4 +- tsdown.config.ts | 2 +- vendor/README.md | 6 +- vendor/hmr/package.json | 3 +- vitest.config.ts | 2 +- vitest.e2e.config.ts | 4 +- yarn.config.cjs | 53 - yarn.lock | 4864 ----------------- 46 files changed, 4697 insertions(+), 5064 deletions(-) delete mode 100644 .yarnrc.yml create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 scripts/check-workspace-constraints.ts delete mode 100644 yarn.config.cjs delete mode 100644 yarn.lock diff --git a/.agents/skills/dsh-code-review/SKILL.md b/.agents/skills/dsh-code-review/SKILL.md index 6e28c77306..a8f740c305 100644 --- a/.agents/skills/dsh-code-review/SKILL.md +++ b/.agents/skills/dsh-code-review/SKILL.md @@ -17,7 +17,7 @@ This is a where-to-look map, not a rules list. The rules live in the docs below ## Where to look first (review-specific, not in the docs) -1. **Docs in sync?** If the PR changes a config key, default, error code, wire field, or event name, did it update the package README + module/JSDoc in the same diff? Stale docs are the most common miss — `yarn doc-sync` only gates compilable `ts` blocks and the event-taxonomy table, so prose drift (config keys, defaults, error codes, wire fields) has no gate and is on the reviewer to catch. +1. **Docs in sync?** If the PR changes a config key, default, error code, wire field, or event name, did it update the package README + module/JSDoc in the same diff? Stale docs are the most common miss — `pnpm run doc-sync` only gates compilable `ts` blocks and the event-taxonomy table, so prose drift (config keys, defaults, error codes, wire fields) has no gate and is on the reviewer to catch. 2. **HMR-safety test present?** Any new registry/registration needs a test that disposes the contributing fiber and asserts cleanup. Its absence is a blocking gap. 3. **Gates green?** typecheck, lint, test, test:coverage (100% per-file on `packages/*/src`), knip, build, publint, constraints. Don't re-review what a gate already enforces — trust the gate, spend attention on what gates can't check (intent, contracts, doc sync). 4. **e2e verifies the world, not the agent's self-report.** For real-API tests, confirm the assertion re-runs the command/checks the file externally — a keyword probe lets a cheating agent pass (see AGENTS.md e2e bullet). diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21965beb21..e3d378fa4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,24 +24,24 @@ jobs: with: node-version: ${{ matrix.node }} - - name: Enable corepack (yarn 4) + - name: Enable corepack (pnpm) run: corepack enable - name: Install (immutable) - run: yarn install --immutable + run: pnpm install --frozen-lockfile - name: Constraints - run: yarn constraints + run: pnpm run constraints # Before lint: the type-aware ESLint config resolves vendor packages via # their built declarations (tsconfig.typecheck.json -> vendor/*/lib), - # which `yarn typecheck` emits. Lint on a fresh checkout would otherwise + # which `pnpm run typecheck` emits. Lint on a fresh checkout would otherwise # see unresolved types and erupt with no-unsafe-* errors. - name: Typecheck (src + tests + examples) - run: yarn typecheck + run: pnpm run typecheck - name: Lint - run: yarn lint + run: pnpm run lint # Doc-sync gates (RFC 006). doc-typecheck compiles the fenced ts blocks in # the docs and resolves vendor packages via their built declarations, which @@ -49,18 +49,18 @@ jobs: # taxonomy check only reads source. Same `doc-sync` script the pre-push # hook runs (ADR 0007: one source of truth). - name: Doc-sync gates (doc code blocks + event taxonomy) - run: yarn doc-sync + run: pnpm run doc-sync - name: Tests with coverage gate (per-file 100%) - run: yarn test:coverage + run: pnpm run test:coverage # Before hygiene: publint validates the packed artifacts (lib/index.js), # which only the tsdown bundling step emits. - name: Build (tsc -b + tsdown bundles) - run: yarn build + run: pnpm run build - name: Hygiene (knip + publint) - run: yarn knip && yarn publint + run: pnpm run knip && pnpm run publint - name: Demo smoke test run: | diff --git a/.gitignore b/.gitignore index 2dbe0baea5..597a96aa60 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,8 @@ CLAUDE.local.md node_modules/ lib/ *.tsbuildinfo -.yarn/ -yarn-error.log +pnpm-debug.log +.pnpm-store/ examples/*/*.jsonl coverage/ .doc-typecheck-*/ diff --git a/.yarnrc.yml b/.yarnrc.yml deleted file mode 100644 index 3186f3f079..0000000000 --- a/.yarnrc.yml +++ /dev/null @@ -1 +0,0 @@ -nodeLinker: node-modules diff --git a/AGENTS.md b/AGENTS.md index ddda1af98e..3a5d13c083 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,7 +36,7 @@ packages/ Harness packages, all named @deepseek-ai/dsh-: examples/ Runnable demos (not workspaces). echo-agent = mock model + echo tool + stdio UI + JSONL persistence, wired via cordis.yml. coding-agent = the real thing: DeepSeek V4 + bash tools - (yarn demo:coding, needs DEEPSEEK_API_KEY). + (pnpm run demo:coding, needs DEEPSEEK_API_KEY). docs/ architecture.md — the design doc. adr/ — decision records (the why behind vendoring, event-sourcing, the schema DSL, …). rfc/ — proposals for substantial future work. @@ -50,33 +50,33 @@ scripts/ repo maintenance scripts (vendor-manifest guard, publint runner). ## Commands ```sh -yarn install # Yarn 4 workspaces (node-modules linker), node >= 24 -yarn test # vitest run (packages/*/tests/**/*.spec.ts) -yarn test:coverage # vitest run --coverage (per-file 100% gate on packages/*/src) -yarn test:e2e # real-API tests (packages|examples/*/tests/**/*.e2e.ts); +pnpm install # pnpm workspaces, node >= 24 +pnpm run test # vitest run (packages/*/tests/**/*.spec.ts) +pnpm run test:coverage # vitest run --coverage (per-file 100% gate on packages/*/src) +pnpm run test:e2e # real-API tests (packages|examples/*/tests/**/*.e2e.ts); # self-skips without DEEPSEEK_API_KEY — see Secrets below -yarn typecheck # tsc -b tsconfig.build.json (declarations) + tsc -p +pnpm run typecheck # tsc -b tsconfig.build.json (declarations) + tsc -p # tsconfig.typecheck.json (tests/examples typecheck too) -yarn lint # eslint . -yarn lint:fix # eslint . --fix -yarn build # tsc -b tsconfig.build.json && tsdown (JS bundles into lib/) -yarn knip # dead-code / unused-dependency check -yarn publint # package.json publish-correctness check (publishable packages/*) -yarn hygiene # knip + publint + yarn constraints -yarn doc-typecheck # typecheck every ```ts block in README.md, docs/**/*.md, +pnpm run lint # eslint . +pnpm run lint:fix # eslint . --fix +pnpm run build # tsc -b tsconfig.build.json && tsdown (JS bundles into lib/) +pnpm run knip # dead-code / unused-dependency check +pnpm run publint # package.json publish-correctness check (publishable packages/*) +pnpm run hygiene # knip + publint + workspace constraints +pnpm run doc-typecheck # typecheck every ```ts block in README.md, docs/**/*.md, # packages/*/README.md (doc/code drift gate) -yarn verify-event-taxonomy # assert the event-taxonomy table in docs/architecture.md +pnpm run verify-event-taxonomy # assert the event-taxonomy table in docs/architecture.md # matches the interface Events declarations in source -yarn doc-sync # doc-typecheck + verify-event-taxonomy (CI runs this) -yarn demo:echo # run examples/echo-agent (no API key; type "echo hi" to +pnpm run doc-sync # doc-typecheck + verify-event-taxonomy (CI runs this) +pnpm run demo:echo # run examples/echo-agent (no API key; type "echo hi" to # see a tool call) — the mock skeleton -yarn demo:coding # run examples/coding-agent — the real agent (needs +pnpm run demo:coding # run examples/coding-agent — the real agent (needs # DEEPSEEK_API_KEY; give it a coding task) ``` ## Secrets / .env -Real-API e2e tests (`yarn test:e2e`) read `DEEPSEEK_API_KEY` (and optionally `DEEPSEEK_BASE_URL`) from the environment, or from a gitignored `.env` at the repo root loaded via Node's native `process.loadEnvFile()`: +Real-API e2e tests (`pnpm run test:e2e`) read `DEEPSEEK_API_KEY` (and optionally `DEEPSEEK_BASE_URL`) from the environment, or from a gitignored `.env` at the repo root loaded via Node's native `process.loadEnvFile()`: ``` DEEPSEEK_API_KEY=sk-… @@ -85,7 +85,7 @@ DEEPSEEK_BASE_URL=https://… # optional; defaults to the public API cordis.yml configs reference env vars with the `!!js` tag: `apiKey: !!js process.env.DEEPSEEK_API_KEY`. Never commit real credentials; CI has no secrets and e2e suites must self-skip without them. -Dev/test/demo run **unbuilt** via tsx + the `paths` map in the root `tsconfig.json` (`vitest` resolves through `tsconfig.test.json`). Building is only needed for publishing/consumption outside the repo — with one exception: `yarn lint`'s type-aware rules resolve vendor packages through their built declarations (`tsconfig.typecheck.json` → `vendor/*/lib`), so run `yarn typecheck` once after a fresh clone (CI does the same) or lint reports unresolved-type `no-unsafe-*` errors. +Dev/test/demo run **unbuilt** via tsx + the `paths` map in the root `tsconfig.json` (`vitest` resolves through `tsconfig.test.json`). Building is only needed for publishing/consumption outside the repo — with one exception: `pnpm run lint`'s type-aware rules resolve vendor packages through their built declarations (`tsconfig.typecheck.json` → `vendor/*/lib`), so run `pnpm run typecheck` once after a fresh clone (CI does the same) or lint reports unresolved-type `no-unsafe-*` errors. ## Conventions @@ -123,7 +123,7 @@ This codebase aims to be **very type-safe and well documented** for maintainabil In the **core** packages (`packages/llm`, `packages/tools`, `packages/agent`, `packages/agent-loop`, `packages/session`, `packages/system-prompt`), **type gymnastics are acceptable when they improve the DX of plugin authors** for common plugin types. The `defineTool` typed schema DSL in `dsh-tools` is the canonical example: the `SchemaSpec` to `InferArgs` type-level mapping gives tool authors zero-cast typed `execute` args, and the cost of the conditional types stays inside the core package. -Verbose documentation is fine **as long as docs and code stay strictly in sync**. Out-of-sync docs are worse than no docs. **When you change code, update its docs in the SAME change** — grep the package README and the module/JSDoc comments for the old behavior (config keys, defaults, error codes, wire field names, event names) and fix every hit. CI runs `yarn doc-sync` (`doc-typecheck` + `verify-event-taxonomy`), which typechecks every fenced `ts` block in `README.md`, `docs/**/*.md`, and `packages/*/README.md` and verifies the event-taxonomy table against source — but that scope does NOT cover `AGENTS.md`, `packages/AGENTS.md`, or `packages/README.md`, nor does it catch prose drift (config keys, defaults, error codes), so keeping those in sync remains on the author. Every module has a module-level doc comment explaining its role. Every exported class, interface, type, function, and non-obvious method has a JSDoc that explains semantics (not just the name) — contracts (what events fire when), disposal behavior, error behavior, and extension intent. Internal helpers get docs only where non-obvious. Prefer one-liners when one line suffices. +Verbose documentation is fine **as long as docs and code stay strictly in sync**. Out-of-sync docs are worse than no docs. **When you change code, update its docs in the SAME change** — grep the package README and the module/JSDoc comments for the old behavior (config keys, defaults, error codes, wire field names, event names) and fix every hit. CI runs `pnpm run doc-sync` (`doc-typecheck` + `verify-event-taxonomy`), which typechecks every fenced `ts` block in `README.md`, `docs/**/*.md`, and `packages/*/README.md` and verifies the event-taxonomy table against source — but that scope does NOT cover `AGENTS.md`, `packages/AGENTS.md`, or `packages/README.md`, nor does it catch prose drift (config keys, defaults, error codes), so keeping those in sync remains on the author. Every module has a module-level doc comment explaining its role. Every exported class, interface, type, function, and non-obvious method has a JSDoc that explains semantics (not just the name) — contracts (what events fire when), disposal behavior, error behavior, and extension intent. Internal helpers get docs only where non-obvious. Prefer one-liners when one line suffices. **Markdown is not hard-wrapped**: write one line per paragraph and let the editor soft-wrap. Hard line breaks mid-paragraph make docs harder to edit and diff — a one-word change reflows and re-diffs the whole paragraph. This applies to prose only: leave fenced code blocks, tables, and list structure intact (a wrapped list item folds to one line per bullet). Code comments / JSDoc are exempt — they stay under the linter's column limit. @@ -131,4 +131,4 @@ Verbose documentation is fine **as long as docs and code stay strictly in sync** ## Vendoring Policy -`vendor/` packages are pinned source copies (manifest with upstream commit SHAs in [vendor/README.md](vendor/README.md)). To update one, follow the sync procedure there; re-apply (or retire) the logged local modifications and rerun `yarn test && yarn build`. +`vendor/` packages are pinned source copies (manifest with upstream commit SHAs in [vendor/README.md](vendor/README.md)). To update one, follow the sync procedure there; re-apply (or retire) the logged local modifications and rerun `pnpm run test && pnpm run build`. diff --git a/README.md b/README.md index 7c203bf953..1ce5aa8960 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ Monorepo for the DeepSeek Harness group. This monorepo is built on the [Cordis](https://github.com/cordiverse/cordis) framework (vendored as source under `vendor/`), microkernel-style: everything is a plugin. ```sh -yarn install -yarn test # vitest -yarn demo:echo # runnable echo-agent example (no API key needed) -yarn demo:coding # the real DeepSeek coding agent (needs DEEPSEEK_API_KEY) +pnpm install +pnpm run test # vitest +pnpm run demo:echo # runnable echo-agent example (no API key needed) +pnpm run demo:coding # the real DeepSeek coding agent (needs DEEPSEEK_API_KEY) ``` For humans, start with the [development guide](docs/development.md) for local setup, hooks, environment variables, and quality gates, then read the [architecture design](docs/architecture.md) before package work. Local context lives in [packages/](packages/) and [vendor/](vendor/). diff --git a/docs/adr/0007-quality-gates.md b/docs/adr/0007-quality-gates.md index 7bcba2a912..45336205ed 100644 --- a/docs/adr/0007-quality-gates.md +++ b/docs/adr/0007-quality-gates.md @@ -13,7 +13,7 @@ Every AGENTS.md promise gets a command that exits non-zero, wired into git hooks - Max-strict TypeScript (`noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, …); tests and examples typecheck in CI via `tsconfig.typecheck.json` (vendored packages resolve as built declarations). - ESLint strict-type-checked + @stylistic (the house style, enforced); vendored code excluded. - Per-file 100% coverage on `packages/*/src` (v8); unreachable defensive guards carry `/* v8 ignore */ ` with stated reasons instead of deletion. -- knip (dead code/deps), publint (package correctness), yarn constraints (workspace rules: private, cordis peer+dev, uniform version, ESM). +- knip (dead code/deps), publint (package correctness), workspace constraints (workspace rules: private, cordis peer+dev, uniform version, ESM). - lefthook pre-commit (lint staged, typecheck, vendor-manifest guard) and pre-push (tests, hygiene); CI runs the full matrix on node 24/26 plus a demo smoke test driving the echo-agent end to end. ## Consequences diff --git a/docs/adr/0008-tsdown-over-dumble.md b/docs/adr/0008-tsdown-over-dumble.md index f6026311ac..a270968cd4 100644 --- a/docs/adr/0008-tsdown-over-dumble.md +++ b/docs/adr/0008-tsdown-over-dumble.md @@ -6,16 +6,16 @@ Status: accepted (2026-06-11) The initial build used **dumble**, the cordiverse zero-config esbuild wrapper that upstream Cordis itself builds with — maximum alignment with the vendored packages' conventions (it reads each package.json and infers entries/formats from the `exports` field). But dumble is a liability as a load-bearing tool in this repo: v0.2.x, ~530 npm downloads/week, effectively one maintainer, and we were invoking it through a custom orchestration script (`scripts/build.ts`) because it has no workspace mode. -Build output currently matters only for `yarn build` + publint (nothing publishes yet; dev/test/demo run unbuilt via tsx), so the switching cost is at its lowest now and only grows once packages publish. +Build output currently matters only for `pnpm run build` + publint (nothing publishes yet; dev/test/demo run unbuilt via tsx), so the switching cost is at its lowest now and only grows once packages publish. ## Decision Replace dumble with **tsdown** (rolldown-based, ~2.5M downloads/week, VoidZero-backed, actively released): -- Root `tsdown.config.ts` with `workspace: ['vendor/*', 'packages/*']` (explicit globs, not `workspace: true`, which would also pick up `examples/*` — they have package.json files but are not yarn workspaces). +- Root `tsdown.config.ts` with `workspace: ['vendor/*', 'packages/*']` (explicit globs, not `workspace: true`, which would also pick up `examples/*` — they have package.json files but are not pnpm workspaces). - Shared shape: entry `src/index.ts`, `outDir: 'lib'`, ESM, `platform: node`, `target: es2024`, `fixedExtension: false` (keeps `.js` for `"type": "module"` packages), `dts: false` (tsc -b owns declarations), `clean: false` (lib/ holds tsc's .d.ts output). - Two per-package overrides in vendor/ (ours, like the regenerated tsconfigs; logged in vendor/README.md): schemastery (dual `.mjs`/`.cjs` via `outExtensions`), logger-console (two single-entry passes so the shared base class is inlined into each entry instead of a hash-named chunk, matching upstream's published shape). -- `scripts/build.ts` deleted; `yarn build` = `tsc -b && tsdown`. +- `scripts/build.ts` deleted; `pnpm run build` = `tsc -b && tsdown`. Alternatives considered: **direct esbuild script** (most established engine, zero wrapper risk, but hand-maintains the per-package spec table tsdown's workspace mode gives us); **pkgroll** (closest drop-in philosophically, but 78k dl/wk and Rollup-based — strictly weaker maintenance story than tsdown); **keep dumble** (perfect upstream alignment, unacceptable bus factor). diff --git a/docs/adr/0014-doc-sync-enforcement.md b/docs/adr/0014-doc-sync-enforcement.md index 9a6596c46b..6c248b9431 100644 --- a/docs/adr/0014-doc-sync-enforcement.md +++ b/docs/adr/0014-doc-sync-enforcement.md @@ -13,7 +13,7 @@ Two gates, mirroring the existing `scripts/` style (tsx ESM, one job each): 1. **`doc-typecheck`** extracts every fenced ` ```ts ` block from `README.md`, `docs/**`, and `packages/*/README.md`, writes them to a temp project, and compiles with `tsc --noEmit`. The temp tsconfig copies only resolution-relevant options and the workspace `paths` map from `tsconfig.typecheck.json` (vendor → built `lib`, harness → `src`) — resolving vendor to `lib` is essential, or tsc type-checks raw vendor source and floods the run. A block that is a deliberate sketch opts out with an explicit ` ```ts ignore-check ` info string; the script reports the opt-out ratio and fails if it exceeds half, so the escape hatch can't quietly become the norm. 2. **`verify-event-taxonomy`** extracts the event names from the `interface Events` blocks across `packages/*/src` and from the taxonomy table in `docs/architecture.md`, and asserts the two sets match exactly. Verify, don't generate: the table keeps its hand-written Mode/Purpose columns; only the set of names is checked. (Landing this surfaced three events the table had been missing — `tools/change`, `llm/adapter-change`, `system-prompt/change`.) -Both run via a shared `doc-sync` package.json script that the lefthook pre-push hook and CI both invoke (ADR 0007: hooks and CI call the same scripts, so the gate fires locally before a push — not only after it). They run after `yarn typecheck` (which emits the vendor `lib/` that doc-typecheck resolves against). API-extractor golden reports (RFC 006 part 3) were deliberately **deferred** — low value for an internal monorepo where reviewers already see the source diff, and a heavy, finicky dependency. +Both run via a shared `doc-sync` package.json script that the lefthook pre-push hook and CI both invoke (ADR 0007: hooks and CI call the same scripts, so the gate fires locally before a push — not only after it). They run after `pnpm run typecheck` (which emits the vendor `lib/` that doc-typecheck resolves against). API-extractor golden reports (RFC 006 part 3) were deliberately **deferred** — low value for an internal monorepo where reviewers already see the source diff, and a heavy, finicky dependency. ## Consequences diff --git a/docs/cookbook/adding-a-package.md b/docs/cookbook/adding-a-package.md index 4780ccca7e..ed40f242e4 100644 --- a/docs/cookbook/adding-a-package.md +++ b/docs/cookbook/adding-a-package.md @@ -15,7 +15,7 @@ packages// README.md # service API, events, extension points, design notes ``` -package.json invariants (enforced by `yarn constraints` / yarn.config.cjs): `private: true`, `version: 0.0.1`, `type: module`, `cordis` in BOTH peerDependencies and devDependencies (same range). Mirror every dsh peer dependency in devDependencies. `schemastery` goes in `dependencies` (it is a runtime validator), matching agent-loop. +package.json invariants (enforced by `pnpm run constraints` / `scripts/check-workspace-constraints.ts`): `private: true`, `version: 0.0.1`, `type: module`, `cordis` in BOTH peerDependencies and devDependencies (same range). Mirror every dsh peer dependency in devDependencies. `schemastery` goes in `dependencies` (it is a runtime validator), matching agent-loop. ## 2. Register it in the root configs @@ -36,10 +36,10 @@ For a swappable capability, split interface / implementation / consumer into sep ## 4. Verify ```sh -yarn install # registers the workspace -yarn constraints && yarn typecheck && yarn lint -yarn test:coverage # 100% per-file over src (types.ts exempt) -yarn build && yarn knip && yarn publint +pnpm install # registers the workspace +pnpm run constraints && pnpm run typecheck && pnpm run lint +pnpm run test:coverage # 100% per-file over src (types.ts exempt) +pnpm run build && pnpm run knip && pnpm run publint ``` Test expectations: every registry/registration needs an HMR-safety test (register from a child fiber, dispose it, assert cleanup). Excessive tests are welcome — see AGENTS.md. diff --git a/docs/cookbook/adding-a-vendored-package.md b/docs/cookbook/adding-a-vendored-package.md index 8a66ed08a8..af0ce7cacd 100644 --- a/docs/cookbook/adding-a-vendored-package.md +++ b/docs/cookbook/adding-a-vendored-package.md @@ -48,9 +48,9 @@ Covered automatically by globs — no edits needed: root `package.json` workspac ## 4. Verify ```sh -yarn install # registers the workspace -yarn typecheck # the base→lib path split means: run once after a fresh add -yarn build && yarn test && yarn constraints +pnpm install # registers the workspace +pnpm run typecheck # the base→lib path split means: run once after a fresh add +pnpm run build && pnpm run test && pnpm run constraints ``` -Note the `tsconfig` two-map split (called out in [AGENTS.md](../../AGENTS.md) § Secrets/.env): `lint`'s type-aware rules resolve vendored packages through their built `lib/` declarations, so run `yarn typecheck` (which builds them) once after adding the package or lint reports unresolved-type errors. +Note the `tsconfig` two-map split (called out in [AGENTS.md](../../AGENTS.md) § Secrets/.env): `lint`'s type-aware rules resolve vendored packages through their built `lib/` declarations, so run `pnpm run typecheck` (which builds them) once after adding the package or lint reports unresolved-type errors. diff --git a/docs/cookbook/adding-an-llm-adapter.md b/docs/cookbook/adding-an-llm-adapter.md index a3ba821b0e..19bc4e9e05 100644 --- a/docs/cookbook/adding-an-llm-adapter.md +++ b/docs/cookbook/adding-an-llm-adapter.md @@ -39,5 +39,5 @@ Split the adapter into testable stages (llm-deepseek's layout): wire types (`typ - **Unit: mock the provider, not the harness.** A scripted `node:http` server speaking the provider's wire format covers happy paths, every error status, malformed payloads, premature closes, and aborts — no network, and it drives the 100% per-file coverage gate. Works for SDK-backed adapters too (point the SDK's baseURL at the mock). - **Hostile framing tests.** Split stream payloads at arbitrary byte positions (including mid-UTF-8) — real networks do. -- **E2E: `tests/*.e2e.ts`** under `yarn test:e2e`, gated with `describe.skipIf(!process.env.MY_KEY)` so CI (no secrets) stays green. Cover each model × each provider mode you map (thinking on/off, effort levels), a tool-call round trip INCLUDING the follow-up turn with results in history, and loose assertions only (substring/structure, bounded maxTokens — real models are nondeterministic). +- **E2E: `tests/*.e2e.ts`** under `pnpm run test:e2e`, gated with `describe.skipIf(!process.env.MY_KEY)` so CI (no secrets) stays green. Cover each model × each provider mode you map (thinking on/off, effort levels), a tool-call round trip INCLUDING the follow-up turn with results in history, and loose assertions only (substring/structure, bounded maxTokens — real models are nondeterministic). - Register the e2e file pattern in `knip.json` (per-workspace `entry` override) or knip flags it unused. diff --git a/docs/cookbook/extension-cookbook.md b/docs/cookbook/extension-cookbook.md index d8d9b3e40d..8746991aae 100644 --- a/docs/cookbook/extension-cookbook.md +++ b/docs/cookbook/extension-cookbook.md @@ -55,4 +55,4 @@ export function apply(ctx: Context) { ## Runnable wirings -Two complete examples load their plugin trees from `cordis.yml` with HMR: [`examples/echo-agent`](../../examples/echo-agent) (mock model + echo tool — the all-mock skeleton check, `yarn demo:echo`) and [`examples/coding-agent`](../../examples/coding-agent) (DeepSeek V4 + the bash tool suite — the real thing, `yarn demo:coding`). +Two complete examples load their plugin trees from `cordis.yml` with HMR: [`examples/echo-agent`](../../examples/echo-agent) (mock model + echo tool — the all-mock skeleton check, `pnpm run demo:echo`) and [`examples/coding-agent`](../../examples/coding-agent) (DeepSeek V4 + the bash tool suite — the real thing, `pnpm run demo:coding`). diff --git a/docs/development.md b/docs/development.md index 123aea44bf..1252157868 100644 --- a/docs/development.md +++ b/docs/development.md @@ -5,7 +5,7 @@ This guide covers the local setup needed to work on DeepSeek Harness and underst ## Prerequisites - Node.js 24 or newer. The repo declares `node >=24`; CI runs the matrix on Node 24 and 26. -- Corepack-enabled Yarn. The repo pins `yarn@4.14.1` in `package.json`; run `corepack enable` if `yarn --version` does not resolve through Corepack. +- Corepack-enabled pnpm. The repo pins `pnpm@11.7.0` in `package.json`; run `corepack enable` if `pnpm --version` does not resolve through Corepack. - Git. - Optional: a DeepSeek API key for the coding-agent demo and real-API e2e tests. @@ -14,32 +14,32 @@ This guide covers the local setup needed to work on DeepSeek Harness and underst Install dependencies from the repo root: ```sh -yarn install +pnpm install ``` -Yarn uses the `node-modules` linker in this repo. The install also runs the root `postinstall` script, which installs lefthook from the repo dev dependency. +The install also runs the root `postinstall` script, which installs lefthook from the repo dev dependency. If hooks are missing because dependencies were restored from cache or `postinstall` was skipped, install them manually: ```sh -yarn lefthook install +pnpm exec lefthook install ``` Run typecheck once after a fresh clone: ```sh -yarn typecheck +pnpm run typecheck ``` -That first typecheck builds declaration output used by type-aware linting for vendored packages. Without it, `yarn lint` can report unresolved-type `no-unsafe-*` errors even when source code is fine. +That first typecheck builds declaration output used by type-aware linting for vendored packages. Without it, `pnpm run lint` can report unresolved-type `no-unsafe-*` errors even when source code is fine. If you are preparing to push from a fresh clone or worktree, also build once: ```sh -yarn build +pnpm run build ``` -`yarn hygiene` includes `publint`, which validates package entrypoints against the built `lib/*.js` files. A fresh worktree has no bundled JS until `yarn build` runs. +`pnpm run hygiene` includes `publint`, which validates package entrypoints against the built `lib/*.js` files. A fresh worktree has no bundled JS until `pnpm run build` runs. ## Environment variables @@ -56,61 +56,61 @@ DEEPSEEK_BASE_URL=https://... # optional lefthook is configured in `lefthook.yml` as an early local checkpoint before review: -- `pre-commit` runs staged-file ESLint fixes, `yarn typecheck`, and the vendor manifest guard. -- `pre-push` runs `yarn test`, `yarn hygiene`, and `yarn doc-sync`. +- `pre-commit` runs staged-file ESLint fixes, `pnpm run typecheck`, and the vendor manifest guard. +- `pre-push` runs `pnpm run test`, `pnpm run hygiene`, and `pnpm run doc-sync`. The vendor manifest guard checks that changes under `vendor/*/src` are staged with the matching `vendor/README.md` manifest update. See `vendor/README.md` before editing vendored code. -These hooks do not exactly mirror CI. Notably, `pre-push` runs unit tests without coverage, while CI runs `yarn test:coverage`; CI also runs an echo-agent smoke test and exercises the matrix on Node 24 and 26. +These hooks do not exactly mirror CI. Notably, `pre-push` runs unit tests without coverage, while CI runs `pnpm run test:coverage`; CI also runs an echo-agent smoke test and exercises the matrix on Node 24 and 26. ## CI gates The GitHub workflow runs these gates on each pull request: -- `yarn install --immutable` -- `yarn constraints` -- `yarn typecheck` -- `yarn lint` -- `yarn doc-sync` -- `yarn test:coverage` -- `yarn build` -- `yarn knip && yarn publint` +- `pnpm install --frozen-lockfile` +- `pnpm run constraints` +- `pnpm run typecheck` +- `pnpm run lint` +- `pnpm run doc-sync` +- `pnpm run test:coverage` +- `pnpm run build` +- `pnpm run knip && pnpm run publint` - an echo-agent smoke test that checks the demo's tool call, tool result, and JSONL output -`yarn hygiene` is the local shorthand for `yarn knip && yarn publint && yarn constraints`; CI splits `yarn constraints` into its own earlier step, then runs `yarn knip && yarn publint` after `yarn build`. +`pnpm run hygiene` is the local shorthand for `pnpm run knip && pnpm run publint && pnpm run constraints`; CI splits `pnpm run constraints` into its own earlier step, then runs `pnpm run knip && pnpm run publint` after `pnpm run build`. ## Daily commands Use these from the repo root: ```sh -yarn test # unit tests -yarn test:coverage # unit tests with per-file coverage gates -yarn test:e2e # real-API tests; self-skips without DEEPSEEK_API_KEY -yarn typecheck # build declarations, then typecheck source, tests, and examples -yarn lint # eslint . -yarn lint:fix # eslint . --fix -yarn doc-typecheck # compile checked TypeScript snippets in Markdown docs -yarn verify-event-taxonomy # compare docs/architecture.md event names with source -yarn doc-sync # doc-typecheck plus event taxonomy verification -yarn build # build declarations and JS bundles -yarn hygiene # knip, publint, and yarn constraints +pnpm run test # unit tests +pnpm run test:coverage # unit tests with per-file coverage gates +pnpm run test:e2e # real-API tests; self-skips without DEEPSEEK_API_KEY +pnpm run typecheck # build declarations, then typecheck source, tests, and examples +pnpm run lint # eslint . +pnpm run lint:fix # eslint . --fix +pnpm run doc-typecheck # compile checked TypeScript snippets in Markdown docs +pnpm run verify-event-taxonomy # compare docs/architecture.md event names with source +pnpm run doc-sync # doc-typecheck plus event taxonomy verification +pnpm run build # build declarations and JS bundles +pnpm run hygiene # knip, publint, and workspace constraints ``` -When changing package public behavior, update the relevant README or JSDoc in the same change. `yarn doc-sync` catches checked TypeScript snippets and event-taxonomy drift, but broader prose/API sync still needs review. +When changing package public behavior, update the relevant README or JSDoc in the same change. `pnpm run doc-sync` catches checked TypeScript snippets and event-taxonomy drift, but broader prose/API sync still needs review. ## Demos The echo demo does not need API credentials: ```sh -yarn demo:echo +pnpm run demo:echo ``` The coding-agent demo uses the real DeepSeek adapter and needs `DEEPSEEK_API_KEY` in the environment or repo-root `.env`: ```sh -yarn demo:coding +pnpm run demo:coding ``` ## Architecture context diff --git a/docs/rfc/007-supply-chain-and-vendor-drift.md b/docs/rfc/007-supply-chain-and-vendor-drift.md index efe8529f29..5f6a8dff70 100644 --- a/docs/rfc/007-supply-chain-and-vendor-drift.md +++ b/docs/rfc/007-supply-chain-and-vendor-drift.md @@ -9,7 +9,7 @@ The vendor manifest (ADR 0001) is enforced at commit time in the *forward* direc ## Proposal 1. **Vendor drift check** (nightly CI): clone the upstream repos at the manifest SHAs (shallow), copy the corresponding package sources, and diff against `vendor/*/src`. The job fails unless the diff matches the logged local modifications (kept as a checked-in patch file per modification — the log entries become verifiable artifacts rather than prose). -2. **Dependency advisories**: osv-scanner (or `yarn npm audit`) job on the lockfile, scheduled + on lockfile-touching PRs. +2. **Dependency advisories**: osv-scanner (or `pnpm audit`) job on the lockfile, scheduled + on lockfile-touching PRs. 3. **License inventory**: a script asserting every vendored package carries its LICENSE and that package.json `license` fields match the inventory in vendor/README.md (we mix vendored MIT with our BSD-3) — CI step. 4. **Renovate** (or a scheduled agent task) proposing npm dependency updates in small PRs that ride the full gate suite; vendored packages are excluded (their updates follow the manifest sync procedure, ideally as a semi-automated agent workflow: fetch upstream, re-apply patches, run gates, open PR with the manifest table updated). diff --git a/docs/rfc/010-acp-agent-client-protocol.md b/docs/rfc/010-acp-agent-client-protocol.md index 42f1bd5c56..ebe40b6f19 100644 --- a/docs/rfc/010-acp-agent-client-protocol.md +++ b/docs/rfc/010-acp-agent-client-protocol.md @@ -45,7 +45,7 @@ Lifecycle and disposal: the connection, listeners, and in-flight permission prom 3. Internal edit — turn-end reason fidelity (sanctioned: edit internals to fit ACP). Extend `TurnEndReasonMap` in the proper places: (a) declaration-merge a `max-tokens` variant in the owning package (`packages/session/src/types.ts`, alongside `completed|aborted|error|disposed`) — add `max-tokens` because `FinishReasonMap` produces it (DeepSeek maps `length` → `max-tokens`); do not add `refusal`, since no current adapter produces it (unknown DeepSeek finish reasons collapse to `error`), but leave a comment in `TurnEndReasonMap` noting `refusal` should be added when an adapter first emits it (`FinishReasonMap` is merge-extensible); (b) make `agent-loop`'s `loop.ts` populate the reason from the model `finish` chunk — `assembler.finish` lives inside `runStep`, so `runStep` must return it up to `runTurn`, and the rule is "the last step's finish reason wins, but any `max-tokens` in the turn surfaces as `max-tokens`"; (c) no consumer exhaustively switches over `TurnEndReason` today (the invariants plugin switches on `SessionEventType`, and `deriveMessages` ignores `turn/end`), so adding `max-tokens` is a non-breaking extension — but recheck before landing; (d) update [docs/architecture.md](../architecture.md) (the CI-verified loop-lifecycle/event-taxonomy doc) and the affected package READMEs/JSDoc (`dsh-session`, `dsh-agent`, `dsh-agent-loop`) per the repo doc-sync policy. This replaces a fragile "observe the finish chunk in the bridge" hack with a real, documented contract. 4. Prompt-turn streaming plus load: translate `agent/stream-chunk` and `session/event` into `session/update`; resolve `session/prompt` on settle, mapping the harness `TurnEndReason` to the ACP `StopReason` wire enum (`completed`→`end_turn`, `max-tokens`→`max_tokens`, `aborted`→`cancelled`) — a small total function with a test asserting the exact wire strings, since the SDK rejects an unknown `stopReason`. Concrete correlation, since the loop batches queued messages into one turn and `send()` does not synchronously flip to running: install listeners before `send()`; gate on an observed `agent/turn-start` (confirms work was accepted) then resolve on the next `agent/turn-end`; reject an empty/whitespace prompt up front rather than calling `send()` (no turn would ever start, so the RPC would hang). Implement `session/load` on RFC 009's resume seam. 5. Permission gate: a single `tools/execute` listener registered with `prepend: true`, owning a `WeakMap` of bridge-created agents; no-op (`next()`) for unowned/no-agent calls; for owned calls → `session/request_permission` → allow (`next()`) / veto; settle the stored resolver exactly once on outcome, cancel, or connection close. -6. Example wiring (extract a shared base). `@cordisjs/plugin-include` is itself a plugin entry that resets `ctx.baseUrl` and loads a path, so a child `cordis.yml` can nest-include a shared base; the extraction is safe because every dependent plugin declares `inject` (loader groups initialize via `Promise.all`, so YAML order is NOT the dependency mechanism — never rely on it). Extract the provider/tool core (`llm, sessions, system-prompt, tools, agents, invariants, llm-deepseek, bash-local, tool-bash`) into `examples/base.yml`; have both `coding-agent` and a new `examples/acp-agent/` include it and add their own UI plugin plus logger. Keep `agent-loop` per-example (NOT in the base): `AgentLoop` creates its configured agents in its constructor, and the two examples disagree — `coding-agent` needs a pre-created `main` (its `stdio-chat` calls `ctx.agents.get('main')`), while `acp-agent` must pre-create none (ACP `session/new` creates agents). So `coding-agent` declares `agent-loop` with `agents: [{ id: main, … }]` and `acp-agent` with `agents: []`. `acp-agent` loads `dsh-session-persistence-jsonl` (from RFC 009 — required for `session/load`), omits the stdout logger (see Risks), and adds `yarn demo:acp` plus the Zed `agent_servers` snippet. +6. Example wiring (extract a shared base). `@cordisjs/plugin-include` is itself a plugin entry that resets `ctx.baseUrl` and loads a path, so a child `cordis.yml` can nest-include a shared base; the extraction is safe because every dependent plugin declares `inject` (loader groups initialize via `Promise.all`, so YAML order is NOT the dependency mechanism — never rely on it). Extract the provider/tool core (`llm, sessions, system-prompt, tools, agents, invariants, llm-deepseek, bash-local, tool-bash`) into `examples/base.yml`; have both `coding-agent` and a new `examples/acp-agent/` include it and add their own UI plugin plus logger. Keep `agent-loop` per-example (NOT in the base): `AgentLoop` creates its configured agents in its constructor, and the two examples disagree — `coding-agent` needs a pre-created `main` (its `stdio-chat` calls `ctx.agents.get('main')`), while `acp-agent` must pre-create none (ACP `session/new` creates agents). So `coding-agent` declares `agent-loop` with `agents: [{ id: main, … }]` and `acp-agent` with `agents: []`. `acp-agent` loads `dsh-session-persistence-jsonl` (from RFC 009 — required for `session/load`), omits the stdout logger (see Risks), and adds `pnpm run demo:acp` plus the Zed `agent_servers` snippet. 7. Tests (the repo cares a lot here): a property-based test for the protocol shape (precedent: RFC 001 / [ADR 0013](../adr/0013-property-based-testing.md)) — fuzz arbitrary harness event sequences and assert ACP-stream invariants (never a `tool_call_update` before its `tool_call`; exactly one `session/prompt` resolution per prompt; monotonic, well-formed ordering; `stopReason` in the legal set); codec unit tests over an in-memory `Duplex` pair (drive `AgentSideConnection` without a subprocess; assert exact frames for `initialize`, `session/new`, a full prompt turn); the mandatory HMR-safety test (dispose the fiber; assert the connection closed, all `ctx.on` listeners gone, any in-flight `request_permission` settled); failure-path tests (connection closes mid-stream; closes with a permission pending; a notification `send()` rejects but the turn survives; `finish{kind:'error'|'aborted'}`; a `tools/execute` throw with no `tool/result`; a second `session/new` rejected; a `session/prompt` while one is in flight; an empty prompt rejected without hanging; a `session/load` re-derives identical history and replays it); and an e2e (`*.e2e.ts`, self-skips without `DEEPSEEK_API_KEY`) that boots `examples/acp-agent`, connects a `ClientSideConnection`, sends a real prompt, owns and disposes the harness in `afterEach`, and verifies the world (files on disk), not the agent's self-report. 8. Docs: module/JSDoc plus a package README; extend [the extension cookbook](../cookbook/extension-cookbook.md) with the client-driver pattern. Flip Status to `implemented` on landing; write an ADR only if a decision proves durable, contested, and surprising (candidates: the `tools/execute` permission-ownership rule, the npm-dependency choice) — not auto-required. diff --git a/docs/rfc/012-optional-code-mode.md b/docs/rfc/012-optional-code-mode.md index 33857ca982..2a88c61f5e 100644 --- a/docs/rfc/012-optional-code-mode.md +++ b/docs/rfc/012-optional-code-mode.md @@ -85,7 +85,7 @@ It is insufficient for the **composition / round-trip** half, which is the decis 2. Scaffold the implementation package `packages/code-runtime-vm/`: the node:vm stub — `safe = false`, a constructor that **throws unless given `{ unsafe: true }`**, transpile/type-erase, async-IIFE wrap, capturing `console`, SDK globals, return-value/logs/error capture, output cap, signal-tied timeout. Tests for output capture, return value, error-as-field, abort, the constructor refusal without `unsafe`, and a README documenting the "not a sandbox, trusted-only" caveat prominently. 3. Scaffold the consumer plugin `packages/code-mode/`: `jsonSchemaToTs` codegen with namespace/quoted-access + alias handling (unit tests, including non-identifier MCP names and unsupported-shape → `unknown`); the registered lazy `ctx.systemPrompt.section()` carrying the SDK `.d.ts`; the `agent/request` listener (`prepend: true`) collapsing `request.tools` to `[run_code]` after `await next()`; the **unsafe-runtime gate** (refuse to register `run_code` when `ctx.codeRuntime.safe === false` unless `allowUnsafeRuntime` is set); the `run_code` tool with the dispatch bridge (per-run serialization queue, deterministic sub-call ids, before/after abort checks, `CodeRunError` on error results); and the `code/dispatch` event declared here via `SessionEventMap` merge. Declare `inject = ['tools', 'systemPrompt', 'codeRuntime']`. 4. Tests: HMR-safety (dispose removes the tool, the section, and the listener); a waterfall test that the wire tool list is exactly `[run_code]` (spy adapter, asserting via `agent/request` and optionally `llm/stream`); an integration test that a program calling two tools returns only its printed/returned output (verify the world, not the self-report); a **serialization test** that `Promise.all([...])` over SDK calls does not overlap the underlying `ctx.tools.execute` invocations (a probe tool records enter/exit; assert no interleaving); `deriveMessages()` ignores `code/dispatch`; abort mid-program stops further dispatches; `CodeRunError` surfaces as `isError: true`; and the **unsafe-runtime refusal test** (§3, the VM-guard): with the unsafe flag unset, a non-mock agent's `run_code` is refused; with it set, the program runs. -5. Wire an example: `examples/coding-agent-code-mode` (or a config flag on the existing example) loading the trio. Running it against the node:vm stub requires both opt-ins (`VmCodeRuntime({ unsafe: true })` and `code-mode`'s `allowUnsafeRuntime`); the example sets them explicitly and comments why, or uses a mock model — a real model never reaches the unsandboxed stub without those deliberate flags. Add a `yarn demo:*` entry. +5. Wire an example: `examples/coding-agent-code-mode` (or a config flag on the existing example) loading the trio. Running it against the node:vm stub requires both opt-ins (`VmCodeRuntime({ unsafe: true })` and `code-mode`'s `allowUnsafeRuntime`); the example sets them explicitly and comments why, or uses a mock model — a real model never reaches the unsandboxed stub without those deliberate flags. Add a `pnpm run demo:*` entry. 6. Docs: update [docs/architecture.md](../architecture.md) (a `ctx.codeRuntime` row in the service map, a Code Mode note under the tool pipeline / capability seams sections); add a [cookbook](../cookbook/) note on writing a `CodeRuntime` backend; and **file the follow-up RFC for the hardened execution substrate** (the isolate/sandboxed-process design, the additional-language backends sketched in §1 — AssemblyScript/WASM, Python — with their per-language SDK generators, plus the tool-visibility-tier design skipped here). Append the `| 012 | … | proposed |` row to [the RFC index](README.md). ## Risks diff --git a/examples/README.md b/examples/README.md index 592dc66930..59d3f70719 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,7 +12,7 @@ A mock model + echo tool + stdio UI + JSONL persistence demo. Demonstrates: - Persisting session events to JSONL via the `session/event` + `session/flush` pattern - A minimal stdio UI consuming `agent/stream-chunk` and session events -Run with: `yarn demo:echo` +Run with: `pnpm run demo:echo` When prompted, type "echo " to trigger a tool call round-trip. @@ -20,4 +20,4 @@ When prompted, type "echo " to trigger a tool call round-trip. The real thing: DeepSeek V4 + the bash tool suite + stdio chat + JSONL persistence, wired from `cordis.yml`. Where echo-agent proves the skeleton with mocks, this is a usable coding assistant. -Run with: `yarn demo:coding` (needs `DEEPSEEK_API_KEY` in the environment or a gitignored repo-root `.env`). See [coding-agent/README.md](coding-agent/README.md) for details. +Run with: `pnpm run demo:coding` (needs `DEEPSEEK_API_KEY` in the environment or a gitignored repo-root `.env`). See [coding-agent/README.md](coding-agent/README.md) for details. diff --git a/examples/coding-agent/README.md b/examples/coding-agent/README.md index 8775bc8891..52c549602e 100644 --- a/examples/coding-agent/README.md +++ b/examples/coding-agent/README.md @@ -9,7 +9,7 @@ The first REAL agent wiring: DeepSeek V4 + the bash tool suite + stdio chat # repo root .env (gitignored) or exported env: # DEEPSEEK_API_KEY=sk-… # DEEPSEEK_BASE_URL=https://… # optional; defaults to the public API -yarn demo:coding +pnpm run demo:coding ``` Type a coding task. The agent's only tools are `bash` (+ `bash_output` / `bash_kill` for background tasks): file reads, writes, searches, and test runs all happen through shell commands, each in a fresh `bash -c` (the system prompt tells the model to pass `workdir` instead of `cd`). Reasoning streams dimmed; tool calls/results render inline. @@ -32,7 +32,7 @@ Type a coding task. The agent's only tools are `bash` (+ `bash_output` / `bash_k | `src/session-jsonl.ts` | write-behind persistence on `session/event` + `session/flush` (copied from echo-agent) | | `src/stdio-chat.ts` | UI as a plugin; copied from echo-agent with reasoning-dimming and an exit-on-idle close handler for piped stdin. Example-local on purpose — extract a shared UI package when a third example needs it | -## End-to-end tests (`yarn test:e2e`, key-gated) +## End-to-end tests (`pnpm run test:e2e`, key-gated) - `tests/full-loop.e2e.ts` — the canary: real model runs `echo e2e-ok` through the real bash tool; asserts `tool/call`/`tool/result` session events and the final answer. - `tests/coding-task.e2e.ts` — the swebench-style smoke: a temp dir holds `add.js` (with `a - b` where `a + b` belongs) and a failing `add.test.js`; the agent must fix the bug and verify. The test re-runs `node add.test.js` ITSELF and inspects the files — agent claims are not trusted. diff --git a/examples/echo-agent/README.md b/examples/echo-agent/README.md index 87a52f2dd9..ebc41db225 100644 --- a/examples/echo-agent/README.md +++ b/examples/echo-agent/README.md @@ -23,7 +23,7 @@ Runnable demo: stdin chat with a scripted mock model and an echo tool. ## Run ```sh -yarn demo:echo +pnpm run demo:echo # or: node --expose-internals --import tsx examples/echo-agent/start.ts ``` diff --git a/lefthook.yml b/lefthook.yml index 6f29bb0990..9789c92029 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -1,6 +1,6 @@ # Git hooks (lefthook). Hooks call the same package.json scripts CI runs — # one source of truth; the hook is just an earlier, faster checkpoint. -# Install: `yarn lefthook install` (runs automatically via postinstall). +# Install: `pnpm exec lefthook install` (runs automatically via postinstall). pre-commit: parallel: true @@ -14,7 +14,7 @@ pre-commit: - name: typecheck glob: '*.ts' - run: yarn typecheck + run: pnpm run typecheck - name: vendor manifest guard run: scripts/check-vendor-manifest.sh @@ -23,10 +23,10 @@ pre-push: parallel: true jobs: - name: test - run: yarn test + run: pnpm run test - name: hygiene - run: yarn hygiene + run: pnpm run hygiene - name: doc-sync - run: yarn doc-sync + run: pnpm run doc-sync diff --git a/package.json b/package.json index c56ba924e5..9ff3536f9b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "type": "module", - "packageManager": "yarn@4.14.1", + "packageManager": "pnpm@11.7.0", "engines": { "node": ">=24" }, @@ -23,8 +23,9 @@ "publint": "tsx scripts/publint-all.ts", "doc-typecheck": "tsx scripts/doc-typecheck.ts", "verify-event-taxonomy": "tsx scripts/verify-event-taxonomy.ts", - "doc-sync": "yarn doc-typecheck && yarn verify-event-taxonomy", - "hygiene": "yarn knip && yarn publint && yarn constraints", + "constraints": "tsx scripts/check-workspace-constraints.ts", + "doc-sync": "pnpm run doc-typecheck && pnpm run verify-event-taxonomy", + "hygiene": "pnpm run knip && pnpm run publint && pnpm run constraints", "demo:echo": "node --expose-internals --import tsx examples/echo-agent/start.ts", "demo:coding": "node --expose-internals --import tsx examples/coding-agent/start.ts", "postinstall": "lefthook install" @@ -33,7 +34,6 @@ "@stylistic/eslint-plugin": "^5.10.0", "@types/node": "^25.3.5", "@vitest/coverage-v8": "^4.1.8", - "@yarnpkg/types": "^4.0.1", "eslint": "^10.4.1", "fast-check": "^4.8.0", "knip": "^6.16.1", diff --git a/packages/AGENTS.md b/packages/AGENTS.md index 6c1f980d95..4dead05337 100644 --- a/packages/AGENTS.md +++ b/packages/AGENTS.md @@ -11,6 +11,6 @@ Naming notes: - Files `src/index.ts` export the service default + all public types - `src/types.ts` contain only types — no runtime code - Tests live at package level under `tests/`, not `src/__tests__/` -- A package's README and module/JSDoc comments are part of the change: when you alter behavior (config keys, defaults, error codes, wire fields), update them in the same commit. CI runs `yarn doc-sync`, which typechecks fenced `ts` blocks in `packages/*/README.md` and verifies the event-taxonomy table — but it does NOT cover this file or prose drift (config keys, defaults, error codes), so those stay on the author. +- A package's README and module/JSDoc comments are part of the change: when you alter behavior (config keys, defaults, error codes, wire fields), update them in the same commit. CI runs `pnpm run doc-sync`, which typechecks fenced `ts` blocks in `packages/*/README.md` and verifies the event-taxonomy table — but it does NOT cover this file or prose drift (config keys, defaults, error codes), so those stay on the author. Read the per-package README.md for package-specific details: service API, events, extension points, TODOs. diff --git a/packages/agent-loop/package.json b/packages/agent-loop/package.json index b93ebeed14..1f2986c5c6 100644 --- a/packages/agent-loop/package.json +++ b/packages/agent-loop/package.json @@ -31,12 +31,12 @@ "schemastery": "^3.18.0" }, "devDependencies": { - "@deepseek-ai/dsh-agent": "^0.0.1", - "@deepseek-ai/dsh-invariants": "^0.0.1", - "@deepseek-ai/dsh-llm": "^0.0.1", - "@deepseek-ai/dsh-session": "^0.0.1", - "@deepseek-ai/dsh-system-prompt": "^0.0.1", - "@deepseek-ai/dsh-tools": "^0.0.1", + "@deepseek-ai/dsh-agent": "workspace:^", + "@deepseek-ai/dsh-invariants": "workspace:^", + "@deepseek-ai/dsh-llm": "workspace:^", + "@deepseek-ai/dsh-session": "workspace:^", + "@deepseek-ai/dsh-system-prompt": "workspace:^", + "@deepseek-ai/dsh-tools": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/agent/package.json b/packages/agent/package.json index 478e461e13..a215f35fb3 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -25,8 +25,8 @@ "cordis": "^4.0.0-rc.6" }, "devDependencies": { - "@deepseek-ai/dsh-llm": "^0.0.1", - "@deepseek-ai/dsh-session": "^0.0.1", + "@deepseek-ai/dsh-llm": "workspace:^", + "@deepseek-ai/dsh-session": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/bash-local/package.json b/packages/bash-local/package.json index b21b139485..b786c1bc37 100644 --- a/packages/bash-local/package.json +++ b/packages/bash-local/package.json @@ -27,7 +27,7 @@ "schemastery": "^3.18.0" }, "devDependencies": { - "@deepseek-ai/dsh-bash": "^0.0.1", + "@deepseek-ai/dsh-bash": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/invariants/package.json b/packages/invariants/package.json index 646114b68c..7508d3e7d8 100644 --- a/packages/invariants/package.json +++ b/packages/invariants/package.json @@ -26,9 +26,9 @@ "cordis": "^4.0.0-rc.6" }, "devDependencies": { - "@deepseek-ai/dsh-agent": "^0.0.1", - "@deepseek-ai/dsh-llm": "^0.0.1", - "@deepseek-ai/dsh-session": "^0.0.1", + "@deepseek-ai/dsh-agent": "workspace:^", + "@deepseek-ai/dsh-llm": "workspace:^", + "@deepseek-ai/dsh-session": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/llm-deepseek/README.md b/packages/llm-deepseek/README.md index 5884136510..76af182580 100644 --- a/packages/llm-deepseek/README.md +++ b/packages/llm-deepseek/README.md @@ -43,4 +43,4 @@ Non-2xx responses throw `LlmError` with stable codes: `AUTH` (401/403), `RATE_LI ## Testing -Unit suites run against a local `node:http` mock SSE server (no network). Real-API coverage lives in `tests/adapter.e2e.ts` (`yarn test:e2e`, key-gated): V4 Flash + V4 Pro across thinking enabled/disabled and both official effort levels, including the thinking+tools round trip with reasoning passback. +Unit suites run against a local `node:http` mock SSE server (no network). Real-API coverage lives in `tests/adapter.e2e.ts` (`pnpm run test:e2e`, key-gated): V4 Flash + V4 Pro across thinking enabled/disabled and both official effort levels, including the thinking+tools round trip with reasoning passback. diff --git a/packages/llm-deepseek/package.json b/packages/llm-deepseek/package.json index 2432894093..077a2db169 100644 --- a/packages/llm-deepseek/package.json +++ b/packages/llm-deepseek/package.json @@ -27,7 +27,7 @@ "schemastery": "^3.18.0" }, "devDependencies": { - "@deepseek-ai/dsh-llm": "^0.0.1", + "@deepseek-ai/dsh-llm": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/llm-pi-ai/README.md b/packages/llm-pi-ai/README.md index 9d0b2f85cf..ae9dc93301 100644 --- a/packages/llm-pi-ai/README.md +++ b/packages/llm-pi-ai/README.md @@ -35,4 +35,4 @@ Same MVP contract as llm-deepseek: `prefill` throws `UNSUPPORTED`, images are no ## Testing -Unit suites run against a local `node:http` mock SSE server (pi-ai's openai SDK happily talks to any base URL). Real-API coverage in `tests/adapter.e2e.ts` (`yarn test:e2e`, key-gated): V4 Flash + V4 Pro across all exposed reasoning levels (off/high/xhigh), the thinking+tools round trip, and a cross-adapter structural-equivalence check against llm-deepseek. +Unit suites run against a local `node:http` mock SSE server (pi-ai's openai SDK happily talks to any base URL). Real-API coverage in `tests/adapter.e2e.ts` (`pnpm run test:e2e`, key-gated): V4 Flash + V4 Pro across all exposed reasoning levels (off/high/xhigh), the thinking+tools round trip, and a cross-adapter structural-equivalence check against llm-deepseek. diff --git a/packages/llm-pi-ai/package.json b/packages/llm-pi-ai/package.json index cd9e620141..6eb08a4b06 100644 --- a/packages/llm-pi-ai/package.json +++ b/packages/llm-pi-ai/package.json @@ -28,8 +28,8 @@ "schemastery": "^3.18.0" }, "devDependencies": { - "@deepseek-ai/dsh-llm": "^0.0.1", - "@deepseek-ai/dsh-llm-deepseek": "^0.0.1", + "@deepseek-ai/dsh-llm": "workspace:^", + "@deepseek-ai/dsh-llm-deepseek": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/session/package.json b/packages/session/package.json index 9773a9b48d..f4aa5839bc 100644 --- a/packages/session/package.json +++ b/packages/session/package.json @@ -24,7 +24,7 @@ "cordis": "^4.0.0-rc.6" }, "devDependencies": { - "@deepseek-ai/dsh-llm": "^0.0.1", + "@deepseek-ai/dsh-llm": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/system-prompt/package.json b/packages/system-prompt/package.json index e2be58448e..eed76b8907 100644 --- a/packages/system-prompt/package.json +++ b/packages/system-prompt/package.json @@ -24,7 +24,7 @@ "cordis": "^4.0.0-rc.6" }, "devDependencies": { - "@deepseek-ai/dsh-llm": "^0.0.1", + "@deepseek-ai/dsh-llm": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/tool-bash/package.json b/packages/tool-bash/package.json index 3bf4f64de0..aaf4fde4cc 100644 --- a/packages/tool-bash/package.json +++ b/packages/tool-bash/package.json @@ -27,14 +27,14 @@ "cordis": "^4.0.0-rc.6" }, "devDependencies": { - "@deepseek-ai/dsh-agent": "^0.0.1", - "@deepseek-ai/dsh-agent-loop": "^0.0.1", - "@deepseek-ai/dsh-bash": "^0.0.1", - "@deepseek-ai/dsh-bash-local": "^0.0.1", - "@deepseek-ai/dsh-llm": "^0.0.1", - "@deepseek-ai/dsh-session": "^0.0.1", - "@deepseek-ai/dsh-system-prompt": "^0.0.1", - "@deepseek-ai/dsh-tools": "^0.0.1", + "@deepseek-ai/dsh-agent": "workspace:^", + "@deepseek-ai/dsh-agent-loop": "workspace:^", + "@deepseek-ai/dsh-bash": "workspace:^", + "@deepseek-ai/dsh-bash-local": "workspace:^", + "@deepseek-ai/dsh-llm": "workspace:^", + "@deepseek-ai/dsh-session": "workspace:^", + "@deepseek-ai/dsh-system-prompt": "workspace:^", + "@deepseek-ai/dsh-tools": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/packages/tools/package.json b/packages/tools/package.json index 143ffdbd6e..a92015e55c 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -26,9 +26,9 @@ "cordis": "^4.0.0-rc.6" }, "devDependencies": { - "@deepseek-ai/dsh-agent": "^0.0.1", - "@deepseek-ai/dsh-llm": "^0.0.1", - "@deepseek-ai/dsh-system-prompt": "^0.0.1", + "@deepseek-ai/dsh-agent": "workspace:^", + "@deepseek-ai/dsh-llm": "workspace:^", + "@deepseek-ai/dsh-system-prompt": "workspace:^", "cordis": "^4.0.0-rc.6" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000000..90f30cacb1 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4440 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@stylistic/eslint-plugin': + specifier: ^5.10.0 + version: 5.10.0(eslint@10.5.0(jiti@2.7.0)) + '@types/node': + specifier: ^25.3.5 + version: 25.9.3 + '@vitest/coverage-v8': + specifier: ^4.1.8 + version: 4.1.8(vitest@4.1.8) + eslint: + specifier: ^10.4.1 + version: 10.5.0(jiti@2.7.0) + fast-check: + specifier: ^4.8.0 + version: 4.8.0 + knip: + specifier: ^6.16.1 + version: 6.16.1 + lefthook: + specifier: ^2.1.9 + version: 2.1.9 + publint: + specifier: ^0.3.21 + version: 0.3.21 + tsdown: + specifier: ^0.22.2 + version: 0.22.2(oxc-resolver@11.20.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3) + tsx: + specifier: ^4.22.4 + version: 4.22.4 + typescript: + specifier: ^6.0.3 + version: 6.0.3 + typescript-eslint: + specifier: ^8.61.0 + version: 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + vite-tsconfig-paths: + specifier: ^6.1.1 + version: 6.1.1(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) + vitest: + specifier: ^4.1.8 + version: 4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) + + packages/agent: + devDependencies: + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + '@deepseek-ai/dsh-session': + specifier: workspace:^ + version: link:../session + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/agent-loop: + dependencies: + schemastery: + specifier: ^3.18.0 + version: 3.18.0 + devDependencies: + '@deepseek-ai/dsh-agent': + specifier: workspace:^ + version: link:../agent + '@deepseek-ai/dsh-invariants': + specifier: workspace:^ + version: link:../invariants + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + '@deepseek-ai/dsh-session': + specifier: workspace:^ + version: link:../session + '@deepseek-ai/dsh-system-prompt': + specifier: workspace:^ + version: link:../system-prompt + '@deepseek-ai/dsh-tools': + specifier: workspace:^ + version: link:../tools + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/bash: + devDependencies: + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/bash-local: + dependencies: + schemastery: + specifier: ^3.18.0 + version: 3.18.0 + devDependencies: + '@deepseek-ai/dsh-bash': + specifier: workspace:^ + version: link:../bash + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/invariants: + devDependencies: + '@deepseek-ai/dsh-agent': + specifier: workspace:^ + version: link:../agent + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + '@deepseek-ai/dsh-session': + specifier: workspace:^ + version: link:../session + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/llm: + devDependencies: + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/llm-deepseek: + dependencies: + schemastery: + specifier: ^3.18.0 + version: 3.18.0 + devDependencies: + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/llm-pi-ai: + dependencies: + '@earendil-works/pi-ai': + specifier: ^0.79.1 + version: 0.79.3(ws@8.21.0)(zod@4.4.3) + schemastery: + specifier: ^3.18.0 + version: 3.18.0 + devDependencies: + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + '@deepseek-ai/dsh-llm-deepseek': + specifier: workspace:^ + version: link:../llm-deepseek + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/session: + devDependencies: + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/system-prompt: + devDependencies: + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/tool-bash: + devDependencies: + '@deepseek-ai/dsh-agent': + specifier: workspace:^ + version: link:../agent + '@deepseek-ai/dsh-agent-loop': + specifier: workspace:^ + version: link:../agent-loop + '@deepseek-ai/dsh-bash': + specifier: workspace:^ + version: link:../bash + '@deepseek-ai/dsh-bash-local': + specifier: workspace:^ + version: link:../bash-local + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + '@deepseek-ai/dsh-session': + specifier: workspace:^ + version: link:../session + '@deepseek-ai/dsh-system-prompt': + specifier: workspace:^ + version: link:../system-prompt + '@deepseek-ai/dsh-tools': + specifier: workspace:^ + version: link:../tools + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + packages/tools: + devDependencies: + '@deepseek-ai/dsh-agent': + specifier: workspace:^ + version: link:../agent + '@deepseek-ai/dsh-llm': + specifier: workspace:^ + version: link:../llm + '@deepseek-ai/dsh-system-prompt': + specifier: workspace:^ + version: link:../system-prompt + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + vendor/cordis: + dependencies: + '@cordisjs/plugin-include': + specifier: ^1.0.4 + version: 1.0.4(@cordisjs/plugin-loader@1.0.0-rc.4)(cordis@4.0.0-rc.6) + '@cordisjs/plugin-loader': + specifier: ^1.0.0-rc.4 + version: 1.0.0-rc.4(cordis@4.0.0-rc.6) + '@standard-schema/spec': + specifier: ^1.1.0 + version: 1.1.0 + cosmokit: + specifier: ^1.8.1 + version: 1.8.1 + + vendor/cosmokit: {} + + vendor/group: + dependencies: + '@cordisjs/plugin-loader': + specifier: ^1.0.0-rc.4 + version: 1.0.0-rc.4(cordis@4.0.0-rc.6) + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + + vendor/hmr: + dependencies: + '@babel/code-frame': + specifier: ^7.29.0 + version: 7.29.7 + '@cordisjs/plugin-timer': + specifier: ^1.1.2 + version: 1.1.2(cordis@4.0.0-rc.6) + chokidar: + specifier: ^4.0.3 + version: 4.0.3 + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: + specifier: ^1.8.1 + version: 1.8.1 + picomatch: + specifier: ^4.0.3 + version: 4.0.4 + schemastery: + specifier: ^3.18.0 + version: 3.18.0 + devDependencies: + '@types/babel__code-frame': + specifier: ^7.27.0 + version: 7.27.0 + '@types/picomatch': + specifier: ^3.0.2 + version: 3.0.2 + esbuild: + specifier: ^0.28.1 + version: 0.28.1 + + vendor/include: + dependencies: + '@cordisjs/plugin-loader': + specifier: ^1.0.0-rc.4 + version: 1.0.0-rc.4(cordis@4.0.0-rc.6) + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: + specifier: ^1.8.1 + version: 1.8.1 + js-yaml: + specifier: ^4.1.0 + version: 4.2.0 + + vendor/loader: + dependencies: + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: + specifier: ^1.8.1 + version: 1.8.1 + + vendor/logger-console: + dependencies: + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: + specifier: ^1.8.1 + version: 1.8.1 + schemastery: + specifier: ^3.18.0 + version: 3.18.0 + supports-color: + specifier: ^9.4.0 + version: 9.4.0 + + vendor/schemastery: + dependencies: + '@standard-schema/spec': + specifier: ^1.1.0 + version: 1.1.0 + cosmokit: + specifier: ^1.8.1 + version: 1.8.1 + + vendor/timer: + dependencies: + cordis: + specifier: ^4.0.0-rc.6 + version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: + specifier: ^1.8.1 + version: 1.8.1 + +packages: + + '@anthropic-ai/sdk@0.91.1': + resolution: {integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/sha256-browser@5.2.0': + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} + + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/supports-web-crypto@5.2.0': + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} + + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + + '@aws-sdk/client-bedrock-runtime@3.1048.0': + resolution: {integrity: sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/core@3.974.20': + resolution: {integrity: sha512-7sDi2B2N3mc3nf1nz6FyEx/FCrJ1N1QnBmraHHQNabFaeAh2IaOOLml48/rHOD1bICHgTRkbBgNTvUzEr5Z35g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.46': + resolution: {integrity: sha512-+GPXVS2srMOlH74S+SmC1gVuP2TvUZ0siuC0onKO93q+udP+M72dmY8wJfVQ5CX9z/9X5A1HHwz5yRIGBtskvQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.48': + resolution: {integrity: sha512-fA5loSdlocacRxyUXtpoHSMuk5rsIKRDzQYVMnMxjcmFeZshaJlJ8lymy/hYKji6sne/UmNGj5pxuEs6kq/Qcg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.972.53': + resolution: {integrity: sha512-ZfdhIOR41q8TcWEnUac+gCOb+O2LBWdHLmjedXpXz4IEFW2ppNuFcm6p0sMTavpM+zD5TYfpH5Gp7guRyqSgsQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.52': + resolution: {integrity: sha512-9hu2oR0qH7Fst5Tzdx+UWxm+w5zCXtErTLtOOW5hwwQc170CLwOeniRxyFY6s9mHfGEfC5zFukNBdKBwJR8mhQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.55': + resolution: {integrity: sha512-zMGLa/dhESVqmCD7mmIFFKSwSFrJGScvCXcjvBZEVOOMauFS5JRQvLTMukFpMEFWiV6dTAlsen2ATDBulLPtbg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.46': + resolution: {integrity: sha512-VUoNFBIjWrUN8NbFiQiuxQEgFjvziAlBRPK+ddh27aj65gk0BYu6bLZnrdrNZwpW6vAihtSUtEMQ1PUJ32QRPA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.972.52': + resolution: {integrity: sha512-nb2/n4o/HQf+FVpVbZe9vCTFngmuDoIsltMgLAtjixaKzvzhB4J8WSDFyWgnErgLHk55ctWH+I4PU+LIHhyffg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.52': + resolution: {integrity: sha512-lKj6aRSGbqLmpYmM24bY7a1Xmfcq2vkE3hv8CSPYfc1yCu0BPu/XEJ1L4Fm61MsU6ULLNSG8UGsffNoFUBjESA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/eventstream-handler-node@3.972.21': + resolution: {integrity: sha512-mVC0hOmwGJmNFezZ+wM8Sqfap/LjsMavEf2Evl0YWrLAcrdZOEdjnY8nRvgakVViWJSGm2eJxLuPVHGdeV06kA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-eventstream@3.972.17': + resolution: {integrity: sha512-tdbnXbw73ww62ABWP0G0Z/euvFowEEvAoi/zG4NaZo7HJFpfGho/Z65HyVzkJLT1cMsUregr4pTyxljlarT0wA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-websocket@3.972.28': + resolution: {integrity: sha512-SCW06Zjugn86pq7+dxGnFcyWJuEWHT753HTU/Vj/OzVxP+NoShwdAr4ynxAcvWL883OgRVbSqW3ohnjIxwXjjw==} + engines: {node: '>= 14.0.0'} + + '@aws-sdk/nested-clients@3.997.20': + resolution: {integrity: sha512-IYJuLpXp2DEILVQpQOy0PMpkftv0AHEOCn52o0atyOaumA0CdWQ3klPyXdViGYLbNpESsVFMVybvHUeZAuiGxA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.996.34': + resolution: {integrity: sha512-mx1L5qlumSOt/nKM3BFaHE2HVkWwz0i4Bw0pyYO42FfX/FeLlo8YI6csC0gSPprEk6fTIqI+CZN9RwUwKd5krQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1048.0': + resolution: {integrity: sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1066.0': + resolution: {integrity: sha512-UqEUJq7dqa44hneLDUcX7UJy95cg8YqEWyakRpvIPnrNS3Mq+UlQHgCDGu5pvwAPtlIW4qcYbvW6reG6++FyvA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.973.12': + resolution: {integrity: sha512-43ajd1NF0RMgX5k0hxCNUyEdrtFUsb2aHT2QvpktSC/2Eyb2Jr/JPVqdp0XIoaHWikZJq5tNWSLO6kB5q2eMCA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-locate-window@3.965.7': + resolution: {integrity: sha512-M0D6oIpohdNHjc7udzTHEQyot0+0iuA36jc2I9Hps+f/GtKi2HO/pyijQnCnNcwZqLB5+rtn81z3eZK/GyjAmA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/xml-builder@3.972.29': + resolution: {integrity: sha512-fk0niuGFxfi8yIJuMVM4mhwObkiQSuwZFj3tAPrLVx64Pk3BkrEIpqjzHKY4hKoEBUD6Jg/S74Zj9jy+5F3DnQ==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.2.4': + resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} + engines: {node: '>=18.0.0'} + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@8.0.0-rc.6': + resolution: {integrity: sha512-6mIzgVK8DgEzvIapoQwhXTMnnkuE4STQmVv9H03i/tZ2ml8oev3TRvZJgTenK2Bsq0YWNtzOrFdTyNzCMFtjJQ==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@8.0.0-rc.6': + resolution: {integrity: sha512-BCkFy+zN6kXQed3YOT7aJl93NfDSzQc3pBfsvTVPs9gU9X3V0aefEF5kwBT0E+mDWH9QgKaZstYUQN9VdQZT4g==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@8.0.0-rc.6': + resolution: {integrity: sha512-nVJ+1JcCgntv8d78rRo++o2wuODT0Irknx2BF8Np4Ft2CRgjLqIs4qzSZ8b66yGbBdMWGmZBO9WEZv1hhNiSpg==} + engines: {node: ^22.18.0 || >=24.11.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/parser@8.0.0-rc.6': + resolution: {integrity: sha512-rOS8IpdO7mQELkTPlCsTgPejO0bFuZdEDCGQJouYbYf9e1FLTym7Fei2pEjq8q7MWbX0ravcd7QQYKs1TxOuog==} + engines: {node: ^22.18.0 || >=24.11.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'} + + '@babel/types@8.0.0-rc.6': + resolution: {integrity: sha512-p7/ABylAYlexb31wtRdIfH9L9A0Z2T/9H6zAqzqndkY2PLkvNNc580wGhp/gGKN4Sp9sQvSkhc6Oga8/O+wTyw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@cordisjs/plugin-include@1.0.4': + resolution: {integrity: sha512-b1Hm1wmue0v7d/jayoXoBjCV2J14XWTL5yyDZEYeL2L9HgcyTq6JbCw99ozSbei98uAbkwq/pBhimsp/HsySeg==} + peerDependencies: + '@cordisjs/plugin-loader': ^1.0.0-rc.4 + cordis: ^4.0.0-rc.5 + + '@cordisjs/plugin-loader@1.0.0-rc.4': + resolution: {integrity: sha512-pocUsZiZ/r2yOJby79tmn22Ifk3tCpOmHNYar4TPAotSja30soSrnMVU8YIRD/vJdjuDCMnM/46nDQWDFLM3SQ==} + peerDependencies: + cordis: ^4.0.0-rc.5 + + '@cordisjs/plugin-timer@1.1.2': + resolution: {integrity: sha512-5z5C3Eewt8JzK9XGy5JgIoYFRqXPWZnT7hHFfuJMQNzSom6iEVeLXpYiMvqVqGfJicHA7IroaOjcLRf99sidrQ==} + peerDependencies: + cordis: ^4.0.0-rc.5 + + '@earendil-works/pi-ai@0.79.3': + resolution: {integrity: sha512-lMSput/haP5uZAGbXhS5rAYd3GB7GYdJkoAUxg3VFummBeqGqGqllaTWrbHFN12kVGyVfWHhdySNXkiqVh65Iw==} + engines: {node: '>=22.19.0'} + hasBin: true + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/core@1.11.0': + resolution: {integrity: sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/runtime@1.11.0': + resolution: {integrity: sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@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] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.6.0': + resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@google/genai@1.52.0': + resolution: {integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.2 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@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==} + + '@mistralai/mistralai@2.2.1': + resolution: {integrity: sha512-uKU8CZmL2RzYKmplsU01hii4p3pe4HqJefpWNRWXm1Tcm0Sm4xXfwSLIy4k7ZCPlbETCGcp69E7hZs+WOJ5itQ==} + + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@nodable/entities@2.2.0': + resolution: {integrity: sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==} + + '@oxc-parser/binding-android-arm-eabi@0.133.0': + resolution: {integrity: sha512-l/44caGse+VpnY9gx0yvvc5QnnG3yG1FO3KZgYvNL1GZrfK86zIwAOgGEVlxDyRymzrU/KHiblPFpevKOmJmUA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.133.0': + resolution: {integrity: sha512-KUHmPMziLBp4u+zbrLdB7iWS7KshuZe+RAp7ELnY9SI9nNXBZ+dp8fiBqWOxhXqn+FQg3a4UcQhwmsJOKV8Jjg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.133.0': + resolution: {integrity: sha512-q8dWmnU/8ea2tga9w2f1PinQ5rcMPDUGkF64T189b65YMjUomET4oy5oRldOr4AwOQkneOG/Zttnz1Dvrc62wg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.133.0': + resolution: {integrity: sha512-cOKeIELIB2bJnCKwqx4Rdj+1Lss/U6uCbLxRySZrhyOOQa1flKhwZFjEHRHxk8fU1NKmhK5OnTdPQ4CpjuFuVw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.133.0': + resolution: {integrity: sha512-OpaSv4pW3KgFrMYQxTaS0aOE4T1DQF3qZE/4B6uqqv1KgPWWd4UQhJALi8PJPX1RRV5K7ThKXRfF7qGg2+3l1A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.133.0': + resolution: {integrity: sha512-JGK1wlGrGwxBIlVSF7KWTX1/ru6BEtf28fRROztDRkLfiW+Kxa4onnriezMIiogfn9hVw2KzYcKiLjkLR2ns8A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.133.0': + resolution: {integrity: sha512-yuZO533Ftonxn/iyoqQzURzLQHMspvsIyfiCSNi1t/ER4eIQaR0SsmUOUm5b/lmSig7IWIUa5/BrbEkAPwcilQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.133.0': + resolution: {integrity: sha512-hvpbqT5pN2rR+3+xtWeizwfR/aZ0vGceg6TqYMl+ToxMpk9/tmnX7kSvQnfEUkoua8mhogzvIKsAkn0wxgblBA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-arm64-musl@0.133.0': + resolution: {integrity: sha512-wJQGamIosQBoJHW9+S5XxrtKRo3eyJxsnS1XCPrqN0LHi8uw1pTqqTfn3t/NVuvbBg7Pumn4ez9Eidgcn0xbEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-ppc64-gnu@0.133.0': + resolution: {integrity: sha512-Koaz32/O5+abIfrNGdyndgRvdOZ9jEf5/z3Ep9h3h2QWpdDiUQpVwgH0OcMXCs+l9aXxPLtkupqyVig9W6FDKw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-gnu@0.133.0': + resolution: {integrity: sha512-R4vOjWzxhnNWHnVLeiB6jNuIifdy9vcMXZGPc7StXcxBovI+U2zg1QhZ9o8OjV80oGivs1lX5NfPLzk4IPqlRA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-riscv64-musl@0.133.0': + resolution: {integrity: sha512-iwgBNUTHiMdxARLYuM0SBlnYeb19iw1Ea5M+4ERZupCsBMLArti6FyZ6UfFjJxIiTDr2oW2DGQFxlQVQ/dW9rA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-linux-s390x-gnu@0.133.0': + resolution: {integrity: sha512-ZwZNo8FZmB/gVfboQl+wXilBigGl+6nQQs+nITOeAP/HcAOjiHl6XZJL9F/KXNEspODQcbjAiyjUbeCJd9a0fA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-gnu@0.133.0': + resolution: {integrity: sha512-govCvWx1dBlED3uu4qXctxpRcouu9I8Kn+DBktGCl760JtlGJzc9l/OmPJKlYWSbrRqKkMZehNeZ/4Wfma7uSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-parser/binding-linux-x64-musl@0.133.0': + resolution: {integrity: sha512-ssTlpXD5Mq9uCssDJPzlRWqBt4Y7Zzd9i+XZhWmK/9Y6KUIuAxVYTYiI8lxcGWi0+3/Cz4A8q9UrD4NK9Y2j7g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-parser/binding-openharmony-arm64@0.133.0': + resolution: {integrity: sha512-51aByfXhPtLEdWG4a2Ihdw6cPWV1ei1AarALpFdDP8MLWDLE2NuUMgbo3DERR2Kt8fT/ok1GUvBiLxVGke9uUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.133.0': + resolution: {integrity: sha512-2e16tkKp+wDO2GTAmXfxbBcCmGEaFPIJEIRBBmVKNVXSc8/fJsSIaBGyFTPHM9ST5GNWgJcYIt94rDTks+PLwA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.133.0': + resolution: {integrity: sha512-KPTNDKbxH1cglrqTyVeXHb4Pk4oksz8EcE1/v8zqU7N4UXbiHfA/IwtXZ2U77fnRAWBbgVkl/lZbL7o3hRdejg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.133.0': + resolution: {integrity: sha512-Una1bNYv9zCavQrfnDR9wuZVB3itLjCEH4Oz7i6CwAJN/Xq9b+zbbcxmvdkKvvJt4Ngc/MBmIYlbLo3zS4TQ0A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.133.0': + resolution: {integrity: sha512-kjBhCiOGSYTwDJQuuZa7a94JbP8htWu7J0X1KwH74kV2K5eYf6eyJRYmkpCDvr0XEL8tMxYI4WU1VekblFCLgg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + + '@oxc-project/types@0.135.0': + resolution: {integrity: sha512-wR+xRdFkUBMvcAjBJ2q2kcZM6d+DKu2NgoOyxZgYwZdLhmiv6+rnO8PZ/P68kMiZtIKm+pW7zyEJ4kSOs0vo+Q==} + + '@oxc-resolver/binding-android-arm-eabi@11.20.0': + resolution: {integrity: sha512-IjfWOXRgJFNdORDl+Uf1aibNgZY2guOD3zmOhx1BGVb/MIiqlFTdmjpQNplSN58lhWehnX4UNqC3QwpUo8pjJg==} + cpu: [arm] + os: [android] + + '@oxc-resolver/binding-android-arm64@11.20.0': + resolution: {integrity: sha512-QqslZAuFQG8Q9xm7JuIn8JUbvywhSBMVhuQHtYW+auirZJloS41oxUUaBXk7uUhZJgp44c5zQLeVvmFaDQB+2Q==} + cpu: [arm64] + os: [android] + + '@oxc-resolver/binding-darwin-arm64@11.20.0': + resolution: {integrity: sha512-MUcavykj2ewlR+kc5arpg4tC2RvzJkUxWtNv74pf7lcNk00GpIpN43vXMj+j6r4eMmfZhlb8hueKoIb8e9kAGQ==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@11.20.0': + resolution: {integrity: sha512-BGB16nRUK5Etiv//ihPyzj8Lj1px0mhh4YIfe0FDf045ywknfSm0GEbiRESpr6Q4K82AvnyaRIhhluHByvS4bg==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@11.20.0': + resolution: {integrity: sha512-JZgtePaqj3qmD5XFHJaSLWzHRxQu0LaPkdoM1KJXYADvAaa83ijXHclV3ej3CueeW0wxfIAbGCZVP45J0CA7uQ==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.20.0': + resolution: {integrity: sha512-hOQ/p3ry3v3SchUBXicrrnszaI/UmYzM4wtS4RGfwgVUX7a+HbyQSzJ5aOzu+o6XZkFkS3ZXN4PZAzhOb77OSg==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm-musleabihf@11.20.0': + resolution: {integrity: sha512-2ArPksaw0AqeuGBfoS715VF+JvJQAhD2niWgjE5hVO+L+nAfikVQopvngCMX9x4BD8itWoQ3dnikrQyl5Ho5Jg==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@11.20.0': + resolution: {integrity: sha512-0bJnmYFp62JdZ4nVMDUZ/C58BCZOCcqgKtnUlp7L9Ojf/czIN+3j72YlLPeWLkzlr6SlYvIQA4SGV/HyO0d+qg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@11.20.0': + resolution: {integrity: sha512-wKHHzPKZo7Ufhv/Bt6yxT7FOgnIgW4gwXcJUipkShGp68W3wGVqvr1Sr0fY65lN0Oy6y41+g2kIDvkgZaMMUkw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-ppc64-gnu@11.20.0': + resolution: {integrity: sha512-RN8goF7Ie0B79L4i4G6OeBocTgSC56vJbQ65VJje+oXnldVpLnOU7j/AQ/dP94TcCS+Yh6WG8u3Qt4ETteXFNQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-gnu@11.20.0': + resolution: {integrity: sha512-5l1yU6/xQEqLZRzxqmMxJfWPslpwCmBsdDGaBvABPehxquCXDC7dd7oraNdKSJUMDXSM7VvVj8H2D2FTjU7oWw==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-riscv64-musl@11.20.0': + resolution: {integrity: sha512-xHEvkbgz6UC+A3JOyDQy76LkUaxsNSfIr3/GV8slwZsnuooJiIB34gzJfsyvR4JdCYNUUPsRJc/w/oWkODu+hg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-s390x-gnu@11.20.0': + resolution: {integrity: sha512-aWPDUUmSeyHvlW+SoEUd+JIJsQhVhu6a5tBpDRMu058naPAchTgAVGCFy35zjbnFlt0i8hLWziff6HX0D3LU4g==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@11.20.0': + resolution: {integrity: sha512-x2YeSimvhJjKLVD8KSu8f/rqU1potcdEMkApIPJqjZWN7c2Fpt4g2X32WDg1p+XDAmyT7nuQGe0vnhvXeLbH+g==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@11.20.0': + resolution: {integrity: sha512-kcRLEIxpZefeYfLChjpgFf3ilBzRDZ+yobMrpRsQlSrxuFGtm3U6PMU7AaEpMqo3NfDGVyJJseAjnRLzMFHjwQ==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-openharmony-arm64@11.20.0': + resolution: {integrity: sha512-HHcfnApSZGtKhTiHqe8OZruOZe5XuFQH5/E0Yhj3u8fnFvzkM4/k6WjacUf4SvA0SPEAbfbgYmVPuo0VX/fIBQ==} + cpu: [arm64] + os: [openharmony] + + '@oxc-resolver/binding-wasm32-wasi@11.20.0': + resolution: {integrity: sha512-Tn0y1XOFYHNfK1wp1Z5QK8Rcld/bsOwRISQXfqAZ5IBpv8Gz1IvV39fUWNprqNdRizgcvFhOzWwFun2zkJsyBg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@11.20.0': + resolution: {integrity: sha512-qPi25YNPe4YenS8MgsQU2+bIFHxxpLx1LVna2444cEHqNPhNjvWf9zqj4aWE43H9LpAsTmkkAlA3eL5ElBU3mA==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@11.20.0': + resolution: {integrity: sha512-Wb14jWEW8huH6It9F6sXd9vrYmIS7pMrgkU6sxpLxkP+9z+wRgs71hUEhRpcn8FOXAFa27FVWfY2tRpbfTzfLw==} + cpu: [x64] + os: [win32] + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.1': + resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==} + + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.1': + resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} + + '@publint/pack@0.1.4': + resolution: {integrity: sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==} + engines: {node: '>=18'} + + '@quansync/fs@1.0.0': + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + + '@rolldown/binding-android-arm64@1.0.3': + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-android-arm64@1.1.1': + resolution: {integrity: sha512-BLf9Wak/gfwVb7NQTQW4wBgL3oAfPy7ArEkhwV543OVw/uY6B47z5xYsqPSZ9PDOorvURPinws6ThaFuNgGLgA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.3': + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-arm64@1.1.1': + resolution: {integrity: sha512-rRZRPy/Ynb+Mxu0O6tfPldHeDgAn0sRij+IOUy6sFdUlv3hArGW/DloE3GfAxtqpOJuRNgF74Nr5gM4xBeU2jQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.3': + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.1.1': + resolution: {integrity: sha512-/MtefPxhKPyWWFM8L45OWiEqRf+eSU2Qv9ZAyTaoZOoGcoPKxbbhjTJO2/U2IThv0uDZ4NWHc3/oTsR6IEOtww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.3': + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-freebsd-x64@1.1.1': + resolution: {integrity: sha512-202K+cpIi1kx/Zn7AtxBi4LTXSY67Aszb2K9rNsuW7FeBeh0nqoNmYLOSZidV0p88VPBzMmTZcHAdPNo3kRYzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm-gnueabihf@1.1.1': + resolution: {integrity: sha512-wl9NfeXNUwrXtUc063tddmZFUI6qiNs1CNOwni0OL4vC7MqVSYugra3ZgtDmtVy8e0DluJTENmzIv2BwqLzT4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.3': + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-gnu@1.1.1': + resolution: {integrity: sha512-at2EO4o7D/PJLC4Xik16bU4CcjQE2tSv1LfqMA0TRYQYQihRm3gZeDB8xaX28A9SFedibcAk5DeMCKt4REKG0A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.3': + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-arm64-musl@1.1.1': + resolution: {integrity: sha512-5PUjZx366h9tkJTPJF5eibxOlK3sGoeRiBJLLjjEB5/kLDuhr6qB3LkhqLz1smXNgsX+pBhnbcJBrPE30HznAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-ppc64-gnu@1.1.1': + resolution: {integrity: sha512-1WK84XPeio3tjP1sM/TMXiC0G1i1iq1qGZ71KfNQjEFLU1kwD+Cv5T8nGySg/JUFwLbaScu6ve9DmeXlmqpkFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.1.1': + resolution: {integrity: sha512-1nS1X5z1uMJ369RU25hTpKCFvUwXZp12dIzlzk4S+UxCTcSVGsAE6tzkOSufv/7jnmAtK0ZlrsJxh2fGmsnVSw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.3': + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.1.1': + resolution: {integrity: sha512-NwX/wspnq4vYyMFsqbYvzums3ki/Tk8FZbMzMAovPDp3OfLeYKby/D+9osokadXuYEV3OvpeHlwnr/bG8QMixA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.3': + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-x64-musl@1.1.1': + resolution: {integrity: sha512-+n46LhDrJFQM+229y4oXtVpj1G50U/+XuHMlpnisFTEXhrg9f/YIjp/HymX+PVJjBEr7XHRs3CFLelV464pqwA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.3': + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-openharmony-arm64@1.1.1': + resolution: {integrity: sha512-qGwEu47zOWYo7LdRHhCWTNhzwGtxXpdY6CERs8QEOqC0PXGGics/e3vHnyEUKt8xK6YkbZXFUCeklrpB6js8ag==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.3': + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-wasm32-wasi@1.1.1': + resolution: {integrity: sha512-qczfgEH8u0wHGGOXtA7UMAybNKuQjjEXairyQaw4WzjiMztfbgatG1h4OKays/smhtwbWltpKCRGtVhU6h40Sg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-arm64-msvc@1.1.1': + resolution: {integrity: sha512-4psXSh63mSbwJF+mB8/9yfUUEzBiHYcUjxa32EO9ZwKy0Ypwjcg4F10D8SvVXgd+isy2UUUjF9HJJnDu1T/4Gg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.3': + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.1.1': + resolution: {integrity: sha512-MUvC/HLXVjzkQkWiExdVTEEWf0py+GfWm8WKSZsekG3ih6a21iy0BHPF07X3JIf3ifoklZXTIaHTLPBgH1C3dw==} + 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.24.7': + resolution: {integrity: sha512-KoUi4M1f3BG6kzN1FnCwL7oyFptTbyBJKjR6yhSib+JHRdUmM1o+VwsFtJ66NZCkCzVfJMWRHJNo0R0jznp0Pg==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.3.9': + resolution: {integrity: sha512-ZlfJ/4Fa3jYb+3eaohPfG9utX9HmdhFNcFtpoGAhUhdynAOmGXtmigbi7eEiONKM+ykHw8RwKuDEb85Lx7t7fA==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.4.7': + resolution: {integrity: sha512-NslaM2ir0N2hisDmzXLstPaVINZheh8SokyOC++kzFPloZucL2R7Y7bS57mSzx/1Fc/fqmn7twjkeezTTrV0EA==} + engines: {node: '>=18.0.0'} + + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + + '@smithy/node-http-handler@4.7.3': + resolution: {integrity: sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==} + engines: {node: '>=18.0.0'} + + '@smithy/node-http-handler@4.7.8': + resolution: {integrity: sha512-f+DbsWUwSbtMu1a/j8Y93KiU1SRg9nyzfjereqn1BJ33QOTUXxdlYvVXMhAYl1vuR1Kmna5aIJe09KSIfyFNYw==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.4.7': + resolution: {integrity: sha512-LwQZazFayImv+IOm0S0enoLeUJwmAlhGC5O6YCcLWezyu08dF46GOxPOq35OpBIHkgd7OvNvBStIFwVNyrvoBw==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.14.4': + resolution: {integrity: sha512-B2S9+UGm1+/pHkcx3ZoLVX1a+pmSk8rqxRR+ZsNqZaJ5q9FWX9AFGQVM4qG5+OBeQUZVy99HY8HqW8gK/wgXzQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@stylistic/eslint-plugin@5.10.0': + resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^9.0.0 || ^10.0.0 + + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + + '@types/babel__code-frame@7.27.0': + resolution: {integrity: sha512-Dwlo+LrxDx/0SpfmJ/BKveHf7QXWvLBLc+x03l5sbzykj3oB9nHygCpSECF1a+s+QIxbghe+KHqC90vGtxLRAA==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@25.9.3': + resolution: {integrity: sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==} + + '@types/picomatch@3.0.2': + resolution: {integrity: sha512-n0i8TD3UDB7paoMMxA3Y65vUncFJXjcUf7lQY7YyKGl6031FNjfsLs6pdLFCy2GNFxItPJG8GvvpbZc2skH7WA==} + + '@types/retry@0.12.0': + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + + '@typescript-eslint/eslint-plugin@8.61.0': + resolution: {integrity: sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.61.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.61.0': + resolution: {integrity: sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.61.0': + resolution: {integrity: sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.61.0': + resolution: {integrity: sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.61.0': + resolution: {integrity: sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.61.0': + resolution: {integrity: sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.61.0': + resolution: {integrity: sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.61.0': + resolution: {integrity: sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.61.0': + resolution: {integrity: sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.61.0': + resolution: {integrity: sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitest/coverage-v8@4.1.8': + resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==} + peerDependencies: + '@vitest/browser': 4.1.8 + vitest: 4.1.8 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@4.1.8': + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} + + '@vitest/mocker@4.1.8': + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} + 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.8': + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} + + '@vitest/runner@4.1.8': + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} + + '@vitest/snapshot@4.1.8': + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} + + '@vitest/spy@4.1.8': + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} + + '@vitest/utils@4.1.8': + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} + engines: {node: '>=14'} + + anynum@1.0.0: + resolution: {integrity: sha512-xjR9/zBVnUOP6ztMIIgShjsxui80nQUQH+5xJnvrYLs+90bF25/KJqaAi8mk+B4RDtX1Nspi6fmp4YTEts8SfA==} + + 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-kit@3.0.0-beta.1: + resolution: {integrity: sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==} + engines: {node: '>=20.19.0'} + + ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + birpc@4.0.0: + resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} + + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cordis@4.0.0-rc.6: + resolution: {integrity: sha512-GzUv7zCKh3FlgM3/Ad2S03UpYO3v4u1GcKa7ig4K2je4lCrgJ/S64ziiZI6XNyKEa1tZwdzj4oBQrhYDLgfEiA==} + hasBin: true + peerDependencies: + '@cordisjs/plugin-include': ^1.0.4 + '@cordisjs/plugin-loader': ^1.0.0-rc.4 + peerDependenciesMeta: + '@cordisjs/plugin-include': + optional: true + '@cordisjs/plugin-loader': + optional: true + + cosmokit@1.8.1: + resolution: {integrity: sha512-PDBv4l90xZKrUsZ0vtoycgZpO/j4iFsqJXrAxsyBDsnQRI7ZMJXIjgDJsKNjd5L8jnVnnlrDCdhkFbTncgCVjQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + 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 + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + dts-resolver@3.0.0: + resolution: {integrity: sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q==} + engines: {node: ^22.18.0 || >=24.0.0} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + engines: {node: '>=14'} + + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.5.0: + resolution: {integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-check@4.8.0: + resolution: {integrity: sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg==} + engines: {node: '>=12.17.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-xml-builder@1.2.0: + resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==} + + fast-xml-parser@5.7.3: + resolution: {integrity: sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==} + hasBin: true + + fd-package-json@2.0.0: + resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} + + 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} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + formatly@0.3.0: + resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} + engines: {node: '>=18.3.0'} + hasBin: true + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gaxios@7.1.5: + resolution: {integrity: sha512-5FZy72Rh8LhtjmvDrKkI+lVhrsQrVKVsItxMoDm5mNQE+xR0WVIIs+jzPSJgBvKVsLi24fZhXJIsNI0bihDzFg==} + engines: {node: '>=18'} + + gcp-metadata@8.1.2: + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} + engines: {node: '>=18'} + + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + + get-tsconfig@5.0.0-beta.5: + resolution: {integrity: sha512-/6gFNr0N04nob252sTQxyFLi3eKFRqIg1I87YcqAMT1i6SQrSF6KujUEQrtrjMV0H/eejTCltLdDSTEMzHbnsQ==} + engines: {node: '>=20.20.0'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + google-auth-library@10.7.0: + resolution: {integrity: sha512-QpTAbNJ36TliZLx3TTtahR8HG0hN9RllL1e3FymOvQSIKK8JmgV58H924ub2wa2DsS3ANjjP1Aw1N+Ramc8hqQ==} + engines: {node: '>=18'} + + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} + engines: {node: '>=14'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-without-cache@0.4.0: + resolution: {integrity: sha512-NkJQA7oZ4YHQhd2+H3BoRFKF3d/XNsiKpHZCQEMH9pDX27hQQLsTyOocyRgaIVtf8gHX3Nt3LPkR4e5EdtPAGQ==} + engines: {node: ^22.18.0 || >=24.0.0} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + 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'} + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-to-ts@3.1.1: + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} + engines: {node: '>=16'} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + 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==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + knip@6.16.1: + resolution: {integrity: sha512-TKMn1rxgH6h9vXR9Y0B+Cq7AdPTr9EI02IwoT65NzqYUkvoDQAaJ/aPybiFpAhZ1px6cNYYwXf86iHkBgzCo9w==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + lefthook-darwin-arm64@2.1.9: + resolution: {integrity: sha512-119HryNcvr4nqn0wUIrNPgpMEPn9yMQzEcW/lezRsnb56PCJriJB92+MCySPVcWDxJnZef7o0T3jdnPNiSH7Qg==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@2.1.9: + resolution: {integrity: sha512-dwo5Tke2XcQCM56DGHgFKBfRbJIL6xs2wZ0zG1TUVZgl4t4mQUt6LiZ4V/ZQfYHTZF9qywvXoIlR5N35qOaiVQ==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@2.1.9: + resolution: {integrity: sha512-+09PVap6nl6xsaHch5JLtq7WvIR++U1Q2MzA2ai0M4uB/VP3AqrvKqHw6+9hjyKnIH+HHL83uqi77EAY+LaxLA==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@2.1.9: + resolution: {integrity: sha512-8XresjKIYpkE9ARgCtBEZgJZxAU3T4MIqzj4zNy15XRT59I1Us+QdqXTNm+pkZ41Yd2X/nxs2Pkvbq3NWWlIGw==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@2.1.9: + resolution: {integrity: sha512-1oNIQfwrPe6rgU2KcDM3aF6+hpZDCKx1TmawQKpXUY5gVsbZ7MqX0Sk/1lnnWxqPm+kQQ5f6J2dpFWd+4xH8jg==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@2.1.9: + resolution: {integrity: sha512-fT+7Q+BJyGp+CslFQkNXmdFRgyVXsPHPi9NAsDX0a6QOyNnoORByAsvx6zeAKuF5rL3BBgNfho1/v2RuGxGy9w==} + cpu: [x64] + os: [linux] + + lefthook-openbsd-arm64@2.1.9: + resolution: {integrity: sha512-4bVuafBk3dddVNo0+3hMbjcJs4mqYAstxpPMmX2ufkudSTYFNIhWoqwuGVQV/SS/xdcOKJAldW4qayAzed2ysw==} + cpu: [arm64] + os: [openbsd] + + lefthook-openbsd-x64@2.1.9: + resolution: {integrity: sha512-PmPoMmLP/wQQWcQ9u2YH86bTZ3UCfBsxuEmVTEyPU2U8R1qSTp5r/Gs3G8cN5Mxo91XB9oBERtF1n+xD3W6aVA==} + cpu: [x64] + os: [openbsd] + + lefthook-windows-arm64@2.1.9: + resolution: {integrity: sha512-KphfkBKmwBnmolyrdhIl3lrBaOyTcCgXBT2AB/9OHnEXhOLvv5uTCUkrD4YRAxXPtFKq6UvnapIeoL3GZq0bdA==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@2.1.9: + resolution: {integrity: sha512-2qlUtkJHZ3MyUxgV5XTEmcrIoNZA07iwaquoswAcqv/1MeBFXlD+O+koFRfrzWng2O5WYEbpJnd8tvaYnV8fTA==} + cpu: [x64] + os: [win32] + + lefthook@2.1.9: + resolution: {integrity: sha512-bwDaIOViTktE8kJLf9jP0p+H2/RDTlFFlc43Am2YgUsX22hI6Sq4RbzsrecwzY5y+MHTipOH7WsmWSEniePHWQ==} + hasBin: true + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + 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'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + 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'} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + 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} + + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} + + openai@6.26.0: + resolution: {integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + oxc-parser@0.133.0: + resolution: {integrity: sha512-661RSx+ZcjBmjBYid+Fpp/2F5EbtildpeoZh5HdgnGs+jZ03nqQEQW8yGkt4BGyOC3OMPDQQRl8M5kqD2/g6jw==} + engines: {node: ^20.19.0 || >=22.12.0} + + oxc-resolver@11.20.0: + resolution: {integrity: sha512-CblytBiV/a/ZXY34dsVU2NxhIOxMXst8CvDCtyBelVITgd7PLrKzbEbA6oKLdPjvDKDzCiW48qzmzZ+mYaqn+g==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-retry@4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + partial-json@0.1.7: + resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} + engines: {node: '>=14.0.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + protobufjs@7.6.4: + resolution: {integrity: sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==} + engines: {node: '>=12.0.0'} + + publint@0.3.21: + resolution: {integrity: sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==} + engines: {node: '>=18'} + hasBin: true + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@8.4.0: + resolution: {integrity: sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==} + + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + rolldown-plugin-dts@0.25.2: + resolution: {integrity: sha512-nMhN/R+vmR8GM45ZW1FWMSjRTSDDn/6w4GTf8RNrEFCBdl8B1kySWrU1ixPtbwzXoRlcO+R/S88VgXuJQwfdDg==} + engines: {node: ^22.18.0 || >=24.0.0} + peerDependencies: + '@ts-macro/tsc': ^0.3.6 + '@typescript/native-preview': '>=7.0.0-dev.20260325.1' + rolldown: ^1.0.0 + typescript: ^5.0.0 || ^6.0.0 + vue-tsc: ~3.2.0 + peerDependenciesMeta: + '@ts-macro/tsc': + optional: true + '@typescript/native-preview': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rolldown@1.1.1: + resolution: {integrity: sha512-IN750c0p+s3jqJIsFLRZrQazmbAB1kkQDTtQjSt/gbS2ywLhlv4R5Shazer0FZKmuo/BsO3/w2UoYnUjuOZqHg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + schemastery@3.18.0: + resolution: {integrity: sha512-Jw2uxjoyyqc/yeurmChUEc/jbi8GsrdXV/KmqRUDZXJAXAmrJiPsz8vKa17l/VckyzljHZ9oGaul443CQiXxtA==} + + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} + engines: {node: '>=10'} + hasBin: true + + 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'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + smol-toml@1.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} + engines: {node: '>= 18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + + strnum@2.4.0: + resolution: {integrity: sha512-sHrVyWWdq28RbhjuJdZsA1SnGRJV6NiXbk6AXBxDOsgAcA+lmpUZCYjOdLBxkXMwis6RRe7dlZt4VlIWFVzkmg==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + + 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'} + + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-algebra@2.0.0: + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + deprecated: unmaintained + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tsdown@0.22.2: + resolution: {integrity: sha512-VX9gsyKXsTnBZjnIM4jsHl9aRv+GfgkE/k1hQslilaBfZMlaw3JuGR+6yhiU0QxWBtOCDnTjwOSoXzgB7Rr50g==} + engines: {node: ^22.18.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@arethetypeswrong/core': ^0.18.1 + '@tsdown/css': 0.22.2 + '@tsdown/exe': 0.22.2 + '@vitejs/devtools': '*' + publint: ^0.3.8 + tsx: '*' + typescript: ^5.0.0 || ^6.0.0 + unplugin-unused: ^0.5.0 + unrun: '*' + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + '@tsdown/css': + optional: true + '@tsdown/exe': + optional: true + '@vitejs/devtools': + optional: true + publint: + optional: true + tsx: + optional: true + typescript: + optional: true + unplugin-unused: + optional: true + unrun: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.22.4: + resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typebox@1.1.38: + resolution: {integrity: sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==} + + typescript-eslint@8.61.0: + resolution: {integrity: sha512-8y31Rd0eGTrDKqhy6vT0HtzhN+YLjQizwX3aA3hPXP/ynSfnrBXcQY5IzsP9/DM7+klX4IUncZZjkchP0z+rUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + unbash@3.0.0: + resolution: {integrity: sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA==} + engines: {node: '>=14'} + + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite-tsconfig-paths@6.1.1: + resolution: {integrity: sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==} + peerDependencies: + vite: '*' + + vite@8.0.16: + resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.18 + 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.8: + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} + 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.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 + 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 + + walk-up-path@4.0.0: + resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} + engines: {node: 20 || >=22} + + 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 + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + 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 + + xml-naming@0.1.0: + resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==} + engines: {node: '>=16.0.0'} + + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + 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: + + '@anthropic-ai/sdk@0.91.1(zod@4.4.3)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 4.4.3 + + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.12 + tslib: 2.8.1 + + '@aws-crypto/sha256-browser@5.2.0': + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.12 + '@aws-sdk/util-locate-window': 3.965.7 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.12 + tslib: 2.8.1 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.8.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.973.12 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/client-bedrock-runtime@3.1048.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.974.20 + '@aws-sdk/credential-provider-node': 3.972.55 + '@aws-sdk/eventstream-handler-node': 3.972.21 + '@aws-sdk/middleware-eventstream': 3.972.17 + '@aws-sdk/middleware-websocket': 3.972.28 + '@aws-sdk/token-providers': 3.1048.0 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/fetch-http-handler': 5.4.7 + '@smithy/node-http-handler': 4.7.3 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/core@3.974.20': + dependencies: + '@aws-sdk/types': 3.973.12 + '@aws-sdk/xml-builder': 3.972.29 + '@aws/lambda-invoke-store': 0.2.4 + '@smithy/core': 3.24.7 + '@smithy/signature-v4': 5.4.7 + '@smithy/types': 4.14.4 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.46': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.48': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/fetch-http-handler': 5.4.7 + '@smithy/node-http-handler': 4.7.8 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.972.53': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/credential-provider-env': 3.972.46 + '@aws-sdk/credential-provider-http': 3.972.48 + '@aws-sdk/credential-provider-login': 3.972.52 + '@aws-sdk/credential-provider-process': 3.972.46 + '@aws-sdk/credential-provider-sso': 3.972.52 + '@aws-sdk/credential-provider-web-identity': 3.972.52 + '@aws-sdk/nested-clients': 3.997.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/credential-provider-imds': 4.3.9 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-login@3.972.52': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/nested-clients': 3.997.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-node@3.972.55': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.46 + '@aws-sdk/credential-provider-http': 3.972.48 + '@aws-sdk/credential-provider-ini': 3.972.53 + '@aws-sdk/credential-provider-process': 3.972.46 + '@aws-sdk/credential-provider-sso': 3.972.52 + '@aws-sdk/credential-provider-web-identity': 3.972.52 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/credential-provider-imds': 4.3.9 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-process@3.972.46': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.972.52': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/nested-clients': 3.997.20 + '@aws-sdk/token-providers': 3.1066.0 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-web-identity@3.972.52': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/nested-clients': 3.997.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/eventstream-handler-node@3.972.21': + dependencies: + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/middleware-eventstream@3.972.17': + dependencies: + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/middleware-websocket@3.972.28': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/fetch-http-handler': 5.4.7 + '@smithy/signature-v4': 5.4.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.997.20': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.974.20 + '@aws-sdk/signature-v4-multi-region': 3.996.34 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/fetch-http-handler': 5.4.7 + '@smithy/node-http-handler': 4.7.8 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/signature-v4-multi-region@3.996.34': + dependencies: + '@aws-sdk/types': 3.973.12 + '@smithy/signature-v4': 5.4.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1048.0': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/nested-clients': 3.997.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1066.0': + dependencies: + '@aws-sdk/core': 3.974.20 + '@aws-sdk/nested-clients': 3.997.20 + '@aws-sdk/types': 3.973.12 + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/types@3.973.12': + dependencies: + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@aws-sdk/util-locate-window@3.965.7': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.29': + dependencies: + '@smithy/types': 4.14.4 + fast-xml-parser: 5.7.3 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.2.4': {} + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/generator@8.0.0-rc.6': + dependencies: + '@babel/parser': 8.0.0-rc.6 + '@babel/types': 8.0.0-rc.6 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-string-parser@8.0.0-rc.6': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-identifier@8.0.0-rc.6': {} + + '@babel/parser@7.29.7': + dependencies: + '@babel/types': 7.29.7 + + '@babel/parser@8.0.0-rc.6': + dependencies: + '@babel/types': 8.0.0-rc.6 + + '@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 + + '@babel/types@8.0.0-rc.6': + dependencies: + '@babel/helper-string-parser': 8.0.0-rc.6 + '@babel/helper-validator-identifier': 8.0.0-rc.6 + + '@bcoe/v8-coverage@1.0.2': {} + + '@cordisjs/plugin-include@1.0.4(@cordisjs/plugin-loader@1.0.0-rc.4)(cordis@4.0.0-rc.6)': + dependencies: + '@cordisjs/plugin-loader': 1.0.0-rc.4(cordis@4.0.0-rc.6) + cordis: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: 1.8.1 + js-yaml: 4.2.0 + + '@cordisjs/plugin-loader@1.0.0-rc.4(cordis@4.0.0-rc.6)': + dependencies: + cordis: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: 1.8.1 + + '@cordisjs/plugin-timer@1.1.2(cordis@4.0.0-rc.6)': + dependencies: + cordis: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4) + cosmokit: 1.8.1 + + '@earendil-works/pi-ai@0.79.3(ws@8.21.0)(zod@4.4.3)': + dependencies: + '@anthropic-ai/sdk': 0.91.1(zod@4.4.3) + '@aws-sdk/client-bedrock-runtime': 3.1048.0 + '@google/genai': 1.52.0 + '@mistralai/mistralai': 2.2.1 + '@smithy/node-http-handler': 4.7.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + openai: 6.26.0(ws@8.21.0)(zod@4.4.3) + partial-json: 0.1.7 + typebox: 1.1.38 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/core@1.11.0': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.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 + + '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.7.0))': + dependencies: + eslint: 10.5.0(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.23.5': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3 + minimatch: 10.2.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.6.0': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/core@1.2.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/object-schema@3.0.5': {} + + '@eslint/plugin-kit@0.7.2': + dependencies: + '@eslint/core': 1.2.1 + levn: 0.4.1 + + '@google/genai@1.52.0': + dependencies: + google-auth-library: 10.7.0 + p-retry: 4.6.2 + protobufjs: 7.6.4 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@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 + + '@mistralai/mistralai@2.2.1': + dependencies: + ws: 8.21.0 + zod: 4.4.3 + zod-to-json-schema: 3.25.2(zod@4.4.3) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)': + dependencies: + '@emnapi/core': 1.11.0 + '@emnapi/runtime': 1.11.0 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@nodable/entities@2.2.0': {} + + '@oxc-parser/binding-android-arm-eabi@0.133.0': + optional: true + + '@oxc-parser/binding-android-arm64@0.133.0': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.133.0': + optional: true + + '@oxc-parser/binding-darwin-x64@0.133.0': + optional: true + + '@oxc-parser/binding-freebsd-x64@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm-musleabihf@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.133.0': + optional: true + + '@oxc-parser/binding-linux-ppc64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-riscv64-musl@0.133.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.133.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.133.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.133.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.133.0': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.133.0': + optional: true + + '@oxc-parser/binding-win32-ia32-msvc@0.133.0': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.133.0': + optional: true + + '@oxc-project/types@0.133.0': {} + + '@oxc-project/types@0.135.0': {} + + '@oxc-resolver/binding-android-arm-eabi@11.20.0': + optional: true + + '@oxc-resolver/binding-android-arm64@11.20.0': + optional: true + + '@oxc-resolver/binding-darwin-arm64@11.20.0': + optional: true + + '@oxc-resolver/binding-darwin-x64@11.20.0': + optional: true + + '@oxc-resolver/binding-freebsd-x64@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-arm-musleabihf@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-ppc64-gnu@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-riscv64-musl@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@11.20.0': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@11.20.0': + optional: true + + '@oxc-resolver/binding-openharmony-arm64@11.20.0': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@11.20.0': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@11.20.0': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@11.20.0': + optional: true + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.1': {} + + '@protobufjs/fetch@1.1.1': + dependencies: + '@protobufjs/aspromise': 1.1.2 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.1': {} + + '@publint/pack@0.1.4': {} + + '@quansync/fs@1.0.0': + dependencies: + quansync: 1.0.0 + + '@rolldown/binding-android-arm64@1.0.3': + optional: true + + '@rolldown/binding-android-arm64@1.1.1': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.3': + optional: true + + '@rolldown/binding-darwin-arm64@1.1.1': + optional: true + + '@rolldown/binding-darwin-x64@1.0.3': + optional: true + + '@rolldown/binding-darwin-x64@1.1.1': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.1.1': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.1.1': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.1.1': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.1.1': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.1.1': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.1.1': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.1.1': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.1.1': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.1.1': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.3': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@rolldown/binding-wasm32-wasi@1.1.1': + dependencies: + '@emnapi/core': 1.11.0 + '@emnapi/runtime': 1.11.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.1.1': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.1.1': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@smithy/core@3.24.7': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.3.9': + dependencies: + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.4.7': + dependencies: + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/node-http-handler@4.7.3': + dependencies: + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.7.8': + dependencies: + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@smithy/signature-v4@5.4.7': + dependencies: + '@smithy/core': 3.24.7 + '@smithy/types': 4.14.4 + tslib: 2.8.1 + + '@smithy/types@4.14.4': + dependencies: + tslib: 2.8.1 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 + + '@standard-schema/spec@1.1.0': {} + + '@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.7.0))': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@typescript-eslint/types': 8.61.0 + eslint: 10.5.0(jiti@2.7.0) + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + estraverse: 5.3.0 + picomatch: 4.0.4 + + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/babel__code-frame@7.27.0': {} + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/esrecurse@4.3.1': {} + + '@types/estree@1.0.9': {} + + '@types/jsesc@2.5.1': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@25.9.3': + dependencies: + undici-types: 7.24.6 + + '@types/picomatch@3.0.2': {} + + '@types/retry@0.12.0': {} + + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/type-utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 + eslint: 10.5.0(jiti@2.7.0) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 + debug: 4.4.3 + eslint: 10.5.0(jiti@2.7.0) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.61.0(typescript@6.0.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + debug: 4.4.3 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.61.0': + dependencies: + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 + + '@typescript-eslint/tsconfig-utils@8.61.0(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 + + '@typescript-eslint/type-utils@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + debug: 4.4.3 + eslint: 10.5.0(jiti@2.7.0) + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.61.0': {} + + '@typescript-eslint/typescript-estree@8.61.0(typescript@6.0.3)': + dependencies: + '@typescript-eslint/project-service': 8.61.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.8.4 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.61.0': + dependencies: + '@typescript-eslint/types': 8.61.0 + eslint-visitor-keys: 5.0.1 + + '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.8 + 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.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) + + '@vitest/expect@4.1.8': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))': + dependencies: + '@vitest/spy': 4.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0) + + '@vitest/pretty-format@4.1.8': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.8': + dependencies: + '@vitest/utils': 4.1.8 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.8': + dependencies: + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.8': {} + + '@vitest/utils@4.1.8': + dependencies: + '@vitest/pretty-format': 4.1.8 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + + acorn@8.17.0: {} + + agent-base@7.1.4: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansis@4.3.1: {} + + anynum@1.0.0: {} + + argparse@2.0.1: {} + + assertion-error@2.0.1: {} + + ast-kit@3.0.0-beta.1: + dependencies: + '@babel/parser': 8.0.0-rc.6 + estree-walker: 3.0.3 + pathe: 2.0.3 + + ast-v8-to-istanbul@1.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + + balanced-match@4.0.4: {} + + base64-js@1.5.1: {} + + bignumber.js@9.3.1: {} + + birpc@4.0.0: {} + + bowser@2.14.1: {} + + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + + buffer-equal-constant-time@1.0.1: {} + + cac@7.0.0: {} + + chai@6.2.2: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + convert-source-map@2.0.0: {} + + cordis@4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4): + dependencies: + '@standard-schema/spec': 1.1.0 + cosmokit: 1.8.1 + optionalDependencies: + '@cordisjs/plugin-include': 1.0.4(@cordisjs/plugin-loader@1.0.0-rc.4)(cordis@4.0.0-rc.6) + '@cordisjs/plugin-loader': 1.0.0-rc.4(cordis@4.0.0-rc.6) + + cosmokit@1.8.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-uri-to-buffer@4.0.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + defu@6.1.7: {} + + detect-libc@2.1.2: {} + + dts-resolver@3.0.0(oxc-resolver@11.20.0): + optionalDependencies: + oxc-resolver: 11.20.0 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + empathic@2.0.1: {} + + es-module-lexer@2.1.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 + + escape-string-regexp@4.0.0: {} + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.9 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@10.5.0(jiti@2.7.0): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.6.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.2 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.7.0 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + eslint-visitor-keys: 4.2.1 + + espree@11.2.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + eslint-visitor-keys: 5.0.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + esutils@2.0.3: {} + + expect-type@1.3.0: {} + + extend@3.0.2: {} + + fast-check@4.8.0: + dependencies: + pure-rand: 8.4.0 + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-xml-builder@1.2.0: + dependencies: + path-expression-matcher: 1.5.0 + xml-naming: 0.1.0 + + fast-xml-parser@5.7.3: + dependencies: + '@nodable/entities': 2.2.0 + fast-xml-builder: 1.2.0 + path-expression-matcher: 1.5.0 + strnum: 2.4.0 + + fd-package-json@2.0.0: + dependencies: + walk-up-path: 4.0.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + formatly@0.3.0: + dependencies: + fd-package-json: 2.0.0 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fsevents@2.3.3: + optional: true + + gaxios@7.1.5: + 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.5 + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + get-tsconfig@5.0.0-beta.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globrex@0.1.2: {} + + google-auth-library@10.7.0: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.5 + gcp-metadata: 8.1.2 + google-logging-utils: 1.1.3 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-logging-utils@1.1.3: {} + + has-flag@4.0.0: {} + + hookable@6.1.1: {} + + html-escaper@2.0.2: {} + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-without-cache@0.4.0: {} + + imurmurhash@0.1.4: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + isexe@2.0.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 + + jiti@2.7.0: {} + + js-tokens@10.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.2.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + + json-buffer@3.0.1: {} + + json-schema-to-ts@3.1.1: + dependencies: + '@babel/runtime': 7.29.7 + ts-algebra: 2.0.0 + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.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 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + knip@6.16.1: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + formatly: 0.3.0 + get-tsconfig: 4.14.0 + jiti: 2.7.0 + oxc-parser: 0.133.0 + oxc-resolver: 11.20.0 + picomatch: 4.0.4 + smol-toml: 1.6.1 + strip-json-comments: 5.0.3 + tinyglobby: 0.2.17 + unbash: 3.0.0 + yaml: 2.9.0 + zod: 4.4.3 + + lefthook-darwin-arm64@2.1.9: + optional: true + + lefthook-darwin-x64@2.1.9: + optional: true + + lefthook-freebsd-arm64@2.1.9: + optional: true + + lefthook-freebsd-x64@2.1.9: + optional: true + + lefthook-linux-arm64@2.1.9: + optional: true + + lefthook-linux-x64@2.1.9: + optional: true + + lefthook-openbsd-arm64@2.1.9: + optional: true + + lefthook-openbsd-x64@2.1.9: + optional: true + + lefthook-windows-arm64@2.1.9: + optional: true + + lefthook-windows-x64@2.1.9: + optional: true + + lefthook@2.1.9: + optionalDependencies: + lefthook-darwin-arm64: 2.1.9 + lefthook-darwin-x64: 2.1.9 + lefthook-freebsd-arm64: 2.1.9 + lefthook-freebsd-x64: 2.1.9 + lefthook-linux-arm64: 2.1.9 + lefthook-linux-x64: 2.1.9 + lefthook-openbsd-arm64: 2.1.9 + lefthook-openbsd-x64: 2.1.9 + lefthook-windows-arm64: 2.1.9 + lefthook-windows-x64: 2.1.9 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + 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 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + long@5.3.2: {} + + 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.4 + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + + mri@1.2.0: {} + + ms@2.1.3: {} + + nanoid@3.3.12: {} + + natural-compare@1.4.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 + + obug@2.1.3: {} + + openai@6.26.0(ws@8.21.0)(zod@4.4.3): + optionalDependencies: + ws: 8.21.0 + zod: 4.4.3 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + oxc-parser@0.133.0: + dependencies: + '@oxc-project/types': 0.133.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.133.0 + '@oxc-parser/binding-android-arm64': 0.133.0 + '@oxc-parser/binding-darwin-arm64': 0.133.0 + '@oxc-parser/binding-darwin-x64': 0.133.0 + '@oxc-parser/binding-freebsd-x64': 0.133.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.133.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.133.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.133.0 + '@oxc-parser/binding-linux-arm64-musl': 0.133.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.133.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.133.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.133.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.133.0 + '@oxc-parser/binding-linux-x64-gnu': 0.133.0 + '@oxc-parser/binding-linux-x64-musl': 0.133.0 + '@oxc-parser/binding-openharmony-arm64': 0.133.0 + '@oxc-parser/binding-wasm32-wasi': 0.133.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.133.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.133.0 + '@oxc-parser/binding-win32-x64-msvc': 0.133.0 + + oxc-resolver@11.20.0: + optionalDependencies: + '@oxc-resolver/binding-android-arm-eabi': 11.20.0 + '@oxc-resolver/binding-android-arm64': 11.20.0 + '@oxc-resolver/binding-darwin-arm64': 11.20.0 + '@oxc-resolver/binding-darwin-x64': 11.20.0 + '@oxc-resolver/binding-freebsd-x64': 11.20.0 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.20.0 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.20.0 + '@oxc-resolver/binding-linux-arm64-gnu': 11.20.0 + '@oxc-resolver/binding-linux-arm64-musl': 11.20.0 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.20.0 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.20.0 + '@oxc-resolver/binding-linux-riscv64-musl': 11.20.0 + '@oxc-resolver/binding-linux-s390x-gnu': 11.20.0 + '@oxc-resolver/binding-linux-x64-gnu': 11.20.0 + '@oxc-resolver/binding-linux-x64-musl': 11.20.0 + '@oxc-resolver/binding-openharmony-arm64': 11.20.0 + '@oxc-resolver/binding-wasm32-wasi': 11.20.0 + '@oxc-resolver/binding-win32-arm64-msvc': 11.20.0 + '@oxc-resolver/binding-win32-x64-msvc': 11.20.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-retry@4.6.2: + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + + package-manager-detector@1.6.0: {} + + partial-json@0.1.7: {} + + path-exists@4.0.0: {} + + path-expression-matcher@1.5.0: {} + + path-key@3.1.1: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.4: {} + + postcss@8.5.15: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + protobufjs@7.6.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.1 + '@protobufjs/fetch': 1.1.1 + '@protobufjs/float': 1.0.2 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.1 + '@types/node': 25.9.3 + long: 5.3.2 + + publint@0.3.21: + dependencies: + '@publint/pack': 0.1.4 + package-manager-detector: 1.6.0 + picocolors: 1.1.1 + sade: 1.8.1 + + punycode@2.3.1: {} + + pure-rand@8.4.0: {} + + quansync@1.0.0: {} + + readdirp@4.1.2: {} + + resolve-pkg-maps@1.0.0: {} + + retry@0.13.1: {} + + rolldown-plugin-dts@0.25.2(oxc-resolver@11.20.0)(rolldown@1.1.1)(typescript@6.0.3): + dependencies: + '@babel/generator': 8.0.0-rc.6 + '@babel/helper-validator-identifier': 8.0.0-rc.6 + '@babel/parser': 8.0.0-rc.6 + ast-kit: 3.0.0-beta.1 + birpc: 4.0.0 + dts-resolver: 3.0.0(oxc-resolver@11.20.0) + get-tsconfig: 5.0.0-beta.5 + obug: 2.1.3 + rolldown: 1.1.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - oxc-resolver + + rolldown@1.0.3: + dependencies: + '@oxc-project/types': 0.133.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 + + rolldown@1.1.1: + dependencies: + '@oxc-project/types': 0.135.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.1.1 + '@rolldown/binding-darwin-arm64': 1.1.1 + '@rolldown/binding-darwin-x64': 1.1.1 + '@rolldown/binding-freebsd-x64': 1.1.1 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.1 + '@rolldown/binding-linux-arm64-gnu': 1.1.1 + '@rolldown/binding-linux-arm64-musl': 1.1.1 + '@rolldown/binding-linux-ppc64-gnu': 1.1.1 + '@rolldown/binding-linux-s390x-gnu': 1.1.1 + '@rolldown/binding-linux-x64-gnu': 1.1.1 + '@rolldown/binding-linux-x64-musl': 1.1.1 + '@rolldown/binding-openharmony-arm64': 1.1.1 + '@rolldown/binding-wasm32-wasi': 1.1.1 + '@rolldown/binding-win32-arm64-msvc': 1.1.1 + '@rolldown/binding-win32-x64-msvc': 1.1.1 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safe-buffer@5.2.1: {} + + schemastery@3.18.0: + dependencies: + '@standard-schema/spec': 1.1.0 + cosmokit: 1.8.1 + + semver@7.8.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + smol-toml@1.6.1: {} + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@4.1.0: {} + + strip-json-comments@5.0.3: {} + + strnum@2.4.0: + dependencies: + anynum: 1.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@9.4.0: {} + + tinybench@2.9.0: {} + + tinyexec@1.2.4: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinyrainbow@3.1.0: {} + + tree-kill@1.2.2: {} + + ts-algebra@2.0.0: {} + + ts-api-utils@2.5.0(typescript@6.0.3): + dependencies: + typescript: 6.0.3 + + tsconfck@3.1.6(typescript@6.0.3): + optionalDependencies: + typescript: 6.0.3 + + tsdown@0.22.2(oxc-resolver@11.20.0)(publint@0.3.21)(tsx@4.22.4)(typescript@6.0.3): + dependencies: + ansis: 4.3.1 + cac: 7.0.0 + defu: 6.1.7 + empathic: 2.0.1 + hookable: 6.1.1 + import-without-cache: 0.4.0 + obug: 2.1.3 + picomatch: 4.0.4 + rolldown: 1.1.1 + rolldown-plugin-dts: 0.25.2(oxc-resolver@11.20.0)(rolldown@1.1.1)(typescript@6.0.3) + semver: 7.8.4 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + optionalDependencies: + publint: 0.3.21 + tsx: 4.22.4 + typescript: 6.0.3 + transitivePeerDependencies: + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - vue-tsc + + tslib@2.8.1: {} + + tsx@4.22.4: + dependencies: + esbuild: 0.28.1 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typebox@1.1.38: {} + + typescript-eslint@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + typescript@6.0.3: {} + + unbash@3.0.0: {} + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 + + undici-types@7.24.6: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite-tsconfig-paths@6.1.1(typescript@6.0.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)): + dependencies: + debug: 4.4.3 + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@6.0.3) + vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0) + transitivePeerDependencies: + - supports-color + - typescript + + vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.0.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 25.9.3 + esbuild: 0.28.1 + fsevents: 2.3.3 + jiti: 2.7.0 + tsx: 4.22.4 + yaml: 2.9.0 + + vitest@4.1.8(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)): + dependencies: + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + 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.0.16(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.9.3 + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) + transitivePeerDependencies: + - msw + + walk-up-path@4.0.0: {} + + 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 + + word-wrap@1.2.5: {} + + ws@8.21.0: {} + + xml-naming@0.1.0: {} + + yaml@2.9.0: {} + + yocto-queue@0.1.0: {} + + zod-to-json-schema@3.25.2(zod@4.4.3): + dependencies: + zod: 4.4.3 + + zod@4.4.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000000..a7b71bf734 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,13 @@ +packages: + - vendor/* + - packages/* + +peerDependencyRules: + allowedVersions: + typescript: '>=5 <7' + +allowBuilds: + '@google/genai': true + esbuild: true + lefthook: true + protobufjs: true diff --git a/scripts/check-workspace-constraints.ts b/scripts/check-workspace-constraints.ts new file mode 100644 index 0000000000..50b1a80078 --- /dev/null +++ b/scripts/check-workspace-constraints.ts @@ -0,0 +1,97 @@ +/** + * Workspace package invariant checks for package-manager-independent quality + * gates. + * + * Run: `tsx scripts/check-workspace-constraints.ts`. + */ + +import { readdirSync, readFileSync } from 'node:fs' +import { join, relative, resolve } from 'node:path' + +const root = resolve(import.meta.dirname, '..') +const workspaceGlobs = ['vendor', 'packages'] as const +const vendoredPackages = new Set([ + 'cordis', + 'cosmokit', + 'schemastery', + '@cordisjs/plugin-loader', + '@cordisjs/plugin-include', + '@cordisjs/plugin-group', + '@cordisjs/plugin-timer', + '@cordisjs/plugin-hmr', + '@cordisjs/plugin-logger-console', +]) + +/** The subset of package.json fields this constraint check cares about. */ +interface PackageManifest { + name?: string + version?: string + private?: boolean + type?: string + peerDependencies?: Record + devDependencies?: Record +} + +/** One workspace manifest and its repo-relative path. */ +interface WorkspaceManifest { + dir: string + manifest: PackageManifest +} + +function readJson(path: string): PackageManifest { + return JSON.parse(readFileSync(path, 'utf8')) as PackageManifest +} + +function workspaceManifests(): WorkspaceManifest[] { + const manifests: WorkspaceManifest[] = [ + { dir: '.', manifest: readJson(join(root, 'package.json')) }, + ] + + for (const workspaceDir of workspaceGlobs) { + for (const entry of readdirSync(join(root, workspaceDir), { withFileTypes: true })) { + if (!entry.isDirectory()) continue + const dir = join(workspaceDir, entry.name) + manifests.push({ dir, manifest: readJson(join(root, dir, 'package.json')) }) + } + } + + return manifests +} + +function checkWorkspace({ dir, manifest }: WorkspaceManifest): string[] { + const errors: string[] = [] + const label = manifest.name ?? dir + + if (manifest.private !== true) { + errors.push(`${label}: package.json must set "private": true`) + } + + if (manifest.name && vendoredPackages.has(manifest.name)) { + return errors + } + + if (manifest.name?.startsWith('@deepseek-ai/dsh-') && manifest.name !== '@deepseek-ai/dsh-root') { + const peer = manifest.peerDependencies?.cordis + const dev = manifest.devDependencies?.cordis + + if (!peer) errors.push(`${label}: cordis must be a peerDependency`) + if (!dev) errors.push(`${label}: cordis must also be a devDependency`) + if (peer && dev && peer !== dev) { + errors.push(`${label}: cordis peer (${peer}) and dev (${dev}) ranges must match`) + } + if (manifest.version !== '0.0.1') { + errors.push(`${label}: package.json must set "version": "0.0.1"`) + } + if (manifest.type !== 'module') { + errors.push(`${label}: package.json must set "type": "module"`) + } + } + + return errors.map(error => `${relative(root, join(root, dir, 'package.json'))}: ${error}`) +} + +const errors = workspaceManifests().flatMap(checkWorkspace) +if (errors.length > 0) { + console.error(errors.join('\n')) + process.exitCode = 1 +} diff --git a/scripts/doc-typecheck.ts b/scripts/doc-typecheck.ts index cd873402c3..f95e4df1f0 100644 --- a/scripts/doc-typecheck.ts +++ b/scripts/doc-typecheck.ts @@ -62,10 +62,10 @@ function extractBlocks(absPath: string): Block[] { /** * Read the workspace `paths` map from tsconfig.typecheck.json (JSONC). This map * resolves vendored packages to their BUILT declarations (`lib`) and harness - * packages to source (`src`) — the same resolution `yarn lint`/`typecheck` use. + * packages to source (`src`) — the same resolution `pnpm run lint`/`typecheck` use. * Resolving vendor to `lib` (not `src`) is essential: otherwise tsc type-checks * raw vendor source and floods the run with unrelated errors. Requires the - * vendor `lib/` to exist (a fresh clone runs `yarn build` first; CI does too). + * vendor `lib/` to exist (a fresh clone runs `pnpm run build` first; CI does too). */ function workspacePaths(): Record { const raw = readFileSync(join(root, 'tsconfig.typecheck.json'), 'utf8') diff --git a/tsdown.config.ts b/tsdown.config.ts index 1ccc12a6d2..3b9039cc36 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -11,7 +11,7 @@ import { defineConfig } from 'tsdown' */ export default defineConfig({ // Explicit globs: `workspace: true` would also discover examples/* (any - // package.json), but only vendor/* and packages/* are yarn workspaces. + // package.json), but only vendor/* and packages/* are pnpm workspaces. workspace: ['vendor/*', 'packages/*'], entry: ['src/index.ts'], outDir: 'lib', diff --git a/vendor/README.md b/vendor/README.md index 8ab3498053..04e63f26c1 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -2,7 +2,7 @@ This directory contains source-vendored copies of the Cordis framework and its foundation libraries. They are copied into this monorepo instead of being depended on via npm, so that the harness fully owns its framework layer (auditable, patchable, pinned). -All vendored packages keep their **original npm names** (they are resolved through Yarn workspaces) and are marked `private: true` — they are never published from this repo. Upstream MIT `LICENSE` files are preserved in each package directory. +All vendored packages keep their **original npm names** (they are resolved through pnpm workspaces) and are marked `private: true` — they are never published from this repo. Upstream MIT `LICENSE` files are preserved in each package directory. This file covers the manifest, the local-modification log, and the procedure for **updating** an existing vendored package. To **add a new** one, see the cookbook guide: [docs/cookbook/adding-a-vendored-package.md](../docs/cookbook/adding-a-vendored-package.md). @@ -31,7 +31,7 @@ Intentionally **not** vendored (verified unused by this set): `reggol`, `@cordis Keep this log exhaustive — every divergence from upstream must be listed. 1. **`hmr/src/index.ts`**: removed the `./locales/en-US.yml` / `./locales/zh-CN.yml` imports, the `.i18n({...})` call on the `Config` schema, and the `src/locales/` directory. Rationale: those imports require a runtime YAML loader hook (`@cordisjs/unyaml`) that we do not vendor; the i18n texts only localize config descriptions. -2. **All `package.json` files**: regenerated — added `private: true`, added `src` to `files` and a `./src/*` export where missing, removed upstream `devDependencies`/`scripts`/`repository` fields. Dependency and peer-dependency ranges preserved. +2. **All `package.json` files**: regenerated — added `private: true`, added `src` to `files` and a `./src/*` export where missing, removed upstream `devDependencies`/`scripts`/`repository` fields. Dependency and peer-dependency ranges preserved, except `hmr` declares `esbuild` as a direct dev dependency because its source imports the `BuildFailure` type and pnpm's strict workspace resolution requires the owner package to name that dependency. 3. **All `tsconfig.json` files**: regenerated to extend the repo-root `tsconfig.base.json` and declare project references. 4. **`schemastery/tsdown.config.ts` and `logger-console/tsdown.config.ts`**: ours, not upstream files — per-package build-shape overrides (dual ESM+CJS output; separate node/browser entries) for the repo-root tsdown build. Like the regenerated tsconfigs, they are not part of the upstream sync surface. @@ -43,4 +43,4 @@ To update a vendored package from upstream: 2. Copy the package's `src/` (and `bin.js`, `README.md`, `LICENSE` if changed) over the vendored directory. 3. Re-apply the local modifications listed above (or drop them if upstream made them unnecessary — update the log either way). 4. Update the version and commit hash in the manifest table. -5. Run `yarn install && yarn test && yarn build` at the repo root. +5. Run `pnpm install && pnpm run test && pnpm run build` at the repo root. diff --git a/vendor/hmr/package.json b/vendor/hmr/package.json index 3d0af11e96..075968a3ba 100644 --- a/vendor/hmr/package.json +++ b/vendor/hmr/package.json @@ -44,6 +44,7 @@ }, "devDependencies": { "@types/babel__code-frame": "^7.27.0", - "@types/picomatch": "^3.0.2" + "@types/picomatch": "^3.0.2", + "esbuild": "^0.28.1" } } diff --git a/vitest.config.ts b/vitest.config.ts index a4dd571127..e8eb5e204e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,7 +11,7 @@ export default defineConfig({ // importing file it discovers the NEAREST tsconfig.json and applies that // file's own `paths`. Every workspace under packages/* and vendor/* has its // own tsconfig.json without `paths`, so native resolution maps nothing, - // falls through to package.json exports (lib/, absent until `yarn build`), + // falls through to package.json exports (lib/, absent until `pnpm run build`), // and every test file fails to import (verified on vite 8.0.16 / // vitest 4.1.8). Making it work would mean copying the paths map into all // 15 workspace tsconfigs — including vendor/* ones, which are pinned diff --git a/vitest.e2e.config.ts b/vitest.e2e.config.ts index 7ae0d0bd17..9316d660da 100644 --- a/vitest.e2e.config.ts +++ b/vitest.e2e.config.ts @@ -1,8 +1,8 @@ import tsconfigPaths from 'vite-tsconfig-paths' import { defineConfig } from 'vitest/config' -// Real-API end-to-end tests: `yarn test:e2e`, file pattern *.e2e.ts. -// Separate from the default suite (`yarn test`, *.spec.ts) on purpose — +// Real-API end-to-end tests: `pnpm run test:e2e`, file pattern *.e2e.ts. +// Separate from the default suite (`pnpm run test`, *.spec.ts) on purpose — // these hit the live DeepSeek API, spend tokens, and need a key. // // Secrets: tests gate themselves with diff --git a/yarn.config.cjs b/yarn.config.cjs deleted file mode 100644 index eb5ecb6f4b..0000000000 --- a/yarn.config.cjs +++ /dev/null @@ -1,53 +0,0 @@ -// Yarn constraints: mechanize the package rules from AGENTS.md. -// Run with `yarn constraints`; CI fails on violations. -// -// 1. Every package is private (nothing publishes from this repo yet). -// 2. Harness packages (@deepseek-ai/dsh-*) declare `cordis` as BOTH a -// peerDependency and a devDependency (upstream Cordis convention). -// 3. Harness packages are versioned 0.0.1 (bumped together, later via tooling). -// 4. Vendored packages keep their upstream versions — constraints don't touch -// them beyond privacy. -// 5. All packages are ESM (`"type": "module"`) — except vendored packages -// whose upstream isn't (schemastery ships dual cjs/mjs without type). - -/** @type {import('@yarnpkg/types')} */ -const { defineConfig } = require('@yarnpkg/types') - -const VENDORED = new Set([ - 'cordis', 'cosmokit', 'schemastery', - '@cordisjs/plugin-loader', '@cordisjs/plugin-include', '@cordisjs/plugin-group', - '@cordisjs/plugin-timer', '@cordisjs/plugin-hmr', '@cordisjs/plugin-logger-console', -]) - -module.exports = defineConfig({ - async constraints({ Yarn }) { - for (const workspace of Yarn.workspaces()) { - const name = workspace.manifest.name - - // (1) everything stays private - workspace.set('private', true) - - if (name?.startsWith('@deepseek-ai/dsh-') && name !== '@deepseek-ai/dsh-root') { - // (2) cordis as peer + dev - const peer = Yarn.dependency({ workspace, ident: 'cordis', type: 'peerDependencies' }) - const dev = Yarn.dependency({ workspace, ident: 'cordis', type: 'devDependencies' }) - if (!peer) workspace.error(`${name}: cordis must be a peerDependency`) - if (!dev) workspace.error(`${name}: cordis must also be a devDependency`) - if (peer && dev && peer.range !== dev.range) { - workspace.error(`${name}: cordis peer (${peer.range}) and dev (${dev.range}) ranges must match`) - } - - // (3) uniform version - workspace.set('version', '0.0.1') - - // (5) ESM - workspace.set('type', 'module') - } - - if (name && VENDORED.has(name)) { - // (4) vendored: privacy only; versions/fields follow upstream - continue - } - } - }, -}) diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index e3e3a55972..0000000000 --- a/yarn.lock +++ /dev/null @@ -1,4864 +0,0 @@ -# This file is generated by running "yarn install" inside your project. -# Manual changes might be lost - proceed with caution! - -__metadata: - version: 9 - cacheKey: 10c0 - -"@anthropic-ai/sdk@npm:0.91.1": - version: 0.91.1 - resolution: "@anthropic-ai/sdk@npm:0.91.1" - dependencies: - json-schema-to-ts: "npm:^3.1.1" - peerDependencies: - zod: ^3.25.0 || ^4.0.0 - peerDependenciesMeta: - zod: - optional: true - bin: - anthropic-ai-sdk: bin/cli - checksum: 10c0/aa9fb1b3d0ae47f492ee7a94b76d341ac7c5486b222a9426b4815b07a65a0b6f502430b0250ff5bf2201a0cdae725a5d4f1f7a4aaa075e9fb32cc2ac10d70241 - languageName: node - linkType: hard - -"@aws-crypto/crc32@npm:5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/crc32@npm:5.2.0" - dependencies: - "@aws-crypto/util": "npm:^5.2.0" - "@aws-sdk/types": "npm:^3.222.0" - tslib: "npm:^2.6.2" - checksum: 10c0/eab9581d3363af5ea498ae0e72de792f54d8890360e14a9d8261b7b5c55ebe080279fb2556e07994d785341cdaa99ab0b1ccf137832b53b5904cd6928f2b094b - languageName: node - linkType: hard - -"@aws-crypto/sha256-browser@npm:5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/sha256-browser@npm:5.2.0" - dependencies: - "@aws-crypto/sha256-js": "npm:^5.2.0" - "@aws-crypto/supports-web-crypto": "npm:^5.2.0" - "@aws-crypto/util": "npm:^5.2.0" - "@aws-sdk/types": "npm:^3.222.0" - "@aws-sdk/util-locate-window": "npm:^3.0.0" - "@smithy/util-utf8": "npm:^2.0.0" - tslib: "npm:^2.6.2" - checksum: 10c0/05f6d256794df800fe9aef5f52f2ac7415f7f3117d461f85a6aecaa4e29e91527b6fd503681a17136fa89e9dd3d916e9c7e4cfb5eba222875cb6c077bdc1d00d - languageName: node - linkType: hard - -"@aws-crypto/sha256-js@npm:5.2.0, @aws-crypto/sha256-js@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/sha256-js@npm:5.2.0" - dependencies: - "@aws-crypto/util": "npm:^5.2.0" - "@aws-sdk/types": "npm:^3.222.0" - tslib: "npm:^2.6.2" - checksum: 10c0/6c48701f8336341bb104dfde3d0050c89c288051f6b5e9bdfeb8091cf3ffc86efcd5c9e6ff2a4a134406b019c07aca9db608128f8d9267c952578a3108db9fd1 - languageName: node - linkType: hard - -"@aws-crypto/supports-web-crypto@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/supports-web-crypto@npm:5.2.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10c0/4d2118e29d68ca3f5947f1e37ce1fbb3239a0c569cc938cdc8ab8390d595609b5caf51a07c9e0535105b17bf5c52ea256fed705a07e9681118120ab64ee73af2 - languageName: node - linkType: hard - -"@aws-crypto/util@npm:^5.2.0": - version: 5.2.0 - resolution: "@aws-crypto/util@npm:5.2.0" - dependencies: - "@aws-sdk/types": "npm:^3.222.0" - "@smithy/util-utf8": "npm:^2.0.0" - tslib: "npm:^2.6.2" - checksum: 10c0/0362d4c197b1fd64b423966945130207d1fe23e1bb2878a18e361f7743c8d339dad3f8729895a29aa34fff6a86c65f281cf5167c4bf253f21627ae80b6dd2951 - languageName: node - linkType: hard - -"@aws-sdk/client-bedrock-runtime@npm:3.1048.0": - version: 3.1048.0 - resolution: "@aws-sdk/client-bedrock-runtime@npm:3.1048.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:^3.974.11" - "@aws-sdk/credential-provider-node": "npm:^3.972.42" - "@aws-sdk/eventstream-handler-node": "npm:^3.972.16" - "@aws-sdk/middleware-eventstream": "npm:^3.972.12" - "@aws-sdk/middleware-websocket": "npm:^3.972.19" - "@aws-sdk/token-providers": "npm:3.1048.0" - "@aws-sdk/types": "npm:^3.973.8" - "@smithy/core": "npm:^3.24.2" - "@smithy/fetch-http-handler": "npm:^5.4.2" - "@smithy/node-http-handler": "npm:^4.7.2" - "@smithy/types": "npm:^4.14.1" - tslib: "npm:^2.6.2" - checksum: 10c0/8172a964cf580631e02906bc1312f1b44ad862a367417600e45f65f79a6f35318a713393ba565af6b73292071ee52751d405696a864820b12c70ffdb75dc06c1 - languageName: node - linkType: hard - -"@aws-sdk/core@npm:^3.974.11, @aws-sdk/core@npm:^3.974.20": - version: 3.974.20 - resolution: "@aws-sdk/core@npm:3.974.20" - dependencies: - "@aws-sdk/types": "npm:^3.973.12" - "@aws-sdk/xml-builder": "npm:^3.972.29" - "@aws/lambda-invoke-store": "npm:^0.2.2" - "@smithy/core": "npm:^3.24.6" - "@smithy/signature-v4": "npm:^5.4.6" - "@smithy/types": "npm:^4.14.3" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10c0/ed6a1b274802c7332dd4e10ab8f615402019de3d86fdae6de928c1ffea83575234410e0ed921a03ef5bf789fbbdbfd00998967fc133c88d93ee7f7e0d31f96b1 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-env@npm:^3.972.46": - version: 3.972.46 - resolution: "@aws-sdk/credential-provider-env@npm:3.972.46" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/b535e8b4b41e15aead05027074dd14dab26eb7273027085508383e0aadbb1fea7c0a58d85cde79071169a2956ecca3035310492d4da2c2275fe869cbc35b69d2 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-http@npm:^3.972.48": - version: 3.972.48 - resolution: "@aws-sdk/credential-provider-http@npm:3.972.48" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/fetch-http-handler": "npm:^5.4.6" - "@smithy/node-http-handler": "npm:^4.7.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/e8418a8faba5a148ef27d28810ddf0152c7dbf45a8087e62afc07e395f654dc647e4ca9c2c5e9e4cfa1089c8c96809c4a23383880c9b8743b1e4c2a128d99257 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-ini@npm:^3.972.53": - version: 3.972.53 - resolution: "@aws-sdk/credential-provider-ini@npm:3.972.53" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/credential-provider-env": "npm:^3.972.46" - "@aws-sdk/credential-provider-http": "npm:^3.972.48" - "@aws-sdk/credential-provider-login": "npm:^3.972.52" - "@aws-sdk/credential-provider-process": "npm:^3.972.46" - "@aws-sdk/credential-provider-sso": "npm:^3.972.52" - "@aws-sdk/credential-provider-web-identity": "npm:^3.972.52" - "@aws-sdk/nested-clients": "npm:^3.997.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/credential-provider-imds": "npm:^4.3.7" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/e43fd1f3d01266ff3b32d8b46b5caf054af9c944acecfd7c556cc75527bad4029f7872fa5f1458a9713cda99ac871a829a28f554b12d8f0bf8826d2f64692407 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-login@npm:^3.972.52": - version: 3.972.52 - resolution: "@aws-sdk/credential-provider-login@npm:3.972.52" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/nested-clients": "npm:^3.997.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/beaaacdc2462a450e247cedf100f0299072cc342783dd27ee3206513870e90d64ab2e68c01c7af4254439418096359294581080213ebdf4499280f2d3f0d7790 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-node@npm:^3.972.42": - version: 3.972.55 - resolution: "@aws-sdk/credential-provider-node@npm:3.972.55" - dependencies: - "@aws-sdk/credential-provider-env": "npm:^3.972.46" - "@aws-sdk/credential-provider-http": "npm:^3.972.48" - "@aws-sdk/credential-provider-ini": "npm:^3.972.53" - "@aws-sdk/credential-provider-process": "npm:^3.972.46" - "@aws-sdk/credential-provider-sso": "npm:^3.972.52" - "@aws-sdk/credential-provider-web-identity": "npm:^3.972.52" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/credential-provider-imds": "npm:^4.3.7" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/230854be40054778d2b55691cfe0b42752ec84407e9ef5c97f4fcaec5fd043827dabc02f5a39a91c6b1518735c19e0dff7bf3c232ea248f02d3d4b13c183c546 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-process@npm:^3.972.46": - version: 3.972.46 - resolution: "@aws-sdk/credential-provider-process@npm:3.972.46" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/942d20417ae2476c36ae3549bf27b4f6adbc5acf35e121e2bb09c3cabbb85299dcf488e8a2c5faaa8208efde5abc4d689afc1966f96ebbb3f8219c9185602ec0 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-sso@npm:^3.972.52": - version: 3.972.52 - resolution: "@aws-sdk/credential-provider-sso@npm:3.972.52" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/nested-clients": "npm:^3.997.20" - "@aws-sdk/token-providers": "npm:3.1066.0" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/bbbdda4307915d5bba83643b69e5841a5097deb51cacb9cae32b1ba1a05c866689fb310d8aea184db0cfd9cea5d4f5a77b96521c5a853e90daca179de3d5d72f - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-web-identity@npm:^3.972.52": - version: 3.972.52 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.52" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/nested-clients": "npm:^3.997.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/febea54b749e6667a0273770f9f7355e66b82cf77ed69c142d95aac24d4834c61afbdb685fc87ec8d7d57e71fa7c284289dd8debec8fe08a8183c67c98f30296 - languageName: node - linkType: hard - -"@aws-sdk/eventstream-handler-node@npm:^3.972.16": - version: 3.972.21 - resolution: "@aws-sdk/eventstream-handler-node@npm:3.972.21" - dependencies: - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/0dc30b031e5d941a1964d2033eefeaada4f736054faadc4c72e51213a74fb7a2d66b820863562bf90cf85e7ea911991cdc40fa738735d30c8d583dbb156a00e5 - languageName: node - linkType: hard - -"@aws-sdk/middleware-eventstream@npm:^3.972.12": - version: 3.972.17 - resolution: "@aws-sdk/middleware-eventstream@npm:3.972.17" - dependencies: - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/b83169e345a93cee689e77ed9a8e8ab050debfc4b74fd4b5f87fc61c9480be968e40eb936b4ecbb0031986a35c2abaaf404acb34e6e81eaef901be69627fe3fa - languageName: node - linkType: hard - -"@aws-sdk/middleware-websocket@npm:^3.972.19": - version: 3.972.28 - resolution: "@aws-sdk/middleware-websocket@npm:3.972.28" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/fetch-http-handler": "npm:^5.4.6" - "@smithy/signature-v4": "npm:^5.4.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/3c7dfb9d89bdb72c24f99a0f550241616e6561b3a77704e6d837bf48dabb12d6a1247eac7d6cf8884d0b5b0e625df1a1eb7e34f15be111e74ee237d2e949ca5c - languageName: node - linkType: hard - -"@aws-sdk/nested-clients@npm:^3.997.20, @aws-sdk/nested-clients@npm:^3.997.9": - version: 3.997.20 - resolution: "@aws-sdk/nested-clients@npm:3.997.20" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/signature-v4-multi-region": "npm:^3.996.34" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/fetch-http-handler": "npm:^5.4.6" - "@smithy/node-http-handler": "npm:^4.7.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/ec7e5fa933b6b01afdc0b911b8bef26f4240dec8ff63a466b1a65b82dc1aa82d4cdc719486718f5df2e06d31384ecf681e122d43f96f8ca0498a3caf4d0582e9 - languageName: node - linkType: hard - -"@aws-sdk/signature-v4-multi-region@npm:^3.996.34": - version: 3.996.34 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.996.34" - dependencies: - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/signature-v4": "npm:^5.4.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/ed50acd3009d744d2684ca3b6f81196a6d7e3afdcb56f1009ff3c4113b6a012f6b659e141bcf3482c80a7eff8df73789ffb2176b81d0da211ad88cae66248eb2 - languageName: node - linkType: hard - -"@aws-sdk/token-providers@npm:3.1048.0": - version: 3.1048.0 - resolution: "@aws-sdk/token-providers@npm:3.1048.0" - dependencies: - "@aws-sdk/core": "npm:^3.974.11" - "@aws-sdk/nested-clients": "npm:^3.997.9" - "@aws-sdk/types": "npm:^3.973.8" - "@smithy/core": "npm:^3.24.2" - "@smithy/types": "npm:^4.14.1" - tslib: "npm:^2.6.2" - checksum: 10c0/4dbca618047f9a051999031e0f027098fbd880fe7732bcd38cd0fd48461c41d7f28797bbf4292aa573815d7a2cdd44a0dad1fafd1922f52792f70c54bfd165b2 - languageName: node - linkType: hard - -"@aws-sdk/token-providers@npm:3.1066.0": - version: 3.1066.0 - resolution: "@aws-sdk/token-providers@npm:3.1066.0" - dependencies: - "@aws-sdk/core": "npm:^3.974.20" - "@aws-sdk/nested-clients": "npm:^3.997.20" - "@aws-sdk/types": "npm:^3.973.12" - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/475af61b6390222f2e9d2bcc61efb98e5aa342ca99796d7ffdaf761559e64830bbf1317bc817eb473a4496244c0005b281988f3dbcb4153310ea007ba5de41ea - languageName: node - linkType: hard - -"@aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.973.12, @aws-sdk/types@npm:^3.973.8": - version: 3.973.12 - resolution: "@aws-sdk/types@npm:3.973.12" - dependencies: - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/ed3730c983a0162e0ee9b6d85f834e53dcbb387396710bdb85c1e5197cf8c48e98622445667a7490cc6c487a575af79b2c99f49276af7719601aabae4de62f40 - languageName: node - linkType: hard - -"@aws-sdk/util-locate-window@npm:^3.0.0": - version: 3.965.7 - resolution: "@aws-sdk/util-locate-window@npm:3.965.7" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10c0/f7730eb16e297b6e7b2e10c9d1fc6f5c28d793d6ff642aed86feae703a6bd877926f44cf57ca1723dc5d12e4a18e6638c8eb99b7470e58976305f815c5af7929 - languageName: node - linkType: hard - -"@aws-sdk/xml-builder@npm:^3.972.29": - version: 3.972.29 - resolution: "@aws-sdk/xml-builder@npm:3.972.29" - dependencies: - "@smithy/types": "npm:^4.14.3" - fast-xml-parser: "npm:5.7.3" - tslib: "npm:^2.6.2" - checksum: 10c0/677936c5f2ecadb73943a63b6835d91b39d6cf2826235e33ba0fd996180fa8eaae6d5f846aee0224fa954307f61afe015a12354058f9fe0f6151f48ac044e356 - languageName: node - linkType: hard - -"@aws/lambda-invoke-store@npm:^0.2.2": - version: 0.2.4 - resolution: "@aws/lambda-invoke-store@npm:0.2.4" - checksum: 10c0/29d874d7c1a2d971e0c02980594204f89cda718f215f2fc52b6c56eacbdad1fa5f6ce1b358e5811f5cd35d04c76299a67a8aff95318446af2bdfb4910f213e13 - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.29.0": - version: 7.29.7 - resolution: "@babel/code-frame@npm:7.29.7" - dependencies: - "@babel/helper-validator-identifier": "npm:^7.29.7" - js-tokens: "npm:^4.0.0" - picocolors: "npm:^1.1.1" - checksum: 10c0/169fc2080169a40c1760155eaaaf739bcb882df0bec76a83adbda5493645bc17270a3434b8848c494b1933e96fe1d147370001e3cda09a39f43ae30f08ef2069 - languageName: node - linkType: hard - -"@babel/generator@npm:8.0.0-rc.6": - version: 8.0.0-rc.6 - resolution: "@babel/generator@npm:8.0.0-rc.6" - dependencies: - "@babel/parser": "npm:^8.0.0-rc.6" - "@babel/types": "npm:^8.0.0-rc.6" - "@jridgewell/gen-mapping": "npm:^0.3.12" - "@jridgewell/trace-mapping": "npm:^0.3.28" - "@types/jsesc": "npm:^2.5.0" - jsesc: "npm:^3.0.2" - checksum: 10c0/bb28a5afee0c28cb68c7910091348938840fe3e5a5f382db5279d50c3fbb99584b718f0862aaaed0fdc95561e771874d3593170d4604f90c56278840651a57ec - languageName: node - linkType: hard - -"@babel/helper-string-parser@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-string-parser@npm:7.29.7" - checksum: 10c0/194bc0f1716e396d5ffde56ad6119745fb9557662c98611590e5e454906783a4ccb21ce93056b8eb69a4909044834e45d96e50ac695bbe9e3221648fe033c06c - languageName: node - linkType: hard - -"@babel/helper-string-parser@npm:^8.0.0-rc.6": - version: 8.0.0-rc.6 - resolution: "@babel/helper-string-parser@npm:8.0.0-rc.6" - checksum: 10c0/22b39a1112c7b3e09c353fe298a82546eed3ece05331d0a0c40e9592e8cd30409a983ae0c53ea8f53756c5fea6c665c8ae7c065c4f183066578304f4d34169f5 - languageName: node - linkType: hard - -"@babel/helper-validator-identifier@npm:8.0.0-rc.6, @babel/helper-validator-identifier@npm:^8.0.0-rc.6": - version: 8.0.0-rc.6 - resolution: "@babel/helper-validator-identifier@npm:8.0.0-rc.6" - checksum: 10c0/85e0f2c746a06467bf952f9ac1cda1dc63702a88bdfa1297d41de42452acbb9dfc5699bf6f4ed928fb3b50bde9635a6e686e1d253fadf47fb27618632e198ce5 - languageName: node - linkType: hard - -"@babel/helper-validator-identifier@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-validator-identifier@npm:7.29.7" - checksum: 10c0/4795354e7ae0dcafa72de1cd04ec51252dc1498517170beaf019e03effc5b7bf13c6b21a3949a77e07b8125be7f106ed1131350d8ebd4566ae874094a726d62b - languageName: node - linkType: hard - -"@babel/parser@npm:8.0.0-rc.6, @babel/parser@npm:^8.0.0-beta.4, @babel/parser@npm:^8.0.0-rc.6": - version: 8.0.0-rc.6 - resolution: "@babel/parser@npm:8.0.0-rc.6" - dependencies: - "@babel/types": "npm:^8.0.0-rc.6" - bin: - parser: ./bin/babel-parser.js - checksum: 10c0/de4fd82e7733532e6c0a71766f9fc1cae3daefc999be8ae8c8c2155e7af32c3b4fdb14cfc3a010c969113fd6dc698cd0603ec13579bff38e8159e36cbff94449 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.29.3": - version: 7.29.7 - resolution: "@babel/parser@npm:7.29.7" - dependencies: - "@babel/types": "npm:^7.29.7" - bin: - parser: ./bin/babel-parser.js - checksum: 10c0/65133038f80b54a714d6027cb77cee3f9a6b5c4c6842ce674301e13947cbcbfa8055e63acaf1b84c085d34226a14425b2c2b97b829e0e226d2e8f1299942a51d - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.18.3": - version: 7.29.7 - resolution: "@babel/runtime@npm:7.29.7" - checksum: 10c0/ca11572f7146b21e0bde6a9ed4bb6a89eafbee5f0944c7eb54d0d8a2dac962c33638a1d611e14faa71dfbb92b4b5f9236232208568a6b7d5c6f3f39ddb91771e - languageName: node - linkType: hard - -"@babel/types@npm:^7.29.0, @babel/types@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/types@npm:7.29.7" - dependencies: - "@babel/helper-string-parser": "npm:^7.29.7" - "@babel/helper-validator-identifier": "npm:^7.29.7" - checksum: 10c0/b6623994c69717fa27294f5fa46d59140338e2d86c6c1c13085c84ef7d53086ee357fbf4fe9abe3dd3da75734dc77c4c0df2f90fb29e667558bb3b3fb705e88f - languageName: node - linkType: hard - -"@babel/types@npm:^8.0.0-rc.6": - version: 8.0.0-rc.6 - resolution: "@babel/types@npm:8.0.0-rc.6" - dependencies: - "@babel/helper-string-parser": "npm:^8.0.0-rc.6" - "@babel/helper-validator-identifier": "npm:^8.0.0-rc.6" - checksum: 10c0/a323db124830cf0bfe5c217411ff9cce2d7d7182d5a02a3ca8c35905dac53878f88d35d1d6abf6132e6c3d353703385083c01a549ea92a364d66523f3ea8904b - languageName: node - linkType: hard - -"@bcoe/v8-coverage@npm:^1.0.2": - version: 1.0.2 - resolution: "@bcoe/v8-coverage@npm:1.0.2" - checksum: 10c0/1eb1dc93cc17fb7abdcef21a6e7b867d6aa99a7ec88ec8207402b23d9083ab22a8011213f04b2cf26d535f1d22dc26139b7929e6c2134c254bd1e14ba5e678c3 - languageName: node - linkType: hard - -"@cordisjs/plugin-group@workspace:vendor/group": - version: 0.0.0-use.local - resolution: "@cordisjs/plugin-group@workspace:vendor/group" - peerDependencies: - "@cordisjs/plugin-loader": ^1.0.0-rc.4 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@cordisjs/plugin-hmr@workspace:vendor/hmr": - version: 0.0.0-use.local - resolution: "@cordisjs/plugin-hmr@workspace:vendor/hmr" - dependencies: - "@babel/code-frame": "npm:^7.29.0" - "@types/babel__code-frame": "npm:^7.27.0" - "@types/picomatch": "npm:^3.0.2" - chokidar: "npm:^4.0.3" - cosmokit: "npm:^1.8.1" - picomatch: "npm:^4.0.3" - schemastery: "npm:^3.18.0" - peerDependencies: - "@cordisjs/plugin-timer": ^1.1.2 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@cordisjs/plugin-include@workspace:vendor/include": - version: 0.0.0-use.local - resolution: "@cordisjs/plugin-include@workspace:vendor/include" - dependencies: - cosmokit: "npm:^1.8.1" - js-yaml: "npm:^4.1.0" - peerDependencies: - "@cordisjs/plugin-loader": ^1.0.0-rc.4 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@cordisjs/plugin-loader@workspace:vendor/loader": - version: 0.0.0-use.local - resolution: "@cordisjs/plugin-loader@workspace:vendor/loader" - dependencies: - cosmokit: "npm:^1.8.1" - peerDependencies: - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@cordisjs/plugin-logger-console@workspace:vendor/logger-console": - version: 0.0.0-use.local - resolution: "@cordisjs/plugin-logger-console@workspace:vendor/logger-console" - dependencies: - cosmokit: "npm:^1.8.1" - schemastery: "npm:^3.18.0" - supports-color: "npm:^9.4.0" - peerDependencies: - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@cordisjs/plugin-timer@workspace:vendor/timer": - version: 0.0.0-use.local - resolution: "@cordisjs/plugin-timer@workspace:vendor/timer" - dependencies: - cosmokit: "npm:^1.8.1" - peerDependencies: - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-agent-loop@npm:^0.0.1, @deepseek-ai/dsh-agent-loop@workspace:packages/agent-loop": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-agent-loop@workspace:packages/agent-loop" - dependencies: - "@deepseek-ai/dsh-agent": "npm:^0.0.1" - "@deepseek-ai/dsh-invariants": "npm:^0.0.1" - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - "@deepseek-ai/dsh-session": "npm:^0.0.1" - "@deepseek-ai/dsh-system-prompt": "npm:^0.0.1" - "@deepseek-ai/dsh-tools": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - schemastery: "npm:^3.18.0" - peerDependencies: - "@deepseek-ai/dsh-agent": ^0.0.1 - "@deepseek-ai/dsh-llm": ^0.0.1 - "@deepseek-ai/dsh-session": ^0.0.1 - "@deepseek-ai/dsh-system-prompt": ^0.0.1 - "@deepseek-ai/dsh-tools": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-agent@npm:^0.0.1, @deepseek-ai/dsh-agent@workspace:packages/agent": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-agent@workspace:packages/agent" - dependencies: - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - "@deepseek-ai/dsh-session": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - "@deepseek-ai/dsh-llm": ^0.0.1 - "@deepseek-ai/dsh-session": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-bash-local@npm:^0.0.1, @deepseek-ai/dsh-bash-local@workspace:packages/bash-local": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-bash-local@workspace:packages/bash-local" - dependencies: - "@deepseek-ai/dsh-bash": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - schemastery: "npm:^3.18.0" - peerDependencies: - "@deepseek-ai/dsh-bash": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-bash@npm:^0.0.1, @deepseek-ai/dsh-bash@workspace:packages/bash": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-bash@workspace:packages/bash" - dependencies: - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-invariants@npm:^0.0.1, @deepseek-ai/dsh-invariants@workspace:packages/invariants": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-invariants@workspace:packages/invariants" - dependencies: - "@deepseek-ai/dsh-agent": "npm:^0.0.1" - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - "@deepseek-ai/dsh-session": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - "@deepseek-ai/dsh-agent": ^0.0.1 - "@deepseek-ai/dsh-llm": ^0.0.1 - "@deepseek-ai/dsh-session": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-llm-deepseek@npm:^0.0.1, @deepseek-ai/dsh-llm-deepseek@workspace:packages/llm-deepseek": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-llm-deepseek@workspace:packages/llm-deepseek" - dependencies: - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - schemastery: "npm:^3.18.0" - peerDependencies: - "@deepseek-ai/dsh-llm": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-llm-pi-ai@workspace:packages/llm-pi-ai": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-llm-pi-ai@workspace:packages/llm-pi-ai" - dependencies: - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - "@deepseek-ai/dsh-llm-deepseek": "npm:^0.0.1" - "@earendil-works/pi-ai": "npm:^0.79.1" - cordis: "npm:^4.0.0-rc.6" - schemastery: "npm:^3.18.0" - peerDependencies: - "@deepseek-ai/dsh-llm": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-llm@npm:^0.0.1, @deepseek-ai/dsh-llm@workspace:packages/llm": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-llm@workspace:packages/llm" - dependencies: - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-root@workspace:.": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-root@workspace:." - dependencies: - "@stylistic/eslint-plugin": "npm:^5.10.0" - "@types/node": "npm:^25.3.5" - "@vitest/coverage-v8": "npm:^4.1.8" - "@yarnpkg/types": "npm:^4.0.1" - eslint: "npm:^10.4.1" - fast-check: "npm:^4.8.0" - knip: "npm:^6.16.1" - lefthook: "npm:^2.1.9" - publint: "npm:^0.3.21" - tsdown: "npm:^0.22.2" - tsx: "npm:^4.22.4" - typescript: "npm:^6.0.3" - typescript-eslint: "npm:^8.61.0" - vite-tsconfig-paths: "npm:^6.1.1" - vitest: "npm:^4.1.8" - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-session@npm:^0.0.1, @deepseek-ai/dsh-session@workspace:packages/session": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-session@workspace:packages/session" - dependencies: - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - "@deepseek-ai/dsh-llm": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-system-prompt@npm:^0.0.1, @deepseek-ai/dsh-system-prompt@workspace:packages/system-prompt": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-system-prompt@workspace:packages/system-prompt" - dependencies: - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - "@deepseek-ai/dsh-llm": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-tool-bash@workspace:packages/tool-bash": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-tool-bash@workspace:packages/tool-bash" - dependencies: - "@deepseek-ai/dsh-agent": "npm:^0.0.1" - "@deepseek-ai/dsh-agent-loop": "npm:^0.0.1" - "@deepseek-ai/dsh-bash": "npm:^0.0.1" - "@deepseek-ai/dsh-bash-local": "npm:^0.0.1" - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - "@deepseek-ai/dsh-session": "npm:^0.0.1" - "@deepseek-ai/dsh-system-prompt": "npm:^0.0.1" - "@deepseek-ai/dsh-tools": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - "@deepseek-ai/dsh-agent": ^0.0.1 - "@deepseek-ai/dsh-bash": ^0.0.1 - "@deepseek-ai/dsh-llm": ^0.0.1 - "@deepseek-ai/dsh-tools": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@deepseek-ai/dsh-tools@npm:^0.0.1, @deepseek-ai/dsh-tools@workspace:packages/tools": - version: 0.0.0-use.local - resolution: "@deepseek-ai/dsh-tools@workspace:packages/tools" - dependencies: - "@deepseek-ai/dsh-agent": "npm:^0.0.1" - "@deepseek-ai/dsh-llm": "npm:^0.0.1" - "@deepseek-ai/dsh-system-prompt": "npm:^0.0.1" - cordis: "npm:^4.0.0-rc.6" - peerDependencies: - "@deepseek-ai/dsh-agent": ^0.0.1 - "@deepseek-ai/dsh-llm": ^0.0.1 - "@deepseek-ai/dsh-system-prompt": ^0.0.1 - cordis: ^4.0.0-rc.6 - languageName: unknown - linkType: soft - -"@earendil-works/pi-ai@npm:^0.79.1": - version: 0.79.1 - resolution: "@earendil-works/pi-ai@npm:0.79.1" - dependencies: - "@anthropic-ai/sdk": "npm:0.91.1" - "@aws-sdk/client-bedrock-runtime": "npm:3.1048.0" - "@google/genai": "npm:1.52.0" - "@mistralai/mistralai": "npm:2.2.1" - "@smithy/node-http-handler": "npm:4.7.3" - http-proxy-agent: "npm:7.0.2" - https-proxy-agent: "npm:7.0.6" - openai: "npm:6.26.0" - partial-json: "npm:0.1.7" - typebox: "npm:1.1.38" - bin: - pi-ai: dist/cli.js - checksum: 10c0/eeb72e3c5df545e1cf646ef14a100199819b9691135ffc3c045536a14ffd27e4600aba70f0a8afee5184c6d50213ea5abc988bd0abcc8011b8f7c93b9db7f977 - languageName: node - linkType: hard - -"@emnapi/core@npm:1.10.0": - version: 1.10.0 - resolution: "@emnapi/core@npm:1.10.0" - dependencies: - "@emnapi/wasi-threads": "npm:1.2.1" - tslib: "npm:^2.4.0" - checksum: 10c0/f51d08227857b60632de7714d708124f0e100a1462dde6df8221760939aa3204a73193830371830fac0716f3ccd2129f2cac1b17cd7d7958bc4da9018a296edb - languageName: node - linkType: hard - -"@emnapi/core@npm:1.11.0": - version: 1.11.0 - resolution: "@emnapi/core@npm:1.11.0" - dependencies: - "@emnapi/wasi-threads": "npm:1.2.2" - tslib: "npm:^2.4.0" - checksum: 10c0/268498d6ea42ff1e51d543725c7c9c3ce01d39be19a5790d1587ebe98dcfb9329666f0ce9864bb23e067caa064199a45ec2c63c4050b5e42166c1d7d40750135 - languageName: node - linkType: hard - -"@emnapi/runtime@npm:1.10.0": - version: 1.10.0 - resolution: "@emnapi/runtime@npm:1.10.0" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/953f14991d1aefb92ee6f8eb27dea725e484791a53a0cb5f47d9e0087b9a2c929ff2e92adf95af15d6ad456db6300c6b761ebf72b50a875b874a83520b3ba093 - languageName: node - linkType: hard - -"@emnapi/runtime@npm:1.11.0": - version: 1.11.0 - resolution: "@emnapi/runtime@npm:1.11.0" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/6c09d93934e4cf036d2a57672c1c932aee7b00063fc5851c0c6d2e65775adb5ec484e1e12b4ed3614d62e785e2472160d3b368fbdb50e49b566e631f7046e7db - languageName: node - linkType: hard - -"@emnapi/wasi-threads@npm:1.2.1": - version: 1.2.1 - resolution: "@emnapi/wasi-threads@npm:1.2.1" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/32fcfa81ab396533b2ec1f4082b1ff779a05d9c836bbbd3f4398405b0e6814c0d9503b7993130e37bc6941dbc1ded49f55e9700ae9ca4e803bab2b5bc5deb331 - languageName: node - linkType: hard - -"@emnapi/wasi-threads@npm:1.2.2": - version: 1.2.2 - resolution: "@emnapi/wasi-threads@npm:1.2.2" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/f0dc8269d6b20ae5a7c7b36e7a6a333452009d461038ef4febb29da2f3f78c1e2b1576d7e8970a5c5789ed3caedc1f80f5b0c2a5373bdaf8d03b20432bb55747 - languageName: node - linkType: hard - -"@esbuild/aix-ppc64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/aix-ppc64@npm:0.28.0" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/android-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/android-arm64@npm:0.28.0" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/android-arm@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/android-arm@npm:0.28.0" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@esbuild/android-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/android-x64@npm:0.28.0" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/darwin-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/darwin-arm64@npm:0.28.0" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/darwin-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/darwin-x64@npm:0.28.0" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/freebsd-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/freebsd-arm64@npm:0.28.0" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/freebsd-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/freebsd-x64@npm:0.28.0" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/linux-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-arm64@npm:0.28.0" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/linux-arm@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-arm@npm:0.28.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@esbuild/linux-ia32@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-ia32@npm:0.28.0" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-loong64@npm:0.28.0" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-mips64el@npm:0.28.0" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-ppc64@npm:0.28.0" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-riscv64@npm:0.28.0" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-s390x@npm:0.28.0" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/linux-x64@npm:0.28.0" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/netbsd-arm64@npm:0.28.0" - conditions: os=netbsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/netbsd-x64@npm:0.28.0" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openbsd-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/openbsd-arm64@npm:0.28.0" - conditions: os=openbsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/openbsd-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/openbsd-x64@npm:0.28.0" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/openharmony-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/openharmony-arm64@npm:0.28.0" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/sunos-x64@npm:0.28.0" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/win32-arm64@npm:0.28.0" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/win32-ia32@npm:0.28.0" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.28.0": - version: 0.28.0 - resolution: "@esbuild/win32-x64@npm:0.28.0" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1": - version: 4.9.1 - resolution: "@eslint-community/eslint-utils@npm:4.9.1" - dependencies: - eslint-visitor-keys: "npm:^3.4.3" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/dc4ab5e3e364ef27e33666b11f4b86e1a6c1d7cbf16f0c6ff87b1619b3562335e9201a3d6ce806221887ff780ec9d828962a290bb910759fd40a674686503f02 - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.12.2": - version: 4.12.2 - resolution: "@eslint-community/regexpp@npm:4.12.2" - checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d - languageName: node - linkType: hard - -"@eslint/config-array@npm:^0.23.5": - version: 0.23.5 - resolution: "@eslint/config-array@npm:0.23.5" - dependencies: - "@eslint/object-schema": "npm:^3.0.5" - debug: "npm:^4.3.1" - minimatch: "npm:^10.2.4" - checksum: 10c0/b24833c4c76e78ee075d306cd3f095db46b2db0f90cc13a6ee6e4275f9889731c05bf5403ab5fefb79c756e07ac9184ed0e04570341382f9eccbccc80e6d1a0c - languageName: node - linkType: hard - -"@eslint/config-helpers@npm:^0.6.0": - version: 0.6.0 - resolution: "@eslint/config-helpers@npm:0.6.0" - dependencies: - "@eslint/core": "npm:^1.2.1" - checksum: 10c0/f9af20e8b60b0ba27edb74b8eb40c0c5d51a9bf9baf9e053bb57833a87cb0a1c49b4dfaad88fc24d49c907ad1324c8a0b668684fa9c321351dac4bc9155ec10a - languageName: node - linkType: hard - -"@eslint/core@npm:^1.2.1": - version: 1.2.1 - resolution: "@eslint/core@npm:1.2.1" - dependencies: - "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/10979b40588ecfef771fcb5013a542a35fb30692cc95a65f3481b0b36fbd89f5679efeb30d57f4eed35203d859aabace2a620177d6c536f71b299a1af2f3398f - languageName: node - linkType: hard - -"@eslint/object-schema@npm:^3.0.5": - version: 3.0.5 - resolution: "@eslint/object-schema@npm:3.0.5" - checksum: 10c0/1db337431f520b99e9edda64ef5fafd7ec6a029843eeb608753025125b6649d861d843cffafafd3c4e37926d7d5f9ec0c6a8e3665c13c3da2144e8132892e92e - languageName: node - linkType: hard - -"@eslint/plugin-kit@npm:^0.7.2": - version: 0.7.2 - resolution: "@eslint/plugin-kit@npm:0.7.2" - dependencies: - "@eslint/core": "npm:^1.2.1" - levn: "npm:^0.4.1" - checksum: 10c0/aafba08077bcd6d7dde6c2e21db18086046a88f914f29971a84cac9ad2d48952ded1b293e665e523805297eff756522dafa16f0062195e2c7143dcd1d47d11ed - languageName: node - linkType: hard - -"@google/genai@npm:1.52.0": - version: 1.52.0 - resolution: "@google/genai@npm:1.52.0" - dependencies: - google-auth-library: "npm:^10.3.0" - p-retry: "npm:^4.6.2" - protobufjs: "npm:^7.5.4" - ws: "npm:^8.18.0" - peerDependencies: - "@modelcontextprotocol/sdk": ^1.25.2 - peerDependenciesMeta: - "@modelcontextprotocol/sdk": - optional: true - checksum: 10c0/2d22f6bd4baa915a402289dae4797410acbd5c5add1ed0c8d1bedef3ac7871fe1f04640d0612aa793fe7055f086719487491f55474a5b21597addfdea8631fa6 - languageName: node - linkType: hard - -"@humanfs/core@npm:^0.19.2": - version: 0.19.2 - resolution: "@humanfs/core@npm:0.19.2" - dependencies: - "@humanfs/types": "npm:^0.15.0" - checksum: 10c0/d0a1d52d7b30c27d49475a53072d1510b81c5803e44b342fb8faf3887f1aa27593a1e6dc76a45268e7892d3f4e198146659281f6b6d55eacf3fd5a38bac30c5c - languageName: node - linkType: hard - -"@humanfs/node@npm:^0.16.6": - version: 0.16.8 - resolution: "@humanfs/node@npm:0.16.8" - dependencies: - "@humanfs/core": "npm:^0.19.2" - "@humanfs/types": "npm:^0.15.0" - "@humanwhocodes/retry": "npm:^0.4.0" - checksum: 10c0/56140579db811af4e160b195d45d0f29acf644d192c93fe24c9e594ebf06f19dfc157494a07c84540b8a071c0e4b37209c2362765d31734f4d0be869c2422e25 - languageName: node - linkType: hard - -"@humanfs/types@npm:^0.15.0": - version: 0.15.0 - resolution: "@humanfs/types@npm:0.15.0" - checksum: 10c0/fc26b9a024b0e55f7eaf64036df94345bf5d36d6a41ef80ef38e78f1f7430ce26cf435af736adae58913baae18eac3f38c18739054a3d379102015978eae862e - languageName: node - linkType: hard - -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 - languageName: node - linkType: hard - -"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": - version: 0.4.3 - resolution: "@humanwhocodes/retry@npm:0.4.3" - checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42 - languageName: node - linkType: hard - -"@isaacs/fs-minipass@npm:^4.0.0": - version: 4.0.1 - resolution: "@isaacs/fs-minipass@npm:4.0.1" - dependencies: - minipass: "npm:^7.0.4" - checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2 - languageName: node - linkType: hard - -"@jridgewell/gen-mapping@npm:^0.3.12": - version: 0.3.13 - resolution: "@jridgewell/gen-mapping@npm:0.3.13" - dependencies: - "@jridgewell/sourcemap-codec": "npm:^1.5.0" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b - languageName: node - linkType: hard - -"@jridgewell/resolve-uri@npm:^3.1.0": - version: 3.1.2 - resolution: "@jridgewell/resolve-uri@npm:3.1.2" - checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e - languageName: node - linkType: hard - -"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": - version: 1.5.5 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" - checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 - languageName: node - linkType: hard - -"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.28, @jridgewell/trace-mapping@npm:^0.3.31": - version: 0.3.31 - resolution: "@jridgewell/trace-mapping@npm:0.3.31" - dependencies: - "@jridgewell/resolve-uri": "npm:^3.1.0" - "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 - languageName: node - linkType: hard - -"@mistralai/mistralai@npm:2.2.1": - version: 2.2.1 - resolution: "@mistralai/mistralai@npm:2.2.1" - dependencies: - ws: "npm:^8.18.0" - zod: "npm:^3.25.0 || ^4.0.0" - zod-to-json-schema: "npm:^3.25.0" - checksum: 10c0/131d218192dde76c38739d498d0b9a5944eb0bacf0c832ed812961e7f366f527de33942bb3274d2be15132a4834a7f57ef2a315e4ee95ad9a050b79d76300535 - languageName: node - linkType: hard - -"@napi-rs/wasm-runtime@npm:^1.1.4, @napi-rs/wasm-runtime@npm:^1.1.5": - version: 1.1.5 - resolution: "@napi-rs/wasm-runtime@npm:1.1.5" - dependencies: - "@tybys/wasm-util": "npm:^0.10.2" - peerDependencies: - "@emnapi/core": ^1.7.1 - "@emnapi/runtime": ^1.7.1 - checksum: 10c0/727f2b6ae0e68bbe5d39aeb68aa6f183314e9f03dc50bb55a962849535b2db53ecc3fbf1554d8656a54488a608df5a2634670595cf5874dc4af2ee59f817c65d - languageName: node - linkType: hard - -"@nodable/entities@npm:^2.1.0": - version: 2.2.0 - resolution: "@nodable/entities@npm:2.2.0" - checksum: 10c0/a5ace5b2f747ae5b851f68a1731526c3e10feacde80469415d15a0df0e960251b515e3cd4ea080a3534e0610ac74b0d3252f607ef2f536bcc97e22d324231578 - languageName: node - linkType: hard - -"@oxc-parser/binding-android-arm-eabi@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-android-arm-eabi@npm:0.133.0" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@oxc-parser/binding-android-arm64@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-android-arm64@npm:0.133.0" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-parser/binding-darwin-arm64@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-darwin-arm64@npm:0.133.0" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-parser/binding-darwin-x64@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-darwin-x64@npm:0.133.0" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@oxc-parser/binding-freebsd-x64@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-freebsd-x64@npm:0.133.0" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-arm-gnueabihf@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-arm-gnueabihf@npm:0.133.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-arm-musleabihf@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-arm-musleabihf@npm:0.133.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-arm64-gnu@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-arm64-gnu@npm:0.133.0" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-arm64-musl@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-arm64-musl@npm:0.133.0" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-ppc64-gnu@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-ppc64-gnu@npm:0.133.0" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-riscv64-gnu@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-riscv64-gnu@npm:0.133.0" - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-riscv64-musl@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-riscv64-musl@npm:0.133.0" - conditions: os=linux & cpu=riscv64 & libc=musl - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-s390x-gnu@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-s390x-gnu@npm:0.133.0" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-x64-gnu@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-x64-gnu@npm:0.133.0" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-parser/binding-linux-x64-musl@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-linux-x64-musl@npm:0.133.0" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@oxc-parser/binding-openharmony-arm64@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-openharmony-arm64@npm:0.133.0" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-parser/binding-wasm32-wasi@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-wasm32-wasi@npm:0.133.0" - dependencies: - "@emnapi/core": "npm:1.10.0" - "@emnapi/runtime": "npm:1.10.0" - "@napi-rs/wasm-runtime": "npm:^1.1.4" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@oxc-parser/binding-win32-arm64-msvc@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-win32-arm64-msvc@npm:0.133.0" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-parser/binding-win32-ia32-msvc@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-win32-ia32-msvc@npm:0.133.0" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@oxc-parser/binding-win32-x64-msvc@npm:0.133.0": - version: 0.133.0 - resolution: "@oxc-parser/binding-win32-x64-msvc@npm:0.133.0" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@oxc-project/types@npm:=0.133.0, @oxc-project/types@npm:^0.133.0": - version: 0.133.0 - resolution: "@oxc-project/types@npm:0.133.0" - checksum: 10c0/70c57ba58644f7ec217b670c301801f4d06995f4ccdba6b2bd106ea3e5ee49d616573e6ef8d55530b87571a960696543687f3850e87ad173d3f88965c30cdd63 - languageName: node - linkType: hard - -"@oxc-project/types@npm:=0.135.0": - version: 0.135.0 - resolution: "@oxc-project/types@npm:0.135.0" - checksum: 10c0/7ae7e65fb044733c6016381b27e84868bbf2fcba85f7e2f7dc28caf59cb7303b60b736e709d599a4495e7297aa7183b5e6366f96f2f692455d1b6d225cfe79b4 - languageName: node - linkType: hard - -"@oxc-resolver/binding-android-arm-eabi@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-android-arm-eabi@npm:11.20.0" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@oxc-resolver/binding-android-arm64@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-android-arm64@npm:11.20.0" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-darwin-arm64@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-darwin-arm64@npm:11.20.0" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-darwin-x64@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-darwin-x64@npm:11.20.0" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-freebsd-x64@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-freebsd-x64@npm:11.20.0" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-arm-gnueabihf@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-arm-gnueabihf@npm:11.20.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-arm-musleabihf@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-arm-musleabihf@npm:11.20.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-arm64-gnu@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-arm64-gnu@npm:11.20.0" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-arm64-musl@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-arm64-musl@npm:11.20.0" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-ppc64-gnu@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-ppc64-gnu@npm:11.20.0" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-riscv64-gnu@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-riscv64-gnu@npm:11.20.0" - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-riscv64-musl@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-riscv64-musl@npm:11.20.0" - conditions: os=linux & cpu=riscv64 & libc=musl - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-s390x-gnu@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-s390x-gnu@npm:11.20.0" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-x64-gnu@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-x64-gnu@npm:11.20.0" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-x64-musl@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-linux-x64-musl@npm:11.20.0" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@oxc-resolver/binding-openharmony-arm64@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-openharmony-arm64@npm:11.20.0" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-wasm32-wasi@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-wasm32-wasi@npm:11.20.0" - dependencies: - "@emnapi/core": "npm:1.10.0" - "@emnapi/runtime": "npm:1.10.0" - "@napi-rs/wasm-runtime": "npm:^1.1.4" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@oxc-resolver/binding-win32-arm64-msvc@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-win32-arm64-msvc@npm:11.20.0" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-win32-x64-msvc@npm:11.20.0": - version: 11.20.0 - resolution: "@oxc-resolver/binding-win32-x64-msvc@npm:11.20.0" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": - version: 1.1.2 - resolution: "@protobufjs/aspromise@npm:1.1.2" - checksum: 10c0/a83343a468ff5b5ec6bff36fd788a64c839e48a07ff9f4f813564f58caf44d011cd6504ed2147bf34835bd7a7dd2107052af755961c6b098fd8902b4f6500d0f - languageName: node - linkType: hard - -"@protobufjs/base64@npm:^1.1.2": - version: 1.1.2 - resolution: "@protobufjs/base64@npm:1.1.2" - checksum: 10c0/eec925e681081af190b8ee231f9bad3101e189abbc182ff279da6b531e7dbd2a56f1f306f37a80b1be9e00aa2d271690d08dcc5f326f71c9eed8546675c8caf6 - languageName: node - linkType: hard - -"@protobufjs/codegen@npm:^2.0.5": - version: 2.0.5 - resolution: "@protobufjs/codegen@npm:2.0.5" - checksum: 10c0/1b8a2ae56ee60a56e9d205cd4b6072a1503c5069b8ebb905710f974ff0098a0d0700641c137e0a8d98dedf14423156a106a9433695cbf52574810f55000fdcab - languageName: node - linkType: hard - -"@protobufjs/eventemitter@npm:^1.1.1": - version: 1.1.1 - resolution: "@protobufjs/eventemitter@npm:1.1.1" - checksum: 10c0/8e06193d4629c5e7c09d4f8c2ddba8fc4dfa739f0149f33a1d901568d35bb7b8b5277a4e8452baf3bdd0b302fd599cf255d193267aa93a0a4747e23cd073c4ac - languageName: node - linkType: hard - -"@protobufjs/fetch@npm:^1.1.1": - version: 1.1.1 - resolution: "@protobufjs/fetch@npm:1.1.1" - dependencies: - "@protobufjs/aspromise": "npm:^1.1.1" - checksum: 10c0/a497ff5433854e8577f0427983ea39b9113b49a8120f94515291d763327061d2c3013e60e24ea436d091dafae01a0f6eb1867e3b1616045d96a31d8b3c646ed4 - languageName: node - linkType: hard - -"@protobufjs/float@npm:^1.0.2": - version: 1.0.2 - resolution: "@protobufjs/float@npm:1.0.2" - checksum: 10c0/18f2bdede76ffcf0170708af15c9c9db6259b771e6b84c51b06df34a9c339dbbeec267d14ce0bddd20acc142b1d980d983d31434398df7f98eb0c94a0eb79069 - languageName: node - linkType: hard - -"@protobufjs/path@npm:^1.1.2": - version: 1.1.2 - resolution: "@protobufjs/path@npm:1.1.2" - checksum: 10c0/cece0a938e7f5dfd2fa03f8c14f2f1cf8b0d6e13ac7326ff4c96ea311effd5fb7ae0bba754fbf505312af2e38500250c90e68506b97c02360a43793d88a0d8b4 - languageName: node - linkType: hard - -"@protobufjs/pool@npm:^1.1.0": - version: 1.1.0 - resolution: "@protobufjs/pool@npm:1.1.0" - checksum: 10c0/eda2718b7f222ac6e6ad36f758a92ef90d26526026a19f4f17f668f45e0306a5bd734def3f48f51f8134ae0978b6262a5c517c08b115a551756d1a3aadfcf038 - languageName: node - linkType: hard - -"@protobufjs/utf8@npm:^1.1.1": - version: 1.1.1 - resolution: "@protobufjs/utf8@npm:1.1.1" - checksum: 10c0/641fc145f00626405e8984b6e90b9edcbcc072ffc82d0647ca3176e09c730b2d022f988e65f011a7a17e2e4d77cde7733643aa10d8ac2bfa30f134dbcad553fd - languageName: node - linkType: hard - -"@publint/pack@npm:^0.1.4": - version: 0.1.4 - resolution: "@publint/pack@npm:0.1.4" - checksum: 10c0/f70b2c8951b5d312ecfd40534e1dd1b0a4fe0fd207879a73c168e3f6979df6202b8b4d4f9a0ee9de6443f0bfb95ef47a0c27c7138c083d9224ef27c67adddefd - languageName: node - linkType: hard - -"@quansync/fs@npm:^1.0.0": - version: 1.0.0 - resolution: "@quansync/fs@npm:1.0.0" - dependencies: - quansync: "npm:^1.0.0" - checksum: 10c0/41a7e145d4fc349eaeac20ee7ffe0c876a7c26b2268d5704b462b3e7379091221336e315b2b346d5b07a531502a41cad15c9f374800cc60b6339d074ef99aa16 - languageName: node - linkType: hard - -"@rolldown/binding-android-arm64@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-android-arm64@npm:1.0.3" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-android-arm64@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-android-arm64@npm:1.1.1" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-darwin-arm64@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-darwin-arm64@npm:1.0.3" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-darwin-arm64@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-darwin-arm64@npm:1.1.1" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-darwin-x64@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-darwin-x64@npm:1.0.3" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-darwin-x64@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-darwin-x64@npm:1.1.1" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-freebsd-x64@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-freebsd-x64@npm:1.0.3" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-freebsd-x64@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-freebsd-x64@npm:1.1.1" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm-gnueabihf@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.0.3" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm-gnueabihf@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.1.1" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm64-gnu@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.0.3" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm64-gnu@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.1.1" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm64-musl@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-linux-arm64-musl@npm:1.0.3" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm64-musl@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-linux-arm64-musl@npm:1.1.1" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@rolldown/binding-linux-ppc64-gnu@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.0.3" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-ppc64-gnu@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.1.1" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-s390x-gnu@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.0.3" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-s390x-gnu@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.1.1" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-x64-gnu@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-linux-x64-gnu@npm:1.0.3" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-x64-gnu@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-linux-x64-gnu@npm:1.1.1" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-x64-musl@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-linux-x64-musl@npm:1.0.3" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@rolldown/binding-linux-x64-musl@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-linux-x64-musl@npm:1.1.1" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@rolldown/binding-openharmony-arm64@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-openharmony-arm64@npm:1.0.3" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-openharmony-arm64@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-openharmony-arm64@npm:1.1.1" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-wasm32-wasi@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-wasm32-wasi@npm:1.0.3" - dependencies: - "@emnapi/core": "npm:1.10.0" - "@emnapi/runtime": "npm:1.10.0" - "@napi-rs/wasm-runtime": "npm:^1.1.4" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@rolldown/binding-wasm32-wasi@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-wasm32-wasi@npm:1.1.1" - dependencies: - "@emnapi/core": "npm:1.11.0" - "@emnapi/runtime": "npm:1.11.0" - "@napi-rs/wasm-runtime": "npm:^1.1.5" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@rolldown/binding-win32-arm64-msvc@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.0.3" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-win32-arm64-msvc@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.1.1" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-win32-x64-msvc@npm:1.0.3": - version: 1.0.3 - resolution: "@rolldown/binding-win32-x64-msvc@npm:1.0.3" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-win32-x64-msvc@npm:1.1.1": - version: 1.1.1 - resolution: "@rolldown/binding-win32-x64-msvc@npm:1.1.1" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/pluginutils@npm:^1.0.0": - version: 1.0.1 - resolution: "@rolldown/pluginutils@npm:1.0.1" - checksum: 10c0/99d9b06d90196823e4d8c841f258db7a16e5dbba5824a2962b05d907b79f1ba929d56f22dd744fd530936e568c865ee56a719dc31e57e13bc0a8eb4764a8d8dd - languageName: node - linkType: hard - -"@smithy/core@npm:^3.24.2, @smithy/core@npm:^3.24.3, @smithy/core@npm:^3.24.6": - version: 3.24.6 - resolution: "@smithy/core@npm:3.24.6" - dependencies: - "@aws-crypto/crc32": "npm:5.2.0" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/4d3db2296a99a4bcb17007b8276a243930f63c3169b9b86b973a2d1422e8dee7e95e3b98eea115e2759b989b23db1ff89ca505bddbacb7391ca3fe4e222b84ff - languageName: node - linkType: hard - -"@smithy/credential-provider-imds@npm:^4.3.7": - version: 4.3.8 - resolution: "@smithy/credential-provider-imds@npm:4.3.8" - dependencies: - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/657c02171c6daba5ebcd0623121b58341cfeeb4cdff596f31954a035fd824f6553a40107e0a86704495550c21d33bb975da6154de1db31b2af64ee06c5a995f2 - languageName: node - linkType: hard - -"@smithy/fetch-http-handler@npm:^5.4.2, @smithy/fetch-http-handler@npm:^5.4.6": - version: 5.4.6 - resolution: "@smithy/fetch-http-handler@npm:5.4.6" - dependencies: - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/06fd6f9a819766d1071ad0eca774ecd936b0b130057076a5e42f1bcc9c751deeddfa279adc4bcddd71ac7699744a2ed06a0405a239a379d98670855d18a6586b - languageName: node - linkType: hard - -"@smithy/is-array-buffer@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/is-array-buffer@npm:2.2.0" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10c0/2f2523cd8cc4538131e408eb31664983fecb0c8724956788b015aaf3ab85a0c976b50f4f09b176f1ed7bbe79f3edf80743be7a80a11f22cd9ce1285d77161aaf - languageName: node - linkType: hard - -"@smithy/node-http-handler@npm:4.7.3": - version: 4.7.3 - resolution: "@smithy/node-http-handler@npm:4.7.3" - dependencies: - "@smithy/core": "npm:^3.24.3" - "@smithy/types": "npm:^4.14.2" - tslib: "npm:^2.6.2" - checksum: 10c0/805002fc7e55f48f61d15de738dcd79f7bf8fbd372157b2967a9ac7616d76b744a410cc58efd672fa9c8f1592f5a8410aff35e3bd77ea5dfc47ff7c08fe42373 - languageName: node - linkType: hard - -"@smithy/node-http-handler@npm:^4.7.2, @smithy/node-http-handler@npm:^4.7.6": - version: 4.7.7 - resolution: "@smithy/node-http-handler@npm:4.7.7" - dependencies: - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/02c4592f83097d46fccc7d8ff80a978767520e3be798c5d851df68d857d6287527684380adfbdd55c8e7ca06f6f1710f7cfc5a3f591aa6ce791d18a109612d5d - languageName: node - linkType: hard - -"@smithy/signature-v4@npm:^5.4.6": - version: 5.4.6 - resolution: "@smithy/signature-v4@npm:5.4.6" - dependencies: - "@smithy/core": "npm:^3.24.6" - "@smithy/types": "npm:^4.14.3" - tslib: "npm:^2.6.2" - checksum: 10c0/7d7db13f4ddb09cca0a902dd760d83ff9770c085657e577153e4a93c0cd0314a36cbafaaae58c7be1aa1162e81ecab8b1395b0b0e488b20c22eb0dd9714b2b25 - languageName: node - linkType: hard - -"@smithy/types@npm:^4.14.1, @smithy/types@npm:^4.14.2, @smithy/types@npm:^4.14.3": - version: 4.14.3 - resolution: "@smithy/types@npm:4.14.3" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10c0/c80244d5ca88992e5609e372eaf2441497d36063688af44e9f0e81ab0ee8d5a4cbdb644822243e4cdfad2dd6484c6274e618dc2a9e91b3b9befe7c7b55e09ddc - languageName: node - linkType: hard - -"@smithy/util-buffer-from@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-buffer-from@npm:2.2.0" - dependencies: - "@smithy/is-array-buffer": "npm:^2.2.0" - tslib: "npm:^2.6.2" - checksum: 10c0/223d6a508b52ff236eea01cddc062b7652d859dd01d457a4e50365af3de1e24a05f756e19433f6ccf1538544076b4215469e21a4ea83dc1d58d829725b0dbc5a - languageName: node - linkType: hard - -"@smithy/util-utf8@npm:^2.0.0": - version: 2.3.0 - resolution: "@smithy/util-utf8@npm:2.3.0" - dependencies: - "@smithy/util-buffer-from": "npm:^2.2.0" - tslib: "npm:^2.6.2" - checksum: 10c0/e18840c58cc507ca57fdd624302aefd13337ee982754c9aa688463ffcae598c08461e8620e9852a424d662ffa948fc64919e852508028d09e89ced459bd506ab - languageName: node - linkType: hard - -"@standard-schema/spec@npm:^1.1.0": - version: 1.1.0 - resolution: "@standard-schema/spec@npm:1.1.0" - checksum: 10c0/d90f55acde4b2deb983529c87e8025fa693de1a5e8b49ecc6eb84d1fd96328add0e03d7d551442156c7432fd78165b2c26ff561b970a9a881f046abb78d6a526 - languageName: node - linkType: hard - -"@stylistic/eslint-plugin@npm:^5.10.0": - version: 5.10.0 - resolution: "@stylistic/eslint-plugin@npm:5.10.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.9.1" - "@typescript-eslint/types": "npm:^8.56.0" - eslint-visitor-keys: "npm:^4.2.1" - espree: "npm:^10.4.0" - estraverse: "npm:^5.3.0" - picomatch: "npm:^4.0.3" - peerDependencies: - eslint: ^9.0.0 || ^10.0.0 - checksum: 10c0/2cc6e592d5b2ab691290cc39ed377c0f6226667b367ffc6a0bf3a4bf6dd36b011d17c83f377600a48946f6bb037390b35a8b3c273b3c40d161c00b44512a129e - languageName: node - linkType: hard - -"@tybys/wasm-util@npm:^0.10.2": - version: 0.10.2 - resolution: "@tybys/wasm-util@npm:0.10.2" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/26165bcd1fd7269f42d7fbe3de318f854a8968de8397e89fc9a423bb3e2da35a52150f382e6323b3367595beb16d9800a6f35971a5599daf76da1742ec3afc25 - languageName: node - linkType: hard - -"@types/babel__code-frame@npm:^7.27.0": - version: 7.27.0 - resolution: "@types/babel__code-frame@npm:7.27.0" - checksum: 10c0/06ff1339d5e0b4bd88819ab43fb6bae3995ba4e020cf0e7f95e868cae62dff12574c3270b2cf0434fdd8de6d8f05973404109eba076ac034f722ebf3f0839665 - languageName: node - linkType: hard - -"@types/chai@npm:^5.2.2": - version: 5.2.3 - resolution: "@types/chai@npm:5.2.3" - dependencies: - "@types/deep-eql": "npm:*" - assertion-error: "npm:^2.0.1" - checksum: 10c0/e0ef1de3b6f8045a5e473e867c8565788c444271409d155588504840ad1a53611011f85072188c2833941189400228c1745d78323dac13fcede9c2b28bacfb2f - languageName: node - linkType: hard - -"@types/deep-eql@npm:*": - version: 4.0.2 - resolution: "@types/deep-eql@npm:4.0.2" - checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 - languageName: node - linkType: hard - -"@types/esrecurse@npm:^4.3.1": - version: 4.3.1 - resolution: "@types/esrecurse@npm:4.3.1" - checksum: 10c0/90dad74d5da3ad27606d8e8e757322f33171cfeaa15ad558b615cf71bb2a516492d18f55f4816384685a3eb2412142e732bbae9a4a7cd2cf3deb7572aa4ebe03 - languageName: node - linkType: hard - -"@types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8": - version: 1.0.9 - resolution: "@types/estree@npm:1.0.9" - checksum: 10c0/3ad3286ca2988cd550dafb8f2ad599c8474868e954fa601a36655bdfefd8039f7c714b8c1c7f2ae219ffbd58bd4660e66fa7479a0120fc02d4777057d4865387 - languageName: node - linkType: hard - -"@types/jsesc@npm:^2.5.0": - version: 2.5.1 - resolution: "@types/jsesc@npm:2.5.1" - checksum: 10c0/12ba7bf5968aeeb36408269f4b5a39718efc6411fa197cf0f5e967ba36ad7b7d555b78787fc480db43ce63ebe6ab0ffe5fd9f64b1ea3b0d073877f0747491b30 - languageName: node - linkType: hard - -"@types/json-schema@npm:^7.0.15": - version: 7.0.15 - resolution: "@types/json-schema@npm:7.0.15" - checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db - languageName: node - linkType: hard - -"@types/node@npm:>=13.7.0": - version: 25.9.3 - resolution: "@types/node@npm:25.9.3" - dependencies: - undici-types: "npm:>=7.24.0 <7.24.7" - checksum: 10c0/72d3aece9d42c2c641bcd3f3cb2dc2828b4bd384dfcbd910c404b8859a68bd69d50c4769ce7defd4ff5e049768e23e615f09407ea2cbbb5f44b90d75a7c6b8ca - languageName: node - linkType: hard - -"@types/node@npm:^25.3.5": - version: 25.9.2 - resolution: "@types/node@npm:25.9.2" - dependencies: - undici-types: "npm:>=7.24.0 <7.24.7" - checksum: 10c0/f14c0d56361febb985eccc45cf0834ee6e2f07c4389a636f3e1a55ebde320077a80bface18c9afd3092f5fa295925502c1a9d55f805efa813f634aa9c941cbac - languageName: node - linkType: hard - -"@types/picomatch@npm:^3.0.2": - version: 3.0.2 - resolution: "@types/picomatch@npm:3.0.2" - checksum: 10c0/f35d16fe10a6e13ead6499dd7d7d317e4fd78e48260398104e837e5ca83d393024bdc6f432cb644c0a69b0726a071fcc6eb09befbbcfafb3c3c5f71dbbfde487 - languageName: node - linkType: hard - -"@types/retry@npm:0.12.0": - version: 0.12.0 - resolution: "@types/retry@npm:0.12.0" - checksum: 10c0/7c5c9086369826f569b83a4683661557cab1361bac0897a1cefa1a915ff739acd10ca0d62b01071046fe3f5a3f7f2aec80785fe283b75602dc6726781ea3e328 - languageName: node - linkType: hard - -"@typescript-eslint/eslint-plugin@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.61.0" - dependencies: - "@eslint-community/regexpp": "npm:^4.12.2" - "@typescript-eslint/scope-manager": "npm:8.61.0" - "@typescript-eslint/type-utils": "npm:8.61.0" - "@typescript-eslint/utils": "npm:8.61.0" - "@typescript-eslint/visitor-keys": "npm:8.61.0" - ignore: "npm:^7.0.5" - natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^2.5.0" - peerDependencies: - "@typescript-eslint/parser": ^8.61.0 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/1141253e18424a9a21d253dcf28e166894b6b914f2138b3e016144e451385f8e23f0f02028c7bd2d21c81953c52e478657aa9e5888cd0bdffdb8d68aab736878 - languageName: node - linkType: hard - -"@typescript-eslint/parser@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/parser@npm:8.61.0" - dependencies: - "@typescript-eslint/scope-manager": "npm:8.61.0" - "@typescript-eslint/types": "npm:8.61.0" - "@typescript-eslint/typescript-estree": "npm:8.61.0" - "@typescript-eslint/visitor-keys": "npm:8.61.0" - debug: "npm:^4.4.3" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/39b122ab20a3b5fbd4e66874f60917b37c49f32eb987531797561d2f96b443e81546f1c9d03d44d37dede89098276e5d8d0f05c1e5f9e1b998f8cf6c24e8e5e7 - languageName: node - linkType: hard - -"@typescript-eslint/project-service@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/project-service@npm:8.61.0" - dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.61.0" - "@typescript-eslint/types": "npm:^8.61.0" - debug: "npm:^4.4.3" - peerDependencies: - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/8ff86b93bfcf103a42e8e996e11c46ded83da07d3a0bc8bd9ec4d536116d7f6253a404786510ab13847e69d6e185b17d15d7140075c26966e9b4f85c03296f21 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/scope-manager@npm:8.61.0" - dependencies: - "@typescript-eslint/types": "npm:8.61.0" - "@typescript-eslint/visitor-keys": "npm:8.61.0" - checksum: 10c0/76cdf1c181ebbc706ddc8b2366e8ebfda529c13d82ff10c0797c96c0b38dd82f6471b24995f58ac267194a753b23d77452d925dd615b1e651922ddbe6e451c6b - languageName: node - linkType: hard - -"@typescript-eslint/tsconfig-utils@npm:8.61.0, @typescript-eslint/tsconfig-utils@npm:^8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.61.0" - peerDependencies: - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/b498675f14ef90a5730de7c58388eb2522085a56c3fcad42ad9f89320b96221eafb5b4f9650375f29092025153d03533e3f23ea8f45ce3bc95a57593059edef3 - languageName: node - linkType: hard - -"@typescript-eslint/type-utils@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/type-utils@npm:8.61.0" - dependencies: - "@typescript-eslint/types": "npm:8.61.0" - "@typescript-eslint/typescript-estree": "npm:8.61.0" - "@typescript-eslint/utils": "npm:8.61.0" - debug: "npm:^4.4.3" - ts-api-utils: "npm:^2.5.0" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/6347f451301ca7089500fe6eb3b98e5efd769e56ffda07eb735130fd209b9053c02e952b6fda7a15acf7851fb63f11fc50166ba8bd90513480732c599644b36b - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:8.61.0, @typescript-eslint/types@npm:^8.56.0, @typescript-eslint/types@npm:^8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/types@npm:8.61.0" - checksum: 10c0/c19407d66fb5ad26e2670cd272bee91d150087d917752422257759e17920220af27cd54593205e9726367a440a237bf8d27ed805cae0b282a79172161f007207 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.61.0" - dependencies: - "@typescript-eslint/project-service": "npm:8.61.0" - "@typescript-eslint/tsconfig-utils": "npm:8.61.0" - "@typescript-eslint/types": "npm:8.61.0" - "@typescript-eslint/visitor-keys": "npm:8.61.0" - debug: "npm:^4.4.3" - minimatch: "npm:^10.2.2" - semver: "npm:^7.7.3" - tinyglobby: "npm:^0.2.15" - ts-api-utils: "npm:^2.5.0" - peerDependencies: - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/460819feeca826bfd895f821a5008c3eaa79b9495259641976fdc6ec319a7e9587bc28603437ea3d9a10c3b28037f1dea883cbe8d2858616dd33847e8db2179e - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/utils@npm:8.61.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.9.1" - "@typescript-eslint/scope-manager": "npm:8.61.0" - "@typescript-eslint/types": "npm:8.61.0" - "@typescript-eslint/typescript-estree": "npm:8.61.0" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/f7b2241fc4defd40107243642e26697193707be12af1552c60bc414e71df1285c9cdff429f913b30ed08ae87a7e6e13388eaf05c1be5fb8310f6a63a6c4f7f73 - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:8.61.0": - version: 8.61.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.61.0" - dependencies: - "@typescript-eslint/types": "npm:8.61.0" - eslint-visitor-keys: "npm:^5.0.0" - checksum: 10c0/5b656aed426a92dfc9a481f0bf535ceb47321303f476f32ba979f73423c739b51d7a5ad76c81d7be9df0a9beb361f4a11ff530dd86d59f41b89bb5f09af7be9f - languageName: node - linkType: hard - -"@vitest/coverage-v8@npm:^4.1.8": - version: 4.1.8 - resolution: "@vitest/coverage-v8@npm:4.1.8" - dependencies: - "@bcoe/v8-coverage": "npm:^1.0.2" - "@vitest/utils": "npm:4.1.8" - ast-v8-to-istanbul: "npm:^1.0.0" - istanbul-lib-coverage: "npm:^3.2.2" - istanbul-lib-report: "npm:^3.0.1" - istanbul-reports: "npm:^3.2.0" - magicast: "npm:^0.5.2" - obug: "npm:^2.1.1" - std-env: "npm:^4.0.0-rc.1" - tinyrainbow: "npm:^3.1.0" - peerDependencies: - "@vitest/browser": 4.1.8 - vitest: 4.1.8 - peerDependenciesMeta: - "@vitest/browser": - optional: true - checksum: 10c0/e3419115fa413e19bda5edd72c8394b255d418af75278b2cd74341257399f8e5921f78b966a547ba8d67ac8268ccdd5af019230084cc1b9a3fc8fae8283ae76b - languageName: node - linkType: hard - -"@vitest/expect@npm:4.1.8": - version: 4.1.8 - resolution: "@vitest/expect@npm:4.1.8" - dependencies: - "@standard-schema/spec": "npm:^1.1.0" - "@types/chai": "npm:^5.2.2" - "@vitest/spy": "npm:4.1.8" - "@vitest/utils": "npm:4.1.8" - chai: "npm:^6.2.2" - tinyrainbow: "npm:^3.1.0" - checksum: 10c0/f7bf6c720d2427c3bd0b35472ebd84d963be7d09ecf52a0fb05e8c4d5d0c9ee164a8c28eee6360947be1b245b47faefab54560cb98e5cb678c1c1074260b9149 - languageName: node - linkType: hard - -"@vitest/mocker@npm:4.1.8": - version: 4.1.8 - resolution: "@vitest/mocker@npm:4.1.8" - dependencies: - "@vitest/spy": "npm:4.1.8" - estree-walker: "npm:^3.0.3" - magic-string: "npm:^0.30.21" - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - checksum: 10c0/f8cb2b8b55dc2cba0b2399aeee528b0187042f22cbc2d50a4fd6141f5aa246ebc41700f45dd1d73eca44ddfb57dcde48b2eb317bfbb1198f5ab2cc4fd04b2ea0 - languageName: node - linkType: hard - -"@vitest/pretty-format@npm:4.1.8": - version: 4.1.8 - resolution: "@vitest/pretty-format@npm:4.1.8" - dependencies: - tinyrainbow: "npm:^3.1.0" - checksum: 10c0/553c456692a4b9ae13cd116c234c74b4495e0f1a0d5c51ffc3fab8ea085e3550769967e29db79bdac0cf127b1bf88b7f70bfba3dcc72be6bddf834433e30cc91 - languageName: node - linkType: hard - -"@vitest/runner@npm:4.1.8": - version: 4.1.8 - resolution: "@vitest/runner@npm:4.1.8" - dependencies: - "@vitest/utils": "npm:4.1.8" - pathe: "npm:^2.0.3" - checksum: 10c0/706808a4b7b95ea9a9268fc152dd39e15a9a754f37c7990aea167486a9094caa913dae454771ae02c18dccfabd667f8cc38eed33a1307a79d32a89878b5bcce1 - languageName: node - linkType: hard - -"@vitest/snapshot@npm:4.1.8": - version: 4.1.8 - resolution: "@vitest/snapshot@npm:4.1.8" - dependencies: - "@vitest/pretty-format": "npm:4.1.8" - "@vitest/utils": "npm:4.1.8" - magic-string: "npm:^0.30.21" - pathe: "npm:^2.0.3" - checksum: 10c0/ba4c32112491d42d24986f921c50ede5edbdb4b7eafa16c72cf8d2c9ecc44121fdb3d9365236747a9841f0d6776affc6457470fcbb082df9dbc28c24792a0c6d - languageName: node - linkType: hard - -"@vitest/spy@npm:4.1.8": - version: 4.1.8 - resolution: "@vitest/spy@npm:4.1.8" - checksum: 10c0/3c10c0325a09d16bc0e77c0be96c47c15416186e33332880c0d1dd0a51d51a866091067b81f2a2ef6fb422a7760e6cf15c04d91a0eca4d59f62e8c8401fa53fc - languageName: node - linkType: hard - -"@vitest/utils@npm:4.1.8": - version: 4.1.8 - resolution: "@vitest/utils@npm:4.1.8" - dependencies: - "@vitest/pretty-format": "npm:4.1.8" - convert-source-map: "npm:^2.0.0" - tinyrainbow: "npm:^3.1.0" - checksum: 10c0/acda9d3d640c1ebc81afb358ac30589d7d7d583af81e2d09419f0af9cbe41f3ce0b90527326943bf0da51614be5fc31afcd32259f6beb32b3417999d6ef380f3 - languageName: node - linkType: hard - -"@yarnpkg/types@npm:^4.0.1": - version: 4.0.1 - resolution: "@yarnpkg/types@npm:4.0.1" - dependencies: - tslib: "npm:^2.4.0" - checksum: 10c0/90226789475680ba599833571dd76c0718dd5b4c5022481263ef309d6a628f6246671cd6ca86e49c966ddefa7aca6ccef82240dc1476d2cea702ea5bee2a6b72 - languageName: node - linkType: hard - -"abbrev@npm:^4.0.0": - version: 4.0.0 - resolution: "abbrev@npm:4.0.0" - checksum: 10c0/b4cc16935235e80702fc90192e349e32f8ef0ed151ef506aa78c81a7c455ec18375c4125414b99f84b2e055199d66383e787675f0bcd87da7a4dbd59f9eac1d5 - languageName: node - linkType: hard - -"acorn-jsx@npm:^5.3.2": - version: 5.3.2 - resolution: "acorn-jsx@npm:5.3.2" - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1 - languageName: node - linkType: hard - -"acorn@npm:^8.15.0, acorn@npm:^8.16.0": - version: 8.16.0 - resolution: "acorn@npm:8.16.0" - bin: - acorn: bin/acorn - checksum: 10c0/c9c52697227661b68d0debaf972222d4f622aa06b185824164e153438afa7b08273432ca43ea792cadb24dada1d46f6f6bb1ef8de9956979288cc1b96bf9914e - languageName: node - linkType: hard - -"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": - version: 7.1.4 - resolution: "agent-base@npm:7.1.4" - checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe - languageName: node - linkType: hard - -"ajv@npm:^6.14.0": - version: 6.15.0 - resolution: "ajv@npm:6.15.0" - dependencies: - fast-deep-equal: "npm:^3.1.1" - fast-json-stable-stringify: "npm:^2.0.0" - json-schema-traverse: "npm:^0.4.1" - uri-js: "npm:^4.2.2" - checksum: 10c0/67966499dd272ecde1c2e467084411132891523d057487587879d39ac04207f4351b7b2324c83198013967fbfa632c1612adc960114a30770fbe07a0773b32c2 - languageName: node - linkType: hard - -"ansis@npm:^4.3.1": - version: 4.3.1 - resolution: "ansis@npm:4.3.1" - checksum: 10c0/d1a48090f9c33b18f254a3496e5336a20391a51140b552a1c0bc38710ae7c8bc36a62658f28759797d7bce15e89b893e9ef1962ea1ea42a291d112263f6e593c - languageName: node - linkType: hard - -"anynum@npm:^1.0.0": - version: 1.0.0 - resolution: "anynum@npm:1.0.0" - checksum: 10c0/c929fed8f4127cd706312da58ae2aa83a06e62059eef04392fe2bacec003b6f6b7ca5f2719bd09c693b100f185bcf6405419744812f1096cdb53aed4034b9209 - languageName: node - linkType: hard - -"argparse@npm:^2.0.1": - version: 2.0.1 - resolution: "argparse@npm:2.0.1" - checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e - languageName: node - linkType: hard - -"assertion-error@npm:^2.0.1": - version: 2.0.1 - resolution: "assertion-error@npm:2.0.1" - checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 - languageName: node - linkType: hard - -"ast-kit@npm:^3.0.0-beta.1": - version: 3.0.0-beta.1 - resolution: "ast-kit@npm:3.0.0-beta.1" - dependencies: - "@babel/parser": "npm:^8.0.0-beta.4" - estree-walker: "npm:^3.0.3" - pathe: "npm:^2.0.3" - checksum: 10c0/27a0309d495100e088c6aa6449e2bb79fdf6321c42bb73c196d646935ff788c2202d8dfc19e04499c623f0676cbe5d6baaeb645ede4b349fac2bd5c276419d5a - languageName: node - linkType: hard - -"ast-v8-to-istanbul@npm:^1.0.0": - version: 1.0.4 - resolution: "ast-v8-to-istanbul@npm:1.0.4" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.31" - estree-walker: "npm:^3.0.3" - js-tokens: "npm:^10.0.0" - checksum: 10c0/48305cc748fcd0c8a84cf5750cca9e220e1cdb977286917e79a3182cd1eda9a6c73db7afb6526d86f3336684d4662b684db7c8a925448122603df048097b1d00 - languageName: node - linkType: hard - -"balanced-match@npm:^4.0.2": - version: 4.0.4 - resolution: "balanced-match@npm:4.0.4" - checksum: 10c0/07e86102a3eb2ee2a6a1a89164f29d0dbaebd28f2ca3f5ca786f36b8b23d9e417eb3be45a4acf754f837be5ac0a2317de90d3fcb7f4f4dc95720a1f36b26a17b - languageName: node - linkType: hard - -"base64-js@npm:^1.3.0": - version: 1.5.1 - resolution: "base64-js@npm:1.5.1" - checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf - languageName: node - linkType: hard - -"bignumber.js@npm:^9.0.0": - version: 9.3.1 - resolution: "bignumber.js@npm:9.3.1" - checksum: 10c0/61342ba5fe1c10887f0ecf5be02ff6709271481aff48631f86b4d37d55a99b87ce441cfd54df3d16d10ee07ceab7e272fc0be430c657ffafbbbf7b7d631efb75 - languageName: node - linkType: hard - -"birpc@npm:^4.0.0": - version: 4.0.0 - resolution: "birpc@npm:4.0.0" - checksum: 10c0/61f4e893ff4c5948b2c587c971c04883af0d8b2658d4632c8e77073db9f9e8b040402f985d56308021890b2ad32ef8392e36a8335cab1e3771d99e1b025d1af6 - languageName: node - linkType: hard - -"bowser@npm:^2.11.0": - version: 2.14.1 - resolution: "bowser@npm:2.14.1" - checksum: 10c0/bb69b55ba7f0456e3dc07d0cfd9467f985581f640ba8fd426b08754a6737ee0d6cf3b50607941e5255f04c83075b952ece0599f978dd4d20f1e95461104c5ffd - languageName: node - linkType: hard - -"brace-expansion@npm:^5.0.5": - version: 5.0.6 - resolution: "brace-expansion@npm:5.0.6" - dependencies: - balanced-match: "npm:^4.0.2" - checksum: 10c0/8c919869b90f61d533b341d3340be5ee4413232ea89b8246cbc2f38eb014f1d8182785c98a006eaf6111d02dc9eeffefdc240d5ac158625b2ed084dccd4bbf9b - languageName: node - linkType: hard - -"buffer-equal-constant-time@npm:^1.0.1": - version: 1.0.1 - resolution: "buffer-equal-constant-time@npm:1.0.1" - checksum: 10c0/fb2294e64d23c573d0dd1f1e7a466c3e978fe94a4e0f8183937912ca374619773bef8e2aceb854129d2efecbbc515bbd0cc78d2734a3e3031edb0888531bbc8e - languageName: node - linkType: hard - -"cac@npm:^7.0.0": - version: 7.0.0 - resolution: "cac@npm:7.0.0" - checksum: 10c0/e9da33cb9f0425546ae92a450d479276f9969a050fe64f5d6fedf058bdd87f22a370797fe1c158e07655fa9fc183749df7cb2037431e3772faa7bee9919fb763 - languageName: node - linkType: hard - -"chai@npm:^6.2.2": - version: 6.2.2 - resolution: "chai@npm:6.2.2" - checksum: 10c0/e6c69e5f0c11dffe6ea13d0290936ebb68fcc1ad688b8e952e131df6a6d5797d5e860bc55cef1aca2e950c3e1f96daf79e9d5a70fb7dbaab4e46355e2635ed53 - languageName: node - linkType: hard - -"chokidar@npm:^4.0.3": - version: 4.0.3 - resolution: "chokidar@npm:4.0.3" - dependencies: - readdirp: "npm:^4.0.1" - checksum: 10c0/a58b9df05bb452f7d105d9e7229ac82fa873741c0c40ddcc7bb82f8a909fbe3f7814c9ebe9bc9a2bef9b737c0ec6e2d699d179048ef06ad3ec46315df0ebe6ad - languageName: node - linkType: hard - -"chownr@npm:^3.0.0": - version: 3.0.0 - resolution: "chownr@npm:3.0.0" - checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10 - languageName: node - linkType: hard - -"convert-source-map@npm:^2.0.0": - version: 2.0.0 - resolution: "convert-source-map@npm:2.0.0" - checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b - languageName: node - linkType: hard - -"cordis@npm:^4.0.0-rc.6, cordis@workspace:vendor/cordis": - version: 0.0.0-use.local - resolution: "cordis@workspace:vendor/cordis" - dependencies: - "@standard-schema/spec": "npm:^1.1.0" - cosmokit: "npm:^1.8.1" - peerDependencies: - "@cordisjs/plugin-include": ^1.0.4 - "@cordisjs/plugin-loader": ^1.0.0-rc.4 - peerDependenciesMeta: - "@cordisjs/plugin-include": - optional: true - "@cordisjs/plugin-loader": - optional: true - bin: - cordis: bin.js - languageName: unknown - linkType: soft - -"cosmokit@npm:^1.8.1, cosmokit@workspace:vendor/cosmokit": - version: 0.0.0-use.local - resolution: "cosmokit@workspace:vendor/cosmokit" - languageName: unknown - linkType: soft - -"cross-spawn@npm:^7.0.6": - version: 7.0.6 - resolution: "cross-spawn@npm:7.0.6" - dependencies: - path-key: "npm:^3.1.0" - shebang-command: "npm:^2.0.0" - which: "npm:^2.0.1" - checksum: 10c0/053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1 - languageName: node - linkType: hard - -"data-uri-to-buffer@npm:^4.0.0": - version: 4.0.1 - resolution: "data-uri-to-buffer@npm:4.0.1" - checksum: 10c0/20a6b93107597530d71d4cb285acee17f66bcdfc03fd81040921a81252f19db27588d87fc8fc69e1950c55cfb0bf8ae40d0e5e21d907230813eb5d5a7f9eb45b - languageName: node - linkType: hard - -"debug@npm:4, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.3": - version: 4.4.3 - resolution: "debug@npm:4.4.3" - dependencies: - ms: "npm:^2.1.3" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6 - languageName: node - linkType: hard - -"deep-is@npm:^0.1.3": - version: 0.1.4 - resolution: "deep-is@npm:0.1.4" - checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c - languageName: node - linkType: hard - -"defu@npm:^6.1.7": - version: 6.1.7 - resolution: "defu@npm:6.1.7" - checksum: 10c0/e6635388103c8be3c574ac31302f6930e5e6eeedba32cb1b30cf993c7d9fb571aec2485446dfa23bfa63e55e66156fe109027a9695db82a50f931e91e8d4bedb - languageName: node - linkType: hard - -"detect-libc@npm:^2.0.3": - version: 2.1.2 - resolution: "detect-libc@npm:2.1.2" - checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4 - languageName: node - linkType: hard - -"dts-resolver@npm:^3.0.0": - version: 3.0.0 - resolution: "dts-resolver@npm:3.0.0" - peerDependencies: - oxc-resolver: ">=11.0.0" - peerDependenciesMeta: - oxc-resolver: - optional: true - checksum: 10c0/ae52c4e09b43def702b02d7edbfa04798522907f22879809f8890e5c61fc762403f46a1c415c2d1a6440b01960bbaf98c72def1771b0962d3b15fec40983a4ab - languageName: node - linkType: hard - -"ecdsa-sig-formatter@npm:1.0.11, ecdsa-sig-formatter@npm:^1.0.11": - version: 1.0.11 - resolution: "ecdsa-sig-formatter@npm:1.0.11" - dependencies: - safe-buffer: "npm:^5.0.1" - checksum: 10c0/ebfbf19d4b8be938f4dd4a83b8788385da353d63307ede301a9252f9f7f88672e76f2191618fd8edfc2f24679236064176fab0b78131b161ee73daa37125408c - languageName: node - linkType: hard - -"empathic@npm:^2.0.1": - version: 2.0.1 - resolution: "empathic@npm:2.0.1" - checksum: 10c0/577f2868bfcad4ffbf911b57c75016125eb8cc8a7d32cf2d3e9fbcb31bfe6e9e6b66d9457ac34ccb2cd38bff353b3af34287899e0360b8c561ff6d4a048aca62 - languageName: node - linkType: hard - -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 - languageName: node - linkType: hard - -"es-module-lexer@npm:^2.0.0": - version: 2.1.0 - resolution: "es-module-lexer@npm:2.1.0" - checksum: 10c0/93bcf2454fa72d67fe3ccd0abef8ce7933f5840a319513418a643dd8e9c6aa8f49709cecfae02ded722805dd327232d30723a807cc52e6809d6ac697c62c29fb - languageName: node - linkType: hard - -"esbuild@npm:~0.28.0": - version: 0.28.0 - resolution: "esbuild@npm:0.28.0" - dependencies: - "@esbuild/aix-ppc64": "npm:0.28.0" - "@esbuild/android-arm": "npm:0.28.0" - "@esbuild/android-arm64": "npm:0.28.0" - "@esbuild/android-x64": "npm:0.28.0" - "@esbuild/darwin-arm64": "npm:0.28.0" - "@esbuild/darwin-x64": "npm:0.28.0" - "@esbuild/freebsd-arm64": "npm:0.28.0" - "@esbuild/freebsd-x64": "npm:0.28.0" - "@esbuild/linux-arm": "npm:0.28.0" - "@esbuild/linux-arm64": "npm:0.28.0" - "@esbuild/linux-ia32": "npm:0.28.0" - "@esbuild/linux-loong64": "npm:0.28.0" - "@esbuild/linux-mips64el": "npm:0.28.0" - "@esbuild/linux-ppc64": "npm:0.28.0" - "@esbuild/linux-riscv64": "npm:0.28.0" - "@esbuild/linux-s390x": "npm:0.28.0" - "@esbuild/linux-x64": "npm:0.28.0" - "@esbuild/netbsd-arm64": "npm:0.28.0" - "@esbuild/netbsd-x64": "npm:0.28.0" - "@esbuild/openbsd-arm64": "npm:0.28.0" - "@esbuild/openbsd-x64": "npm:0.28.0" - "@esbuild/openharmony-arm64": "npm:0.28.0" - "@esbuild/sunos-x64": "npm:0.28.0" - "@esbuild/win32-arm64": "npm:0.28.0" - "@esbuild/win32-ia32": "npm:0.28.0" - "@esbuild/win32-x64": "npm:0.28.0" - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-arm64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-arm64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/openharmony-arm64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 10c0/8acd95c238ec6c4a9d16163277faf228a8994b642d187b3fe667ffbb469008e6748cde144fdc3c175bf8e78ee49e15a0ed9b9f183fdb5fcea1772f87fb1372a4 - languageName: node - linkType: hard - -"escape-string-regexp@npm:^4.0.0": - version: 4.0.0 - resolution: "escape-string-regexp@npm:4.0.0" - checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 - languageName: node - linkType: hard - -"eslint-scope@npm:^9.1.2": - version: 9.1.2 - resolution: "eslint-scope@npm:9.1.2" - dependencies: - "@types/esrecurse": "npm:^4.3.1" - "@types/estree": "npm:^1.0.8" - esrecurse: "npm:^4.3.0" - estraverse: "npm:^5.2.0" - checksum: 10c0/9fb8bca5a73e5741efb6cec84467027b6cb6f4203ff9b43a938e272c5cd30800bde46a5c20dfd1609f840225f0b62b7673be391b20acadf8658ca9fa4729b3dd - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^3.4.3": - version: 3.4.3 - resolution: "eslint-visitor-keys@npm:3.4.3" - checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^4.2.1": - version: 4.2.1 - resolution: "eslint-visitor-keys@npm:4.2.1" - checksum: 10c0/fcd43999199d6740db26c58dbe0c2594623e31ca307e616ac05153c9272f12f1364f5a0b1917a8e962268fdecc6f3622c1c2908b4fcc2e047a106fe6de69dc43 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^5.0.0, eslint-visitor-keys@npm:^5.0.1": - version: 5.0.1 - resolution: "eslint-visitor-keys@npm:5.0.1" - checksum: 10c0/16190bdf2cbae40a1109384c94450c526a79b0b9c3cb21e544256ed85ac48a4b84db66b74a6561d20fe6ab77447f150d711c2ad5ad74df4fcc133736bce99678 - languageName: node - linkType: hard - -"eslint@npm:^10.4.1": - version: 10.4.1 - resolution: "eslint@npm:10.4.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.8.0" - "@eslint-community/regexpp": "npm:^4.12.2" - "@eslint/config-array": "npm:^0.23.5" - "@eslint/config-helpers": "npm:^0.6.0" - "@eslint/core": "npm:^1.2.1" - "@eslint/plugin-kit": "npm:^0.7.2" - "@humanfs/node": "npm:^0.16.6" - "@humanwhocodes/module-importer": "npm:^1.0.1" - "@humanwhocodes/retry": "npm:^0.4.2" - "@types/estree": "npm:^1.0.6" - ajv: "npm:^6.14.0" - cross-spawn: "npm:^7.0.6" - debug: "npm:^4.3.2" - escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^9.1.2" - eslint-visitor-keys: "npm:^5.0.1" - espree: "npm:^11.2.0" - esquery: "npm:^1.7.0" - esutils: "npm:^2.0.2" - fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^8.0.0" - find-up: "npm:^5.0.0" - glob-parent: "npm:^6.0.2" - ignore: "npm:^5.2.0" - imurmurhash: "npm:^0.1.4" - is-glob: "npm:^4.0.0" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - minimatch: "npm:^10.2.4" - natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.3" - peerDependencies: - jiti: "*" - peerDependenciesMeta: - jiti: - optional: true - bin: - eslint: bin/eslint.js - checksum: 10c0/c5e6bb5158fb0d62f090c8e2671de5c98283bbb37a58b6d871bada63af3018e683483c96c1a92272fedc8f4e5279a273a0451acf0da67c487406639daa05aedb - languageName: node - linkType: hard - -"espree@npm:^10.4.0": - version: 10.4.0 - resolution: "espree@npm:10.4.0" - dependencies: - acorn: "npm:^8.15.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^4.2.1" - checksum: 10c0/c63fe06131c26c8157b4083313cb02a9a54720a08e21543300e55288c40e06c3fc284bdecf108d3a1372c5934a0a88644c98714f38b6ae8ed272b40d9ea08d6b - languageName: node - linkType: hard - -"espree@npm:^11.2.0": - version: 11.2.0 - resolution: "espree@npm:11.2.0" - dependencies: - acorn: "npm:^8.16.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^5.0.1" - checksum: 10c0/cf87e18ffd9dc113eb8d16588e7757701bc10c9934a71cce8b89c2611d51672681a918307bd6b19ac3ccd0e7ba1cbccc2f815b36b52fa7e73097b251014c3d81 - languageName: node - linkType: hard - -"esquery@npm:^1.7.0": - version: 1.7.0 - resolution: "esquery@npm:1.7.0" - dependencies: - estraverse: "npm:^5.1.0" - checksum: 10c0/77d5173db450b66f3bc685d11af4c90cffeedb340f34a39af96d43509a335ce39c894fd79233df32d38f5e4e219fa0f7076f6ec90bae8320170ba082c0db4793 - languageName: node - linkType: hard - -"esrecurse@npm:^4.3.0": - version: 4.3.0 - resolution: "esrecurse@npm:4.3.0" - dependencies: - estraverse: "npm:^5.2.0" - checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 - languageName: node - linkType: hard - -"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": - version: 5.3.0 - resolution: "estraverse@npm:5.3.0" - checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 - languageName: node - linkType: hard - -"estree-walker@npm:^3.0.3": - version: 3.0.3 - resolution: "estree-walker@npm:3.0.3" - dependencies: - "@types/estree": "npm:^1.0.0" - checksum: 10c0/c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d - languageName: node - linkType: hard - -"esutils@npm:^2.0.2": - version: 2.0.3 - resolution: "esutils@npm:2.0.3" - checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 - languageName: node - linkType: hard - -"expect-type@npm:^1.3.0": - version: 1.3.0 - resolution: "expect-type@npm:1.3.0" - checksum: 10c0/8412b3fe4f392c420ab41dae220b09700e4e47c639a29ba7ba2e83cc6cffd2b4926f7ac9e47d7e277e8f4f02acda76fd6931cb81fd2b382fa9477ef9ada953fd - languageName: node - linkType: hard - -"exponential-backoff@npm:^3.1.1": - version: 3.1.3 - resolution: "exponential-backoff@npm:3.1.3" - checksum: 10c0/77e3ae682b7b1f4972f563c6dbcd2b0d54ac679e62d5d32f3e5085feba20483cf28bd505543f520e287a56d4d55a28d7874299941faf637e779a1aa5994d1267 - languageName: node - linkType: hard - -"extend@npm:^3.0.2": - version: 3.0.2 - resolution: "extend@npm:3.0.2" - checksum: 10c0/73bf6e27406e80aa3e85b0d1c4fd987261e628064e170ca781125c0b635a3dabad5e05adbf07595ea0cf1e6c5396cacb214af933da7cbaf24fe75ff14818e8f9 - languageName: node - linkType: hard - -"fast-check@npm:^4.8.0": - version: 4.8.0 - resolution: "fast-check@npm:4.8.0" - dependencies: - pure-rand: "npm:^8.0.0" - checksum: 10c0/f72556a29db4ff386a8b6e50d420b06c7e5eaafff7db5560a99136c57d8d4777998155eb02d1bbeff396f575cc0b1442c8a1c4ddb798c4a919b542de1a1904ff - languageName: node - linkType: hard - -"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": - version: 3.1.3 - resolution: "fast-deep-equal@npm:3.1.3" - checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 - languageName: node - linkType: hard - -"fast-json-stable-stringify@npm:^2.0.0": - version: 2.1.0 - resolution: "fast-json-stable-stringify@npm:2.1.0" - checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b - languageName: node - linkType: hard - -"fast-levenshtein@npm:^2.0.6": - version: 2.0.6 - resolution: "fast-levenshtein@npm:2.0.6" - checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4 - languageName: node - linkType: hard - -"fast-xml-builder@npm:^1.1.7": - version: 1.2.0 - resolution: "fast-xml-builder@npm:1.2.0" - dependencies: - path-expression-matcher: "npm:^1.5.0" - xml-naming: "npm:^0.1.0" - checksum: 10c0/84bb105cd04e91d6dcb746c4dbaeb12903b510e7ab9a06ffde55b5a582e005559a87d84467f18a655c6c4baf098f696fd74cee3cbe1aea9d01385907768ba32d - languageName: node - linkType: hard - -"fast-xml-parser@npm:5.7.3": - version: 5.7.3 - resolution: "fast-xml-parser@npm:5.7.3" - dependencies: - "@nodable/entities": "npm:^2.1.0" - fast-xml-builder: "npm:^1.1.7" - path-expression-matcher: "npm:^1.5.0" - strnum: "npm:^2.2.3" - bin: - fxparser: src/cli/cli.js - checksum: 10c0/eeb802855e852ce16121396297f04131c6dbc74f863be94f19e26e386656bdb31677af469ddc6627983a48b99d8842888460ac5413063cb648fde547bb579978 - languageName: node - linkType: hard - -"fd-package-json@npm:^2.0.0": - version: 2.0.0 - resolution: "fd-package-json@npm:2.0.0" - dependencies: - walk-up-path: "npm:^4.0.0" - checksum: 10c0/a0a48745257bc09c939486608dad9f2ced238f0c64266222cc881618ed4c8f6aa0ccfe45a1e6d4f9ce828509e8d617cec60e2a114851bebb1ff4886dc5ed5112 - languageName: node - linkType: hard - -"fdir@npm:^6.5.0": - version: 6.5.0 - resolution: "fdir@npm:6.5.0" - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f - languageName: node - linkType: hard - -"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4": - version: 3.2.0 - resolution: "fetch-blob@npm:3.2.0" - dependencies: - node-domexception: "npm:^1.0.0" - web-streams-polyfill: "npm:^3.0.3" - checksum: 10c0/60054bf47bfa10fb0ba6cb7742acec2f37c1f56344f79a70bb8b1c48d77675927c720ff3191fa546410a0442c998d27ab05e9144c32d530d8a52fbe68f843b69 - languageName: node - linkType: hard - -"file-entry-cache@npm:^8.0.0": - version: 8.0.0 - resolution: "file-entry-cache@npm:8.0.0" - dependencies: - flat-cache: "npm:^4.0.0" - checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 - languageName: node - linkType: hard - -"find-up@npm:^5.0.0": - version: 5.0.0 - resolution: "find-up@npm:5.0.0" - dependencies: - locate-path: "npm:^6.0.0" - path-exists: "npm:^4.0.0" - checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a - languageName: node - linkType: hard - -"flat-cache@npm:^4.0.0": - version: 4.0.1 - resolution: "flat-cache@npm:4.0.1" - dependencies: - flatted: "npm:^3.2.9" - keyv: "npm:^4.5.4" - checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc - languageName: node - linkType: hard - -"flatted@npm:^3.2.9": - version: 3.4.2 - resolution: "flatted@npm:3.4.2" - checksum: 10c0/a65b67aae7172d6cdf63691be7de6c5cd5adbdfdfe2e9da1a09b617c9512ed794037741ee53d93114276bff3f93cd3b0d97d54f9b316e1e4885dde6e9ffdf7ed - languageName: node - linkType: hard - -"formatly@npm:^0.3.0": - version: 0.3.0 - resolution: "formatly@npm:0.3.0" - dependencies: - fd-package-json: "npm:^2.0.0" - bin: - formatly: bin/index.mjs - checksum: 10c0/ef9dbd3cdaee649e9604ea060d8d62d8131eb81117634336592ee2193fc7c98a3f1f1b5d09a045dbd36287ba88edf868ef179d39fbda2f34fbe2be70c42dd014 - languageName: node - linkType: hard - -"formdata-polyfill@npm:^4.0.10": - version: 4.0.10 - resolution: "formdata-polyfill@npm:4.0.10" - dependencies: - fetch-blob: "npm:^3.1.2" - checksum: 10c0/5392ec484f9ce0d5e0d52fb5a78e7486637d516179b0eb84d81389d7eccf9ca2f663079da56f761355c0a65792810e3b345dc24db9a8bbbcf24ef3c8c88570c6 - languageName: node - linkType: hard - -"fsevents@npm:~2.3.3": - version: 2.3.3 - resolution: "fsevents@npm:2.3.3" - dependencies: - node-gyp: "npm:latest" - checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 - conditions: os=darwin - languageName: node - linkType: hard - -"fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": - version: 2.3.3 - resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" - dependencies: - node-gyp: "npm:latest" - conditions: os=darwin - languageName: node - linkType: hard - -"gaxios@npm:^7.0.0, gaxios@npm:^7.1.4": - version: 7.1.5 - resolution: "gaxios@npm:7.1.5" - dependencies: - extend: "npm:^3.0.2" - https-proxy-agent: "npm:^7.0.1" - node-fetch: "npm:^3.3.2" - checksum: 10c0/a3d12a9d2b781c548b40b4f2d7792281d091b63ffdd92713301a6e55bc9072fe7c1c54fa014416ca1fcdba40c171389bd409d0e3e326f4ae5ae60b25ae8ea540 - languageName: node - linkType: hard - -"gcp-metadata@npm:8.1.2": - version: 8.1.2 - resolution: "gcp-metadata@npm:8.1.2" - dependencies: - gaxios: "npm:^7.0.0" - google-logging-utils: "npm:^1.0.0" - json-bigint: "npm:^1.0.0" - checksum: 10c0/15a61231a9410dc11c2828d2c9fdc8b0a939f1af746195c44edc6f2ffea0acab52cef3a7b9828069a36fd5d68bda730f7328a415fe42a01258f6e249dfba6908 - languageName: node - linkType: hard - -"get-tsconfig@npm:4.14.0": - version: 4.14.0 - resolution: "get-tsconfig@npm:4.14.0" - dependencies: - resolve-pkg-maps: "npm:^1.0.0" - checksum: 10c0/abc2b9275468eb589079a0b7a95eb5107c14fdd0ca6dda1bff116fe774ea1f79975421dcb22a0c86b4f820fcc69a7655dddf9b6d6a8a2c06fcb59e19794c0724 - languageName: node - linkType: hard - -"get-tsconfig@npm:5.0.0-beta.5": - version: 5.0.0-beta.5 - resolution: "get-tsconfig@npm:5.0.0-beta.5" - dependencies: - resolve-pkg-maps: "npm:^1.0.0" - checksum: 10c0/fd96e2a7d872703d8c5d7ed5d5d884a4e33f6cd9f012aa68a3c7aae700b84b502e41c06641a3d0667b1e8c8f7d497857dd6d3bba3987d2e5f59d95e49fb6e3b9 - languageName: node - linkType: hard - -"glob-parent@npm:^6.0.2": - version: 6.0.2 - resolution: "glob-parent@npm:6.0.2" - dependencies: - is-glob: "npm:^4.0.3" - checksum: 10c0/317034d88654730230b3f43bb7ad4f7c90257a426e872ea0bf157473ac61c99bf5d205fad8f0185f989be8d2fa6d3c7dce1645d99d545b6ea9089c39f838e7f8 - languageName: node - linkType: hard - -"globrex@npm:^0.1.2": - version: 0.1.2 - resolution: "globrex@npm:0.1.2" - checksum: 10c0/a54c029520cf58bda1d8884f72bd49b4cd74e977883268d931fd83bcbd1a9eb96d57c7dbd4ad80148fb9247467ebfb9b215630b2ed7563b2a8de02e1ff7f89d1 - languageName: node - linkType: hard - -"google-auth-library@npm:^10.3.0": - version: 10.7.0 - resolution: "google-auth-library@npm:10.7.0" - dependencies: - base64-js: "npm:^1.3.0" - ecdsa-sig-formatter: "npm:^1.0.11" - gaxios: "npm:^7.1.4" - gcp-metadata: "npm:8.1.2" - google-logging-utils: "npm:1.1.3" - jws: "npm:^4.0.0" - checksum: 10c0/e8827ff84a69bbd6573229d8245d8fbb8870304e255c213571541d039c33764a6f4a8d773c002a16d6d75e35b9a596310b5c6f8e25b189a02eb4cebd6f022321 - languageName: node - linkType: hard - -"google-logging-utils@npm:1.1.3": - version: 1.1.3 - resolution: "google-logging-utils@npm:1.1.3" - checksum: 10c0/e65201c7e96543bd1423b9324013736646b9eed60941e0bfa47b9bfd146d2f09cf3df1c99ca60b7d80a726075263ead049ee72de53372cb8458c3bc55c2c1e59 - languageName: node - linkType: hard - -"google-logging-utils@npm:^1.0.0": - version: 1.1.4 - resolution: "google-logging-utils@npm:1.1.4" - checksum: 10c0/860873974dd31678553f1074eb8fcf49c6417807086f4645ee8d4eaa81e8dce39f8f7a4b6856be4fda6e5d812b2df10e7abeb6dfe28353d28724cf81357c5a53 - languageName: node - linkType: hard - -"graceful-fs@npm:^4.2.6": - version: 4.2.11 - resolution: "graceful-fs@npm:4.2.11" - checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 - languageName: node - linkType: hard - -"has-flag@npm:^4.0.0": - version: 4.0.0 - resolution: "has-flag@npm:4.0.0" - checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 - languageName: node - linkType: hard - -"hookable@npm:^6.1.1": - version: 6.1.1 - resolution: "hookable@npm:6.1.1" - checksum: 10c0/bb46cd9ffc0a997af21febd97835da4e59a6989adec73dc3c215fcc44c7ac01de4781f251c3d420bf45862d2592a695f5f0de095b6f5df52db8afb5166938212 - languageName: node - linkType: hard - -"html-escaper@npm:^2.0.0": - version: 2.0.2 - resolution: "html-escaper@npm:2.0.2" - checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0 - languageName: node - linkType: hard - -"http-proxy-agent@npm:7.0.2": - version: 7.0.2 - resolution: "http-proxy-agent@npm:7.0.2" - dependencies: - agent-base: "npm:^7.1.0" - debug: "npm:^4.3.4" - checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 - languageName: node - linkType: hard - -"https-proxy-agent@npm:7.0.6, https-proxy-agent@npm:^7.0.1": - version: 7.0.6 - resolution: "https-proxy-agent@npm:7.0.6" - dependencies: - agent-base: "npm:^7.1.2" - debug: "npm:4" - checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac - languageName: node - linkType: hard - -"ignore@npm:^5.2.0": - version: 5.3.2 - resolution: "ignore@npm:5.3.2" - checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 - languageName: node - linkType: hard - -"ignore@npm:^7.0.5": - version: 7.0.5 - resolution: "ignore@npm:7.0.5" - checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d - languageName: node - linkType: hard - -"import-without-cache@npm:^0.4.0": - version: 0.4.0 - resolution: "import-without-cache@npm:0.4.0" - checksum: 10c0/5ba51078dc15f08cd1ef4e12f3d274a7e1906319ac831b5ddf036a033ab3b4395264b93c64be8b6050be27546754a4c3a84fcfbe8e827ba221203cc47c608a46 - languageName: node - linkType: hard - -"imurmurhash@npm:^0.1.4": - version: 0.1.4 - resolution: "imurmurhash@npm:0.1.4" - checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.1": - version: 2.1.1 - resolution: "is-extglob@npm:2.1.1" - checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 - languageName: node - linkType: hard - -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.3": - version: 4.0.3 - resolution: "is-glob@npm:4.0.3" - dependencies: - is-extglob: "npm:^2.1.1" - checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a - languageName: node - linkType: hard - -"isexe@npm:^2.0.0": - version: 2.0.0 - resolution: "isexe@npm:2.0.0" - checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d - languageName: node - linkType: hard - -"isexe@npm:^4.0.0": - version: 4.0.0 - resolution: "isexe@npm:4.0.0" - checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce - languageName: node - linkType: hard - -"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2": - version: 3.2.2 - resolution: "istanbul-lib-coverage@npm:3.2.2" - checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b - languageName: node - linkType: hard - -"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": - version: 3.0.1 - resolution: "istanbul-lib-report@npm:3.0.1" - dependencies: - istanbul-lib-coverage: "npm:^3.0.0" - make-dir: "npm:^4.0.0" - supports-color: "npm:^7.1.0" - checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 - languageName: node - linkType: hard - -"istanbul-reports@npm:^3.2.0": - version: 3.2.0 - resolution: "istanbul-reports@npm:3.2.0" - dependencies: - html-escaper: "npm:^2.0.0" - istanbul-lib-report: "npm:^3.0.0" - checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc - languageName: node - linkType: hard - -"jiti@npm:^2.7.0": - version: 2.7.0 - resolution: "jiti@npm:2.7.0" - bin: - jiti: lib/jiti-cli.mjs - checksum: 10c0/1b1e2310a490dce1aeea3da5f5dfe18273516c20ce48be2e98eb8ea452d5f3dcc8fd0cfd6d28b4052a24c5dbab6e3089b2d7e79f0bce7915b10d750929563c42 - languageName: node - linkType: hard - -"js-tokens@npm:^10.0.0": - version: 10.0.0 - resolution: "js-tokens@npm:10.0.0" - checksum: 10c0/a93498747812ba3e0c8626f95f75ab29319f2a13613a0de9e610700405760931624433a0de59eb7c27ff8836e526768fb20783861b86ef89be96676f2c996b64 - languageName: node - linkType: hard - -"js-tokens@npm:^4.0.0": - version: 4.0.0 - resolution: "js-tokens@npm:4.0.0" - checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed - languageName: node - linkType: hard - -"js-yaml@npm:^4.1.0": - version: 4.2.0 - resolution: "js-yaml@npm:4.2.0" - dependencies: - argparse: "npm:^2.0.1" - bin: - js-yaml: bin/js-yaml.js - checksum: 10c0/1916456c118746603b067d74bbcbb0445d9a1d5e474ad4ae775e7b20525bed902e01d9d97dd0c81fcd8d4f596162309d0eb057f4aa38f3e9647f14075e9dea45 - languageName: node - linkType: hard - -"jsesc@npm:^3.0.2": - version: 3.1.0 - resolution: "jsesc@npm:3.1.0" - bin: - jsesc: bin/jsesc - checksum: 10c0/531779df5ec94f47e462da26b4cbf05eb88a83d9f08aac2ba04206508fc598527a153d08bd462bae82fc78b3eaa1a908e1a4a79f886e9238641c4cdefaf118b1 - languageName: node - linkType: hard - -"json-bigint@npm:^1.0.0": - version: 1.0.0 - resolution: "json-bigint@npm:1.0.0" - dependencies: - bignumber.js: "npm:^9.0.0" - checksum: 10c0/e3f34e43be3284b573ea150a3890c92f06d54d8ded72894556357946aeed9877fd795f62f37fe16509af189fd314ab1104d0fd0f163746ad231b9f378f5b33f4 - languageName: node - linkType: hard - -"json-buffer@npm:3.0.1": - version: 3.0.1 - resolution: "json-buffer@npm:3.0.1" - checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 - languageName: node - linkType: hard - -"json-schema-to-ts@npm:^3.1.1": - version: 3.1.1 - resolution: "json-schema-to-ts@npm:3.1.1" - dependencies: - "@babel/runtime": "npm:^7.18.3" - ts-algebra: "npm:^2.0.0" - checksum: 10c0/609bae04aa5e860a11b6d30ccf41445fae1c7f66fb600c1d170257cf33aa468aa9d03aa046428c3688aff0ff450c2b0c76584b66fa4a5d0da8e33799e4c439a6 - languageName: node - linkType: hard - -"json-schema-traverse@npm:^0.4.1": - version: 0.4.1 - resolution: "json-schema-traverse@npm:0.4.1" - checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce - languageName: node - linkType: hard - -"json-stable-stringify-without-jsonify@npm:^1.0.1": - version: 1.0.1 - resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" - checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 - languageName: node - linkType: hard - -"jwa@npm:^2.0.1": - version: 2.0.1 - resolution: "jwa@npm:2.0.1" - dependencies: - buffer-equal-constant-time: "npm:^1.0.1" - ecdsa-sig-formatter: "npm:1.0.11" - safe-buffer: "npm:^5.0.1" - checksum: 10c0/ab3ebc6598e10dc11419d4ed675c9ca714a387481466b10e8a6f3f65d8d9c9237e2826f2505280a739cf4cbcf511cb288eeec22b5c9c63286fc5a2e4f97e78cf - languageName: node - linkType: hard - -"jws@npm:^4.0.0": - version: 4.0.1 - resolution: "jws@npm:4.0.1" - dependencies: - jwa: "npm:^2.0.1" - safe-buffer: "npm:^5.0.1" - checksum: 10c0/6be1ed93023aef570ccc5ea8d162b065840f3ef12f0d1bb3114cade844de7a357d5dc558201d9a65101e70885a6fa56b17462f520e6b0d426195510618a154d0 - languageName: node - linkType: hard - -"keyv@npm:^4.5.4": - version: 4.5.4 - resolution: "keyv@npm:4.5.4" - dependencies: - json-buffer: "npm:3.0.1" - checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e - languageName: node - linkType: hard - -"knip@npm:^6.16.1": - version: 6.16.1 - resolution: "knip@npm:6.16.1" - dependencies: - fdir: "npm:^6.5.0" - formatly: "npm:^0.3.0" - get-tsconfig: "npm:4.14.0" - jiti: "npm:^2.7.0" - oxc-parser: "npm:^0.133.0" - oxc-resolver: "npm:^11.20.0" - picomatch: "npm:^4.0.4" - smol-toml: "npm:^1.6.1" - strip-json-comments: "npm:5.0.3" - tinyglobby: "npm:^0.2.16" - unbash: "npm:^3.0.0" - yaml: "npm:^2.9.0" - zod: "npm:^4.1.11" - bin: - knip: bin/knip.js - knip-bun: bin/knip-bun.js - checksum: 10c0/b723ee43f2a5170d5330d3d6cbd54452620ca76e2bffc11d8c8615d5f42c3aa60e9f7763f768210c0b97babff046df668479cb7f4ca78e3e7a8312ef12530370 - languageName: node - linkType: hard - -"lefthook-darwin-arm64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-darwin-arm64@npm:2.1.9" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"lefthook-darwin-x64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-darwin-x64@npm:2.1.9" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"lefthook-freebsd-arm64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-freebsd-arm64@npm:2.1.9" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"lefthook-freebsd-x64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-freebsd-x64@npm:2.1.9" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"lefthook-linux-arm64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-linux-arm64@npm:2.1.9" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"lefthook-linux-x64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-linux-x64@npm:2.1.9" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"lefthook-openbsd-arm64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-openbsd-arm64@npm:2.1.9" - conditions: os=openbsd & cpu=arm64 - languageName: node - linkType: hard - -"lefthook-openbsd-x64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-openbsd-x64@npm:2.1.9" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"lefthook-windows-arm64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-windows-arm64@npm:2.1.9" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"lefthook-windows-x64@npm:2.1.9": - version: 2.1.9 - resolution: "lefthook-windows-x64@npm:2.1.9" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"lefthook@npm:^2.1.9": - version: 2.1.9 - resolution: "lefthook@npm:2.1.9" - dependencies: - lefthook-darwin-arm64: "npm:2.1.9" - lefthook-darwin-x64: "npm:2.1.9" - lefthook-freebsd-arm64: "npm:2.1.9" - lefthook-freebsd-x64: "npm:2.1.9" - lefthook-linux-arm64: "npm:2.1.9" - lefthook-linux-x64: "npm:2.1.9" - lefthook-openbsd-arm64: "npm:2.1.9" - lefthook-openbsd-x64: "npm:2.1.9" - lefthook-windows-arm64: "npm:2.1.9" - lefthook-windows-x64: "npm:2.1.9" - dependenciesMeta: - lefthook-darwin-arm64: - optional: true - lefthook-darwin-x64: - optional: true - lefthook-freebsd-arm64: - optional: true - lefthook-freebsd-x64: - optional: true - lefthook-linux-arm64: - optional: true - lefthook-linux-x64: - optional: true - lefthook-openbsd-arm64: - optional: true - lefthook-openbsd-x64: - optional: true - lefthook-windows-arm64: - optional: true - lefthook-windows-x64: - optional: true - bin: - lefthook: bin/index.js - checksum: 10c0/676d9798942439d1cd5373bb0b2c9907f6a8097b29c05cc028d87d897d2a2cfe15a8f7e4f40b02fa93cd1ae0f02528f24053a10fb5c5967210a9c23f3c7b5059 - languageName: node - linkType: hard - -"levn@npm:^0.4.1": - version: 0.4.1 - resolution: "levn@npm:0.4.1" - dependencies: - prelude-ls: "npm:^1.2.1" - type-check: "npm:~0.4.0" - checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e - languageName: node - linkType: hard - -"lightningcss-android-arm64@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-android-arm64@npm:1.32.0" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"lightningcss-darwin-arm64@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-darwin-arm64@npm:1.32.0" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"lightningcss-darwin-x64@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-darwin-x64@npm:1.32.0" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"lightningcss-freebsd-x64@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-freebsd-x64@npm:1.32.0" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"lightningcss-linux-arm-gnueabihf@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-linux-arm-gnueabihf@npm:1.32.0" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"lightningcss-linux-arm64-gnu@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-linux-arm64-gnu@npm:1.32.0" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"lightningcss-linux-arm64-musl@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-linux-arm64-musl@npm:1.32.0" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"lightningcss-linux-x64-gnu@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-linux-x64-gnu@npm:1.32.0" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"lightningcss-linux-x64-musl@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-linux-x64-musl@npm:1.32.0" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"lightningcss-win32-arm64-msvc@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-win32-arm64-msvc@npm:1.32.0" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"lightningcss-win32-x64-msvc@npm:1.32.0": - version: 1.32.0 - resolution: "lightningcss-win32-x64-msvc@npm:1.32.0" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"lightningcss@npm:^1.32.0": - version: 1.32.0 - resolution: "lightningcss@npm:1.32.0" - dependencies: - detect-libc: "npm:^2.0.3" - lightningcss-android-arm64: "npm:1.32.0" - lightningcss-darwin-arm64: "npm:1.32.0" - lightningcss-darwin-x64: "npm:1.32.0" - lightningcss-freebsd-x64: "npm:1.32.0" - lightningcss-linux-arm-gnueabihf: "npm:1.32.0" - lightningcss-linux-arm64-gnu: "npm:1.32.0" - lightningcss-linux-arm64-musl: "npm:1.32.0" - lightningcss-linux-x64-gnu: "npm:1.32.0" - lightningcss-linux-x64-musl: "npm:1.32.0" - lightningcss-win32-arm64-msvc: "npm:1.32.0" - lightningcss-win32-x64-msvc: "npm:1.32.0" - dependenciesMeta: - lightningcss-android-arm64: - optional: true - lightningcss-darwin-arm64: - optional: true - lightningcss-darwin-x64: - optional: true - lightningcss-freebsd-x64: - optional: true - lightningcss-linux-arm-gnueabihf: - optional: true - lightningcss-linux-arm64-gnu: - optional: true - lightningcss-linux-arm64-musl: - optional: true - lightningcss-linux-x64-gnu: - optional: true - lightningcss-linux-x64-musl: - optional: true - lightningcss-win32-arm64-msvc: - optional: true - lightningcss-win32-x64-msvc: - optional: true - checksum: 10c0/70945bd55097af46fc9fab7f5ed09cd5869d85940a2acab7ee06d0117004a1d68155708a2d462531cea2fc3c67aefc9333a7068c80b0b78dd404c16838809e03 - languageName: node - linkType: hard - -"locate-path@npm:^6.0.0": - version: 6.0.0 - resolution: "locate-path@npm:6.0.0" - dependencies: - p-locate: "npm:^5.0.0" - checksum: 10c0/d3972ab70dfe58ce620e64265f90162d247e87159b6126b01314dd67be43d50e96a50b517bce2d9452a79409c7614054c277b5232377de50416564a77ac7aad3 - languageName: node - linkType: hard - -"long@npm:^5.3.2": - version: 5.3.2 - resolution: "long@npm:5.3.2" - checksum: 10c0/7130fe1cbce2dca06734b35b70d380ca3f70271c7f8852c922a7c62c86c4e35f0c39290565eca7133c625908d40e126ac57c02b1b1a4636b9457d77e1e60b981 - languageName: node - linkType: hard - -"magic-string@npm:^0.30.21": - version: 0.30.21 - resolution: "magic-string@npm:0.30.21" - dependencies: - "@jridgewell/sourcemap-codec": "npm:^1.5.5" - checksum: 10c0/299378e38f9a270069fc62358522ddfb44e94244baa0d6a8980ab2a9b2490a1d03b236b447eee309e17eb3bddfa482c61259d47960eb018a904f0ded52780c4a - languageName: node - linkType: hard - -"magicast@npm:^0.5.2": - version: 0.5.3 - resolution: "magicast@npm:0.5.3" - dependencies: - "@babel/parser": "npm:^7.29.3" - "@babel/types": "npm:^7.29.0" - source-map-js: "npm:^1.2.1" - checksum: 10c0/e288c027ae5f2a794a59148cb114f4b60f1d5c03090de6c60b4d187f12d1de9158779cd7c39cea391609f4f10cd7ea737929f25f7ce44f7a96ba96ec1a477e39 - languageName: node - linkType: hard - -"make-dir@npm:^4.0.0": - version: 4.0.0 - resolution: "make-dir@npm:4.0.0" - dependencies: - semver: "npm:^7.5.3" - checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68 - languageName: node - linkType: hard - -"minimatch@npm:^10.2.2, minimatch@npm:^10.2.4": - version: 10.2.5 - resolution: "minimatch@npm:10.2.5" - dependencies: - brace-expansion: "npm:^5.0.5" - checksum: 10c0/6bb058bd6324104b9ec2f763476a35386d05079c1f5fe4fbf1f324a25237cd4534d6813ecd71f48208f4e635c1221899bef94c3c89f7df55698fe373aaae20fd - languageName: node - linkType: hard - -"minipass@npm:^7.0.4, minipass@npm:^7.1.2": - version: 7.1.3 - resolution: "minipass@npm:7.1.3" - checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb - languageName: node - linkType: hard - -"minizlib@npm:^3.1.0": - version: 3.1.0 - resolution: "minizlib@npm:3.1.0" - dependencies: - minipass: "npm:^7.1.2" - checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec - languageName: node - linkType: hard - -"mri@npm:^1.1.0": - version: 1.2.0 - resolution: "mri@npm:1.2.0" - checksum: 10c0/a3d32379c2554cf7351db6237ddc18dc9e54e4214953f3da105b97dc3babe0deb3ffe99cf409b38ea47cc29f9430561ba6b53b24ab8f9ce97a4b50409e4a50e7 - languageName: node - linkType: hard - -"ms@npm:^2.1.3": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 - languageName: node - linkType: hard - -"nanoid@npm:^3.3.12": - version: 3.3.12 - resolution: "nanoid@npm:3.3.12" - bin: - nanoid: bin/nanoid.cjs - checksum: 10c0/ba142b7b39e11e80c16dd74b0365d407880c87c1cf7e1480956981ae940ee36060fa5b6f092cd1e315184dd19244c657bd017d03327bd3c62247d691c5e8edfb - languageName: node - linkType: hard - -"natural-compare@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare@npm:1.4.0" - checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447 - languageName: node - linkType: hard - -"node-domexception@npm:^1.0.0": - version: 1.0.0 - resolution: "node-domexception@npm:1.0.0" - checksum: 10c0/5e5d63cda29856402df9472335af4bb13875e1927ad3be861dc5ebde38917aecbf9ae337923777af52a48c426b70148815e890a5d72760f1b4d758cc671b1a2b - languageName: node - linkType: hard - -"node-fetch@npm:^3.3.2": - version: 3.3.2 - resolution: "node-fetch@npm:3.3.2" - dependencies: - data-uri-to-buffer: "npm:^4.0.0" - fetch-blob: "npm:^3.1.4" - formdata-polyfill: "npm:^4.0.10" - checksum: 10c0/f3d5e56190562221398c9f5750198b34cf6113aa304e34ee97c94fd300ec578b25b2c2906edba922050fce983338fde0d5d34fcb0fc3336ade5bd0e429ad7538 - languageName: node - linkType: hard - -"node-gyp@npm:latest": - version: 12.4.0 - resolution: "node-gyp@npm:12.4.0" - dependencies: - env-paths: "npm:^2.2.0" - exponential-backoff: "npm:^3.1.1" - graceful-fs: "npm:^4.2.6" - nopt: "npm:^9.0.0" - proc-log: "npm:^6.0.0" - semver: "npm:^7.3.5" - tar: "npm:^7.5.4" - tinyglobby: "npm:^0.2.12" - undici: "npm:^6.25.0" - which: "npm:^6.0.0" - bin: - node-gyp: bin/node-gyp.js - checksum: 10c0/9acb7c798e124275a6f9c1f7eb64b5abd6196bb885a3945fb44ee0dccf435514e88cdfb0f228ee7ff76ef25107c1f39ff37a067bf92fd00b9aff9234db29ff9e - languageName: node - linkType: hard - -"nopt@npm:^9.0.0": - version: 9.0.0 - resolution: "nopt@npm:9.0.0" - dependencies: - abbrev: "npm:^4.0.0" - bin: - nopt: bin/nopt.js - checksum: 10c0/1822eb6f9b020ef6f7a7516d7b64a8036e09666ea55ac40416c36e4b2b343122c3cff0e2f085675f53de1d2db99a2a89a60ccea1d120bcd6a5347bf6ceb4a7fd - languageName: node - linkType: hard - -"obug@npm:^2.1.1": - version: 2.1.2 - resolution: "obug@npm:2.1.2" - checksum: 10c0/e857080ef23c018bd4ad8553238cd97008cd4ab8472b4b83eafe75c19e9b6f84ac8fe53ef7f50b515a1dbf83e6372dd0b198aece33bc716edfa70366f6f6ed5e - languageName: node - linkType: hard - -"openai@npm:6.26.0": - version: 6.26.0 - resolution: "openai@npm:6.26.0" - peerDependencies: - ws: ^8.18.0 - zod: ^3.25 || ^4.0 - peerDependenciesMeta: - ws: - optional: true - zod: - optional: true - bin: - openai: bin/cli - checksum: 10c0/dc045e8ed317dead468ecb342040eaee1e5388f2042f926dab4d0d0ec51b3dce41167edf16003ca850d594cbdbc8cc279a0529ec7820d8c86f3b8d33b6941b40 - languageName: node - linkType: hard - -"optionator@npm:^0.9.3": - version: 0.9.4 - resolution: "optionator@npm:0.9.4" - dependencies: - deep-is: "npm:^0.1.3" - fast-levenshtein: "npm:^2.0.6" - levn: "npm:^0.4.1" - prelude-ls: "npm:^1.2.1" - type-check: "npm:^0.4.0" - word-wrap: "npm:^1.2.5" - checksum: 10c0/4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675 - languageName: node - linkType: hard - -"oxc-parser@npm:^0.133.0": - version: 0.133.0 - resolution: "oxc-parser@npm:0.133.0" - dependencies: - "@oxc-parser/binding-android-arm-eabi": "npm:0.133.0" - "@oxc-parser/binding-android-arm64": "npm:0.133.0" - "@oxc-parser/binding-darwin-arm64": "npm:0.133.0" - "@oxc-parser/binding-darwin-x64": "npm:0.133.0" - "@oxc-parser/binding-freebsd-x64": "npm:0.133.0" - "@oxc-parser/binding-linux-arm-gnueabihf": "npm:0.133.0" - "@oxc-parser/binding-linux-arm-musleabihf": "npm:0.133.0" - "@oxc-parser/binding-linux-arm64-gnu": "npm:0.133.0" - "@oxc-parser/binding-linux-arm64-musl": "npm:0.133.0" - "@oxc-parser/binding-linux-ppc64-gnu": "npm:0.133.0" - "@oxc-parser/binding-linux-riscv64-gnu": "npm:0.133.0" - "@oxc-parser/binding-linux-riscv64-musl": "npm:0.133.0" - "@oxc-parser/binding-linux-s390x-gnu": "npm:0.133.0" - "@oxc-parser/binding-linux-x64-gnu": "npm:0.133.0" - "@oxc-parser/binding-linux-x64-musl": "npm:0.133.0" - "@oxc-parser/binding-openharmony-arm64": "npm:0.133.0" - "@oxc-parser/binding-wasm32-wasi": "npm:0.133.0" - "@oxc-parser/binding-win32-arm64-msvc": "npm:0.133.0" - "@oxc-parser/binding-win32-ia32-msvc": "npm:0.133.0" - "@oxc-parser/binding-win32-x64-msvc": "npm:0.133.0" - "@oxc-project/types": "npm:^0.133.0" - dependenciesMeta: - "@oxc-parser/binding-android-arm-eabi": - optional: true - "@oxc-parser/binding-android-arm64": - optional: true - "@oxc-parser/binding-darwin-arm64": - optional: true - "@oxc-parser/binding-darwin-x64": - optional: true - "@oxc-parser/binding-freebsd-x64": - optional: true - "@oxc-parser/binding-linux-arm-gnueabihf": - optional: true - "@oxc-parser/binding-linux-arm-musleabihf": - optional: true - "@oxc-parser/binding-linux-arm64-gnu": - optional: true - "@oxc-parser/binding-linux-arm64-musl": - optional: true - "@oxc-parser/binding-linux-ppc64-gnu": - optional: true - "@oxc-parser/binding-linux-riscv64-gnu": - optional: true - "@oxc-parser/binding-linux-riscv64-musl": - optional: true - "@oxc-parser/binding-linux-s390x-gnu": - optional: true - "@oxc-parser/binding-linux-x64-gnu": - optional: true - "@oxc-parser/binding-linux-x64-musl": - optional: true - "@oxc-parser/binding-openharmony-arm64": - optional: true - "@oxc-parser/binding-wasm32-wasi": - optional: true - "@oxc-parser/binding-win32-arm64-msvc": - optional: true - "@oxc-parser/binding-win32-ia32-msvc": - optional: true - "@oxc-parser/binding-win32-x64-msvc": - optional: true - checksum: 10c0/62d4ce93d819d47d4a295744bb3966c66b658bb33f35f6ebc0650ba854d6b070e62baa6f933366f45dc65983a77be9527ed15cacc0f532a252f2e049623c4ce2 - languageName: node - linkType: hard - -"oxc-resolver@npm:^11.20.0": - version: 11.20.0 - resolution: "oxc-resolver@npm:11.20.0" - dependencies: - "@oxc-resolver/binding-android-arm-eabi": "npm:11.20.0" - "@oxc-resolver/binding-android-arm64": "npm:11.20.0" - "@oxc-resolver/binding-darwin-arm64": "npm:11.20.0" - "@oxc-resolver/binding-darwin-x64": "npm:11.20.0" - "@oxc-resolver/binding-freebsd-x64": "npm:11.20.0" - "@oxc-resolver/binding-linux-arm-gnueabihf": "npm:11.20.0" - "@oxc-resolver/binding-linux-arm-musleabihf": "npm:11.20.0" - "@oxc-resolver/binding-linux-arm64-gnu": "npm:11.20.0" - "@oxc-resolver/binding-linux-arm64-musl": "npm:11.20.0" - "@oxc-resolver/binding-linux-ppc64-gnu": "npm:11.20.0" - "@oxc-resolver/binding-linux-riscv64-gnu": "npm:11.20.0" - "@oxc-resolver/binding-linux-riscv64-musl": "npm:11.20.0" - "@oxc-resolver/binding-linux-s390x-gnu": "npm:11.20.0" - "@oxc-resolver/binding-linux-x64-gnu": "npm:11.20.0" - "@oxc-resolver/binding-linux-x64-musl": "npm:11.20.0" - "@oxc-resolver/binding-openharmony-arm64": "npm:11.20.0" - "@oxc-resolver/binding-wasm32-wasi": "npm:11.20.0" - "@oxc-resolver/binding-win32-arm64-msvc": "npm:11.20.0" - "@oxc-resolver/binding-win32-x64-msvc": "npm:11.20.0" - dependenciesMeta: - "@oxc-resolver/binding-android-arm-eabi": - optional: true - "@oxc-resolver/binding-android-arm64": - optional: true - "@oxc-resolver/binding-darwin-arm64": - optional: true - "@oxc-resolver/binding-darwin-x64": - optional: true - "@oxc-resolver/binding-freebsd-x64": - optional: true - "@oxc-resolver/binding-linux-arm-gnueabihf": - optional: true - "@oxc-resolver/binding-linux-arm-musleabihf": - optional: true - "@oxc-resolver/binding-linux-arm64-gnu": - optional: true - "@oxc-resolver/binding-linux-arm64-musl": - optional: true - "@oxc-resolver/binding-linux-ppc64-gnu": - optional: true - "@oxc-resolver/binding-linux-riscv64-gnu": - optional: true - "@oxc-resolver/binding-linux-riscv64-musl": - optional: true - "@oxc-resolver/binding-linux-s390x-gnu": - optional: true - "@oxc-resolver/binding-linux-x64-gnu": - optional: true - "@oxc-resolver/binding-linux-x64-musl": - optional: true - "@oxc-resolver/binding-openharmony-arm64": - optional: true - "@oxc-resolver/binding-wasm32-wasi": - optional: true - "@oxc-resolver/binding-win32-arm64-msvc": - optional: true - "@oxc-resolver/binding-win32-x64-msvc": - optional: true - checksum: 10c0/4a0b0fae7a8b8a25d5173aaeb7348c53d5f60d5bb37a66c3177dcf416319d1f7065b625afa37b924a288dec5b401ba92b003cbce26b91e6631bd8690052c80de - languageName: node - linkType: hard - -"p-limit@npm:^3.0.2": - version: 3.1.0 - resolution: "p-limit@npm:3.1.0" - dependencies: - yocto-queue: "npm:^0.1.0" - checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a - languageName: node - linkType: hard - -"p-locate@npm:^5.0.0": - version: 5.0.0 - resolution: "p-locate@npm:5.0.0" - dependencies: - p-limit: "npm:^3.0.2" - checksum: 10c0/2290d627ab7903b8b70d11d384fee714b797f6040d9278932754a6860845c4d3190603a0772a663c8cb5a7b21d1b16acb3a6487ebcafa9773094edc3dfe6009a - languageName: node - linkType: hard - -"p-retry@npm:^4.6.2": - version: 4.6.2 - resolution: "p-retry@npm:4.6.2" - dependencies: - "@types/retry": "npm:0.12.0" - retry: "npm:^0.13.1" - checksum: 10c0/d58512f120f1590cfedb4c2e0c42cb3fa66f3cea8a4646632fcb834c56055bb7a6f138aa57b20cc236fb207c9d694e362e0b5c2b14d9b062f67e8925580c73b0 - languageName: node - linkType: hard - -"package-manager-detector@npm:^1.6.0": - version: 1.6.0 - resolution: "package-manager-detector@npm:1.6.0" - checksum: 10c0/6419d0b840be64fd45bcdcb7a19f09b81b65456d5e7f7a3daac305a4c90643052122f6ac0308afe548ffee75e36148532a2002ea9d292754f1e385aa2e1ea03b - languageName: node - linkType: hard - -"partial-json@npm:0.1.7": - version: 0.1.7 - resolution: "partial-json@npm:0.1.7" - checksum: 10c0/cd5f994c3a5ca903918c028a6947ebc1d46459234c1c57c7ab98e234d8dca49cb46b05a71889ee422b39d1f66b95c59a5ce3a6ae06966aca95a8960ad20c12d2 - languageName: node - linkType: hard - -"path-exists@npm:^4.0.0": - version: 4.0.0 - resolution: "path-exists@npm:4.0.0" - checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b - languageName: node - linkType: hard - -"path-expression-matcher@npm:^1.5.0": - version: 1.5.0 - resolution: "path-expression-matcher@npm:1.5.0" - checksum: 10c0/646cb5bc66cd7d809a52288336f3ac1e6223f156fd8e912936e490e590f7f93e8056d4fd25fcbcc7da61bb698fa520112cb050372a3f65e7b79bd4afa0f77610 - languageName: node - linkType: hard - -"path-key@npm:^3.1.0": - version: 3.1.1 - resolution: "path-key@npm:3.1.1" - checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c - languageName: node - linkType: hard - -"pathe@npm:^2.0.3": - version: 2.0.3 - resolution: "pathe@npm:2.0.3" - checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1 - languageName: node - linkType: hard - -"picocolors@npm:^1.1.1": - version: 1.1.1 - resolution: "picocolors@npm:1.1.1" - checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 - languageName: node - linkType: hard - -"picomatch@npm:^4.0.3, picomatch@npm:^4.0.4": - version: 4.0.4 - resolution: "picomatch@npm:4.0.4" - checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0 - languageName: node - linkType: hard - -"postcss@npm:^8.5.15": - version: 8.5.15 - resolution: "postcss@npm:8.5.15" - dependencies: - nanoid: "npm:^3.3.12" - picocolors: "npm:^1.1.1" - source-map-js: "npm:^1.2.1" - checksum: 10c0/7f2e63ae22fbe43aace1bf652bd99da4e90737c64194d49e51ddc9cd0f9e51ff2861a7d734379b494deffa03a880a5c65eec70bc29ee9ebaa7136dde3eee8f31 - languageName: node - linkType: hard - -"prelude-ls@npm:^1.2.1": - version: 1.2.1 - resolution: "prelude-ls@npm:1.2.1" - checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd - languageName: node - linkType: hard - -"proc-log@npm:^6.0.0": - version: 6.1.0 - resolution: "proc-log@npm:6.1.0" - checksum: 10c0/4f178d4062733ead9d71a9b1ab24ebcecdfe2250916a5b1555f04fe2eda972a0ec76fbaa8df1ad9c02707add6749219d118a4fc46dc56bdfe4dde4b47d80bb82 - languageName: node - linkType: hard - -"protobufjs@npm:^7.5.4": - version: 7.6.4 - resolution: "protobufjs@npm:7.6.4" - dependencies: - "@protobufjs/aspromise": "npm:^1.1.2" - "@protobufjs/base64": "npm:^1.1.2" - "@protobufjs/codegen": "npm:^2.0.5" - "@protobufjs/eventemitter": "npm:^1.1.1" - "@protobufjs/fetch": "npm:^1.1.1" - "@protobufjs/float": "npm:^1.0.2" - "@protobufjs/path": "npm:^1.1.2" - "@protobufjs/pool": "npm:^1.1.0" - "@protobufjs/utf8": "npm:^1.1.1" - "@types/node": "npm:>=13.7.0" - long: "npm:^5.3.2" - checksum: 10c0/6403eaa9c5a72cc6450c11f38fefafdde243fd806e7ac606ac8d591bc3fdaec45ae764febf83181a2d9aac51aca624e0f46dec368ceea191f7e85e2d6ccaaf93 - languageName: node - linkType: hard - -"publint@npm:^0.3.21": - version: 0.3.21 - resolution: "publint@npm:0.3.21" - dependencies: - "@publint/pack": "npm:^0.1.4" - package-manager-detector: "npm:^1.6.0" - picocolors: "npm:^1.1.1" - sade: "npm:^1.8.1" - bin: - publint: src/cli.js - checksum: 10c0/46f54061b112f852523e8b1357c5b454633008056de86f6acbbabcb155a8ab758d3e575df9f82fa37b7ba4a25bde8e68f98866763929eaef8c6d96ff1f761cea - languageName: node - linkType: hard - -"punycode@npm:^2.1.0": - version: 2.3.1 - resolution: "punycode@npm:2.3.1" - checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 - languageName: node - linkType: hard - -"pure-rand@npm:^8.0.0": - version: 8.4.0 - resolution: "pure-rand@npm:8.4.0" - checksum: 10c0/6414bbc1c6f45fb774173431c7205e79783b77cfae0e2145e741b6999363554dbd2f4210d2a5bc08683e0b2f6823198c9308766b1d0911e1dccd7beb8842f860 - languageName: node - linkType: hard - -"quansync@npm:^1.0.0": - version: 1.0.0 - resolution: "quansync@npm:1.0.0" - checksum: 10c0/076542634399a0cc46078baab6b31acee7a88c5a435234345f645aedaa42bc6a63836e655fb39b1b21a83c98ec86a4b73ec5e2b2d6f3fdc22711eeeff9463253 - languageName: node - linkType: hard - -"readdirp@npm:^4.0.1": - version: 4.1.2 - resolution: "readdirp@npm:4.1.2" - checksum: 10c0/60a14f7619dec48c9c850255cd523e2717001b0e179dc7037cfa0895da7b9e9ab07532d324bfb118d73a710887d1e35f79c495fa91582784493e085d18c72c62 - languageName: node - linkType: hard - -"resolve-pkg-maps@npm:^1.0.0": - version: 1.0.0 - resolution: "resolve-pkg-maps@npm:1.0.0" - checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab - languageName: node - linkType: hard - -"retry@npm:^0.13.1": - version: 0.13.1 - resolution: "retry@npm:0.13.1" - checksum: 10c0/9ae822ee19db2163497e074ea919780b1efa00431d197c7afdb950e42bf109196774b92a49fc9821f0b8b328a98eea6017410bfc5e8a0fc19c85c6d11adb3772 - languageName: node - linkType: hard - -"rolldown-plugin-dts@npm:^0.25.2": - version: 0.25.2 - resolution: "rolldown-plugin-dts@npm:0.25.2" - dependencies: - "@babel/generator": "npm:8.0.0-rc.6" - "@babel/helper-validator-identifier": "npm:8.0.0-rc.6" - "@babel/parser": "npm:8.0.0-rc.6" - ast-kit: "npm:^3.0.0-beta.1" - birpc: "npm:^4.0.0" - dts-resolver: "npm:^3.0.0" - get-tsconfig: "npm:5.0.0-beta.5" - obug: "npm:^2.1.1" - peerDependencies: - "@ts-macro/tsc": ^0.3.6 - "@typescript/native-preview": ">=7.0.0-dev.20260325.1" - rolldown: ^1.0.0 - typescript: ^5.0.0 || ^6.0.0 - vue-tsc: ~3.2.0 - peerDependenciesMeta: - "@ts-macro/tsc": - optional: true - "@typescript/native-preview": - optional: true - typescript: - optional: true - vue-tsc: - optional: true - checksum: 10c0/8bfce712dcbabf8a3554cf1e106644920b500790382c7ec4026f27293db267dd0709d85c6587680b3d1d4591908281bc435f2469c265b258c129d00a579f7bbd - languageName: node - linkType: hard - -"rolldown@npm:1.0.3": - version: 1.0.3 - resolution: "rolldown@npm:1.0.3" - dependencies: - "@oxc-project/types": "npm:=0.133.0" - "@rolldown/binding-android-arm64": "npm:1.0.3" - "@rolldown/binding-darwin-arm64": "npm:1.0.3" - "@rolldown/binding-darwin-x64": "npm:1.0.3" - "@rolldown/binding-freebsd-x64": "npm:1.0.3" - "@rolldown/binding-linux-arm-gnueabihf": "npm:1.0.3" - "@rolldown/binding-linux-arm64-gnu": "npm:1.0.3" - "@rolldown/binding-linux-arm64-musl": "npm:1.0.3" - "@rolldown/binding-linux-ppc64-gnu": "npm:1.0.3" - "@rolldown/binding-linux-s390x-gnu": "npm:1.0.3" - "@rolldown/binding-linux-x64-gnu": "npm:1.0.3" - "@rolldown/binding-linux-x64-musl": "npm:1.0.3" - "@rolldown/binding-openharmony-arm64": "npm:1.0.3" - "@rolldown/binding-wasm32-wasi": "npm:1.0.3" - "@rolldown/binding-win32-arm64-msvc": "npm:1.0.3" - "@rolldown/binding-win32-x64-msvc": "npm:1.0.3" - "@rolldown/pluginutils": "npm:^1.0.0" - dependenciesMeta: - "@rolldown/binding-android-arm64": - optional: true - "@rolldown/binding-darwin-arm64": - optional: true - "@rolldown/binding-darwin-x64": - optional: true - "@rolldown/binding-freebsd-x64": - optional: true - "@rolldown/binding-linux-arm-gnueabihf": - optional: true - "@rolldown/binding-linux-arm64-gnu": - optional: true - "@rolldown/binding-linux-arm64-musl": - optional: true - "@rolldown/binding-linux-ppc64-gnu": - optional: true - "@rolldown/binding-linux-s390x-gnu": - optional: true - "@rolldown/binding-linux-x64-gnu": - optional: true - "@rolldown/binding-linux-x64-musl": - optional: true - "@rolldown/binding-openharmony-arm64": - optional: true - "@rolldown/binding-wasm32-wasi": - optional: true - "@rolldown/binding-win32-arm64-msvc": - optional: true - "@rolldown/binding-win32-x64-msvc": - optional: true - bin: - rolldown: ./bin/cli.mjs - checksum: 10c0/5f9dd47b7abf203b16bc600db68542f245e974c800e59ff50b76157d1dada1403657690435b036fabca88e93d13a67c31abe5cfaa6f61ce33717f61720204cdf - languageName: node - linkType: hard - -"rolldown@npm:~1.1.0": - version: 1.1.1 - resolution: "rolldown@npm:1.1.1" - dependencies: - "@oxc-project/types": "npm:=0.135.0" - "@rolldown/binding-android-arm64": "npm:1.1.1" - "@rolldown/binding-darwin-arm64": "npm:1.1.1" - "@rolldown/binding-darwin-x64": "npm:1.1.1" - "@rolldown/binding-freebsd-x64": "npm:1.1.1" - "@rolldown/binding-linux-arm-gnueabihf": "npm:1.1.1" - "@rolldown/binding-linux-arm64-gnu": "npm:1.1.1" - "@rolldown/binding-linux-arm64-musl": "npm:1.1.1" - "@rolldown/binding-linux-ppc64-gnu": "npm:1.1.1" - "@rolldown/binding-linux-s390x-gnu": "npm:1.1.1" - "@rolldown/binding-linux-x64-gnu": "npm:1.1.1" - "@rolldown/binding-linux-x64-musl": "npm:1.1.1" - "@rolldown/binding-openharmony-arm64": "npm:1.1.1" - "@rolldown/binding-wasm32-wasi": "npm:1.1.1" - "@rolldown/binding-win32-arm64-msvc": "npm:1.1.1" - "@rolldown/binding-win32-x64-msvc": "npm:1.1.1" - "@rolldown/pluginutils": "npm:^1.0.0" - dependenciesMeta: - "@rolldown/binding-android-arm64": - optional: true - "@rolldown/binding-darwin-arm64": - optional: true - "@rolldown/binding-darwin-x64": - optional: true - "@rolldown/binding-freebsd-x64": - optional: true - "@rolldown/binding-linux-arm-gnueabihf": - optional: true - "@rolldown/binding-linux-arm64-gnu": - optional: true - "@rolldown/binding-linux-arm64-musl": - optional: true - "@rolldown/binding-linux-ppc64-gnu": - optional: true - "@rolldown/binding-linux-s390x-gnu": - optional: true - "@rolldown/binding-linux-x64-gnu": - optional: true - "@rolldown/binding-linux-x64-musl": - optional: true - "@rolldown/binding-openharmony-arm64": - optional: true - "@rolldown/binding-wasm32-wasi": - optional: true - "@rolldown/binding-win32-arm64-msvc": - optional: true - "@rolldown/binding-win32-x64-msvc": - optional: true - bin: - rolldown: ./bin/cli.mjs - checksum: 10c0/85500de91284b4abbffb3e8c68b2538d9d766ed9482bc4fd59247c8d1eb42d71ef00f44be56642dca298e2ea00b12208dde5478746fbc8777fde05a0720d0e6d - languageName: node - linkType: hard - -"sade@npm:^1.8.1": - version: 1.8.1 - resolution: "sade@npm:1.8.1" - dependencies: - mri: "npm:^1.1.0" - checksum: 10c0/da8a3a5d667ad5ce3bf6d4f054bbb9f711103e5df21003c5a5c1a8a77ce12b640ed4017dd423b13c2307ea7e645adee7c2ae3afe8051b9db16a6f6d3da3f90b1 - languageName: node - linkType: hard - -"safe-buffer@npm:^5.0.1": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 - languageName: node - linkType: hard - -"schemastery@npm:^3.18.0, schemastery@workspace:vendor/schemastery": - version: 0.0.0-use.local - resolution: "schemastery@workspace:vendor/schemastery" - dependencies: - "@standard-schema/spec": "npm:^1.1.0" - cosmokit: "npm:^1.8.1" - languageName: unknown - linkType: soft - -"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.7.3, semver@npm:^7.8.1": - version: 7.8.4 - resolution: "semver@npm:7.8.4" - bin: - semver: bin/semver.js - checksum: 10c0/81b7c296fd7927b80f67fa516b75fa1017caac8167795320de28e76ccbc6f7f01763c30ecd10d6a0d8fd089708ab0548a5aebb94b0870e99c2a2b4600a46389b - languageName: node - linkType: hard - -"shebang-command@npm:^2.0.0": - version: 2.0.0 - resolution: "shebang-command@npm:2.0.0" - dependencies: - shebang-regex: "npm:^3.0.0" - checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e - languageName: node - linkType: hard - -"shebang-regex@npm:^3.0.0": - version: 3.0.0 - resolution: "shebang-regex@npm:3.0.0" - checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 - languageName: node - linkType: hard - -"siginfo@npm:^2.0.0": - version: 2.0.0 - resolution: "siginfo@npm:2.0.0" - checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 - languageName: node - linkType: hard - -"smol-toml@npm:^1.6.1": - version: 1.6.1 - resolution: "smol-toml@npm:1.6.1" - checksum: 10c0/511a78722f99c7616fdb46af708de3d7e81434b5a3d58061166da73f28bfc6cae4f0cd04683f60515b9c490cd10152fce72287c960b337419c0299cc1f0f2a22 - languageName: node - linkType: hard - -"source-map-js@npm:^1.2.1": - version: 1.2.1 - resolution: "source-map-js@npm:1.2.1" - checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf - languageName: node - linkType: hard - -"stackback@npm:0.0.2": - version: 0.0.2 - resolution: "stackback@npm:0.0.2" - checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 - languageName: node - linkType: hard - -"std-env@npm:^4.0.0-rc.1": - version: 4.1.0 - resolution: "std-env@npm:4.1.0" - checksum: 10c0/2e14b6b490db34cb969a48d9cf7c35bca4a47653914aac2814221baae7b867a5b15940d133625c391621971f98cd2266a5dc7036669960e883f1081db2a56558 - languageName: node - linkType: hard - -"strip-json-comments@npm:5.0.3": - version: 5.0.3 - resolution: "strip-json-comments@npm:5.0.3" - checksum: 10c0/daaf20b29f69fb51112698f4a9a662490dbb78d5baf6127c75a0a83c2ac6c078a8c0f74b389ad5e0519d6fc359c4a57cb9971b1ae201aef62ce45a13247791e0 - languageName: node - linkType: hard - -"strnum@npm:^2.2.3": - version: 2.4.0 - resolution: "strnum@npm:2.4.0" - dependencies: - anynum: "npm:^1.0.0" - checksum: 10c0/36ac1ca6f511d8216d9b07934359f78afb158eedee73fb057c77b1cffa160a60cb848b35f219bd2c115b0037e8ec3962f492874ea4b10ef021ab6403dbb10e7e - languageName: node - linkType: hard - -"supports-color@npm:^7.1.0": - version: 7.2.0 - resolution: "supports-color@npm:7.2.0" - dependencies: - has-flag: "npm:^4.0.0" - checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 - languageName: node - linkType: hard - -"supports-color@npm:^9.4.0": - version: 9.4.0 - resolution: "supports-color@npm:9.4.0" - checksum: 10c0/6c24e6b2b64c6a60e5248490cfa50de5924da32cf09ae357ad8ebbf305cc5d2717ba705a9d4cb397d80bbf39417e8fdc8d7a0ce18bd0041bf7b5b456229164e4 - languageName: node - linkType: hard - -"tar@npm:^7.5.4": - version: 7.5.16 - resolution: "tar@npm:7.5.16" - dependencies: - "@isaacs/fs-minipass": "npm:^4.0.0" - chownr: "npm:^3.0.0" - minipass: "npm:^7.1.2" - minizlib: "npm:^3.1.0" - yallist: "npm:^5.0.0" - checksum: 10c0/4f37f3c4bd2ca2755fd736a5df1d573c1a868ec1b1e893346aeafa95ac510f9e2fd1469420bd866cc7904799e5bd4ac62b5d4f03fe27747d6e1e373b44505c5c - languageName: node - linkType: hard - -"tinybench@npm:^2.9.0": - version: 2.9.0 - resolution: "tinybench@npm:2.9.0" - checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c - languageName: node - linkType: hard - -"tinyexec@npm:^1.0.2, tinyexec@npm:^1.2.4": - version: 1.2.4 - resolution: "tinyexec@npm:1.2.4" - checksum: 10c0/153b8db6b080194b558ff145b9cffc36b80a6e07babd644dcfbe49c807eee668c876049d28bdee90b96304476f883352f2dad91b3f86bc23832532f4363e66ff - languageName: node - linkType: hard - -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15, tinyglobby@npm:^0.2.16, tinyglobby@npm:^0.2.17": - version: 0.2.17 - resolution: "tinyglobby@npm:0.2.17" - dependencies: - fdir: "npm:^6.5.0" - picomatch: "npm:^4.0.4" - checksum: 10c0/7f7bb0f197c88bc4b20c231e0deca4240ca3bf313a88f5a7fee93a872b84966a4d50220947c0455ad07a60b3b360961c5b7fd979222aeb716a9f99b412002e4c - languageName: node - linkType: hard - -"tinyrainbow@npm:^3.1.0": - version: 3.1.0 - resolution: "tinyrainbow@npm:3.1.0" - checksum: 10c0/f11cf387a26c5c9255bec141a90ac511b26172981b10c3e50053bc6700ea7d2336edcc4a3a21dbb8412fe7c013477d2ba4d7e4877800f3f8107be5105aad6511 - languageName: node - linkType: hard - -"tree-kill@npm:^1.2.2": - version: 1.2.2 - resolution: "tree-kill@npm:1.2.2" - bin: - tree-kill: cli.js - checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2 - languageName: node - linkType: hard - -"ts-algebra@npm:^2.0.0": - version: 2.0.0 - resolution: "ts-algebra@npm:2.0.0" - checksum: 10c0/4ae93bec1bada635bba425854eec323dad50b6ffe86bc04ad2d7f9ce3fb129d673dcf483e19a6e70d07a3a9083e6a0a7f4e004bb8d2164cddc60cc9540ba187f - languageName: node - linkType: hard - -"ts-api-utils@npm:^2.5.0": - version: 2.5.0 - resolution: "ts-api-utils@npm:2.5.0" - peerDependencies: - typescript: ">=4.8.4" - checksum: 10c0/767849383c114e7f1971fa976b20e73ac28fd0c70d8d65c0004790bf4d8f89888c7e4cf6d5949f9c1beae9bc3c64835bef77bbe27fddf45a3c7b60cebcf85c8c - languageName: node - linkType: hard - -"tsconfck@npm:^3.0.3": - version: 3.1.6 - resolution: "tsconfck@npm:3.1.6" - peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - bin: - tsconfck: bin/tsconfck.js - checksum: 10c0/269c3c513540be44844117bb9b9258fe6f8aeab026d32aeebf458d5299125f330711429dbb556dbf125a0bc25f4a81e6c24ac96de2740badd295c3fb400f66c4 - languageName: node - linkType: hard - -"tsdown@npm:^0.22.2": - version: 0.22.2 - resolution: "tsdown@npm:0.22.2" - dependencies: - ansis: "npm:^4.3.1" - cac: "npm:^7.0.0" - defu: "npm:^6.1.7" - empathic: "npm:^2.0.1" - hookable: "npm:^6.1.1" - import-without-cache: "npm:^0.4.0" - obug: "npm:^2.1.1" - picomatch: "npm:^4.0.4" - rolldown: "npm:~1.1.0" - rolldown-plugin-dts: "npm:^0.25.2" - semver: "npm:^7.8.1" - tinyexec: "npm:^1.2.4" - tinyglobby: "npm:^0.2.17" - tree-kill: "npm:^1.2.2" - unconfig-core: "npm:^7.5.0" - peerDependencies: - "@arethetypeswrong/core": ^0.18.1 - "@tsdown/css": 0.22.2 - "@tsdown/exe": 0.22.2 - "@vitejs/devtools": "*" - publint: ^0.3.8 - tsx: "*" - typescript: ^5.0.0 || ^6.0.0 - unplugin-unused: ^0.5.0 - unrun: "*" - peerDependenciesMeta: - "@arethetypeswrong/core": - optional: true - "@tsdown/css": - optional: true - "@tsdown/exe": - optional: true - "@vitejs/devtools": - optional: true - publint: - optional: true - tsx: - optional: true - typescript: - optional: true - unplugin-unused: - optional: true - unrun: - optional: true - bin: - tsdown: ./dist/run.mjs - checksum: 10c0/5c36e071fe32b42759dcc8f37491b03984aac8111fd4a97bb421924d47d9233a46e8d37e8ea98a122ad2ac2e84bd6a30ed633e9086ca79f9ff97c06a71a72be2 - languageName: node - linkType: hard - -"tslib@npm:^2.4.0, tslib@npm:^2.6.2": - version: 2.8.1 - resolution: "tslib@npm:2.8.1" - checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 - languageName: node - linkType: hard - -"tsx@npm:^4.22.4": - version: 4.22.4 - resolution: "tsx@npm:4.22.4" - dependencies: - esbuild: "npm:~0.28.0" - fsevents: "npm:~2.3.3" - dependenciesMeta: - fsevents: - optional: true - bin: - tsx: dist/cli.mjs - checksum: 10c0/3df31eb4929ff501b40b122163705b201ea57a492581e14312ae95d21eb015b33ded46a3fd564f9c89a0e8083186987fc4f10dd38182c4ad6241605974f6c927 - languageName: node - linkType: hard - -"type-check@npm:^0.4.0, type-check@npm:~0.4.0": - version: 0.4.0 - resolution: "type-check@npm:0.4.0" - dependencies: - prelude-ls: "npm:^1.2.1" - checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58 - languageName: node - linkType: hard - -"typebox@npm:1.1.38": - version: 1.1.38 - resolution: "typebox@npm:1.1.38" - checksum: 10c0/b4a5996a25b9265e88335a75697630be82822fae5e7b1993d5eb52ac6b71e80fec924ffa1976269a05524a0954b3f9e6e52f380348ea6836f76920e556fa3ca1 - languageName: node - linkType: hard - -"typescript-eslint@npm:^8.61.0": - version: 8.61.0 - resolution: "typescript-eslint@npm:8.61.0" - dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.61.0" - "@typescript-eslint/parser": "npm:8.61.0" - "@typescript-eslint/typescript-estree": "npm:8.61.0" - "@typescript-eslint/utils": "npm:8.61.0" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/172ba723c7ea07e5b22541ca3e8eb1b5e0b837e21278a915a293a2d5e7cac7ce9f0ad73cd61a3cdec98a511c76586eb3865d1581f2acc0b691e007703d4764b2 - languageName: node - linkType: hard - -"typescript@npm:^6.0.3": - version: 6.0.3 - resolution: "typescript@npm:6.0.3" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/4a25ff5045b984370f48f196b3a0120779b1b343d40b9a68d114ea5e5fff099809b2bb777576991a63a5cd59cf7bffd96ff6fe10afcefbcb8bd6fb96ad4b6606 - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A^6.0.3#optional!builtin": - version: 6.0.3 - resolution: "typescript@patch:typescript@npm%3A6.0.3#optional!builtin::version=6.0.3&hash=5786d5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/2f25c74e65663c248fa1ade2b8459d9ce5372ff9dad07067310f132966ebec1d93f6c42f0baf77a6b6a7a91460463f708e6887013aaade22111037457c6b25df - languageName: node - linkType: hard - -"unbash@npm:^3.0.0": - version: 3.0.0 - resolution: "unbash@npm:3.0.0" - checksum: 10c0/8d237237805c8d23a6a7ba9ba1dac612b79431f2458aaa7975c472eba9f429991e46417fd8cdb14c1ad88adffbc0b914d0556ad5978bc42bbd2fa9b0942a4f91 - languageName: node - linkType: hard - -"unconfig-core@npm:^7.5.0": - version: 7.5.0 - resolution: "unconfig-core@npm:7.5.0" - dependencies: - "@quansync/fs": "npm:^1.0.0" - quansync: "npm:^1.0.0" - checksum: 10c0/9c9f745254aa8e267140430a432353d17ee87f625b0ea0668e189d88736828d117b66bd2dd41f1d48bd40d44d5b7c7d160e8b7996a60c8f484e2975ef73c7cb7 - languageName: node - linkType: hard - -"undici-types@npm:>=7.24.0 <7.24.7": - version: 7.24.6 - resolution: "undici-types@npm:7.24.6" - checksum: 10c0/d9cd8befb643ac904615c280a095ba4240531f6bb4a5e75a22a7483630ca8d3f1016d2ab6ace6ceda1f63b3a2db2fe037fafe121d6917a0187573aa548ff78ca - languageName: node - linkType: hard - -"undici@npm:^6.25.0": - version: 6.26.0 - resolution: "undici@npm:6.26.0" - checksum: 10c0/cf2b4caf58c33d6582970991290cc7a6486d6e738845f25dcdd16952d708ec844815c6d30362919764fcaf30f719891289341f1ada496f003ce2700310453a47 - languageName: node - linkType: hard - -"uri-js@npm:^4.2.2": - version: 4.4.1 - resolution: "uri-js@npm:4.4.1" - dependencies: - punycode: "npm:^2.1.0" - checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c - languageName: node - linkType: hard - -"vite-tsconfig-paths@npm:^6.1.1": - version: 6.1.1 - resolution: "vite-tsconfig-paths@npm:6.1.1" - dependencies: - debug: "npm:^4.1.1" - globrex: "npm:^0.1.2" - tsconfck: "npm:^3.0.3" - peerDependencies: - vite: "*" - checksum: 10c0/5e61080991418fefa08c5b98995cdcada4931ae01ac97ef9e2ee941051f61b76890a6e7ba48bed3b2a229ec06fef33a06621bba4ce457b3f4233ad31dc0c1d1b - languageName: node - linkType: hard - -"vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": - version: 8.0.16 - resolution: "vite@npm:8.0.16" - dependencies: - fsevents: "npm:~2.3.3" - lightningcss: "npm:^1.32.0" - picomatch: "npm:^4.0.4" - postcss: "npm:^8.5.15" - rolldown: "npm:1.0.3" - tinyglobby: "npm:^0.2.17" - peerDependencies: - "@types/node": ^20.19.0 || >=22.12.0 - "@vitejs/devtools": ^0.1.18 - 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 - dependenciesMeta: - fsevents: - optional: true - 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 - bin: - vite: bin/vite.js - checksum: 10c0/d75be3fbe2f63e6a8145325970338afaf0dd4d96ba9175c13f9a286fd5f95afc489401b693e4fa6c0899a4dd0e137be91cdf9401a40a635563911ad5036e3467 - languageName: node - linkType: hard - -"vitest@npm:^4.1.8": - version: 4.1.8 - resolution: "vitest@npm:4.1.8" - dependencies: - "@vitest/expect": "npm:4.1.8" - "@vitest/mocker": "npm:4.1.8" - "@vitest/pretty-format": "npm:4.1.8" - "@vitest/runner": "npm:4.1.8" - "@vitest/snapshot": "npm:4.1.8" - "@vitest/spy": "npm:4.1.8" - "@vitest/utils": "npm:4.1.8" - es-module-lexer: "npm:^2.0.0" - expect-type: "npm:^1.3.0" - magic-string: "npm:^0.30.21" - obug: "npm:^2.1.1" - pathe: "npm:^2.0.3" - picomatch: "npm:^4.0.3" - std-env: "npm:^4.0.0-rc.1" - tinybench: "npm:^2.9.0" - tinyexec: "npm:^1.0.2" - tinyglobby: "npm:^0.2.15" - tinyrainbow: "npm:^3.1.0" - vite: "npm:^6.0.0 || ^7.0.0 || ^8.0.0" - why-is-node-running: "npm:^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.8 - "@vitest/browser-preview": 4.1.8 - "@vitest/browser-webdriverio": 4.1.8 - "@vitest/coverage-istanbul": 4.1.8 - "@vitest/coverage-v8": 4.1.8 - "@vitest/ui": 4.1.8 - 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 - vite: - optional: false - bin: - vitest: vitest.mjs - checksum: 10c0/f459c500f8818c7a2318cd23228b4e5c0b5efb25bf8e5cb7f116c6d26e51482b2f800a8bb19837c0b5f0d05c51519edbf502bc8ceb5bd86868e8facf1d2c498e - languageName: node - linkType: hard - -"walk-up-path@npm:^4.0.0": - version: 4.0.0 - resolution: "walk-up-path@npm:4.0.0" - checksum: 10c0/fabe344f91387d1d41df230af962ef18bf703dd4178006d55cd6412caacd187b54440002d4d53a982d4f7f0455567dcffb6d3884533c8b2268928eca3ebd8a19 - languageName: node - linkType: hard - -"web-streams-polyfill@npm:^3.0.3": - version: 3.3.3 - resolution: "web-streams-polyfill@npm:3.3.3" - checksum: 10c0/64e855c47f6c8330b5436147db1c75cb7e7474d924166800e8e2aab5eb6c76aac4981a84261dd2982b3e754490900b99791c80ae1407a9fa0dcff74f82ea3a7f - languageName: node - linkType: hard - -"which@npm:^2.0.1": - version: 2.0.2 - resolution: "which@npm:2.0.2" - dependencies: - isexe: "npm:^2.0.0" - bin: - node-which: ./bin/node-which - checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f - languageName: node - linkType: hard - -"which@npm:^6.0.0": - version: 6.0.1 - resolution: "which@npm:6.0.1" - dependencies: - isexe: "npm:^4.0.0" - bin: - node-which: bin/which.js - checksum: 10c0/7e710e54ea36d2d6183bee2f9caa27a3b47b9baf8dee55a199b736fcf85eab3b9df7556fca3d02b50af7f3dfba5ea3a45644189836df06267df457e354da66d5 - languageName: node - linkType: hard - -"why-is-node-running@npm:^2.3.0": - version: 2.3.0 - resolution: "why-is-node-running@npm:2.3.0" - dependencies: - siginfo: "npm:^2.0.0" - stackback: "npm:0.0.2" - bin: - why-is-node-running: cli.js - checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 - languageName: node - linkType: hard - -"word-wrap@npm:^1.2.5": - version: 1.2.5 - resolution: "word-wrap@npm:1.2.5" - checksum: 10c0/e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20 - languageName: node - linkType: hard - -"ws@npm:^8.18.0": - version: 8.21.0 - resolution: "ws@npm:8.21.0" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 10c0/ef4a243476283fc49bc7550966c4af4aa0eef56273837211e700de3b664e08604a760cdddcb5ba43c049140e74ccfec5b0ee0bb439e08c2adf9138902fdde5f9 - languageName: node - linkType: hard - -"xml-naming@npm:^0.1.0": - version: 0.1.0 - resolution: "xml-naming@npm:0.1.0" - checksum: 10c0/8c7614865361bcb7e53e3e091dac21c567e2b92d447919b2f072775aa9dcfc94a5255bd52fbaa0fd53c93513e53a23a6a835218ad2af512451dbc678392f85fe - languageName: node - linkType: hard - -"yallist@npm:^5.0.0": - version: 5.0.0 - resolution: "yallist@npm:5.0.0" - checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416 - languageName: node - linkType: hard - -"yaml@npm:^2.9.0": - version: 2.9.0 - resolution: "yaml@npm:2.9.0" - bin: - yaml: bin.mjs - checksum: 10c0/f340718df45e97a9551b9bf9dac61c80050bc464513b710debfb5067c380c8472e3b67809cffacb4ab5ffb5e66ef9310816c88b05f371cec60abfedd8c88e0a2 - languageName: node - linkType: hard - -"yocto-queue@npm:^0.1.0": - version: 0.1.0 - resolution: "yocto-queue@npm:0.1.0" - checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f - languageName: node - linkType: hard - -"zod-to-json-schema@npm:^3.25.0": - version: 3.25.2 - resolution: "zod-to-json-schema@npm:3.25.2" - peerDependencies: - zod: ^3.25.28 || ^4 - checksum: 10c0/dd300554393903022487688af14fbda5c719ba8179702bb55b3aa86318830467f0f7beb7d654036975ac963dc4843b72e59636448bfff9a0608f277bb6a14939 - languageName: node - linkType: hard - -"zod@npm:^3.25.0 || ^4.0.0, zod@npm:^4.1.11": - version: 4.4.3 - resolution: "zod@npm:4.4.3" - checksum: 10c0/7ea31b558e88f9faf44f31dd185e2e1cbf51fed3081787fb96cc2534749b50c0acfc6da7f0922a7353ed092dd358c7d50c28ea96c94d04af64191bd33152eca3 - languageName: node - linkType: hard From 49e74ed8d0fc3c30841fecb5e2dcfe82ed777d81 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 15:38:45 +0800 Subject: [PATCH 02/12] docs: add ADR 0016 for the pnpm migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Records the why behind the Yarn 4 → pnpm move (PR #39): ecosystem alignment, strict-linker phantom-dependency safety, build-script allowlisting, and the package-manager-independent constraints script. Captures migration-time install benchmarks and notes the gate suite passes unchanged on pnpm. --- docs/adr/0016-pnpm-over-yarn.md | 37 +++++++++++++++++++++++++++++++++ docs/adr/README.md | 1 + 2 files changed, 38 insertions(+) create mode 100644 docs/adr/0016-pnpm-over-yarn.md diff --git a/docs/adr/0016-pnpm-over-yarn.md b/docs/adr/0016-pnpm-over-yarn.md new file mode 100644 index 0000000000..eb76b958a9 --- /dev/null +++ b/docs/adr/0016-pnpm-over-yarn.md @@ -0,0 +1,37 @@ +# ADR 0016: pnpm as the package manager instead of Yarn 4 + +Status: accepted (2026-06-16) + +## Context + +The repo shipped on **Yarn 4** with the `node-modules` linker — a deliberately conservative choice that behaves like npm's flat layout while giving us Yarn's workspaces and `yarn constraints`. It worked. But Yarn 4's Plug'n'Play heritage makes the `node-modules` linker the off-the-beaten-path mode, and the broader JS ecosystem — tooling defaults, CI actions, Corepack examples, contributor familiarity — increasingly centers on pnpm. For a repo that is built primarily by agents and read by occasional human contributors, "the package manager most tools and people expect" has real value: fewer surprises, better-trodden failure paths, more copy-pasteable answers. + +The switching cost is at its lowest right now. Nothing publishes from this repo yet (every package is `private: true`); dev/test/demo all run **unbuilt** via tsx, so the package manager only has to (a) resolve and link `node_modules`, (b) run the workspace scripts, and (c) enforce the workspace constraints. The one Yarn-specific asset is `yarn.config.cjs` (the `@yarnpkg/types` constraints engine), which is small and mechanical to re-express. This mirrors the reasoning in [ADR 0008](0008-tsdown-over-dumble.md): swap a load-bearing tool for the healthier-ecosystem option while the blast radius is still small. + +## Decision + +Adopt **pnpm 11.7.0**, pinned via the `packageManager` field and installed through Corepack (same mechanism Yarn used): + +- **Workspaces** move from the `package.json` `workspaces` array + `.yarnrc.yml` to `pnpm-workspace.yaml` (`vendor/*`, `packages/*` — the same globs; `examples/*` stay non-workspace, matching the prior setup and tsdown's explicit globs). +- **Strict symlinked linker** (pnpm's default) replaces Yarn's hoisted `node-modules` linker. We deliberately add **no** `node-linker=hoisted` / `shamefully-hoist` escape hatch: pnpm's non-flat `node_modules` makes phantom dependencies (importing an undeclared transitive dep) fail loudly, which is a *feature* for a repo whose whole quality story is mechanical gates ([ADR 0007](0007-quality-gates.md)). The gate suite — typecheck, lint, test, build, knip — is the safety net that proves no such phantom imports exist. +- **Build-script allowlist.** pnpm 10+ does not run dependency lifecycle scripts unless allowlisted. `pnpm-workspace.yaml` carries an explicit `allowBuilds` map (`esbuild`, `lefthook`, `@google/genai`, `protobufjs`) — the same supply-chain-hardening posture the repo already takes toward model/tool output, now applied to install-time code execution. `peerDependencyRules.allowedVersions.typescript: '>=5 <7'` silences benign peer-range warnings for the in-repo TypeScript. +- **Constraints become package-manager-independent.** `yarn.config.cjs` (which imported `@yarnpkg/types` and used `Yarn.workspaces()` / `workspace.set()`) is replaced by `scripts/check-workspace-constraints.ts`, a plain tsx script run as `pnpm run constraints`. It enforces the identical invariants — every package `private: true`; `@deepseek-ai/dsh-*` packages declare `cordis` as both a peer- and dev-dependency with matching ranges, `version: 0.0.1`, `type: module`; vendored packages checked for privacy only — over the same `vendor` + `packages` scope. +- All `yarn …` verbs across CI, lefthook hooks, `package.json` scripts, and docs become `pnpm …` / `pnpm run …`. `yarn.lock` → `pnpm-lock.yaml` (lockfile v9). `.gitignore` swaps `.yarn/` for `.pnpm-store/`. Vendored READMEs (e.g. `vendor/cordis/README.md`) keep their upstream `yarn` examples untouched per the Vendoring Policy. + +Alternatives considered: **keep Yarn 4** (zero churn, but bets on the less-traveled linker mode and a constraints engine tied to one package manager); **npm workspaces** (ubiquitous, but no constraints story and weaker monorepo ergonomics); **pnpm with hoisted linker** (smoother migration, but throws away the phantom-dependency safety that is the main correctness reason to move). + +## Consequences + +The constraints check loses Yarn's auto-**fix** (`workspace.set()` could rewrite a manifest in place); the tsx script is check-only and exits non-zero with a message instead. This is acceptable — CI never ran `--fix`, and a one-line manual edit is rare. Contributors now `corepack enable` for pnpm rather than Yarn; `pnpm exec lefthook install` replaces `yarn lefthook install` (the `postinstall` hook still runs `lefthook install`). + +Performance (measured at migration time on the dev NFS filesystem; single-digit-run samples, high variance — directional, not a benchmark suite): + +| Scenario | Yarn 4 | pnpm 11 | +|---|---|---| +| Cold (empty cache/store, no `node_modules`) | ~14 s | ~16 s | +| Warm relink (cache/store warm, `node_modules` removed) | ~12–14 s | ~15–22 s | +| Frozen, `node_modules` present (no-op revalidate) | ~2–8 s | ~0.5–7 s | + +On a fast local disk pnpm's content-addressed store typically wins on cold/warm installs and, especially, on **disk footprint** across multiple checkouts (one global store hardlinked into every `node_modules` vs Yarn copying ~279 MB per worktree — some devs regularly keep ~10 or more worktrees for this repo). That dedup advantage did **not** show in the migration-time numbers above because the test store and `node_modules` sat on different filesystems, defeating hardlinks; on a single-filesystem dev box or CI cache it applies. The honest summary: install speed on our NFS dev filesystem is a wash within noise; the move is justified by ecosystem alignment, phantom-dependency safety, and cross-checkout disk dedup — not by a raw install-time win. + +All quality gates (constraints, typecheck, lint, doc-sync, test:coverage at 100%, build, knip, publint, echo-agent demo smoke) pass unchanged on pnpm, which is the correctness proof that the linker swap introduced no phantom-dependency breakage. diff --git a/docs/adr/README.md b/docs/adr/README.md index 963e8f47bd..b634e6eb15 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -27,3 +27,4 @@ Do NOT write an ADR for: a mechanical or local choice (a variable name, a one-fi | [0013](0013-property-based-testing.md) | Property-based testing for protocol-shaped code | accepted | | [0014](0014-doc-sync-enforcement.md) | Doc-sync enforcement (doc code blocks + event taxonomy) | accepted | | [0015](0015-structured-error-taxonomy.md) | Structured error taxonomy (HarnessError base) | accepted | +| [0016](0016-pnpm-over-yarn.md) | pnpm as the package manager instead of Yarn 4 | accepted | From ce484c0e2d7599a0cdfd565f50d66060ea1dc847 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:17:03 +0800 Subject: [PATCH 03/12] build: deny build scripts for unused pi-ai transitive deps @google/genai and protobufjs are pulled in transitively by the dsh-llm-pi-ai adapter and consumed prebuilt; their lifecycle scripts are no-ops we don't need. Set them to false in allowBuilds (was true) so no unnecessary install-time code runs, and document why each entry is the way it is. --- pnpm-workspace.yaml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a7b71bf734..4d6e79ada1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,8 +6,19 @@ peerDependencyRules: allowedVersions: typescript: '>=5 <7' +# pnpm 10+ blocks any dependency shipping an install/build script until it is +# explicitly reviewed here (strictDepBuilds defaults to true: an unlisted script +# is a hard install error). Every such package MUST be listed; we deny by +# default and only allow scripts we need. esbuild (native binary) and lefthook +# (git hooks) genuinely need theirs. allowBuilds: - '@google/genai': true esbuild: true lefthook: true - protobufjs: true + # Transitive deps of @earendil-works/pi-ai (the dsh-llm-pi-ai design-twin + # adapter, ADR 0010), consumed prebuilt — surprising to see here, but pnpm + # lists them only because they ship lifecycle scripts. Those scripts are + # no-ops we don't need (@google/genai's preinstall is an `echo`; protobufjs's + # postinstall only warns about version schemes and returns early when unset), + # so we deny them: install still succeeds, no needless code runs. + '@google/genai': false + protobufjs: false From 6c931b8869f30faeae7f2c6fe230d21123b39695 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:25:24 +0800 Subject: [PATCH 04/12] docs: tighten allowBuilds comments --- pnpm-workspace.yaml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4d6e79ada1..2f957141fe 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,11 +14,8 @@ peerDependencyRules: allowBuilds: esbuild: true lefthook: true - # Transitive deps of @earendil-works/pi-ai (the dsh-llm-pi-ai design-twin - # adapter, ADR 0010), consumed prebuilt — surprising to see here, but pnpm - # lists them only because they ship lifecycle scripts. Those scripts are - # no-ops we don't need (@google/genai's preinstall is an `echo`; protobufjs's - # postinstall only warns about version schemes and returns early when unset), - # so we deny them: install still succeeds, no needless code runs. + # Pulled in by @earendil-works/pi-ai (optional LLM API backend). pnpm lists + # them only because they ship lifecycle scripts, but those are no-ops we don't + # need, so we deny them — install still succeeds. '@google/genai': false protobufjs: false From 3a6ebd1954b803e2196b2dbd4514e4767ed6bdb3 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:51:59 +0800 Subject: [PATCH 05/12] =?UTF-8?q?docs(session):=20renumber=20session-persi?= =?UTF-8?q?stence=20ADR=20reference=200016=E2=86=920018?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit master's pnpm migration claimed ADR 0016 (0016-pnpm-over-yarn), which collides with this stack's session-persistence ADR. Renumbering the session-persistence ADR to 0018 (turn-enclosure stays 0017); update the json.ts module-doc reference accordingly. --- packages/session/src/json.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/session/src/json.ts b/packages/session/src/json.ts index 99fe80ea80..e226becee8 100644 --- a/packages/session/src/json.ts +++ b/packages/session/src/json.ts @@ -1,7 +1,7 @@ /** * JSON-serializability validation for session event data. * - * The session event log is the durable source of truth (ADR 0003/0016): every + * The session event log is the durable source of truth (ADR 0003/0018): every * `event.data` must round-trip losslessly through JSON so any persistence * backend can store and reload it byte-identically. This invariant belongs to * the log itself — `Session.append` enforces it at the source, so a From 3bef6b38c7dab583acc2b87c290a6ff8ce4fb702 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 20:35:01 +0800 Subject: [PATCH 06/12] refactor(session-persistence-sqlite): drop the materialized column; use row existence as the signal (review #35) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `materialized` INTEGER column was redundant: create()/update() already keep a lazy session in memory and write no row, so a `sessions` row is written only by the first append. Its EXISTENCE is the materialization signal — has()/list() now report exactly the sessions that have a row, matching the JSONL backend's "file exists ⇔ materialized". The column only existed to force has()/list() to FALSE for an all-tail crash (a partial first turn, zero committed events). That actually DIVERGED from the JSONL backend, whose file (and thus has()=true) survives a first append that never reached turn/end. Removing the column drops that special case: an all-tail session keeps its row and stays present, the same as JSONL. The orphaned tail rows are still removed by the deferred truncation-repair on the next append, and load() stays non-mutating. Also: add a TODO to route through a cordis db service if one is adopted, and correct the README's Node-version framing to the repo's engines (>=24). --- packages/session-persistence-sqlite/README.md | 10 ++-- .../session-persistence-sqlite/src/index.ts | 49 ++++++++----------- .../session-persistence-sqlite/src/schema.ts | 13 +++-- .../tests/sqlite.spec.ts | 13 +++-- 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/packages/session-persistence-sqlite/README.md b/packages/session-persistence-sqlite/README.md index 9c0ac07b39..dd72ddfde4 100644 --- a/packages/session-persistence-sqlite/README.md +++ b/packages/session-persistence-sqlite/README.md @@ -2,17 +2,19 @@ A SQLite durable session-persistence backend — a second `SessionPersistence` implementation ([ADR 0018](../../docs/adr/0018-session-persistence.md)), built to validate that the abstract seam and the shared `runPersistenceContract` suite are genuinely backend-agnostic. It satisfies the SAME contract as `dsh-session-persistence-jsonl` (append-only, contiguous-seq, lazy materialization, crash-tail-on-load), expressed over `node:sqlite` rows instead of file bytes. +> **TODO:** this backend talks to `node:sqlite` directly. If a cordis database service (`cordis/db` / a `@cordisjs` SQL driver plugin) is adopted, route through that instead of holding a raw `DatabaseSync` here — the contract surface (`SessionPersistence`) would not change, only the storage driver. + ## Storage model -Each `SessionEvent` maps 1:1 onto a row in an `events` table `(session_id, seq, type, time, data)` — `data` is the event payload as JSON text, so the row shape is the event verbatim (including `assistant/chunk`, keeping `seq` contiguous). Out-of-log metadata (`SessionMeta`) lives in a `sessions` row, including the mutable `SessionSummary` fields (`updatedAt`, `title`, `firstPrompt`) that `update()` rewrites without touching the event log. +Each `SessionEvent` maps 1:1 onto a row in an `events` table `(session_id, seq, type, time, data)` — `data` is the event payload as JSON text, so the row shape is the event verbatim (including `assistant/chunk`, keeping `seq` contiguous). Out-of-log metadata (`SessionMeta`) lives in a `sessions` row, including the mutable `SessionSummary` fields (`updatedAt`, `title`, `firstPrompt`) that `update()` rewrites without touching the event log. A `sessions` row is written only by the first `append` — its existence is the lazy-materialization signal (`has`/`list` report exactly the sessions that have a row), so no separate column is needed. -`node:sqlite` requires Node ≥ 22.5 (this repo runs Node ≥ 24); the database opens with `foreign_keys = ON` (so `ON DELETE CASCADE` drops a session's events with its row) and `journal_mode = WAL`. The table-layout version is stored in `PRAGMA user_version` and checked on open: a fresh database is stamped with the current `SCHEMA_VERSION`; a database written by a newer, incompatible build (higher `user_version`) is rejected rather than opened against an unknown layout. +The repo targets Node ≥ 24 (the root `engines` field), which includes the stable `node:sqlite` module. The database opens with `foreign_keys = ON` (so `ON DELETE CASCADE` drops a session's events with its row) and `journal_mode = WAL`. The table-layout version is stored in `PRAGMA user_version` and checked on open: a fresh database is stamped with the current `SCHEMA_VERSION`; a database written by a newer, incompatible build (higher `user_version`) is rejected rather than opened against an unknown layout. ## Contract semantics over rows - **Append = a transaction.** `append` runs `BEGIN`/`COMMIT` around the batch: it runs any deferred crash-tail repair, materializes the `sessions` row (if still lazy), and INSERTs every event, asserting the contiguous-seq contract first (the first event's `seq` must equal the stored next-seq). A mid-batch failure (a UNIQUE violation on a duplicated seq) rolls back entirely, so the stored log and the in-memory cursor stay consistent. -- **Lazy materialization.** `create()` records intent in memory only — no row is written until the first `append`. A created-but-never-appended session is absent from `has()`/`list()` (a `materialized` flag on the row, set inside the first append transaction; `has`/`list` filter to materialized rows). -- **Crash-tail-on-load.** `load()` reads every stored event ordered by `seq` and returns only the prefix through the **last complete `turn/end`** (the `SessionPersistence.load` contract), computed from the `seq`/`type` columns so a malformed `data` in the uncommitted tail is never parsed. A batch that landed without its closing `turn/end` (a process killed mid-turn) is an uncommitted tail: `load()` stays non-mutating w.r.t. the event log and records a repair point; the **next `append`** physically DELETEs the orphaned rows inside its transaction (the one-time truncation-repair, matching the JSONL backend and the abstract contract). A `seq` gap inside the committed region makes the session unloadable. If the discarded tail was the session's only committed content, `load()` also flips the metadata row's `materialized` flag to 0 so `has()`/`list()` immediately stop reporting the now-empty session. +- **Lazy materialization.** `create()` records intent in memory only — no row is written until the first `append`. A created-but-never-appended session has no `sessions` row, so it is absent from `has()`/`list()` (which report exactly the sessions that have a row). +- **Crash-tail-on-load.** `load()` reads every stored event ordered by `seq` and returns only the prefix through the **last complete `turn/end`** (the `SessionPersistence.load` contract), computed from the `seq`/`type` columns so a malformed `data` in the uncommitted tail is never parsed. A batch that landed without its closing `turn/end` (a process killed mid-turn) is an uncommitted tail: `load()` stays non-mutating w.r.t. the event log and records a repair point; the **next `append`** physically DELETEs the orphaned rows inside its transaction (the one-time truncation-repair, matching the JSONL backend and the abstract contract). A `seq` gap inside the committed region makes the session unloadable. A session materialized by a partial first turn (all-tail, zero committed events) keeps its metadata row and stays present in `has()`/`list()` — the same as the JSONL backend, whose file likewise survives a first append that never reached `turn/end`. ## Configuration (schemastery) diff --git a/packages/session-persistence-sqlite/src/index.ts b/packages/session-persistence-sqlite/src/index.ts index 51a03475dd..45d0215384 100644 --- a/packages/session-persistence-sqlite/src/index.ts +++ b/packages/session-persistence-sqlite/src/index.ts @@ -245,18 +245,12 @@ export class SessionPersistenceSqlite extends SessionPersistence { // returns the committed prefix; the next append performs the one-time // physical repair). Record the repair point so the next appendCore DELETEs // the orphaned tail inside its own transaction before inserting. - const materialized = committed.length > 0 - if (committed.length === 0 && row.materialized === 1) { - // All-tail discard: the only committed events were a crash tail, so the - // session now has NO committed events. The metadata row, however, still - // reads materialized = 1 from the prior append — which would make has() - // and list() report a session that load() just emptied. Correct the - // materialized FLAG (metadata, not the event log) so has()/list() are - // immediately consistent. The orphaned tail rows are still removed by the - // deferred repair on the next append. - this.db.prepare('UPDATE sessions SET materialized = 0 WHERE id = ?').run(id) - } - + // + // The metadata row stays as-is even when committed.length === 0 (an all-tail + // crash): the session WAS materialized by the partial append, so its row + // exists and has()/list() report it present — the same as the JSONL backend, + // whose file likewise survives a first append that never reached turn/end. + // // Record state so a later append continues at the committed length and runs // the deferred tail repair. The state keeps its OWN copy of the meta; the // returned value is separate so a consumer mutating loaded.meta cannot @@ -264,7 +258,7 @@ export class SessionPersistenceSqlite extends SessionPersistence { this.states.set(id, { meta: { ...meta }, cursor: committed.length, - materialized, + materialized: true, ...cutTail ? { repairFrom: committed.length } : {}, }) return { meta, events } @@ -272,11 +266,11 @@ export class SessionPersistenceSqlite extends SessionPersistence { async list(): Promise { await this.ready - // Materialized rows only: a created-but-never-appended (lazy) session has no - // row at all, and a load that cut every event back to zero leaves - // materialized = 0. Both are excluded, matching has(). + // Every metadata row is a materialized session: the row is written only by + // the first append (a created-but-never-appended session has no row), so + // listing all rows is exactly the materialized set. const rows = this.db - .prepare('SELECT * FROM sessions WHERE materialized = 1') + .prepare('SELECT * FROM sessions') .all() as unknown as SessionRow[] return rows.map(rowToMeta) } @@ -285,8 +279,8 @@ export class SessionPersistenceSqlite extends SessionPersistence { await this.ready const state = this.states.get(id) if (state?.materialized) return true - const row = this.rowFor(id) - return row !== undefined && row.materialized === 1 + // A metadata row exists iff the session was materialized by a first append. + return this.rowFor(id) !== undefined } delete(id: SessionId): Promise { @@ -326,15 +320,15 @@ export class SessionPersistenceSqlite extends SessionPersistence { } /** - * Insert-or-replace a session's metadata row, marked materialized. The only - * callers are the first materializing `append` and a post-materialization - * `update` — a row is written only once a session has durable events, so - * `materialized` is always 1 (a never-appended session has no row at all). + * Insert-or-replace a session's metadata row. The only callers are the first + * materializing `append` and a post-materialization `update`, so writing the + * row IS the materialization (its existence is the signal `has`/`list` read); + * a never-appended session has no row at all. */ private writeRow(meta: SessionMeta): void { this.db.prepare(` - INSERT INTO sessions (id, version, created_at, cwd, parent_session, updated_at, title, first_prompt, materialized) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1) + INSERT INTO sessions (id, version, created_at, cwd, parent_session, updated_at, title, first_prompt) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET version = excluded.version, created_at = excluded.created_at, @@ -342,8 +336,7 @@ export class SessionPersistenceSqlite extends SessionPersistence { parent_session = excluded.parent_session, updated_at = excluded.updated_at, title = excluded.title, - first_prompt = excluded.first_prompt, - materialized = excluded.materialized + first_prompt = excluded.first_prompt `).run( meta.id, meta.version, @@ -466,7 +459,7 @@ export class SessionPersistenceSqlite extends SessionPersistence { } const row = this.rowFor(id) - if (row !== undefined && row.materialized === 1) { + if (row !== undefined) { const stored = this.eventsFor(id) if (!seedCoversPrefix(seed, stored)) { throw new Error(`session "${id}" already has a persisted log that does not match this live session (id collision)`) diff --git a/packages/session-persistence-sqlite/src/schema.ts b/packages/session-persistence-sqlite/src/schema.ts index ff01f65fe2..c3ef9ca051 100644 --- a/packages/session-persistence-sqlite/src/schema.ts +++ b/packages/session-persistence-sqlite/src/schema.ts @@ -18,10 +18,11 @@ import type { SessionEvent, SessionId, SessionMeta } from '@deepseek-ai/dsh-sess export const SCHEMA_VERSION = 1 /** - * A row of the `sessions` table — the out-of-log metadata (`SessionMeta`) plus - * the `materialized` flag that implements lazy materialization (a created-but- - * never-appended session has `materialized = 0` and is excluded from - * `has`/`list`, mirroring the JSONL backend's "no file until first append"). + * A row of the `sessions` table — the out-of-log metadata (`SessionMeta`). The + * row's EXISTENCE is the materialization signal: it is written only by the + * first `append` (lazy materialization), so a created-but-never-appended + * session has no row and is absent from `has`/`list`, mirroring the JSONL + * backend's "no file until first append". */ export interface SessionRow { id: string @@ -32,7 +33,6 @@ export interface SessionRow { updated_at: number title: string | null first_prompt: string | null - materialized: number } /** An `events` table row: one `SessionEvent` mapped 1:1 (`data` is JSON text). */ @@ -81,8 +81,7 @@ export function openDatabase(path: string): DatabaseSync { parent_session TEXT, updated_at INTEGER NOT NULL, title TEXT, - first_prompt TEXT, - materialized INTEGER NOT NULL DEFAULT 0 + first_prompt TEXT ) STRICT `) db.exec(` diff --git a/packages/session-persistence-sqlite/tests/sqlite.spec.ts b/packages/session-persistence-sqlite/tests/sqlite.spec.ts index 92a389687f..6ab4dae30b 100644 --- a/packages/session-persistence-sqlite/tests/sqlite.spec.ts +++ b/packages/session-persistence-sqlite/tests/sqlite.spec.ts @@ -139,7 +139,7 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { await b2.dispose() }) - it('all-tail load: a session whose only content is a crash tail is absent from has()/list()', async () => { + it('all-tail load: a session materialized by a partial first turn stays present (JSONL parity), load returns zero committed events', async () => { const path = await freshDbPath() const m = meta('all-tail') const b1 = await backend(path) @@ -153,12 +153,15 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { await b1.dispose() // A fresh backend loads it: the committed prefix is empty (no turn/end), so - // the session has no committed content. has()/list() must NOT report it. + // load returns zero events — but the session WAS materialized (its metadata + // row exists), so has()/list() still report it present, matching the JSONL + // backend whose file likewise survives a first append that never reached + // turn/end. The orphaned tail rows are removed by the next append's repair. const b2 = await backend(path) const loaded = await b2.ctx.sessionPersistence.load(m.id) expect(loaded.events).toEqual([]) - expect(await b2.ctx.sessionPersistence.has(m.id)).toBe(false) - expect((await b2.ctx.sessionPersistence.list()).map(x => x.id)).not.toContain(m.id) + expect(await b2.ctx.sessionPersistence.has(m.id)).toBe(true) + expect((await b2.ctx.sessionPersistence.list()).map(x => x.id)).toContain(m.id) await b2.dispose() }) @@ -269,7 +272,7 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { const path = await freshDbPath() // Materialize a row with version 2 directly via the real schema. const db = openDatabase(path) - db.prepare('INSERT INTO sessions (id, version, created_at, updated_at, materialized) VALUES (?, ?, ?, ?, 1)') + db.prepare('INSERT INTO sessions (id, version, created_at, updated_at) VALUES (?, ?, ?, ?)') .run('v2', 2, 1, 1) db.close() From 4c8c1da8b37cd35191b00888285c2d2965db4056 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:00:24 +0800 Subject: [PATCH 07/12] feat: generate module dependency graph with freshness gate Add scripts/gen-module-graph.ts, which derives the inter-package dependency graph from each package's @deepseek-ai/dsh-* peerDependencies and renders docs/module-graph.md (a GitHub-native Mermaid graph plus a dependency table). Output is deterministic so a regenerate-and-diff check is stable. Wire a freshness gate the same way doc-sync is wired (ADR 0007: hooks and CI run the same package.json scripts): verify-module-graph runs in pre-push (lefthook) and as a CI step. It fails if the committed file drifts from what the generator would produce. --- .github/workflows/ci.yml | 6 +++ AGENTS.md | 4 +- docs/module-graph.md | 49 +++++++++++++++++ lefthook.yml | 3 ++ package.json | 2 + scripts/gen-module-graph.ts | 103 ++++++++++++++++++++++++++++++++++++ 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 docs/module-graph.md create mode 100644 scripts/gen-module-graph.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3d378fa4a..f0293d1ddb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,12 @@ jobs: - name: Doc-sync gates (doc code blocks + event taxonomy) run: pnpm run doc-sync + # Module-graph freshness: regenerate docs/module-graph.md from the + # packages' peerDependencies and fail if it differs from the committed + # file. Only reads source package.json — no build needed. + - name: Module-graph freshness + run: pnpm run verify-module-graph + - name: Tests with coverage gate (per-file 100%) run: pnpm run test:coverage diff --git a/AGENTS.md b/AGENTS.md index 3a5d13c083..c602ff4872 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,7 +37,9 @@ examples/ Runnable demos (not workspaces). echo-agent = mock model + echo tool + stdio UI + JSONL persistence, wired via cordis.yml. coding-agent = the real thing: DeepSeek V4 + bash tools (pnpm run demo:coding, needs DEEPSEEK_API_KEY). -docs/ architecture.md — the design doc. adr/ — decision records (the +docs/ architecture.md — the design doc. module-graph.md — generated + inter-package dependency graph (Mermaid; `pnpm run gen-module-graph`). + adr/ — decision records (the why behind vendoring, event-sourcing, the schema DSL, …). rfc/ — proposals for substantial future work. cookbook/ — step-by-step guides: adding a package, a tool, diff --git a/docs/module-graph.md b/docs/module-graph.md new file mode 100644 index 0000000000..4caee085f4 --- /dev/null +++ b/docs/module-graph.md @@ -0,0 +1,49 @@ + + +# Module dependency graph + +Inter-package dependencies among the `@deepseek-ai/dsh-*` harness packages, derived from each +package's `peerDependencies` (the canonical runtime-dependency signal). An edge `a --> b` means +package `a` depends on package `b`. Names have the `@deepseek-ai/dsh-` prefix stripped. + +```mermaid +graph TD + agent --> llm + agent --> session + agent-loop --> agent + agent-loop --> llm + agent-loop --> session + agent-loop --> system-prompt + agent-loop --> tools + bash-local --> bash + invariants --> agent + invariants --> llm + invariants --> session + llm-deepseek --> llm + llm-pi-ai --> llm + session --> llm + system-prompt --> llm + tool-bash --> agent + tool-bash --> bash + tool-bash --> llm + tool-bash --> tools + tools --> agent + tools --> llm + tools --> system-prompt +``` + +| Package | Depends on | +| --- | --- | +| `agent` | `llm`, `session` | +| `agent-loop` | `agent`, `llm`, `session`, `system-prompt`, `tools` | +| `bash` | — | +| `bash-local` | `bash` | +| `invariants` | `agent`, `llm`, `session` | +| `llm` | — | +| `llm-deepseek` | `llm` | +| `llm-pi-ai` | `llm` | +| `session` | `llm` | +| `system-prompt` | `llm` | +| `tool-bash` | `agent`, `bash`, `llm`, `tools` | +| `tools` | `agent`, `llm`, `system-prompt` | diff --git a/lefthook.yml b/lefthook.yml index 9789c92029..24600e4985 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -30,3 +30,6 @@ pre-push: - name: doc-sync run: pnpm run doc-sync + + - name: module-graph freshness + run: pnpm run verify-module-graph diff --git a/package.json b/package.json index 9ff3536f9b..b0a7e5ae4d 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ "publint": "tsx scripts/publint-all.ts", "doc-typecheck": "tsx scripts/doc-typecheck.ts", "verify-event-taxonomy": "tsx scripts/verify-event-taxonomy.ts", + "gen-module-graph": "tsx scripts/gen-module-graph.ts", + "verify-module-graph": "tsx scripts/gen-module-graph.ts --check", "constraints": "tsx scripts/check-workspace-constraints.ts", "doc-sync": "pnpm run doc-typecheck && pnpm run verify-event-taxonomy", "hygiene": "pnpm run knip && pnpm run publint && pnpm run constraints", diff --git a/scripts/gen-module-graph.ts b/scripts/gen-module-graph.ts new file mode 100644 index 0000000000..58e8bd0a36 --- /dev/null +++ b/scripts/gen-module-graph.ts @@ -0,0 +1,103 @@ +/** + * Generate (and verify) the module dependency graph in docs/module-graph.md. + * + * The architectural shape of the harness lives implicitly in each package's + * `peerDependencies` — the canonical runtime-dependency signal (devDeps mirror + * these as `workspace:^` plus test-only extras, which would add noise). This + * script reads every `packages/* /package.json`, keeps only the + * `@deepseek-ai/dsh-*` peer edges (dropping the `cordis` peer), and renders a + * GitHub-viewable Mermaid graph plus a dependency table. + * + * The file is fully generated — never hand-edit it. Output is deterministic + * (packages and edges sorted) so a regenerate-and-diff freshness check is + * stable. + * + * `tsx scripts/gen-module-graph.ts` → write docs/module-graph.md + * `tsx scripts/gen-module-graph.ts --check` → exit 1 if the committed file + * is stale (CI / pre-push gate) + */ + +import { globSync, readFileSync, writeFileSync } from 'node:fs' +import { resolve } from 'node:path' + +const root = resolve(import.meta.dirname, '..') +const OUT = 'docs/module-graph.md' +const SCOPE = '@deepseek-ai/dsh-' + +interface Pkg { + /** Short name, `@deepseek-ai/dsh-` prefix stripped (e.g. `agent-loop`). */ + short: string + /** Short names of this package's in-repo peer dependencies, sorted. */ + deps: string[] +} + +/** Read every workspace package and its `@deepseek-ai/dsh-*` peer edges. */ +function collect(): Pkg[] { + const pkgs: Pkg[] = [] + for (const rel of globSync('packages/*/package.json', { cwd: root })) { + const json = JSON.parse(readFileSync(resolve(root, rel), 'utf8')) as { + name: string + peerDependencies?: Record + } + if (!json.name.startsWith(SCOPE)) continue + const deps = Object.keys(json.peerDependencies ?? {}) + .filter(d => d.startsWith(SCOPE)) + .map(d => d.slice(SCOPE.length)) + .sort() + pkgs.push({ short: json.name.slice(SCOPE.length), deps }) + } + return pkgs.sort((a, b) => a.short.localeCompare(b.short)) +} + +/** Render the full docs/module-graph.md content (pure, deterministic). */ +function render(pkgs: Pkg[]): string { + const edges: string[] = [] + for (const p of pkgs) { + for (const d of p.deps) edges.push(` ${p.short} --> ${d}`) + } + const rows = pkgs.map(p => `| \`${p.short}\` | ${p.deps.length ? p.deps.map(d => `\`${d}\``).join(', ') : '—'} |`) + return [ + '', + '', + '# Module dependency graph', + '', + 'Inter-package dependencies among the `@deepseek-ai/dsh-*` harness packages, derived from each', + 'package\'s `peerDependencies` (the canonical runtime-dependency signal). An edge `a --> b` means', + 'package `a` depends on package `b`. Names have the `@deepseek-ai/dsh-` prefix stripped.', + '', + '```mermaid', + 'graph TD', + ...edges, + '```', + '', + '| Package | Depends on |', + '| --- | --- |', + ...rows, + '', + ].join('\n') +} + +const content = render(collect()) + +if (process.argv.includes('--check')) { + let committed: string | null = null + try { + committed = readFileSync(resolve(root, OUT), 'utf8') + } catch { + // Only an ENOENT (file not yet generated) is expected here; readFileSync of + // a present-but-unreadable file is not a state this repo produces. Either + // way the remedy is the same — regenerate — so we treat a read failure as + // "stale" and fall through to the failure branch below. + committed = null + } + if (committed === content) { + console.log(`gen-module-graph: ${OUT} is up to date.`) + process.exit(0) + } + console.error(`gen-module-graph: ${OUT} is stale. Run \`pnpm run gen-module-graph\` and commit ${OUT}.`) + process.exit(1) +} + +writeFileSync(resolve(root, OUT), content) +console.log(`gen-module-graph: wrote ${OUT}.`) From b33668ef0586cc66416a12a1e383ad620afa1742 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:11:09 +0800 Subject: [PATCH 08/12] =?UTF-8?q?refactor:=20order=20module-graph=20table?= =?UTF-8?q?=20topologically=20(low=E2=86=92high=20level)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the alphabetical package ordering with a Kahn-style topological sort (alphabetical tiebreak within each layer to stay deterministic), so the table and graph list leaf interfaces first and dependents last. --- docs/module-graph.md | 32 ++++++++++++++++---------------- scripts/gen-module-graph.ts | 27 ++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/docs/module-graph.md b/docs/module-graph.md index 4caee085f4..e488f61ea1 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -9,41 +9,41 @@ package `a` depends on package `b`. Names have the `@deepseek-ai/dsh-` prefix st ```mermaid graph TD + bash-local --> bash + llm-deepseek --> llm + llm-pi-ai --> llm + session --> llm + system-prompt --> llm agent --> llm agent --> session + invariants --> agent + invariants --> llm + invariants --> session + tools --> agent + tools --> llm + tools --> system-prompt agent-loop --> agent agent-loop --> llm agent-loop --> session agent-loop --> system-prompt agent-loop --> tools - bash-local --> bash - invariants --> agent - invariants --> llm - invariants --> session - llm-deepseek --> llm - llm-pi-ai --> llm - session --> llm - system-prompt --> llm tool-bash --> agent tool-bash --> bash tool-bash --> llm tool-bash --> tools - tools --> agent - tools --> llm - tools --> system-prompt ``` | Package | Depends on | | --- | --- | -| `agent` | `llm`, `session` | -| `agent-loop` | `agent`, `llm`, `session`, `system-prompt`, `tools` | | `bash` | — | -| `bash-local` | `bash` | -| `invariants` | `agent`, `llm`, `session` | | `llm` | — | +| `bash-local` | `bash` | | `llm-deepseek` | `llm` | | `llm-pi-ai` | `llm` | | `session` | `llm` | | `system-prompt` | `llm` | -| `tool-bash` | `agent`, `bash`, `llm`, `tools` | +| `agent` | `llm`, `session` | +| `invariants` | `agent`, `llm`, `session` | | `tools` | `agent`, `llm`, `system-prompt` | +| `agent-loop` | `agent`, `llm`, `session`, `system-prompt`, `tools` | +| `tool-bash` | `agent`, `bash`, `llm`, `tools` | diff --git a/scripts/gen-module-graph.ts b/scripts/gen-module-graph.ts index 58e8bd0a36..865211ccde 100644 --- a/scripts/gen-module-graph.ts +++ b/scripts/gen-module-graph.ts @@ -46,7 +46,32 @@ function collect(): Pkg[] { .sort() pkgs.push({ short: json.name.slice(SCOPE.length), deps }) } - return pkgs.sort((a, b) => a.short.localeCompare(b.short)) + return topoSort(pkgs) +} + +/** + * Order packages low-level → high-level: a package appears only after every + * package it depends on. Kahn-style layering with an alphabetical tiebreak + * within each layer, so the output stays deterministic (the freshness check + * compares whole-file). The graph is a DAG, so this always terminates; a cycle + * would leave nodes unplaced and throw. + */ +function topoSort(pkgs: Pkg[]): Pkg[] { + const remaining = new Map(pkgs.map(p => [p.short, p])) + const placed = new Set() + const out: Pkg[] = [] + while (remaining.size > 0) { + const ready = [...remaining.values()] + .filter(p => p.deps.every(d => placed.has(d))) + .sort((a, b) => a.short.localeCompare(b.short)) + if (ready.length === 0) throw new Error(`gen-module-graph: dependency cycle among ${[...remaining.keys()].join(', ')}`) + for (const p of ready) { + out.push(p) + placed.add(p.short) + remaining.delete(p.short) + } + } + return out } /** Render the full docs/module-graph.md content (pure, deterministic). */ From 8e6fd91e15fc9d8380cf535988bfef00dcef48ef Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:21:21 +0800 Subject: [PATCH 09/12] docs: document module-graph gate; unwrap generated prose Codex review follow-up: - Update docs/development.md: add verify-module-graph to the pre-push and CI gate lists and gen/verify-module-graph to the daily commands, so the contributor guide matches the new freshness gate. - Emit the module-graph.md intro paragraph as a single line (repo Markdown convention: one line per paragraph), since regenerating would otherwise reintroduce hard wrapping. --- docs/development.md | 5 ++++- docs/module-graph.md | 4 +--- scripts/gen-module-graph.ts | 4 +--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/development.md b/docs/development.md index 1252157868..0defe20cec 100644 --- a/docs/development.md +++ b/docs/development.md @@ -57,7 +57,7 @@ DEEPSEEK_BASE_URL=https://... # optional lefthook is configured in `lefthook.yml` as an early local checkpoint before review: - `pre-commit` runs staged-file ESLint fixes, `pnpm run typecheck`, and the vendor manifest guard. -- `pre-push` runs `pnpm run test`, `pnpm run hygiene`, and `pnpm run doc-sync`. +- `pre-push` runs `pnpm run test`, `pnpm run hygiene`, `pnpm run doc-sync`, and `pnpm run verify-module-graph`. The vendor manifest guard checks that changes under `vendor/*/src` are staged with the matching `vendor/README.md` manifest update. See `vendor/README.md` before editing vendored code. @@ -72,6 +72,7 @@ The GitHub workflow runs these gates on each pull request: - `pnpm run typecheck` - `pnpm run lint` - `pnpm run doc-sync` +- `pnpm run verify-module-graph` - `pnpm run test:coverage` - `pnpm run build` - `pnpm run knip && pnpm run publint` @@ -93,6 +94,8 @@ pnpm run lint:fix # eslint . --fix pnpm run doc-typecheck # compile checked TypeScript snippets in Markdown docs pnpm run verify-event-taxonomy # compare docs/architecture.md event names with source pnpm run doc-sync # doc-typecheck plus event taxonomy verification +pnpm run gen-module-graph # regenerate docs/module-graph.md from package peerDeps +pnpm run verify-module-graph # fail if docs/module-graph.md is stale pnpm run build # build declarations and JS bundles pnpm run hygiene # knip, publint, and workspace constraints ``` diff --git a/docs/module-graph.md b/docs/module-graph.md index e488f61ea1..4e01fdd7d3 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -3,9 +3,7 @@ # Module dependency graph -Inter-package dependencies among the `@deepseek-ai/dsh-*` harness packages, derived from each -package's `peerDependencies` (the canonical runtime-dependency signal). An edge `a --> b` means -package `a` depends on package `b`. Names have the `@deepseek-ai/dsh-` prefix stripped. +Inter-package dependencies among the `@deepseek-ai/dsh-*` harness packages, derived from each package's `peerDependencies` (the canonical runtime-dependency signal). An edge `a --> b` means package `a` depends on package `b`. Names have the `@deepseek-ai/dsh-` prefix stripped. ```mermaid graph TD diff --git a/scripts/gen-module-graph.ts b/scripts/gen-module-graph.ts index 865211ccde..6314b39399 100644 --- a/scripts/gen-module-graph.ts +++ b/scripts/gen-module-graph.ts @@ -87,9 +87,7 @@ function render(pkgs: Pkg[]): string { '', '# Module dependency graph', '', - 'Inter-package dependencies among the `@deepseek-ai/dsh-*` harness packages, derived from each', - 'package\'s `peerDependencies` (the canonical runtime-dependency signal). An edge `a --> b` means', - 'package `a` depends on package `b`. Names have the `@deepseek-ai/dsh-` prefix stripped.', + 'Inter-package dependencies among the `@deepseek-ai/dsh-*` harness packages, derived from each package\'s `peerDependencies` (the canonical runtime-dependency signal). An edge `a --> b` means package `a` depends on package `b`. Names have the `@deepseek-ai/dsh-` prefix stripped.', '', '```mermaid', 'graph TD', From efee449cfecac1080c733b2afde9d9184cfc174e Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:27:50 +0800 Subject: [PATCH 10/12] feat(session-persistence): preserve interrupted turns on crash; don't truncate (review #33) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A crash can leave a durable log whose final turn never closed. The old behavior truncated everything after the last turn/end as a "crash tail". But a single turn can be HUGE in a long-horizon task (many steps, large tool output), so truncating it silently destroys real, durably-written work — truncating a turn is wrong. New crash recovery (ADR 0018): load() PRESERVES the interrupted turn's events and CLOSES the orphaned turn by durably appending synthetic boundary events — a step/end if a step was open, then a turn/end carrying the new merge-extensible TurnEndReason {kind:'interrupted'}. load() returns the balanced log, so a resumed session is immediately usable. Only a never-fully-written TORN tail fragment is discarded; corruption in the committed region is still unloadable. - dsh-session: TurnEndReason {kind:'interrupted'} + shared interruptedTurnClosers() repair helper. - JSONL backend: scanLog preserves the longest contiguous prefix (including a partial final turn); loadCore truncates a torn fragment and durably writes the closers, returning the balanced log. - runPersistenceContract gains a crash-recovery test (both backends + mock). - Docs: ADR 0018/0017, architecture.md, package READMEs. Also (review #33): RFC 013 records the "move event vocabulary to Zod" question (merge-extensible maps → runtime schema registry) + blast radius; deferred, not done here. --- docs/adr/0017-turn-enclosure-invariant.md | 2 +- docs/adr/0018-session-persistence.md | 2 +- docs/architecture.md | 2 +- docs/rfc/013-typed-event-schemas.md | 65 +++++++++++++++ docs/rfc/README.md | 1 + packages/session-persistence-jsonl/README.md | 2 +- .../session-persistence-jsonl/src/format.ts | 71 +++++++++------- .../session-persistence-jsonl/src/index.ts | 57 ++++++++----- .../tests/jsonl.spec.ts | 83 ++++++++++++------- packages/session-persistence/README.md | 4 +- packages/session-persistence/src/index.ts | 40 +++++---- .../session-persistence/tests/contract.ts | 38 +++++++++ .../tests/persistence.spec.ts | 7 +- packages/session/src/index.ts | 1 + packages/session/src/repair.ts | 79 ++++++++++++++++++ packages/session/src/types.ts | 11 +++ 16 files changed, 361 insertions(+), 104 deletions(-) create mode 100644 docs/rfc/013-typed-event-schemas.md create mode 100644 packages/session/src/repair.ts diff --git a/docs/adr/0017-turn-enclosure-invariant.md b/docs/adr/0017-turn-enclosure-invariant.md index f4b88420ea..6261968060 100644 --- a/docs/adr/0017-turn-enclosure-invariant.md +++ b/docs/adr/0017-turn-enclosure-invariant.md @@ -4,7 +4,7 @@ Status: accepted (2026-06-15) ## Context -A durable session-persistence backend (added in a companion change) uses the **turn** as its crash-recovery boundary: `load` returns events only up to the last complete `turn/end`, and the first post-load `append` truncates whatever follows as a never-committed crash tail. This is safe only if nothing *legitimately* durable can sit after the last `turn/end`. +A durable session-persistence backend (added in a companion change) uses the **turn** as its crash-recovery boundary: a crash can leave an unclosed final turn, which `load` closes with a synthetic `turn/end {kind:'interrupted'}` while preserving the turn's real events (see [ADR 0018](0018-session-persistence.md)). This recovery is only well-defined if nothing *legitimately* durable sits OUTSIDE a turn — between the last `turn/end` and the next `turn/start` — since such an event would be swept into the next turn's interrupted close. That assumption did not hold. Two paths recorded events outside any turn: diff --git a/docs/adr/0018-session-persistence.md b/docs/adr/0018-session-persistence.md index 0de9f968bd..2a90377d4f 100644 --- a/docs/adr/0018-session-persistence.md +++ b/docs/adr/0018-session-persistence.md @@ -18,7 +18,7 @@ Persistence is an abstract **capability seam** ([ADR 0009](0009-capability-seams Key choices recorded here because they are durable, contested, and surprising: - **The canonical durable log persists every `SessionEvent` verbatim, including `assistant/chunk`.** `deriveMessages()` skips chunks, and a chunk-filtered rollout (Codex's `policy.rs`) is tempting — but `seq = log.length` and the load-validation `events[i].seq === i` require a *contiguous* log; filtering chunks out would leave holes and break both the contract and resume. A chunk-filtered projection is possible later as a derived view with its own renumbering, but it is NOT the canonical log. -- **Append-only with a single exception.** Committed events — those at or below a flushed `turn/end` — are never rewritten. The loop only flushes at `turn/end`, so a crash can leave a half-written final turn below the last checkpoint; `load` returns events only up to the **last complete `turn/end`**, and the first post-load `append` runs a one-time **truncation-repair** (`ftruncate` + `fsync`) that physically discards only that never-committed crash tail before writing. +- **Append-only; a crashed turn is closed, never truncated.** Committed events — those at or below a flushed `turn/end` — are never rewritten. The loop only flushes at `turn/end`, so a crash can leave a durable log whose final turn never closed: real, fully-written events sit after the last `turn/end`. **A single turn can be huge in a long-horizon task** (many steps, large tool output spanning a long autonomous run), so discarding the interrupted turn would silently destroy a large amount of real work — truncating a turn is wrong. Instead, on reload `load` PRESERVES those events and CLOSES the orphaned turn by durably appending the minimal synthetic boundary events: a `step/end` if a step was still open, then a `turn/end` carrying the merge-extensible `{ kind: 'interrupted' }` reason (a marker that records the turn was cut short by a crash, not completed by the model — no loop ever emits it). `load` returns the balanced log, so a resumed session is immediately usable. The ONLY thing discarded is a never-fully-written **torn tail fragment** — a final record whose bytes (JSONL) or row were never completely flushed; that fragment is not a valid event and is dropped before the synthetic closers are written. A parse error or `seq` gap in the COMMITTED region (at or before the last real `turn/end`) is genuine corruption and makes the session unloadable. - **File backend canonical, DB backend a drop-in.** `SessionEvent` maps 1:1 onto a row `(session_id, seq, type, time, data)` — `append` is INSERT (in a transaction asserting the contiguous-seq contract), `load` is SELECT … ORDER BY seq. A future `dsh-session-persistence-sqlite` is a `SessionPersistence` subclass with no interface change (opencode runs this exact shape on SQLite/WAL). - **Metadata is out-of-log.** Format version, cwd, and lineage are storage concerns, not replayable conversation state, so they live in a `SessionMeta` (`SessionHeader & SessionSummary`) owned by `dsh-session` and attached to a `Session` via a new readonly `session.header` — never in `SessionEventMap`, never reaching `deriveMessages()`. The alternative (a merge-extensible `session/meta` event as log line 0) was rejected: an in-log event would ride along with a seeded/forked session for free, but metadata is not replayable state, so the explicit out-of-log header seam is the cleaner cost. - **`load` returns a resumable event log, not just bytes.** `load(sessionId)` yields the `SessionMeta` plus the committed `SessionEvent[]` (through the last complete `turn/end`), shaped so a caller can reconstruct a live session with the loaded events as seed (so `lastTurnNumber`/`deriveMessages` continue) on the SAME session id. The agent-facing create/resume factory that consumes this is a separate seam (a follow-up on `ctx.agents`); the persistence layer deliberately stops at the `load` primitive and does NOT reach into the loop. The agent-loop does NOT hard-inject `sessionPersistence` (that would pend non-persistent demos forever), so any resume path built on this rejects with a clear error when the backend is absent. diff --git a/docs/architecture.md b/docs/architecture.md index c5e0675a43..9ec0977b61 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -95,7 +95,7 @@ A `Session` is an append-only log of typed `SessionEvent`s — the single source Replay/fork = `ctx.sessions.create(id, { seed: seedEvents })`. Trace/telemetry = listen to `session/event`. -**Durability seam**: `session/event` is a synchronous notification; persistence plugins buffer (write-behind) and drain at the awaited `session/flush` checkpoint the loop fires at every turn end. The durable backend is a real **capability seam**: the abstract `SessionPersistence` service (`dsh-session-persistence`, `ctx.sessionPersistence`) defines create/append/load/list/update over the existing `SessionEvent` (no parallel persisted type), and `dsh-session-persistence-jsonl` is the first implementation — an append-only JSONL log per session with crash-safe atomic writes, truncation-repair of a never-committed crash tail, and a read/replay path. Session metadata (format version, cwd, lineage) travels separately as `SessionMeta`, attached to a `Session` via `session.header`. `ctx.sessionPersistence.load(sessionId)` returns the committed event log so a caller can reconstruct a live session and continue it. A SQLite/WAL backend is a future drop-in `SessionPersistence` subclass (the row shape `(session_id, seq, type, time, data)` maps 1:1 onto `SessionEvent`). +**Durability seam**: `session/event` is a synchronous notification; persistence plugins buffer (write-behind) and drain at the awaited `session/flush` checkpoint the loop fires at every turn end. The durable backend is a real **capability seam**: the abstract `SessionPersistence` service (`dsh-session-persistence`, `ctx.sessionPersistence`) defines create/append/load/list/update over the existing `SessionEvent` (no parallel persisted type), and `dsh-session-persistence-jsonl` is the first implementation — an append-only JSONL log per session with crash-safe atomic writes, crash recovery that PRESERVES an interrupted turn (closing it with a synthetic `turn/end {interrupted}` rather than truncating — a turn can be huge), and a read/replay path. Session metadata (format version, cwd, lineage) travels separately as `SessionMeta`, attached to a `Session` via `session.header`. `ctx.sessionPersistence.load(sessionId)` returns the committed event log so a caller can reconstruct a live session and continue it. A SQLite/WAL backend is a future drop-in `SessionPersistence` subclass (the row shape `(session_id, seq, type, time, data)` maps 1:1 onto `SessionEvent`). ## Prompt assembly (dsh-system-prompt) diff --git a/docs/rfc/013-typed-event-schemas.md b/docs/rfc/013-typed-event-schemas.md new file mode 100644 index 0000000000..5b659a7281 --- /dev/null +++ b/docs/rfc/013-typed-event-schemas.md @@ -0,0 +1,65 @@ +# RFC 013: Runtime schemas for the event vocabulary (Zod vs the merge-extensible-map pattern) + +Status: proposed + +## Problem + +The harness models its core vocabulary — content blocks, message sources, finish reasons, turn triggers, turn-end reasons, and session events — as **merge-extensible maps**: a TypeScript `interface` (e.g. `SessionEventMap`, `ContentBlockMap`) that plugins augment via declaration merging, with the public union derived as `Map[keyof Map]`. This is the repo's universal extension pattern, documented in [docs/architecture.md](../architecture.md) ("The same merge-extensible-map pattern is used for `MessageSource`, `FinishReason`, `TurnTrigger`, and `TurnEndReason`") and relied on by the `defineTool` `InferArgs` DSL and the `assertNever` exhaustiveness convention. + +The pattern is **compile-time only**. The types vanish at runtime: there is no schema object to validate an incoming value against, parse untrusted input with, or enumerate at runtime. Two concrete consequences surfaced in review of the session-persistence work (#33): + +1. **Persistence treats `event.data` as opaque JSON.** The JSONL/SQLite backends `JSON.stringify`/`JSON.parse` each event verbatim; the only runtime guard is `isJsonValue` (round-trip serializability — rejects BigInt, functions, cycles, non-finite numbers, …), NOT structural validation. A corrupted-but-still-JSON event datum (wrong field types, missing fields) round-trips silently and is only caught later, if at all, by a consumer's `switch`. +2. **No runtime contract for plugin-added variants.** A plugin that declaration-merges a new `SessionEventMap` key gets compile-time typing for its own code, but nothing validates that the values it produces match the shape it declared — at the producer, at the persistence boundary, or on reload. + +A reviewer asked whether the project should move "all the JSON serialization/deserialization" — and ultimately the event vocabulary itself — to **Zod** (or a similar runtime-schema library), so the durable boundary and the plugin extension points are backed by runtime schemas rather than erased types. + +This RFC scopes that question. It does **not** propose an implementation; it records the tradeoff so the decision is made deliberately rather than incrementally inside a persistence PR. + +## Why this is not a persistence change + +It is tempting to read "use Zod for serialization" as a local change to `dsh-session-persistence-jsonl/src/format.ts`. It is not, for one structural reason: **a plugin cannot declaration-merge a Zod schema.** Declaration merging is a TypeScript compile-time mechanism; a Zod schema is a runtime value. To validate events with Zod you need a **runtime registry** that every event-producing package contributes its schema to (e.g. `ctx.sessionEvents.register('compaction/marker', z.object({…}))`), and every consumer reads from. That registry — not the persistence backend — becomes the source of truth for the vocabulary, replacing the merge-extensible interface. + +So the real proposal is: **replace the compile-time merge-extensible-map pattern with a runtime schema registry, repo-wide.** That is a core-vocabulary redesign. + +## Blast radius (measured) + +A migration of the event/vocabulary surface to runtime schemas touches, at minimum: + +- **Six merge-extensible maps** (~370 LOC of core types): `ContentBlockMap`, `MessageSourceMap`, `FinishReasonMap` (in `dsh-llm`); `TurnTriggerMap`, `TurnEndReasonMap`, `SessionEventMap` (in `dsh-session`). +- **~10 `declare module` augmentation sites** across `dsh-agent`, `dsh-agent-loop`, `dsh-bash`, `dsh-llm`, `dsh-session`, `dsh-session-persistence`, `dsh-system-prompt`, `dsh-tools` — each would move from declaration merging to a runtime `register()` call. +- **The event producers** — 16 `session.append(...)` call sites in the loop — unchanged in shape but now validated at the boundary. +- **~7 switch-consumers** that branch on these unions: `deriveMessages` (`dsh-session`), `BlockAssembler` (`dsh-llm`), the `dsh-invariants` plugin, both LLM adapters (`dsh-llm-deepseek`, `dsh-llm-pi-ai`), and the tool schema layer (`dsh-tools`). The `assertNever`-on-closed-unions vs fall-through-on-extensible-unions convention (a documented lint rule) would need rethinking — runtime variants are not statically exhaustive. +- **The `defineTool` `InferArgs` DSL** (`dsh-tools`), which derives zero-cast `execute` arg types from a compile-time schema spec — the showcase of the current approach. +- **Docs**: architecture.md (the pattern is described as foundational), ADR 0012 (dev-invariants), and any ADR/RFC that references the pattern. + +This is a HUGE change. It is not in scope for the RFC-009 session-persistence work and must not be smuggled in through it. + +## Options + +### A. Status quo — merge-extensible types + `isJsonValue` at the durable boundary +Keep the compile-time pattern. Persistence stays opaque-JSON + serializability guard. Plugins extend via declaration merging; correctness of event *shape* is the producer's responsibility, enforced by TypeScript at compile time and by the `dsh-invariants` plugin's structural checks in dev. + +- **Pros**: zero churn; plugin extension is a one-line `interface` augmentation with full type inference and no runtime registration ceremony; no new runtime dependency; the `defineTool` DSL and `assertNever` exhaustiveness keep working. +- **Cons**: no runtime structural validation at the persistence boundary or at plugin seams; a malformed-but-JSON datum is caught late. + +### B. Header/closed-shape validation only (schemastery), events stay opaque +Tighten only the genuinely-closed shapes that already have hand-rolled type guards — e.g. the JSONL `HeaderLine` guard (`isHeaderLine`) — using **schemastery** (the repo's existing schema library, already used for every plugin `static Config`). Leave the merge-extensible event union as-is. + +- **Pros**: small, fits the existing convention (schemastery, not a new lib); replaces hand-rolled guards on closed shapes with declarative schemas; no core redesign. +- **Cons**: does not address event-data validation (the thing the reviewer actually asked about); only helps the fixed metadata records. + +### C. Runtime schema registry for the whole vocabulary (Zod or schemastery) +Replace the merge-extensible maps with a runtime registry the producers contribute to and the persistence/consumer paths validate against. + +- **Pros**: real runtime validation at the durable boundary and at plugin seams; one source of truth; enables generic tooling (auto-generated docs, fuzzing, wire-format checks). +- **Cons**: the full blast radius above; **Zod is not currently a direct dependency** (only a transitive dep of `@earendil-works/pi-ai`) and the repo's chosen schema lib is **schemastery** — adopting Zod broadly is itself a dependency decision; declaration-merge ergonomics (one-line plugin extension, full inference) are replaced by runtime registration + manual type wiring; the `assertNever` exhaustiveness guarantee weakens (runtime variants aren't statically exhaustive). + +## Recommendation + +Defer. Do **not** change #33. If runtime validation is wanted at the durable boundary in the near term, **Option B** (schemastery on the closed header/metadata shapes) is the proportionate step and stays within the existing convention. **Option C** is a genuine architecture decision that should be evaluated on its own merits — including whether the chosen library is Zod or schemastery — and, if accepted, land as its own change with its own ADR, not as a side effect of persistence serialization. + +## Open questions + +- If a registry is adopted, is the library **schemastery** (already in the tree, already the config schema lib) or **Zod** (richer ecosystem, currently only transitive)? Adopting two schema libraries is a cost in itself. +- Can a hybrid keep compile-time inference (so `defineTool` and plugin DX survive) while adding an *optional* runtime schema per variant, validated only at the persistence/wire boundary rather than on every in-process append? +- Does the `dsh-invariants` plugin already cover enough of the runtime-shape gap in dev that boundary validation is only needed for genuinely untrusted input (reload of an externally-modified log)? diff --git a/docs/rfc/README.md b/docs/rfc/README.md index 55ec59150d..dbd1468489 100644 --- a/docs/rfc/README.md +++ b/docs/rfc/README.md @@ -16,3 +16,4 @@ Proposals for substantial future work — reviewed before implementation, unlike | [010](010-acp-agent-client-protocol.md) | Agent Client Protocol (ACP) support for external editors | proposed | | [011](011-acp-multi-session.md) | Multiplex concurrent ACP sessions over one connection | proposed | | [012](012-optional-code-mode.md) | Optional Code Mode — model writes TypeScript against an SDK of all tools | proposed | +| [013](013-typed-event-schemas.md) | Runtime schemas for the event vocabulary (Zod vs the merge-extensible-map pattern) | proposed | diff --git a/packages/session-persistence-jsonl/README.md b/packages/session-persistence-jsonl/README.md index 115e5bfe08..8d1d55d9a7 100644 --- a/packages/session-persistence-jsonl/README.md +++ b/packages/session-persistence-jsonl/README.md @@ -24,7 +24,7 @@ The JSONL durable session-persistence backend — a concrete `SessionPersistence - **Lazy materialization.** `create(meta)` writes nothing; the `.jsonl` (header + first batch) is written atomically (temp-write + `fsync` + rename) on the first `append`. A created-but-never-appended session leaves nothing on disk and is absent from `has`/`list`. - **Append-only.** Committed events (at or below a flushed `turn/end`) are never rewritten. Subsequent appends are line appends at EOF + `fsync`. -- **Truncation-repair.** `load` returns events only up to the last complete `turn/end` and records the byte offset of any never-committed crash tail; the first post-load `append` `ftruncate`s to that offset (+ `fsync`) before writing, atomically discarding only the uncommitted tail. +- **Crash recovery — close, don't truncate.** A crash can leave a log whose final turn never closed (real events after the last `turn/end`). `load` PRESERVES those events (a turn can be huge — they are real work) and closes the orphaned turn by durably appending synthetic boundary events (a `step/end` if a step was open, then `turn/end {kind:'interrupted'}`), returning a balanced log. Only a never-fully-written **torn tail fragment** (a final line with no newline / unparseable) is `ftruncate`d away before the closers are written. See ADR 0018. - **Contiguous-seq.** `load` rejects a mid-log parse error or `seq` gap (unloadable); `append` rejects a batch whose first `seq` does not continue the stored log, and rejects non-JSON-serializable `event.data` naming the offending event type. - **Format version.** Only v1 is supported; `load` rejects an unknown version. A future format change requires a version bump + migration. diff --git a/packages/session-persistence-jsonl/src/format.ts b/packages/session-persistence-jsonl/src/format.ts index e3834b6578..5b498c66f7 100644 --- a/packages/session-persistence-jsonl/src/format.ts +++ b/packages/session-persistence-jsonl/src/format.ts @@ -120,16 +120,23 @@ export function eventLine(event: SessionEvent): string { } /** - * Compute the byte offset of the END of the last complete `turn/end` line in a - * JSONL log buffer (the header line is index 0). Returns the offset to which a - * crash tail should be truncated, and the contiguous events up to and including - * that `turn/end`. A parse error or a `seq` gap in the MIDDLE (at or before the - * last `turn/end`) makes the session unloadable and throws; trailing garbage - * AFTER the last `turn/end` is the tolerated crash tail and is excluded. + * Parse a JSONL log buffer into its preserved event prefix (the header is line + * 0). Returns the longest prefix of complete, seq-contiguous events plus the + * byte offset of the end of the last preserved line (`committedBytes`). + * + * A crash can leave a durable log whose final turn never closed: real, + * fully-written events sit after the last `turn/end`. Those are PRESERVED (a + * single turn can be huge in a long-horizon task — truncating it would destroy + * real work); the backend closes the orphaned open turn with a synthetic + * `turn/end {kind:'interrupted'}` on reload (ADR 0018). Only a TORN trailing + * fragment — a final line never fully flushed (no newline, unparseable, or a + * seq gap) — is excluded; it bounds the preserved region. A parse error or seq + * gap AT OR BEFORE the last committed `turn/end` is committed-data corruption + * and makes the session unloadable (throws). * * This relies on the session-log invariant that every event lives inside a turn - * (`Session.append` enforces it): the last `turn/end` is therefore the last - * durable boundary, and nothing committed can sit outside a completed turn. + * (`Session.append` enforces it): only the final turn can be open, so the + * preserved tail is at most one unclosed turn. */ export function scanLog(buffer: Buffer): { meta: SessionMeta; events: SessionEvent[]; committedBytes: number } { const text = buffer.toString('utf8') @@ -187,38 +194,46 @@ export function scanLog(buffer: Buffer): { meta: SessionMeta; events: SessionEve } }) - // The last index (into eventEntries) that is a valid `turn/end`. + // The last index (into eventEntries) that is a valid `turn/end` — the last + // fully-committed boundary (the loop flushes only at turn/end). let lastTurnEnd = -1 for (let i = parsed.length - 1; i >= 0; i--) { const p = parsed[i] if (p?.ok && p.event?.type === 'turn/end') { lastTurnEnd = i; break } } - // No committed turn/end anywhere: nothing is committed. The whole event - // region is an uncommitted (first-turn) tail — committedBytes is the header. - if (lastTurnEnd < 0) { - const meta = metaFrom(headerLine) - return { meta, events: [], committedBytes: headerEntry.endByte } - } - - // Pass 2: the committed prefix [0..lastTurnEnd] must be fully intact and - // contiguous (line i is a parsed event with seq === i). A hole or seq gap in - // the committed region means committed data was damaged → unloadable. - const committed: SessionEvent[] = [] - for (let i = 0; i <= lastTurnEnd; i++) { + // Walk the longest PREFIX of complete, seq-contiguous, parseable event lines + // (line i is a parsed event with seq === i). This is the preservable region: + // it includes any fully-written events of an interrupted final turn AFTER the + // last turn/end — those are real, durably-written work and must NOT be + // truncated (a single turn can be huge in a long-horizon task; the orphaned + // open turn is closed with a synthetic turn/end on reload, not discarded — + // ADR 0018). The walk stops at the first hole (unparseable line or seq gap): + // - if that hole is AT OR BEFORE the last committed turn/end, committed data + // was damaged → the session is unloadable (throw); + // - if it is AFTER (or there is no committed turn/end yet), it is the + // tolerated crash boundary — a torn final line never fully flushed — and + // it simply bounds the preserved tail. + const preserved: SessionEvent[] = [] + for (let i = 0; i < parsed.length; i++) { const p = parsed[i] if (!p?.ok || p.event === undefined) { - throw new Error(`corrupt session log: unparsable committed event at line ${i + 1}`) + if (i <= lastTurnEnd) throw new Error(`corrupt session log: unparsable committed event at line ${i + 1}`) + break // torn tail fragment after the last turn/end — stop, tolerate } if (p.event.seq !== i) { - throw new Error(`corrupt session log: seq gap in committed region at line ${i + 1} (expected ${i}, got ${p.event.seq})`) + if (i <= lastTurnEnd) throw new Error(`corrupt session log: seq gap in committed region at line ${i + 1} (expected ${i}, got ${p.event.seq})`) + break // gap after the last turn/end — torn tail, stop } - committed.push(p.event) + preserved.push(p.event) } - const lastEntry = parsed[lastTurnEnd] - /* v8 ignore next -- lastTurnEnd indexes a parsed entry by construction */ - const committedBytes = lastEntry ? lastEntry.endByte : headerEntry.endByte - return { meta: metaFrom(headerLine), events: committed, committedBytes } + + // committedBytes = end of the last PRESERVED line (header if none): the next + // append truncates any torn bytes past this point before writing the + // synthetic closers + new events. + const lastPreserved = parsed[preserved.length - 1] + const committedBytes = preserved.length > 0 && lastPreserved ? lastPreserved.endByte : headerEntry.endByte + return { meta: metaFrom(headerLine), events: preserved, committedBytes } } /** Build the load-time {@link SessionMeta} from a header line (summary overlaid later). */ diff --git a/packages/session-persistence-jsonl/src/index.ts b/packages/session-persistence-jsonl/src/index.ts index 7f8b80a215..3e5320c3a9 100644 --- a/packages/session-persistence-jsonl/src/index.ts +++ b/packages/session-persistence-jsonl/src/index.ts @@ -27,7 +27,7 @@ import { open, mkdir, readFile, readdir, rename, link, rm, truncate } from 'node import { resolve } from 'node:path' import { randomBytes } from 'node:crypto' import { SessionPersistence } from '@deepseek-ai/dsh-session-persistence' -import { isJsonValue } from '@deepseek-ai/dsh-session' +import { isJsonValue, interruptedTurnClosers } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent, SessionId, SessionMeta, SessionSummary } from '@deepseek-ai/dsh-session' import { encodeSegment, eventLine, logPath, parseHeaderMeta, scanLog, sessionDir, sidecarPath, toHeaderLine, @@ -58,11 +58,6 @@ interface SessionState { * new session's events to be dropped against the old cursor). */ owner?: Session - /** - * If a load truncation-repair is pending, the byte offset to truncate the - * file to before the next append (discards the never-committed crash tail). - */ - repairTo?: number } /** @@ -238,13 +233,6 @@ export class SessionPersistenceJsonl extends SessionPersistence { let state = this.states.get(id) if (state === undefined) state = await this.adopt(id) // calls loadCore, not load - // Truncation-repair: on the first append after a load that found a crash - // tail, physically discard the orphaned bytes before writing. - if (state.repairTo !== undefined) { - await this.repair(state, state.repairTo) - delete state.repairTo - } - // Contiguity contract: each event's seq must continue the stored log. for (const [i, event] of events.entries()) { if (event.seq !== state.cursor + i) { @@ -280,19 +268,42 @@ export class SessionPersistenceJsonl extends SessionPersistence { const summary = await this.readSidecar(id, meta.cwd) const fullMeta: SessionMeta = { ...meta, ...summary } - // Record the state so the next append repairs the crash tail (if any) and - // continues at the committed length. The state keeps its OWN copy of the - // meta; the value returned to the caller is a SEPARATE copy so a consumer - // mutating `loaded.meta` (e.g. `cwd`) cannot corrupt the backend's pathing - // metadata and send later reads/writes to the wrong log. - const needsRepair = committedBytes < buffer.byteLength - this.states.set(id, { + // Crash-recovery: if the log ended mid-turn (an open turn with real, + // preserved events but no closing turn/end), close it durably DURING load so + // disk, the returned log, and the cursor all agree — both append routes then + // continue with no special-casing. Synthesize the boundary events (a + // step/end if a step was open, then a turn/end {kind:'interrupted'}); the + // interrupted turn's real events are preserved, never truncated (a turn can + // be huge — ADR 0018). + const closers = interruptedTurnClosers(events) + const balanced = [...events, ...closers] + + // Set state BEFORE the repair writes so they can resolve the log path. + const needsTorn = committedBytes < buffer.byteLength + const state: SessionState = { meta: { ...fullMeta }, cursor: events.length, materialized: true, - ...needsRepair ? { repairTo: committedBytes } : {}, - }) - return { meta: fullMeta, events } + } + this.states.set(id, state) + + if (needsTorn) { + // Discard the torn trailing fragment (a final line never fully flushed) + // before writing the closers, so the closers land at a clean EOF. + await this.repair(state, committedBytes) + } + if (closers.length > 0) { + // Durably append the synthetic closers, then advance the cursor to the + // balanced length. After this, disk == balanced and the next append (live + // or direct) continues cleanly. No sidecar touch here: load is not a + // summary-changing op (the closers carry no new title/firstPrompt), and + // the next real append bumps `updatedAt` — keeping the summary write off + // the recovery path avoids a second best-effort failure mode. + await this.appendLines(state, closers) + state.cursor = balanced.length + } + + return { meta: fullMeta, events: balanced } } async list(): Promise { diff --git a/packages/session-persistence-jsonl/tests/jsonl.spec.ts b/packages/session-persistence-jsonl/tests/jsonl.spec.ts index a91e6f9138..563dd8c627 100644 --- a/packages/session-persistence-jsonl/tests/jsonl.spec.ts +++ b/packages/session-persistence-jsonl/tests/jsonl.spec.ts @@ -107,36 +107,41 @@ describe('SessionPersistenceJsonl: durability and crash semantics', () => { expect(loaded.events).toEqual(log) // chunks preserved, contiguous seqs }) - it('crash tolerance: load truncates an uncommitted final turn back to the last turn/end', async () => { + it('crash recovery: load preserves the interrupted turn and closes it with a synthetic turn/end {interrupted}', async () => { const m = meta('crash', '/proj') await ctx.sessionPersistence.create(m) await ctx.sessionPersistence.append(m.id, oneTurnLog()) // seqs 0..5, turn/end at 5 // Simulate a crash mid-second-turn: append raw lines that are NOT closed by - // a turn/end (and a final partial line with no newline). + // a turn/end (turn/start + step/start are fully written), plus a final + // partial line with no newline (a torn fragment never fully flushed). const path = logPath(root, '/proj', m.id) - const tail = [ + await writeFile(path, [ JSON.stringify({ type: 'turn/start', seq: 6, time: 8, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }), JSON.stringify({ type: 'step/start', seq: 7, time: 9, data: { turn: 2, step: 1 } }), - '{"type":"assistant/chunk","seq":8,"ti', // truncated partial line - ].join('\n') - await writeFile(path, tail, { flag: 'a' }) + '{"type":"assistant/chunk","seq":8,"ti', // truncated partial line (no newline) + ].join('\n'), { flag: 'a' }) - // load returns only the committed first turn. + // load PRESERVES the interrupted turn's real events (turn/start 6, step/start + // 7) — a turn can be huge, so they must not be truncated — and durably closes + // the orphaned turn with synthetic step/end (8) + turn/end {interrupted} (9). const loaded = await ctx.sessionPersistence.load(m.id) - expect(loaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5]) + expect(loaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + const last = loaded.events.at(-1)! + expect(last.type === 'turn/end' && last.data.reason).toEqual({ kind: 'interrupted' }) + const stepEnd = loaded.events[8]! + expect(stepEnd.type).toBe('step/end') + // the torn seq-8 chunk fragment did not survive + expect(loaded.events.some(e => e.type === 'assistant/chunk' && e.seq === 8)).toBe(false) - // The next append repairs the file (discarding the crash tail) and resumes - // at seq 6. - const turn2 = [ - { type: 'turn/start', seq: 6, time: 10, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'turn/end', seq: 7, time: 11, data: { turn: 2, reason: { kind: 'completed' } } }, + // The next append continues at seq 10 (the balanced length). + const turn3 = [ + { type: 'turn/start', seq: 10, time: 11, data: { turn: 3, trigger: { kind: 'message', source: { kind: 'user' } } } }, + { type: 'turn/end', seq: 11, time: 12, data: { turn: 3, reason: { kind: 'completed' } } }, ] as SessionEvent[] - await ctx.sessionPersistence.append(m.id, turn2) + await ctx.sessionPersistence.append(m.id, turn3) const reloaded = await ctx.sessionPersistence.load(m.id) - expect(reloaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7]) - // and no orphaned seq-8 chunk survived - expect(reloaded.events.some(e => e.seq === 8)).toBe(false) + expect(reloaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) }) it('committed events are never rewritten: only the crash tail is repaired', async () => { @@ -490,15 +495,17 @@ describe('SessionPersistenceJsonl: scanLog unit', () => { expect(() => scanLog(Buffer.from('{"type":"event"}\n'))).toThrow(/session header/) }) - it('a seq gap with NO committed turn/end yields zero committed events (uncommitted tail)', () => { + it('a seq gap after the last turn/end bounds the preserved tail (torn fragment tolerated)', () => { const log = [ JSON.stringify({ type: 'session', version: 1, id: 'g', createdAt: 1 }), JSON.stringify({ type: 'turn/start', seq: 0, time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }), JSON.stringify({ type: 'step/start', seq: 2, time: 2, data: { turn: 1, step: 1 } }), // gap: missing seq 1 ].join('\n') + '\n' - // Nothing reached a turn/end, so nothing is committed — the whole region is - // an uncommitted (crash) tail. Safe to load as empty, NOT a corruption. - expect(scanLog(Buffer.from(log)).events).toEqual([]) + // No committed turn/end, so the gap is a tolerated crash boundary: scanLog + // PRESERVES the contiguous prefix (turn/start seq 0) — real interrupted-turn + // work, not discarded — and stops at the gap. The orphaned open turn is + // closed by loadCore's synthetic turn/end, not here. + expect(scanLog(Buffer.from(log)).events.map(e => e.seq)).toEqual([0]) }) it('rejects a seq gap BEFORE a later committed turn/end (committed data damaged)', () => { @@ -522,13 +529,23 @@ describe('SessionPersistenceJsonl: scanLog unit', () => { expect(() => scanLog(Buffer.from(log))).toThrow(/unparsable committed event/) }) - it('a corrupt line with NO committed turn/end yields zero committed events', () => { + it('a header-only log (no event lines at all) preserves nothing — committedBytes is the header', () => { + const log = JSON.stringify({ type: 'session', version: 1, id: 'h0', createdAt: 1 }) + '\n' + const scanned = scanLog(Buffer.from(log)) + expect(scanned.events).toEqual([]) + // committedBytes falls back to the header line's end (no preserved events). + expect(scanned.committedBytes).toBe(Buffer.byteLength(log, 'utf8')) + }) + + it('a corrupt line after the last turn/end bounds the preserved tail', () => { const log = [ JSON.stringify({ type: 'session', version: 1, id: 'c2', createdAt: 1 }), JSON.stringify({ type: 'turn/start', seq: 0, time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }), '{not json', // corrupt crash fragment, no turn/end committed ].join('\n') + '\n' - expect(scanLog(Buffer.from(log)).events).toEqual([]) + // The contiguous prefix (turn/start seq 0) is preserved; the corrupt + // fragment after it is the tolerated crash boundary. + expect(scanLog(Buffer.from(log)).events.map(e => e.seq)).toEqual([0]) }) it('tolerates a seq gap AFTER a turn/end (uncommitted tail)', () => { @@ -1066,13 +1083,19 @@ describe('SessionPersistenceJsonl: edge cases', () => { await ctx2.fiber.dispose() }) - it('a header-only log (no turn/end) loads as zero committed events', () => { - const log = [ - JSON.stringify({ type: 'session', version: 1, id: 'open', createdAt: 1 }), - JSON.stringify({ type: 'turn/start', seq: 0, time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }), - ].join('\n') + '\n' - const { events } = scanLog(Buffer.from(log)) - expect(events).toEqual([]) // nothing committed (no turn/end) + it('a header-only log (open turn, no turn/end) preserves the open turn on load and closes it', async () => { + // A session whose only durable content is an unclosed first turn. scanLog + // preserves the turn/start; loadCore closes it with a synthetic + // turn/end {interrupted} so the returned log is balanced. + const m = meta('open-turn', '/h') + await ctx.sessionPersistence.create(m) + await ctx.sessionPersistence.append(m.id, [ + { type: 'turn/start', seq: 0, time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, + ] as SessionEvent[]) + const { events } = await ctx.sessionPersistence.load(m.id) + expect(events.map(e => e.type)).toEqual(['turn/start', 'turn/end']) + const end = events[1]! + expect(end.type === 'turn/end' && end.data.reason).toEqual({ kind: 'interrupted' }) }) it('initFor is idempotent: a re-seeded existing session is not re-initialized', async () => { diff --git a/packages/session-persistence/README.md b/packages/session-persistence/README.md index aa30d7c028..8f534fbc36 100644 --- a/packages/session-persistence/README.md +++ b/packages/session-persistence/README.md @@ -10,14 +10,14 @@ The persisted unit IS the existing `SessionEvent` (event-sourced model — the l |---|---| | `create(meta): Promise` | Register a new session's metadata. MAY defer the physical write until the first `append` (lazy materialization). | | `append(id, events): Promise` | Durably persist a batch (from the `session/flush` drain). Append-only; first event `seq` == stored next-seq after any repair; rejects non-JSON-serializable data naming the offending type. | -| `load(id): Promise<{ meta; events }>` | Reload meta + log up to the last complete `turn/end`; events contiguous (`events[i].seq === i`); rejects a mid-log gap/parse error or unknown `version`. | +| `load(id): Promise<{ meta; events }>` | Reload meta + log. Preserves an interrupted (unclosed) final turn and closes it with synthetic `step/end?`+`turn/end {interrupted}` (a turn can be huge — never truncated); only a torn tail fragment is dropped. Events contiguous (`events[i].seq === i`); rejects a committed-region gap/parse error or unknown `version`. | | `list(): Promise` | Lightweight listing from metadata, no full-log parse. | | `has(id)` / `delete(id)` | Existence / removal. A zero-event lazily-materialized session is absent from `has`/`list`. | | `update(id, summary): Promise` | Update mutable `SessionSummary` fields without touching the append-only log. | ## Invariants every backend must honor -- **Append-only.** Committed events (at or below a flushed `turn/end`) are never rewritten. The only exception is the one-time truncation-repair of a never-committed crash tail on the first `append` after a `load`. +- **Append-only; a crashed turn is closed, not truncated.** Committed events (at or below a flushed `turn/end`) are never rewritten. A crash can leave an unclosed final turn whose events are real and possibly large; `load` preserves them and durably appends synthetic closers (`step/end?`+`turn/end {interrupted}`) to balance the log. Only a never-fully-written torn tail fragment is discarded. - **Contiguous seq.** `load` rejects a `seq` gap/parse error in the MIDDLE of the log; `append`'s first `seq` must equal the stored next-seq. - **JSON-serializable data.** `append` rejects non-serializable `event.data`; backends snapshot each event when buffering (the live `session.events` object is mutable). - **Durability.** `append` returns only once the batch is durable. diff --git a/packages/session-persistence/src/index.ts b/packages/session-persistence/src/index.ts index 8a7d1da992..e770b5b86c 100644 --- a/packages/session-persistence/src/index.ts +++ b/packages/session-persistence/src/index.ts @@ -39,14 +39,16 @@ declare module 'cordis' { * Contracts every implementation MUST honor (a DB backend asserts them inside * a transaction; a file backend appends at EOF): * - * - **Append-only.** Committed events — those at or below a flushed `turn/end` - * — are never rewritten. The ONLY exception is the one-time truncation-repair - * of a never-committed crash tail on the first {@link append} after a - * {@link load} (see {@link load}). + * - **Append-only; a crashed turn is closed, not truncated.** Committed events + * — those at or below a flushed `turn/end` — are never rewritten. A crash can + * leave an unclosed final turn whose events are real (and possibly large); + * {@link load} preserves them and closes the orphaned turn with synthetic + * boundary events (see {@link load}). Only a never-fully-written torn tail + * fragment is discarded. * - **Contiguous seq.** A persisted log is contiguous: `events[i].seq === i`. - * {@link load} rejects a parse error or a `seq` gap in the MIDDLE of the log + * {@link load} rejects a parse error or a `seq` gap in the COMMITTED region * (unloadable); {@link append}'s first event `seq` MUST equal the backend's - * stored next-seq after any repair. + * stored next-seq (after `load` has balanced any interrupted turn). * - **JSON-serializable data.** `SessionEventMap` is merge-extensible and * `event.data` is typed only as `SessionEventMap[K]`, so {@link append} * REJECTS non-JSON-serializable data with an error naming the offending @@ -72,9 +74,9 @@ export abstract class SessionPersistence extends Service { /** * Durably persist a batch of events (called from the write-behind drain at * the `session/flush` checkpoint). Honors the append-only and contiguous-seq - * contracts: the first event's `seq` MUST equal the stored next-seq after - * any truncation-repair of a crash tail. Rejects non-JSON-serializable - * `event.data` with an error naming the offending event type. + * contracts: the first event's `seq` MUST equal the stored next-seq (after + * `load` has durably closed any interrupted turn). Rejects non-JSON- + * serializable `event.data` with an error naming the offending event type. */ abstract append(id: SessionId, events: readonly SessionEvent[]): Promise @@ -83,13 +85,19 @@ export abstract class SessionPersistence extends Service { * durable checkpoint. Returns `meta` AND `events` so the live session is * reconstructed with its `cwd`/lineage, not just its log. * - * The loop only flushes at `turn/end`, so a crash can leave a half-written - * final turn below the last committed checkpoint. `load` returns events only - * up to the **last complete `turn/end`**; a subsequent {@link append} runs - * the one-time truncation-repair that physically discards the orphaned tail - * before writing. Returned events are contiguous (`events[i].seq === i`); a - * parse error or a `seq` gap in the MIDDLE of the log makes the session - * unloadable (reject). Rejects an unknown format `version`. + * The loop only flushes at `turn/end`, so a crash can leave a durable log + * whose final turn never closed: real, fully-written events sit after the last + * `turn/end`. Those events are PRESERVED — a single turn can be huge in a + * long-horizon task, so truncating it would destroy real work — and `load` + * CLOSES the orphaned turn by durably appending the minimal synthetic boundary + * events (a `step/end` if a step was open, then a `turn/end` carrying the + * `{ kind: 'interrupted' }` reason). The returned `events` therefore end on a + * balanced `turn/end` and are immediately usable as a session seed. Only a + * never-fully-written TORN tail fragment (a half-written final record) is + * discarded. Returned events are contiguous (`events[i].seq === i`); a parse + * error or a `seq` gap in the COMMITTED region (at or before the last real + * `turn/end`) makes the session unloadable (reject). Rejects an unknown format + * `version`. See ADR 0018 for the crash-recovery contract. */ abstract load(id: SessionId): Promise<{ meta: SessionMeta; events: SessionEvent[] }> diff --git a/packages/session-persistence/tests/contract.ts b/packages/session-persistence/tests/contract.ts index 3c4e739b60..189a4e10c2 100644 --- a/packages/session-persistence/tests/contract.ts +++ b/packages/session-persistence/tests/contract.ts @@ -64,6 +64,44 @@ export function runPersistenceContract(name: string, make: () => Promise { + const { persistence, dispose } = await make() + try { + const m = meta('interrupted') + await persistence.create(m) + await persistence.append(m.id, oneTurnLog()) // turn 1, committed (seqs 0..5) + // A second turn that crashed mid-flight: turn/start + step/start were + // durably written, but no step/end / turn/end ever arrived. + await persistence.append(m.id, [ + { type: 'turn/start', seq: 6, time: 7, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }, + { type: 'step/start', seq: 7, time: 8, data: { turn: 2, step: 1 } }, + ]) + + // load PRESERVES the interrupted turn's events (a turn can be huge — they + // must not be truncated) and closes the orphaned turn with synthetic + // boundary events: step/end (the step was open) then turn/end {interrupted}. + const loaded = await persistence.load(m.id) + expect(loaded.events.map(e => e.type)).toEqual([ + 'turn/start', 'user/message', 'step/start', 'assistant/message', 'step/end', 'turn/end', // turn 1 + 'turn/start', 'step/start', 'step/end', 'turn/end', // turn 2: real events + synthetic closers + ]) + expect(loaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + const last = loaded.events.at(-1)! + expect(last.type === 'turn/end' && last.data.reason).toEqual({ kind: 'interrupted' }) + + // The closed log is durable and continuable: a fresh append continues at + // the balanced length (seq 10), and a reload round-trips identically. + await persistence.append(m.id, [ + { type: 'turn/start', seq: 10, time: 9, data: { turn: 3, trigger: { kind: 'message', source: { kind: 'user' } } } }, + { type: 'turn/end', seq: 11, time: 10, data: { turn: 3, reason: { kind: 'completed' } } }, + ]) + const reloaded = await persistence.load(m.id) + expect(reloaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) + } finally { + await dispose() + } + }) + it('has()/list() exclude a created-but-never-appended (zero-event) session', async () => { const { persistence, dispose } = await make() try { diff --git a/packages/session-persistence/tests/persistence.spec.ts b/packages/session-persistence/tests/persistence.spec.ts index 9d211fff52..ea55f75d9c 100644 --- a/packages/session-persistence/tests/persistence.spec.ts +++ b/packages/session-persistence/tests/persistence.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { Context } from 'cordis' -import { SessionId, isJsonValue } from '@deepseek-ai/dsh-session' +import { SessionId, isJsonValue, interruptedTurnClosers } from '@deepseek-ai/dsh-session' import type { SessionEvent, SessionMeta, SessionSummary } from '@deepseek-ai/dsh-session' import { SessionPersistence } from '../src/index.ts' import { runPersistenceContract, meta, oneTurnLog } from './contract.ts' @@ -46,6 +46,11 @@ class MemoryPersistence extends SessionPersistence { async load(id: SessionId): Promise<{ meta: SessionMeta; events: SessionEvent[] }> { const entry = this.store.get(id) if (!entry) throw new Error(`session "${id}" not found`) + // Honor the crash-recovery contract: if the stored log ends mid-turn, close + // the orphaned turn durably with synthetic boundary events and continue from + // the balanced length. + const closers = interruptedTurnClosers(entry.events) + if (closers.length > 0) entry.events.push(...structuredClone(closers)) return { meta: structuredClone(entry.meta), events: structuredClone(entry.events) } } diff --git a/packages/session/src/index.ts b/packages/session/src/index.ts index 8fe54cb97b..34eefb24a3 100644 --- a/packages/session/src/index.ts +++ b/packages/session/src/index.ts @@ -15,6 +15,7 @@ import { isJsonValue } from './json.ts' export * from './types.ts' export { isJsonValue } from './json.ts' +export { interruptedTurnClosers } from './repair.ts' declare module 'cordis' { interface Context { diff --git a/packages/session/src/repair.ts b/packages/session/src/repair.ts new file mode 100644 index 0000000000..c09d15eee6 --- /dev/null +++ b/packages/session/src/repair.ts @@ -0,0 +1,79 @@ +/** + * Crash-recovery repair for an interrupted session log. + * + * A persistence backend flushes only at `turn/end`, so a crash can leave a + * durable log whose final turn never closed: real, fully-written events sit + * after the last `turn/end` with no closing boundary. A single turn can be huge + * in a long-horizon task (many steps, large tool output), so those events MUST + * be preserved — truncating the turn would silently destroy real work. Instead, + * on reload the backend CLOSES the orphaned turn by appending the minimal + * synthetic boundary events (a `step/end` if a step was still open, then a + * `turn/end` carrying the merge-extensible `{ kind: 'interrupted' }` reason). + * The marker records that the turn was cut short by a crash, not completed by + * the model. See ADR 0018. + * + * This module computes those synthetic closers from an event list; the backend + * returns them inline from `load` (so the reconstructed session is balanced and + * immediately usable) and persists them on the first post-load `append`. + * + * @module @deepseek-ai/dsh-session/repair + */ + +import type { SessionEvent } from './types.ts' + +/** + * Scan `events` for an open turn/step at the tail and return the synthetic + * boundary events that close them, with `seq` continuing the log and `time` + * copied from the last real event (the closers stand in for the crash moment; + * reusing the last timestamp keeps them deterministic and never invents a + * "future" time). Returns an empty array when the log is already balanced + * (ends on a `turn/end`, or is empty) — the common, non-crash case. + * + * Only the LAST turn can be open: the invariants plugin guarantees a `turn/end` + * before any later `turn/start`, so an interior open turn is impossible in a + * valid committed log. Likewise at most one step is open within that turn. + */ +export function interruptedTurnClosers(events: readonly SessionEvent[]): SessionEvent[] { + let openTurn: number | null = null + let openStep: number | null = null + for (const event of events) { + switch (event.type) { + case 'turn/start': + openTurn = event.data.turn + break + case 'turn/end': + openTurn = null + openStep = null + break + case 'step/start': + openStep = event.data.step + break + case 'step/end': + openStep = null + break + // Other event types do not move the turn/step boundary cursor. + default: + break + } + } + + // Balanced log (no crash mid-turn): nothing to close. An open turn implies + // `events` is non-empty (its turn/start was logged), so `last` exists. + const last = events.at(-1) + if (openTurn === null || last === undefined) return [] + + // The last real event supplies the seq base and the timestamp for the + // synthetic closers (reusing the last timestamp keeps them deterministic and + // never invents a "future" time). + let seq = last.seq + 1 + const time = last.time + const closers: SessionEvent[] = [] + + // Close an open step first — a turn/end while a step is open is an invariant + // violation, so the step's boundary must be synthesized before the turn's. + if (openStep !== null) { + closers.push({ type: 'step/end', seq: seq++, time, data: { turn: openTurn, step: openStep } }) + } + closers.push({ type: 'turn/end', seq: seq++, time, data: { turn: openTurn, reason: { kind: 'interrupted' } } }) + return closers +} diff --git a/packages/session/src/types.ts b/packages/session/src/types.ts index 197e251b59..d8ffaf9dc8 100644 --- a/packages/session/src/types.ts +++ b/packages/session/src/types.ts @@ -99,6 +99,17 @@ export interface TurnEndReasonMap { aborted: { kind: 'aborted'; reason?: string } error: { kind: 'error'; message: string; code?: string } disposed: { kind: 'disposed' } + /** + * The turn never ended on its own: the process crashed mid-turn and a + * persistence backend later closed the orphaned (open) turn on reload so the + * log stays balanced. SYNTHESIZED by the backend's crash-recovery repair — no + * loop ever emits this. Its events are real (they were durably appended before + * the crash) and are PRESERVED, not discarded: a single turn can be huge in a + * long-horizon task (many steps, large tool output), so truncating it would + * lose real work. The marker records that the turn was cut short, not that the + * model completed it. See ADR 0018. + */ + interrupted: { kind: 'interrupted' } } export type TurnEndReason = TurnEndReasonMap[keyof TurnEndReasonMap] From 0000cdb2c2584ffdf13ca91e947ec0fa737631db Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:28:01 +0800 Subject: [PATCH 11/12] feat(agent-loop): config-driven session resume via RESUME_SESSION_ID A config agent with `resumeSessionId` set continues a persisted session instead of starting a fresh `${id}-session-`. The id is sourced from an env var in cordis.yml, so the coding-agent demo can resume a prior conversation without code changes. The resume is deferred until the `sessionPersistence` backend loads (via ctx.inject) and is contained: a missing/unreadable id logs a warning and starts no agent. Adds a real-API resume e2e proving cross-process continuity through the JSONL backend. --- examples/coding-agent/README.md | 11 +++ examples/coding-agent/cordis.yml | 3 + examples/coding-agent/tests/harness.ts | 7 +- examples/coding-agent/tests/resume.e2e.ts | 69 +++++++++++++++++ packages/agent-loop/src/index.ts | 55 ++++++++++++-- .../tests/config-session-id.spec.ts | 74 ++++++++++++++++++- 6 files changed, 212 insertions(+), 7 deletions(-) create mode 100644 examples/coding-agent/tests/resume.e2e.ts diff --git a/examples/coding-agent/README.md b/examples/coding-agent/README.md index dee1c83b09..44445adc5d 100644 --- a/examples/coding-agent/README.md +++ b/examples/coding-agent/README.md @@ -22,6 +22,16 @@ Type a coding task. The agent's only tools are `bash` (+ `bash_output` / `bash_k … ``` +### Resuming a prior session + +Each run starts a fresh session by default (its event log lands under `./.sessions/`). To **continue** a previous conversation, set `RESUME_SESSION_ID` to that session's id — the `main` agent then rehydrates the persisted log instead of starting fresh, so the model sees the earlier turns as history: + +```sh +RESUME_SESSION_ID= pnpm run demo:coding +``` + +The id is wired through `cordis.yml` (`resumeSessionId: !!js process.env.RESUME_SESSION_ID`); unset, the agent starts a new session. A missing/unreadable id is non-fatal — it logs a warning and starts no `main` agent. + ## What each plugin demonstrates | Entry | Demonstrates | @@ -36,5 +46,6 @@ Type a coding task. The agent's only tools are `bash` (+ `bash_output` / `bash_k - `tests/full-loop.e2e.ts` — the canary: real model runs `echo e2e-ok` through the real bash tool; asserts `tool/call`/`tool/result` session events and the final answer. - `tests/coding-task.e2e.ts` — the swebench-style smoke: a temp dir holds `add.js` (with `a - b` where `a + b` belongs) and a failing `add.test.js`; the agent must fix the bug and verify. The test re-runs `node add.test.js` ITSELF and inspects the files — agent claims are not trusted. +- `tests/resume.e2e.ts` — durable continuity across processes: run 1 tells the real model a secret code and persists the turn to a temp JSONL root, then the whole context is disposed; run 2 is a fresh context over the same root that RESUMES the session id and asks the model to recall the code. The recall can only come from the rehydrated log. Both self-skip without `DEEPSEEK_API_KEY`. diff --git a/examples/coding-agent/cordis.yml b/examples/coding-agent/cordis.yml index 47eaad8a9b..07eb04d123 100644 --- a/examples/coding-agent/cordis.yml +++ b/examples/coding-agent/cordis.yml @@ -61,6 +61,9 @@ agents: - id: main model: deepseek-v4-flash + # Set RESUME_SESSION_ID to continue a prior persisted session (the ids + # live under ./.sessions); unset starts a fresh session each run. + resumeSessionId: !!js process.env.RESUME_SESSION_ID systemPrompt: | You are coding-agent, a CLI coding assistant. diff --git a/examples/coding-agent/tests/harness.ts b/examples/coding-agent/tests/harness.ts index db89b2c183..ca303691e9 100644 --- a/examples/coding-agent/tests/harness.ts +++ b/examples/coding-agent/tests/harness.ts @@ -9,6 +9,7 @@ import AgentLoop, { LoopAgent } from '@deepseek-ai/dsh-agent-loop' import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local' import * as ToolBash from '@deepseek-ai/dsh-tool-bash' import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek' +import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl' /** * Shared harness for the coding-agent e2e suites: the full plugin stack @@ -20,7 +21,7 @@ export const SYSTEM_PROMPT = 'You are a coding agent. Your only tool is bash; ' + 'do file operations with cat/grep/heredocs, check [exit code: N] markers, ' + 'and report results briefly.' -export async function codingHarness(workdir: string): Promise { +export async function codingHarness(workdir: string, persistenceRoot?: string): Promise { const ctx = new Context() await ctx.plugin(LlmService) await ctx.plugin(SessionStore) @@ -31,6 +32,10 @@ export async function codingHarness(workdir: string): Promise { await ctx.plugin(LlmDeepSeek, { models: ['deepseek-v4-flash'] }) await ctx.plugin(LocalBashExecutor, { cwd: workdir, timeoutMs: 30_000 }) await ctx.plugin(ToolBash) + // Durable JSONL persistence is opt-in: only the resume e2e needs it, and the + // other suites stay file-free. Loaded last so a resume's deferred + // `ctx.inject(['sessionPersistence'])` resolves once this is present. + if (persistenceRoot !== undefined) await ctx.plugin(SessionPersistenceJsonl, { root: persistenceRoot }) return ctx } diff --git a/examples/coding-agent/tests/resume.e2e.ts b/examples/coding-agent/tests/resume.e2e.ts new file mode 100644 index 0000000000..6fd2dcb567 --- /dev/null +++ b/examples/coding-agent/tests/resume.e2e.ts @@ -0,0 +1,69 @@ +import { mkdtemp, rm } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import type { Context } from 'cordis' +import type { LoopAgent } from '@deepseek-ai/dsh-agent-loop' +import { codingHarness, finalText, SYSTEM_PROMPT, waitForIdle } from './harness.ts' + +/** + * Proves durable conversation continuity end-to-end: run 1 tells the REAL model + * a fact and persists the turn to JSONL; run 2 is a fresh harness (new Context, + * same `.sessions` root) that RESUMES the persisted session id and asks the + * model to recall the fact. The recall can only come from the rehydrated event + * log — a fresh session would have no idea. Key-gated like the other e2es. + */ + +const SECRET = 'plum-galaxy-1791' +const SESSION_ID = 'resume-e2e-session' + +let ctx: Context | undefined +let root: string | undefined + +afterEach(async () => { + // Dispose even on failure/retry: agent-loop teardown stops the loop and the + // JSONL backend flushes; then drop the on-disk session log. + await ctx?.fiber.dispose() + ctx = undefined + if (root !== undefined) await rm(root, { recursive: true, force: true }) + root = undefined +}) + +describe.skipIf(!process.env.DEEPSEEK_API_KEY)('resume: continue a persisted session across processes', () => { + it('recalls a fact stored in a prior, separately-disposed session', async () => { + root = await mkdtemp(join(tmpdir(), 'dsh-resume-e2e-')) + + // Run 1: a fresh agent on a KNOWN session id learns a secret, then we + // dispose the whole context (simulating process exit) so only the JSONL + // log on disk survives. + ctx = await codingHarness(process.cwd(), root) + const first = ctx.agents.create({ + agentId: 'resume-1', + sessionId: SESSION_ID, + agentOptions: { model: 'deepseek-v4-flash', systemPrompt: SYSTEM_PROMPT }, + }) as LoopAgent + first.send([{ type: 'text', text: `Remember this code for later: ${SECRET}. Just acknowledge it.` }]) + await waitForIdle(ctx, first) + await ctx.fiber.dispose() + ctx = undefined + + // Run 2: a brand-new context over the SAME root resumes the persisted + // session. The loaded event log seeds the live session, so the model sees + // run 1's exchange as conversation history. + ctx = await codingHarness(process.cwd(), root) + const resumed = await ctx.agents.resume({ + agentId: 'resume-2', + resumeSessionId: SESSION_ID, + agentOptions: { model: 'deepseek-v4-flash', systemPrompt: SYSTEM_PROMPT }, + }) as LoopAgent + expect(resumed.session.id).toBe(SESSION_ID) + // The prior user turn is in the rehydrated log before the model is asked. + expect(JSON.stringify(resumed.session.deriveMessages())).toContain(SECRET) + + resumed.send([{ type: 'text', text: 'What was the code I asked you to remember? Reply with just the code.' }]) + await waitForIdle(ctx, resumed) + + // The model recalls it — only possible from the resumed history. + expect(finalText([...resumed.session.events])).toContain(SECRET) + }, 180_000) +}) diff --git a/packages/agent-loop/src/index.ts b/packages/agent-loop/src/index.ts index a1efc78d56..9b40b1f770 100644 --- a/packages/agent-loop/src/index.ts +++ b/packages/agent-loop/src/index.ts @@ -17,7 +17,7 @@ import { SessionId } from '@deepseek-ai/dsh-session' import type { Session } from '@deepseek-ai/dsh-session' import type {} from '@deepseek-ai/dsh-system-prompt' import type {} from '@deepseek-ai/dsh-tools' -import type {} from '@deepseek-ai/dsh-session-persistence' +import type { SessionPersistence } from '@deepseek-ai/dsh-session-persistence' import { LoopAgent } from './agent.ts' export { LoopAgent } from './agent.ts' @@ -32,7 +32,19 @@ declare module 'cordis' { export interface Config { /** Agents created from configuration at startup. */ - agents: (AgentOptions & { id: string })[] + agents: (AgentOptions & { + id: string + /** + * If set, the config agent RESUMES this persisted session id instead of + * starting a fresh `${id}-session-`. Sourced from an env var in + * cordis.yml (`resumeSessionId: !!js process.env.RESUME_SESSION_ID`), so a + * demo can continue a prior conversation without code changes. Requires a + * `dsh-session-persistence` backend; the resume is deferred until that + * service is available (via `ctx.inject`) and the loaded session's events + * seed the live session so history continues. + */ + resumeSessionId?: string + })[] } /** @@ -53,6 +65,7 @@ export class AgentLoop extends Service implements AgentFactory { id: z.string().required(), model: z.string(), systemPrompt: z.string(), + resumeSessionId: z.string(), })).default([]), }) @@ -61,8 +74,27 @@ export class AgentLoop extends Service implements AgentFactory { // Provide the agent-creation factory to the registry (effect-scoped: the // slot is cleared on dispose). ctx.effect(() => this.ctx.agents.setFactory(this), 'agentLoop.setFactory()') - for (const { id, ...options } of config.agents) { - this.create(id, options) + for (const { id, resumeSessionId, ...options } of config.agents) { + if (resumeSessionId !== undefined && resumeSessionId !== '') { + // Resume a prior session instead of starting fresh. resume() needs + // `ctx.sessionPersistence`, which may load AFTER this plugin (cordis.yml + // lists the backend later). `ctx.inject(['sessionPersistence'], cb)` + // runs `cb` with a child ctx once the service exists; the child reads + // the persistence and hands it to resumeWith (which uses this.ctx — the + // parent — for sessions/registry, all in AgentLoop's static inject). A + // failed resume is contained + logged: startup must not crash. + ctx.effect(() => { + const fiber = this.ctx.inject(['sessionPersistence'], (childCtx: Context) => { + void this.resumeWith(childCtx.sessionPersistence, { agentId: id, resumeSessionId, agentOptions: options }) + .catch((error: unknown) => { + this.ctx.logger.warn(`agent "${id}": config-driven resume of "${resumeSessionId}" failed: ${String(error)}`) + }) + }) + return () => void fiber.dispose() + }, `agentLoop.resume(${id})`) + } else { + this.create(id, options) + } } } @@ -120,7 +152,6 @@ export class AgentLoop extends Service implements AgentFactory { * by the time this runs the service exists. */ async resume(options: ResumeAgentOptions): Promise { - this.assertAgentIdFree(options.agentId) const persistence = this.ctx.sessionPersistence // `sessionPersistence` is declaration-merged onto Context as non-optional, // but the service is only present when a backend plugin is loaded — and @@ -130,6 +161,20 @@ export class AgentLoop extends Service implements AgentFactory { if (persistence === undefined) { throw new Error('cannot resume: session persistence is not configured (load a dsh-session-persistence backend)') } + return this.resumeWith(persistence, options) + } + + /** + * Resume against an EXPLICIT persistence handle. Factored out of {@link resume} + * so the config-driven path can pass the handle it obtained from a + * `ctx.inject(['sessionPersistence'], …)` child context: `this.ctx` (the + * service's own fiber) did not inject `sessionPersistence`, so reading it + * there from inside the inject child trips the cordis inject guard. The + * sessions store + registry are still read through `this.ctx` (both are in + * AgentLoop's static inject, so they resolve fine). + */ + private async resumeWith(persistence: SessionPersistence, options: ResumeAgentOptions): Promise { + this.assertAgentIdFree(options.agentId) const { meta, events } = await persistence.load(SessionId(options.resumeSessionId)) // Re-check the agent id AFTER the await: the pre-load check above can go // stale while load() is pending (a concurrent resume/create may register the diff --git a/packages/agent-loop/tests/config-session-id.spec.ts b/packages/agent-loop/tests/config-session-id.spec.ts index b905d54145..52f0223564 100644 --- a/packages/agent-loop/tests/config-session-id.spec.ts +++ b/packages/agent-loop/tests/config-session-id.spec.ts @@ -1,4 +1,4 @@ -import { afterEach, describe, expect, it } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest' import { Context } from 'cordis' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' @@ -62,4 +62,76 @@ describe('config-driven session id', () => { await waitForIdle(ctx2, a2) await ctx2.fiber.dispose() }) + + it('config-driven resumeSessionId continues a persisted session (env-var resume)', async () => { + const root = await mkdtemp(join(tmpdir(), 'dsh-cfg-resume-')) + dirs.push(root) + + // Run 1: a programmatically-created agent on a KNOWN session id persists a + // completed turn, so run 2 has a concrete id to resume. + const ctx1 = new Context() + await ctx1.plugin(LlmService) + await ctx1.plugin(SessionStore) + await ctx1.plugin(SystemPrompt) + await ctx1.plugin(ToolRegistry) + await ctx1.plugin(AgentRegistry) + await ctx1.plugin(AgentLoop, { agents: [] }) + await ctx1.plugin(SessionPersistenceJsonl, { root }) + ctx1.llm.registerAdapter(['mock'], new MockAdapter([textResponse('first')])) + const a1 = ctx1.agents.create({ agentId: 'main', sessionId: 'sticky-1' }) as LoopAgent + a1.send([{ type: 'text', text: 'remember me' }], { source: { kind: 'user' } }) + await waitForIdle(ctx1, a1) + await ctx1.fiber.dispose() + + // Run 2: a CONFIG agent with resumeSessionId continues that session. The + // resume is deferred until sessionPersistence loads (ctx.inject), so wait + // for the agent to appear, then assert it is on the resumed id with history. + const ctx2 = new Context() + await ctx2.plugin(LlmService) + await ctx2.plugin(SessionStore) + await ctx2.plugin(SystemPrompt) + await ctx2.plugin(ToolRegistry) + await ctx2.plugin(AgentRegistry) + await ctx2.plugin(AgentLoop, { agents: [{ id: 'main', model: 'mock', systemPrompt: '', resumeSessionId: 'sticky-1' }] }) + await ctx2.plugin(SessionPersistenceJsonl, { root }) + ctx2.llm.registerAdapter(['mock'], new MockAdapter([textResponse('second')])) + + // The deferred resume runs on a microtask after the backend is available. + let resumed: LoopAgent | undefined + for (let i = 0; i < 50 && !resumed; i++) { + await new Promise(r => setTimeout(r, 5)) + resumed = ctx2.agents.get('main') as LoopAgent | undefined + } + expect(resumed).toBeDefined() + // The live session id IS the resumed id (NOT a fresh ${id}-session-), + // and the prior turn's user message is in the derived history. + expect(resumed!.session.id).toBe('sticky-1') + const derived = resumed!.session.deriveMessages() + expect(JSON.stringify(derived)).toContain('remember me') + await ctx2.fiber.dispose() + }) + + it('config-driven resume of a missing session is contained: logs a warning, no agent, no crash', async () => { + const root = await mkdtemp(join(tmpdir(), 'dsh-cfg-resume-miss-')) + dirs.push(root) + const ctx = new Context() + await ctx.plugin(LlmService) + await ctx.plugin(SessionStore) + await ctx.plugin(SystemPrompt) + await ctx.plugin(ToolRegistry) + await ctx.plugin(AgentRegistry) + await ctx.plugin(AgentLoop, { agents: [{ id: 'main', model: 'mock', systemPrompt: '', resumeSessionId: 'does-not-exist' }] }) + const warn = vi.spyOn((ctx.agentLoop as unknown as { ctx: { logger: { warn: (...a: unknown[]) => void } } }).ctx.logger, 'warn') + .mockImplementation(() => undefined) + await ctx.plugin(SessionPersistenceJsonl, { root }) + ctx.llm.registerAdapter(['mock'], new MockAdapter([textResponse('x')])) + + // The deferred resume fails (no such session on disk). It must be contained: + // a warning is logged, no 'main' agent is registered, and the app stays up. + await new Promise(r => setTimeout(r, 200)) + expect(ctx.agents.get('main')).toBeUndefined() + expect(warn).toHaveBeenCalledWith(expect.stringContaining('config-driven resume of "does-not-exist" failed')) + warn.mockRestore() + await ctx.fiber.dispose() + }) }) From ce4b32ace9f46d8967d7bffd788e7aa14b4a2cf8 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:56:17 +0800 Subject: [PATCH 12/12] feat(session-persistence-sqlite): preserve interrupted turns on load, don't truncate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror the JSONL backend's crash-recovery contract change: load() now PRESERVES the real events of an interrupted final turn (a turn can be huge — truncating it would destroy work) and durably CLOSES the orphaned turn with synthetic boundary events (step/end if open, then turn/end {interrupted}) inside one transaction that also deletes any torn tail row. load() is therefore mutating; the deferred truncation-repair on the next append is gone. Replaces cutAtLastTurnEnd with scanRows (longest preserved prefix + torn-tail offset). Updates the sqlite tests and README to the preserve-and-close semantics; the shared runPersistenceContract suite now holds both backends to identical interrupted-turn behavior. --- packages/session-persistence-sqlite/README.md | 6 +- .../session-persistence-sqlite/src/index.ts | 135 +++++++++------- .../session-persistence-sqlite/src/schema.ts | 92 +++++++---- .../tests/sqlite.spec.ts | 149 +++++++++++------- 4 files changed, 232 insertions(+), 150 deletions(-) diff --git a/packages/session-persistence-sqlite/README.md b/packages/session-persistence-sqlite/README.md index dd72ddfde4..3a7a3c8163 100644 --- a/packages/session-persistence-sqlite/README.md +++ b/packages/session-persistence-sqlite/README.md @@ -1,6 +1,6 @@ # @deepseek-ai/dsh-session-persistence-sqlite -A SQLite durable session-persistence backend — a second `SessionPersistence` implementation ([ADR 0018](../../docs/adr/0018-session-persistence.md)), built to validate that the abstract seam and the shared `runPersistenceContract` suite are genuinely backend-agnostic. It satisfies the SAME contract as `dsh-session-persistence-jsonl` (append-only, contiguous-seq, lazy materialization, crash-tail-on-load), expressed over `node:sqlite` rows instead of file bytes. +A SQLite durable session-persistence backend — a second `SessionPersistence` implementation ([ADR 0018](../../docs/adr/0018-session-persistence.md)), built to validate that the abstract seam and the shared `runPersistenceContract` suite are genuinely backend-agnostic. It satisfies the SAME contract as `dsh-session-persistence-jsonl` (append-only, contiguous-seq, lazy materialization, interrupted-turn close on load), expressed over `node:sqlite` rows instead of file bytes. > **TODO:** this backend talks to `node:sqlite` directly. If a cordis database service (`cordis/db` / a `@cordisjs` SQL driver plugin) is adopted, route through that instead of holding a raw `DatabaseSync` here — the contract surface (`SessionPersistence`) would not change, only the storage driver. @@ -12,9 +12,9 @@ The repo targets Node ≥ 24 (the root `engines` field), which includes the stab ## Contract semantics over rows -- **Append = a transaction.** `append` runs `BEGIN`/`COMMIT` around the batch: it runs any deferred crash-tail repair, materializes the `sessions` row (if still lazy), and INSERTs every event, asserting the contiguous-seq contract first (the first event's `seq` must equal the stored next-seq). A mid-batch failure (a UNIQUE violation on a duplicated seq) rolls back entirely, so the stored log and the in-memory cursor stay consistent. +- **Append = a transaction.** `append` runs `BEGIN`/`COMMIT` around the batch: it materializes the `sessions` row (if still lazy) and INSERTs every event, asserting the contiguous-seq contract first (the first event's `seq` must equal the stored next-seq). A mid-batch failure (a UNIQUE violation on a duplicated seq) rolls back entirely, so the stored log and the in-memory cursor stay consistent. (`load()` already balanced the stored log, so `append` never has to repair a crash tail.) - **Lazy materialization.** `create()` records intent in memory only — no row is written until the first `append`. A created-but-never-appended session has no `sessions` row, so it is absent from `has()`/`list()` (which report exactly the sessions that have a row). -- **Crash-tail-on-load.** `load()` reads every stored event ordered by `seq` and returns only the prefix through the **last complete `turn/end`** (the `SessionPersistence.load` contract), computed from the `seq`/`type` columns so a malformed `data` in the uncommitted tail is never parsed. A batch that landed without its closing `turn/end` (a process killed mid-turn) is an uncommitted tail: `load()` stays non-mutating w.r.t. the event log and records a repair point; the **next `append`** physically DELETEs the orphaned rows inside its transaction (the one-time truncation-repair, matching the JSONL backend and the abstract contract). A `seq` gap inside the committed region makes the session unloadable. A session materialized by a partial first turn (all-tail, zero committed events) keeps its metadata row and stays present in `has()`/`list()` — the same as the JSONL backend, whose file likewise survives a first append that never reached `turn/end`. +- **Interrupted-turn close on load.** `load()` reads every stored event ordered by `seq` and finds the longest seq-contiguous, parseable prefix — INCLUDING the real events of an interrupted final turn after the last `turn/end` (the loop only flushes at `turn/end`, so a process killed mid-turn leaves real, fully-written rows past it). A single turn can be huge in a long-horizon task, so those events are **preserved, never truncated**: `load()` CLOSES the orphaned turn by durably appending the minimal synthetic boundary events (a `step/end` if a step was open, then a `turn/end` carrying `{ kind: 'interrupted' }`), inside one transaction that also DELETEs any never-fully-written torn tail row. `load()` is therefore mutating — after it the stored rows are balanced and the cursor is truthful, so the next `append` continues cleanly. The boundary (last `turn/end`, torn-tail detection) is computed from the `seq`/`type` columns so a malformed `data` in a torn tail row is never parsed (discarded, not unloadable). A parse error or `seq` gap inside the committed region (at or before the last real `turn/end`) makes the session unloadable. A session whose only turn never closed keeps its metadata row and stays present in `has()`/`list()` — the same as the JSONL backend, whose file likewise survives a first append that never reached `turn/end`. ## Configuration (schemastery) diff --git a/packages/session-persistence-sqlite/src/index.ts b/packages/session-persistence-sqlite/src/index.ts index 45d0215384..bd4b4d9435 100644 --- a/packages/session-persistence-sqlite/src/index.ts +++ b/packages/session-persistence-sqlite/src/index.ts @@ -4,10 +4,10 @@ * A SECOND {@link SessionPersistence} implementation, built to validate that * the abstract seam + the shared `runPersistenceContract` suite are genuinely * backend-agnostic: the same append-only / contiguous-seq / lazy-materialization - * / crash-tail-on-load semantics the JSONL backend expresses over file bytes, - * expressed here over `node:sqlite` rows. Each `SessionEvent` maps 1:1 onto a - * row `(session_id, seq, type, time, data)`; `append` is an INSERT inside a - * transaction that asserts the contiguous-seq contract; the mutable + * / interrupted-turn-close-on-load semantics the JSONL backend expresses over + * file bytes, expressed here over `node:sqlite` rows. Each `SessionEvent` maps + * 1:1 onto a row `(session_id, seq, type, time, data)`; `append` is an INSERT + * inside a transaction that asserts the contiguous-seq contract; the mutable * `SessionSummary` lives in the `sessions` metadata row. * * Like the JSONL backend it is also the write-path plugin: it installs the @@ -25,10 +25,10 @@ import { DatabaseSync } from 'node:sqlite' import { mkdir } from 'node:fs/promises' import { dirname, resolve } from 'node:path' import { SessionPersistence } from '@deepseek-ai/dsh-session-persistence' -import { isJsonValue } from '@deepseek-ai/dsh-session' +import { isJsonValue, interruptedTurnClosers } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent, SessionId, SessionMeta, SessionSummary } from '@deepseek-ai/dsh-session' import { - cutAtLastTurnEnd, openDatabase, rowToEvent, rowToMeta, type EventRow, type SessionRow, + openDatabase, rowToMeta, scanRows, type EventRow, type SessionRow, } from './schema.ts' export { SCHEMA_VERSION } from './schema.ts' @@ -50,14 +50,6 @@ interface SessionState { cursor: number /** Whether the session has at least one persisted event (materialized). */ materialized: boolean - /** - * If a load found a crash tail, the seq from which the next {@link append} - * must DELETE before inserting (the one-time truncation-repair). load() stays - * non-mutating w.r.t. the event log — it only records this marker — so the - * public contract matches the JSONL backend: load returns the committed - * prefix; the subsequent append performs the physical repair. - */ - repairFrom?: number /** The live Session that owns this state (collision detection); see onCreated. */ owner?: Session } @@ -179,24 +171,19 @@ export class SessionPersistenceSqlite extends SessionPersistence { } } - // The transaction is the durability + atomicity boundary: run any deferred - // crash-tail repair, materialize the sessions row (if lazy), and INSERT - // every event, or roll back entirely. A BEGIN/COMMIT around the batch means - // a mid-batch failure (a UNIQUE violation on a duplicated seq from a - // concurrent writer) leaves the stored log untouched, so the cursor stays - // truthful and a retry is clean. + // The transaction is the durability + atomicity boundary: materialize the + // sessions row (if lazy) and INSERT every event, or roll back entirely. A + // BEGIN/COMMIT around the batch means a mid-batch failure (a UNIQUE + // violation on a duplicated seq from a concurrent writer) leaves the stored + // log untouched, so the cursor stays truthful and a retry is clean. (A crash + // tail is already gone: load() physically deletes the torn fragment and + // durably closes the interrupted turn before returning, so by the time any + // append runs the stored log is balanced and contiguous.) const insertEvent = this.db.prepare( 'INSERT INTO events (session_id, seq, type, time, data) VALUES (?, ?, ?, ?, ?)', ) this.db.exec('BEGIN') try { - // One-time truncation-repair: a prior load() found a crash tail and - // deferred its physical removal to here (load stays non-mutating). DELETE - // the orphaned rows (seq >= repairFrom) before inserting, inside the same - // transaction, so the repair + first new append commit atomically. - if (state.repairFrom !== undefined) { - this.db.prepare('DELETE FROM events WHERE session_id = ? AND seq >= ?').run(id, state.repairFrom) - } if (!state.materialized) this.writeRow(state.meta) for (const event of events) { insertEvent.run(id, event.seq, event.type, event.time, JSON.stringify(event.data)) @@ -210,7 +197,6 @@ export class SessionPersistenceSqlite extends SessionPersistence { this.db.exec('ROLLBACK') throw error } - delete state.repairFrom state.materialized = true state.cursor += events.length } @@ -226,42 +212,68 @@ export class SessionPersistenceSqlite extends SessionPersistence { const meta = rowToMeta(row) this.assertVersion(meta) - // Read every stored row ordered by seq, then cut at the last complete - // turn/end — the same crash-tail semantics as the JSONL backend. The cut is - // computed from seq+type COLUMNS only, so a malformed `data` in the - // uncommitted tail is discarded (not unloadable); only `data` in the - // COMMITTED prefix is parsed (rowToEvent), where a parse error correctly - // surfaces. A row that landed without its closing turn/end is an - // uncommitted tail and is excluded; a seq gap in the committed region makes - // the session unloadable (cutAtLastTurnEnd throws). + // Read every stored row ordered by seq, then scan for the preserved prefix: + // the longest seq-contiguous, parseable run, INCLUDING the real events of an + // interrupted final turn after the last turn/end (a turn can be huge — they + // are never truncated). scanRows works off the seq+type COLUMNS for the + // last-turn/end boundary, so a malformed `data` in a torn tail row is + // discarded (not unloadable); only a parse error / seq gap in the COMMITTED + // region (at or before the last turn/end) throws (genuine corruption). const eventRows = this.db .prepare('SELECT seq, type, time, data FROM events WHERE session_id = ? ORDER BY seq') .all(id) as unknown as EventRow[] - const { committed, cutTail } = cutAtLastTurnEnd(eventRows) - const events = committed.map(rowToEvent) + const { preserved, tornFrom } = scanRows(eventRows) - // Do NOT delete the crash tail here: load() stays non-mutating w.r.t. the - // event log, matching the abstract contract and the JSONL backend (load - // returns the committed prefix; the next append performs the one-time - // physical repair). Record the repair point so the next appendCore DELETEs - // the orphaned tail inside its own transaction before inserting. - // - // The metadata row stays as-is even when committed.length === 0 (an all-tail - // crash): the session WAS materialized by the partial append, so its row - // exists and has()/list() report it present — the same as the JSONL backend, - // whose file likewise survives a first append that never reached turn/end. - // - // Record state so a later append continues at the committed length and runs - // the deferred tail repair. The state keeps its OWN copy of the meta; the - // returned value is separate so a consumer mutating loaded.meta cannot - // corrupt the backend's row metadata. + // Crash-recovery (mutating load, same as the JSONL backend): if the log ended + // mid-turn, close it DURING load so disk, the returned log, and the cursor all + // agree — both append routes then continue with no special-casing. Synthesize + // the boundary events (a step/end if a step was open, then a + // turn/end {kind:'interrupted'}); the interrupted turn's real events are + // preserved, never truncated (ADR 0018). + const closers = interruptedTurnClosers(preserved) + const balanced = [...preserved, ...closers] + + // Physically repair the stored log inside one transaction: DELETE the torn + // tail fragment (if any), then INSERT the synthetic closers. After COMMIT the + // stored rows == balanced, so the cursor is truthful and the next append + // continues cleanly with no deferred repair. The metadata row stays as-is + // even when preserved.length === 0 (an all-tail crash): the session WAS + // materialized by the partial append, so has()/list() still report it — the + // same as the JSONL backend, whose file likewise survives a first append that + // never reached turn/end. + if (tornFrom !== undefined || closers.length > 0) { + this.db.exec('BEGIN') + try { + if (tornFrom !== undefined) { + this.db.prepare('DELETE FROM events WHERE session_id = ? AND seq >= ?').run(id, tornFrom) + } + if (closers.length > 0) { + const insertEvent = this.db.prepare('INSERT INTO events (session_id, seq, type, time, data) VALUES (?, ?, ?, ?, ?)') + for (const event of closers) { + insertEvent.run(id, event.seq, event.type, event.time, JSON.stringify(event.data)) + } + } + this.db.exec('COMMIT') + } catch (error) { + // The DELETE+INSERT cannot collide (a row at a closer's seq is preserved + // or deleted as torn first); this rolls back a DB-level failure (disk + // full, etc.), unreachable in test. + /* v8 ignore start */ + this.db.exec('ROLLBACK') + throw error + /* v8 ignore stop */ + } + } + + // Record state at the balanced length. The state keeps its OWN copy of the + // meta; the returned value is separate so a consumer mutating loaded.meta + // cannot corrupt the backend's row metadata. this.states.set(id, { meta: { ...meta }, - cursor: committed.length, + cursor: balanced.length, materialized: true, - ...cutTail ? { repairFrom: committed.length } : {}, }) - return { meta, events } + return { meta, events: balanced } } async list(): Promise { @@ -482,14 +494,17 @@ export class SessionPersistenceSqlite extends SessionPersistence { if (seed.length > 0) await this.append(id, seed) } - /** The committed events for a session id (last-turn/end cut applied). */ + /** The preserved events for a session id (torn tail excluded, turn NOT yet closed). */ private eventsFor(id: SessionId): SessionEvent[] { const rows = this.db .prepare('SELECT seq, type, time, data FROM events WHERE session_id = ? ORDER BY seq') .all(id) as unknown as EventRow[] - // Cut on seq+type columns, then parse `data` only for the committed prefix - // (a malformed tail must not throw here — same as loadCore). - return cutAtLastTurnEnd(rows).committed.map(rowToEvent) + // Scan on seq+type columns, parsing `data` only for the preserved prefix (a + // malformed torn tail must not throw here — same as loadCore). Returns the + // preserved events WITHOUT the synthetic closers, so a collision check + // compares a live seed against the real on-disk events, mirroring the JSONL + // backend's scanLog use in onCreated. + return scanRows(rows).preserved } /** Whether a live session's seed reproduces the first `cursor` stored events. */ diff --git a/packages/session-persistence-sqlite/src/schema.ts b/packages/session-persistence-sqlite/src/schema.ts index c3ef9ca051..1dad51698b 100644 --- a/packages/session-persistence-sqlite/src/schema.ts +++ b/packages/session-persistence-sqlite/src/schema.ts @@ -122,41 +122,69 @@ export function rowToEvent(row: EventRow): SessionEvent { } /** - * The committed prefix of an ordered event list: everything up to and including - * the LAST `turn/end`, plus whether a crash tail (items after it) was cut. + * The preserved prefix of an ordered event-row list (mirrors the JSONL + * backend's `scanLog`): the longest prefix of complete, seq-contiguous, + * parseable rows, PLUS the seq from which a never-committed torn tail must be + * deleted (or `undefined` if the whole list is intact). * - * Generic over anything carrying `seq` + `type` (an {@link EventRow} or a - * {@link SessionEvent}) so the cut is computed from those COLUMNS alone — the - * caller parses each row's `data` only for the committed items it returns, - * never for the tail. This matters for the contract: a malformed `data` in an - * uncommitted crash tail must be discarded, not make the session unloadable — - * only a parse error / gap in the COMMITTED region is unloadable (see - * `SessionPersistence.load`). Mirrors the JSONL backend's `scanLog`, which - * likewise tolerates a corrupt tail after the last committed `turn/end`. + * A crash can leave a durable log whose final turn never closed: real, + * fully-written rows sit after the last `turn/end`. Those are PRESERVED — a + * single turn can be huge in a long-horizon task, so truncating it would + * destroy real work; the backend closes the orphaned open turn with a synthetic + * `turn/end {kind:'interrupted'}` on load (ADR 0018). The ONLY thing excluded is + * a torn trailing fragment — a row whose `data` never parses, or a seq gap — + * AFTER the last committed `turn/end`; that bounds the preserved region and its + * seq is returned as `tornFrom` so `load` can physically delete it. * - * The loop only flushes at `turn/end`, so the last `turn/end` is the last - * durable boundary; anything after it is a never-committed crash tail (a batch - * that landed without its closing `turn/end`, e.g. a process killed mid-turn). - * The committed region MUST be contiguous (`item.seq === i`); a gap there means - * committed data was lost and the session is unloadable. + * The last `turn/end` is computed from the `type` COLUMN (never parsing tail + * `data`), so a malformed `data` in an uncommitted tail row is discarded rather + * than making the session unloadable. A parse error or seq gap AT OR BEFORE the + * last committed `turn/end` is committed-data corruption and throws. + * + * This relies on the session-log invariant that every event lives inside a turn + * (`Session.append` enforces it): only the final turn can be open, so the + * preserved tail is at most one unclosed turn. */ -export function cutAtLastTurnEnd( - items: readonly T[], -): { committed: T[]; cutTail: boolean } { - let lastTurnEnd = -1 - items.forEach((item, i) => { - if (item.type === 'turn/end') lastTurnEnd = i - }) - // No committed turn/end anywhere: the whole list is an uncommitted first-turn - // tail. Nothing is committed (mirrors scanLog returning zero events). - if (lastTurnEnd < 0) { - return { committed: [], cutTail: items.length > 0 } - } - const committed = items.slice(0, lastTurnEnd + 1) - committed.forEach((item, i) => { - if (item.seq !== i) { - throw new Error(`corrupt session log: seq gap in committed region at index ${i} (expected ${i}, got ${item.seq})`) +export function scanRows(rows: readonly EventRow[]): { preserved: SessionEvent[]; tornFrom?: number } { + // Pass 1: parse each row's data; a row whose data is not valid JSON is a hole. + // (The seq/type COLUMNS are always present even when `data` is corrupt.) + interface Parsed { ok: boolean; event?: SessionEvent } + const parsed: Parsed[] = rows.map((row) => { + try { + return { ok: true, event: rowToEvent(row) } + } catch { + return { ok: false } } }) - return { committed, cutTail: lastTurnEnd < items.length - 1 } + + // The last index that is a valid `turn/end` — the last fully-committed + // boundary (the loop flushes only at turn/end). + let lastTurnEnd = -1 + for (let i = parsed.length - 1; i >= 0; i--) { + if (parsed[i]?.ok && rows[i]?.type === 'turn/end') { lastTurnEnd = i; break } + } + + // Walk the longest PREFIX of complete, seq-contiguous, parseable rows + // (row i has seq === i). This includes the fully-written rows of an + // interrupted final turn AFTER the last turn/end — real work, never + // truncated. The walk stops at the first hole: + // - at or before the last committed turn/end → committed corruption (throw); + // - after it (or no committed turn/end) → tolerated torn tail (stop). + const preserved: SessionEvent[] = [] + for (let i = 0; i < rows.length; i++) { + const p = parsed[i] + if (!p?.ok || p.event === undefined) { + if (i <= lastTurnEnd) throw new Error(`corrupt session log: unparsable committed event at seq ${rows[i]?.seq}`) + break // torn tail fragment after the last turn/end — stop, tolerate + } + if (p.event.seq !== i) { + if (i <= lastTurnEnd) throw new Error(`corrupt session log: seq gap in committed region (expected ${i}, got ${p.event.seq})`) + break // gap after the last turn/end — torn tail, stop + } + preserved.push(p.event) + } + + // Any rows past the preserved prefix are a never-committed torn tail; their + // first seq is the deletion point for load's physical repair. + return preserved.length < rows.length ? { preserved, tornFrom: preserved.length } : { preserved } } diff --git a/packages/session-persistence-sqlite/tests/sqlite.spec.ts b/packages/session-persistence-sqlite/tests/sqlite.spec.ts index 6ab4dae30b..44d788ab72 100644 --- a/packages/session-persistence-sqlite/tests/sqlite.spec.ts +++ b/packages/session-persistence-sqlite/tests/sqlite.spec.ts @@ -6,7 +6,7 @@ import { join } from 'node:path' import SessionStore, { SessionId } from '@deepseek-ai/dsh-session' import type { Session, SessionEvent, SessionMeta } from '@deepseek-ai/dsh-session' import SessionPersistenceSqlite, { SCHEMA_VERSION } from '@deepseek-ai/dsh-session-persistence-sqlite' -import { cutAtLastTurnEnd, openDatabase } from '../src/schema.ts' +import { openDatabase, scanRows, type EventRow } from '../src/schema.ts' import { runPersistenceContract, meta, oneTurnLog } from '../../session-persistence/tests/contract.ts' const dirs: string[] = [] @@ -38,49 +38,78 @@ runPersistenceContract('sqlite', async () => { } }) -describe('cutAtLastTurnEnd', () => { - it('returns the prefix through the last complete turn/end and flags a cut tail', () => { - const log = oneTurnLog() - const withTail: SessionEvent[] = [ - ...log, +describe('scanRows', () => { + // scanRows works off EventRows (data is a JSON string column); build them from + // SessionEvents so the unit tests read in terms of the event vocabulary. + const rows = (events: SessionEvent[]): EventRow[] => + events.map(e => ({ seq: e.seq, type: e.type, time: e.time, data: JSON.stringify(e.data) })) + + it('preserves the full log when it ends exactly on a turn/end (no torn tail)', () => { + const { preserved, tornFrom } = scanRows(rows(oneTurnLog())) + expect(preserved).toEqual(oneTurnLog()) + expect(tornFrom).toBeUndefined() + }) + + it('PRESERVES the real events of an interrupted turn after the last turn/end', () => { + // turn 1 committed (0..5) + a crashed turn 2 (turn/start 6, step/start 7, no + // close): all 8 rows are intact, so the whole prefix is preserved and there + // is no torn fragment to delete. (load() then synthesizes the closers.) + const withOpenTurn: SessionEvent[] = [ + ...oneTurnLog(), { type: 'turn/start', seq: 6, time: 7, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'user/message', seq: 7, time: 8, data: { content: [{ type: 'text', text: 'q2' }], source: { kind: 'user' } } }, + { type: 'step/start', seq: 7, time: 8, data: { turn: 2, step: 1 } }, ] - const { committed, cutTail } = cutAtLastTurnEnd(withTail) - expect(committed).toEqual(log) - expect(cutTail).toBe(true) + const { preserved, tornFrom } = scanRows(rows(withOpenTurn)) + expect(preserved.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7]) + expect(tornFrom).toBeUndefined() }) - it('treats a log with no turn/end as fully uncommitted', () => { - const partial: SessionEvent[] = [ + it('preserves the contiguous prefix and flags a torn tail at a seq gap', () => { + // A gap after seq 0 (no committed turn/end): seq 0 is the preserved + // interrupted-turn event; the gap bounds it and marks the torn fragment. + const gapped: SessionEvent[] = [ { type: 'turn/start', seq: 0, time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'user/message', seq: 1, time: 2, data: { content: [{ type: 'text', text: 'hi' }], source: { kind: 'user' } } }, + { type: 'step/start', seq: 2, time: 2, data: { turn: 1, step: 1 } }, // seq 1 missing ] - expect(cutAtLastTurnEnd(partial)).toEqual({ committed: [], cutTail: true }) + const { preserved, tornFrom } = scanRows(rows(gapped)) + expect(preserved.map(e => e.seq)).toEqual([0]) + expect(tornFrom).toBe(1) }) - it('reports no cut when the log ends exactly on a turn/end', () => { - const { committed, cutTail } = cutAtLastTurnEnd(oneTurnLog()) - expect(committed).toEqual(oneTurnLog()) - expect(cutTail).toBe(false) + it('an empty log preserves nothing and has no torn tail', () => { + expect(scanRows([])).toEqual({ preserved: [] }) }) - it('an empty log is committed-empty with no tail', () => { - expect(cutAtLastTurnEnd([])).toEqual({ committed: [], cutTail: false }) - }) - - it('throws on a seq gap inside the committed region', () => { + it('throws on a seq gap inside the committed region (before the last turn/end)', () => { const gapped: SessionEvent[] = [ { type: 'turn/start', seq: 0, time: 1, data: { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } } }, { type: 'step/start', seq: 2, time: 2, data: { turn: 1, step: 1 } }, // seq 1 missing { type: 'turn/end', seq: 3, time: 3, data: { turn: 1, reason: { kind: 'completed' } } }, ] - expect(() => cutAtLastTurnEnd(gapped)).toThrow(/seq gap in committed region/) + expect(() => scanRows(rows(gapped))).toThrow(/seq gap in committed region/) + }) + + it('throws on an unparsable row inside the committed region', () => { + const withCorruptCommitted: EventRow[] = [ + { seq: 0, type: 'turn/start', time: 1, data: '{not json' }, // corrupt, sits before a turn/end + { seq: 1, type: 'turn/end', time: 2, data: JSON.stringify({ turn: 1, reason: { kind: 'completed' } }) }, + ] + expect(() => scanRows(withCorruptCommitted)).toThrow(/unparsable committed event/) + }) + + it('tolerates an unparsable torn-tail row after the last turn/end', () => { + const withCorruptTail: EventRow[] = [ + ...rows(oneTurnLog()), + { seq: 6, type: 'turn/start', time: 7, data: '{not json' }, // torn fragment, no committed turn/end after + ] + const { preserved, tornFrom } = scanRows(withCorruptTail) + expect(preserved).toEqual(oneTurnLog()) + expect(tornFrom).toBe(6) }) }) describe('SessionPersistenceSqlite: durability and crash semantics', () => { - it('a crash tail (rows after the last turn/end) is excluded on load and repaired on the next append', async () => { + it('an interrupted turn (rows after the last turn/end) is PRESERVED and closed during load', async () => { const path = await freshDbPath() const m = meta('crash') // Run 1: persist a complete turn, then a half-written second turn (no turn/end). @@ -91,37 +120,44 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { await ctx1.sessionPersistence.append(m.id, oneTurnLog()) await ctx1.sessionPersistence.append(m.id, [ { type: 'turn/start', seq: 6, time: 7, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'user/message', seq: 7, time: 8, data: { content: [{ type: 'text', text: 'q2' }], source: { kind: 'user' } } }, + { type: 'step/start', seq: 7, time: 8, data: { turn: 2, step: 1 } }, ]) await fiber1.dispose() - // Run 2: load returns only the committed first turn (tail excluded). + // Run 2: load PRESERVES the interrupted turn's real events (a turn can be huge + // — never truncated) and closes the orphaned turn with synthetic boundary + // events: step/end (the step was open) then turn/end {interrupted}. const ctx2 = new Context() await ctx2.plugin(SessionStore) const fiber2 = await ctx2.plugin(SessionPersistenceSqlite, { path }) const loaded = await ctx2.sessionPersistence.load(m.id) - expect(loaded.events).toEqual(oneTurnLog()) + expect(loaded.events.map(e => e.type)).toEqual([ + 'turn/start', 'user/message', 'step/start', 'assistant/message', 'step/end', 'turn/end', // turn 1 + 'turn/start', 'step/start', 'step/end', 'turn/end', // turn 2: real events + synthetic closers + ]) + expect(loaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + const last = loaded.events.at(-1)! + expect(last.type === 'turn/end' && last.data.reason).toEqual({ kind: 'interrupted' }) - // The next append continues at seq 6 and performs the deferred truncation- - // repair inside its transaction (DELETE seq >= 6 before inserting), so the - // orphaned tail rows are gone and there is no UNIQUE collision. + // load durably closed the turn, so the next append continues at the balanced + // length (seq 10) and a reload round-trips identically. await ctx2.sessionPersistence.append(m.id, [ - { type: 'turn/start', seq: 6, time: 9, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }, - { type: 'turn/end', seq: 7, time: 10, data: { turn: 2, reason: { kind: 'completed' } } }, + { type: 'turn/start', seq: 10, time: 9, data: { turn: 3, trigger: { kind: 'message', source: { kind: 'user' } } } }, + { type: 'turn/end', seq: 11, time: 10, data: { turn: 3, reason: { kind: 'completed' } } }, ]) const reloaded = await ctx2.sessionPersistence.load(m.id) - expect(reloaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7]) + expect(reloaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) await fiber2.dispose() }) - it('load() is non-mutating: the crash tail rows survive until the next append repairs them', async () => { + it('load() durably closes the interrupted turn: the synthetic closers are on disk after load', async () => { const path = await freshDbPath() - const m = meta('load-nonmutating') + const m = meta('load-closes') const b1 = await backend(path) await b1.ctx.sessionPersistence.create(m) await b1.ctx.sessionPersistence.append(m.id, oneTurnLog()) // seqs 0..5 await b1.dispose() - // Hand-write an uncommitted tail (seq 6, no turn/end). + // Hand-write an interrupted turn (turn/start seq 6, no turn/end). const db = openDatabase(path) db.prepare('INSERT INTO events (session_id, seq, type, time, data) VALUES (?, 6, ?, 7, ?)') .run(m.id, 'turn/start', JSON.stringify({ turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } })) @@ -129,17 +165,20 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { const b2 = await backend(path) const loaded = await b2.ctx.sessionPersistence.load(m.id) - expect(loaded.events).toEqual(oneTurnLog()) - // load() must NOT have deleted the tail row (contract: load returns the - // prefix; the next append repairs). Verify the row is still on disk. + // turn 2's real turn/start (seq 6) is preserved + a synthetic turn/end (seq 7). + expect(loaded.events.map(e => e.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7]) + expect(loaded.events.at(-1)!.type).toBe('turn/end') + // load() is mutating: the synthetic turn/end MUST be on disk so the stored log + // is balanced and the cursor is truthful (contract: load closes, not defers). const probe = openDatabase(path) - const tailRows = probe.prepare('SELECT seq FROM events WHERE session_id = ? AND seq >= 6').all(m.id) + const stored = probe.prepare('SELECT seq, type FROM events WHERE session_id = ? ORDER BY seq').all(m.id) as { seq: number; type: string }[] probe.close() - expect(tailRows).toHaveLength(1) + expect(stored.map(r => r.seq)).toEqual([0, 1, 2, 3, 4, 5, 6, 7]) + expect(stored.at(-1)!.type).toBe('turn/end') await b2.dispose() }) - it('all-tail load: a session materialized by a partial first turn stays present (JSONL parity), load returns zero committed events', async () => { + it('all-tail load: a session whose only turn never closed is preserved and closed on load', async () => { const path = await freshDbPath() const m = meta('all-tail') const b1 = await backend(path) @@ -152,14 +191,13 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { expect(await b1.ctx.sessionPersistence.has(m.id)).toBe(true) // materialized await b1.dispose() - // A fresh backend loads it: the committed prefix is empty (no turn/end), so - // load returns zero events — but the session WAS materialized (its metadata - // row exists), so has()/list() still report it present, matching the JSONL - // backend whose file likewise survives a first append that never reached - // turn/end. The orphaned tail rows are removed by the next append's repair. + // A fresh backend loads it: the interrupted (only) turn's real events are + // preserved and closed with a synthetic turn/end {interrupted} — NOT + // truncated. The session was materialized, so has()/list() report it present. const b2 = await backend(path) const loaded = await b2.ctx.sessionPersistence.load(m.id) - expect(loaded.events).toEqual([]) + expect(loaded.events.map(e => e.type)).toEqual(['turn/start', 'user/message', 'turn/end']) + expect(loaded.events.at(-1)!.type === 'turn/end' && loaded.events.at(-1)!.data).toMatchObject({ reason: { kind: 'interrupted' } }) expect(await b2.ctx.sessionPersistence.has(m.id)).toBe(true) expect((await b2.ctx.sessionPersistence.list()).map(x => x.id)).toContain(m.id) await b2.dispose() @@ -208,10 +246,11 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { await b1.ctx.sessionPersistence.append(m.id, oneTurnLog()) // committed: seqs 0..5 await b1.dispose() - // Hand-insert an uncommitted tail row (seq 6, no closing turn/end) whose - // `data` is invalid JSON. The contract: only a parse error in the COMMITTED - // region is unloadable; a corrupt tail must be discarded (load cuts at the - // last turn/end using seq+type columns, never parsing tail `data`). + // Hand-insert a torn tail row (seq 6, no closing turn/end) whose `data` is + // invalid JSON. The contract: only a parse error in the COMMITTED region is + // unloadable; a torn tail must be discarded. scanRows finds the last + // turn/end on the seq+type columns (never parsing tail `data`), so the + // unparsable row after it bounds the preserved prefix and is deleted by load. const db = openDatabase(path) db.prepare('INSERT INTO events (session_id, seq, type, time, data) VALUES (?, 6, ?, 7, ?)') .run(m.id, 'turn/start', '{not valid json') @@ -219,8 +258,8 @@ describe('SessionPersistenceSqlite: durability and crash semantics', () => { const b2 = await backend(path) const loaded = await b2.ctx.sessionPersistence.load(m.id) - expect(loaded.events).toEqual(oneTurnLog()) // tail discarded, committed intact - // The corrupt tail row was physically deleted, so a fresh append continues. + expect(loaded.events).toEqual(oneTurnLog()) // torn tail discarded, committed intact (turn 1 already balanced → no closers) + // load physically deleted the corrupt tail row, so a fresh append continues. await b2.ctx.sessionPersistence.append(m.id, [ { type: 'turn/start', seq: 6, time: 8, data: { turn: 2, trigger: { kind: 'message', source: { kind: 'user' } } } }, { type: 'turn/end', seq: 7, time: 9, data: { turn: 2, reason: { kind: 'completed' } } },