diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1fdc3ad9..cd0a9a82b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24.13.0 + node-version: 24.21.0 - run: node --test scripts/ci/*.test.mjs - name: Classify changed paths id: classify @@ -65,7 +65,7 @@ jobs: echo "PROTOC_INCLUDE=/usr/include" >> "$GITHUB_ENV" - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with: - toolchain: 1.97.1 + toolchain: 1.99.0 components: rustfmt, clippy - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 - run: cargo fmt --all -- --check @@ -73,7 +73,7 @@ jobs: - run: cargo test --workspace --locked - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24.13.0 + node-version: 24.21.0 - name: Exercise embedded migration ledger env: LIGHTSPEED_TEST_POSTGRES_URL: postgres://lightspeed:lightspeed@127.0.0.1:55432/lightspeed @@ -105,7 +105,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24.13.0 + node-version: 24.21.0 cache: npm cache-dependency-path: package-lock.json - run: npm ci @@ -122,10 +122,10 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24.13.0 + node-version: 24.21.0 cache: npm cache-dependency-path: package-lock.json - - run: npm ci --workspace @lightspeed/docs --include-workspace-root + - run: npm ci --workspace @lightspeed-ai/docs --include-workspace-root - run: npm run check:docs required: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index bad865783..bc2b15ac1 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -20,14 +20,14 @@ jobs: ref: ${{ inputs.ref }} - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with: - toolchain: 1.97.1 + toolchain: 1.99.0 - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 - name: Compile and smoke-test native Apple Silicon executables run: | cargo build --locked \ - -p temporal-server -p environment-provider-incus \ + -p temporal-runtime -p environment-provider-incus \ -p environment-daemon -p cli - target/debug/lightspeed-server --version | grep -F "$(git rev-parse HEAD)" + target/debug/lightspeed-runtime --version | grep -F "$(git rev-parse HEAD)" target/debug/lightspeed-provider-incus --version | grep -F "$(git rev-parse HEAD)" target/debug/lightspeed-envd --version | grep -F "$(git rev-parse HEAD)" target/debug/lightspeed --version | grep -F "$(git rev-parse HEAD)" diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index bb11a183a..5641490c9 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -74,11 +74,11 @@ jobs: echo "PROTOC_INCLUDE=${{ steps.protoc.outputs.path }}/include" >> "$GITHUB_ENV" - uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 with: - toolchain: 1.97.1 + toolchain: 1.99.0 - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24.13.0 + node-version: 24.21.0 cache: npm cache-dependency-path: package-lock.json - name: Test the exact tagged source @@ -182,14 +182,14 @@ jobs: run: | set -euo pipefail declare -A files=( - [server]="$(find dist/archives -name '*-server-*' -print -quit)" + [runtime]="$(find dist/archives -name '*-runtime-*' -print -quit)" [provider-incus]="$(find dist/archives -name '*-provider-incus-*' -print -quit)" [envd]="$(find dist/archives -name '*-envd-*' -print -quit)" [cli]="$(find dist/archives -name '*-cli-*' -print -quit)" [demo]="$(find dist/archives -name '*-demo-*' -print -quit)" [docs]="$(find dist/archives -name '*-docs-*' -print -quit)" ) - for name in server provider-incus envd cli demo docs; do + for name in runtime provider-incus envd cli demo docs; do test -n "${files[$name]}" ref="$GHCR_ROOT/${name}-bundle:$STAGING_TAG" oras push "$ref" "${files[$name]}:application/gzip" @@ -207,7 +207,7 @@ jobs: LIGHTSPEED_PLATFORM_IMAGE: ghcr.io/${{ github.repository }}/platform@${{ steps.platform.outputs.digest }} LIGHTSPEED_PLATFORM_WORKERS_IMAGE: ghcr.io/${{ github.repository }}/platform-workers@${{ steps.platform_workers.outputs.digest }} LIGHTSPEED_RELEASE_BUILD_IMAGE: ghcr.io/${{ github.repository }}/build-env@${{ steps.build_environment.outputs.digest }} - LIGHTSPEED_BINARY_URL_SERVER: ${{ steps.archives.outputs.SERVER_URL }} + LIGHTSPEED_BINARY_URL_RUNTIME: ${{ steps.archives.outputs.RUNTIME_URL }} LIGHTSPEED_BINARY_URL_PROVIDER_INCUS: ${{ steps.archives.outputs.PROVIDER_INCUS_URL }} LIGHTSPEED_BINARY_URL_ENVD: ${{ steps.archives.outputs.ENVD_URL }} LIGHTSPEED_BINARY_URL_CLI: ${{ steps.archives.outputs.CLI_URL }} @@ -245,8 +245,8 @@ jobs: container_id="$(docker create "$RUNTIME_IMAGE" --version)" trap 'docker rm -f "$container_id" >/dev/null 2>&1 || true' EXIT mkdir image-check - docker cp "$container_id:/usr/local/bin/lightspeed-server" image-check/lightspeed-server - cmp dist/bin/lightspeed-server image-check/lightspeed-server + docker cp "$container_id:/usr/local/bin/lightspeed-runtime" image-check/lightspeed-runtime + cmp dist/bin/lightspeed-runtime image-check/lightspeed-runtime docker run --rm "$RUNTIME_IMAGE" --version | grep -F "$EXPECTED_SHA" scripts/release/smoke-images.sh - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 @@ -289,7 +289,7 @@ jobs: - uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24.13.0 + node-version: 24.21.0 registry-url: https://registry.npmjs.org - name: Retrieve and verify this build's bundle by digest run: | @@ -325,7 +325,7 @@ jobs: const digest = crypto.createHash("sha512").update(fs.readFileSync(process.argv[1])).digest("base64"); process.stdout.write(`sha512-${digest}`); ' "$package_file")" - if published_integrity="$(npm view "@lightspeed-ai/agent-client@$VERSION" dist.integrity 2>/dev/null)"; then + if published_integrity="$(npm view "@lightspeed-ai/sdk@$VERSION" dist.integrity 2>/dev/null)"; then test "$published_integrity" = "$expected_integrity" || { echo "npm version $VERSION already exists with different bytes" >&2 exit 1 @@ -333,7 +333,7 @@ jobs: else npm publish "$package_file" --access public --tag latest fi - npm dist-tag add "@lightspeed-ai/agent-client@$VERSION" latest + npm dist-tag add "@lightspeed-ai/sdk@$VERSION" latest - name: Create GitHub Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/snapshot-main.yml b/.github/workflows/snapshot-main.yml index 84b2eac2e..fb25162a6 100644 --- a/.github/workflows/snapshot-main.yml +++ b/.github/workflows/snapshot-main.yml @@ -64,7 +64,7 @@ jobs: toolchain: ${{ steps.identity.outputs.rust_version }} - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24.13.0 + node-version: 24.21.0 - name: Fetch locked dependencies for offline metadata verification run: cargo fetch --locked - name: Verify release metadata @@ -156,14 +156,14 @@ jobs: run: | set -euo pipefail declare -A files=( - [server]="$(find dist/archives -name '*-server-*' -print -quit)" + [runtime]="$(find dist/archives -name '*-runtime-*' -print -quit)" [provider-incus]="$(find dist/archives -name '*-provider-incus-*' -print -quit)" [envd]="$(find dist/archives -name '*-envd-*' -print -quit)" [cli]="$(find dist/archives -name '*-cli-*' -print -quit)" [demo]="$(find dist/archives -name '*-demo-*' -print -quit)" [docs]="$(find dist/archives -name '*-docs-*' -print -quit)" ) - for name in server provider-incus envd cli demo docs; do + for name in runtime provider-incus envd cli demo docs; do test -n "${files[$name]}" ref="$GHCR_ROOT/${name}-bundle:$STAGING_TAG" oras push "$ref" "${files[$name]}:application/gzip" @@ -181,7 +181,7 @@ jobs: LIGHTSPEED_PLATFORM_IMAGE: ghcr.io/${{ github.repository }}/platform@${{ steps.platform.outputs.digest }} LIGHTSPEED_PLATFORM_WORKERS_IMAGE: ghcr.io/${{ github.repository }}/platform-workers@${{ steps.platform_workers.outputs.digest }} LIGHTSPEED_RELEASE_BUILD_IMAGE: ghcr.io/${{ github.repository }}/build-env@${{ steps.build_environment.outputs.digest }} - LIGHTSPEED_BINARY_URL_SERVER: ${{ steps.archives.outputs.SERVER_URL }} + LIGHTSPEED_BINARY_URL_RUNTIME: ${{ steps.archives.outputs.RUNTIME_URL }} LIGHTSPEED_BINARY_URL_PROVIDER_INCUS: ${{ steps.archives.outputs.PROVIDER_INCUS_URL }} LIGHTSPEED_BINARY_URL_ENVD: ${{ steps.archives.outputs.ENVD_URL }} LIGHTSPEED_BINARY_URL_CLI: ${{ steps.archives.outputs.CLI_URL }} @@ -218,8 +218,8 @@ jobs: container_id="$(docker create "$RUNTIME_IMAGE" --version)" trap 'docker rm -f "$container_id" >/dev/null 2>&1 || true' EXIT mkdir image-check - docker cp "$container_id:/usr/local/bin/lightspeed-server" image-check/lightspeed-server - cmp dist/bin/lightspeed-server image-check/lightspeed-server + docker cp "$container_id:/usr/local/bin/lightspeed-runtime" image-check/lightspeed-runtime + cmp dist/bin/lightspeed-runtime image-check/lightspeed-runtime docker run --rm "$RUNTIME_IMAGE" --version | grep -F "$EXPECTED_SHA" scripts/release/smoke-images.sh - name: Confirm this is still the current main commit diff --git a/AGENTS.md b/AGENTS.md index dc38d96c8..71195b510 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,13 +26,13 @@ change (see Maintenance for sign-off). ## Architecture Boundaries -- `crates/engine` is deterministic and event-sourced. It must not perform +- `crates/harness` is deterministic and event-sourced. It must not perform network, provider, shell, filesystem, database, or workflow I/O. It emits intents that effectful adapters execute. - Keep provider request and response structures native to each provider. The - engine may retain only the provider-neutral facts needed for deterministic + harness may retain only the provider-neutral facts needed for deterministic branching; wire materialization and transport configuration belong outside - the engine and outside durable session state. + the harness and outside durable session state. - Public clients depend on `crates/api`, never reducer internals. Keep public wire documentation on the Rust manifest and DTOs so generated consumers stay aligned. @@ -40,7 +40,7 @@ change (see Maintenance for sign-off). packages. Domain crates such as `bots`, `channels`, and `environments` define records, validation, and policy without taking on infrastructure I/O. - The Incus environment provider depends only on the environment protocol - boundary. It must not depend on Lightspeed stores, API internals, the engine, + boundary. It must not depend on Lightspeed stores, API internals, the harness, or Temporal runtime. - The hosted runtime remains one binary with selectable roles. Cross-subsystem work uses workflow starts and signals, not activities dispatched onto another @@ -90,7 +90,7 @@ environment and always serialize them, including filtered runs: ```bash source scripts/dev/env.sh -cargo test -p temporal-server --test [test_name] -- --ignored --test-threads=1 +cargo test -p temporal-runtime --test [test_name] -- --ignored --test-threads=1 ``` Avoid running `runs_live_slow`: it waits out production activity budgets and @@ -118,7 +118,7 @@ Use `./dev.sh` as the supported local entry point; profiles and lifecycle commands are in `docs/documentation/development/local-development.md`. The Rust server never migrates PostgreSQL implicitly. Before manual startup -against a new or upgraded database, run `cargo run -p temporal-server -- migrate`. +against a new or upgraded database, run `cargo run -p temporal-runtime -- migrate`. When adding, removing, or renumbering Rust schema migrations, keep `crates/store-pg`'s `REQUIRED_SCHEMA_REVISION` and @@ -128,6 +128,10 @@ release boundary with `scripts/release/verify-metadata.sh`. ## Maintenance - Keep changes focused and preserve unrelated work in a dirty worktree. +- Preserve concise Cargo dependency ranges such as `"1"` and `"0.1"`; + `Cargo.lock` records the exact tested versions. Change manifest ranges for + breaking upgrades or when a required API or fix needs a higher minimum, + rather than expanding every range to the latest full version. - Edit the root `README.md` only with explicit user permission. General requests to update documentation do not authorize changes to that file. - Never cite letter-P numeric roadmap identifiers in source comments, symbols, @@ -141,6 +145,6 @@ release boundary with `scripts/release/verify-metadata.sh`. change. - Record implementation progress in an active roadmap document, but do not promote completed roadmap detail into this file. -- Add or update tests for behavioral changes. For deterministic engine changes, +- Add or update tests for behavioral changes. For deterministic harness changes, include replay coverage or vectors where appropriate. - When asked for repository line counts, use `cloc $(git ls-files)`. diff --git a/Cargo.lock b/Cargo.lock index b5535d6c2..3281a4774 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,37 +10,37 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ - "crypto-common", - "generic-array", + "crypto-common 0.2.2", + "inout", ] [[package]] name = "aes" -version = "0.8.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +checksum = "35f0f96ce78e38c3dc6d8948aa8163d06385be74000f3c7a95bf1eef35d3ea32" dependencies = [ - "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpubits", + "cpufeatures 0.3.1", ] [[package]] name = "aes-gcm" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +checksum = "7f2b8006a0c83f52b62ba44a97b58bf76fe2f70a329e588f67f89691d93d498f" dependencies = [ "aead", "aes", "cipher", "ctr", + "ctutils", "ghash", - "subtle", ] [[package]] @@ -59,9 +59,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -74,18 +74,18 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -98,15 +98,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -138,7 +138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "093d520274bfff7278d776f7ea12981a0a0a6f96db90964658e0f38fc6e9a6a6" dependencies = [ "better_any", - "bit-set", + "bit-set 0.8.0", "byteorder", "lazy_static", "murmur3", @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "api" @@ -163,7 +163,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", "uuid", ] @@ -173,22 +173,31 @@ name = "api-projection" version = "0.1.0" dependencies = [ "api", - "engine", "futures-util", + "harness", "llm-clients", "serde_json", "tokio", ] +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -200,6 +209,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +dependencies = [ + "bytemuck", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -212,19 +230,19 @@ version = "0.1.0" dependencies = [ "api", "async-trait", - "base64 0.22.1", - "engine", + "base64 0.23.1", "futures-util", + "harness", "hex", "jsonwebtoken", "oauth2", - "rand 0.8.6", - "reqwest 0.13.4", + "rand 0.10.3", + "reqwest", "rmcp", "serde", "serde_json", - "sha2", - "thiserror 1.0.69", + "sha2 0.11.0", + "thiserror 2.0.21", "tokio", "uuid", ] @@ -237,19 +255,20 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" dependencies = [ "aws-lc-sys", + "untrusted 0.7.1", "zeroize", ] [[package]] name = "aws-lc-sys" -version = "0.44.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" dependencies = [ "cc", "cmake", @@ -260,14 +279,14 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.9" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ - "async-trait", - "axum-core 0.4.5", + "axum-core", "base64 0.22.1", "bytes", + "form_urlencoded", "futures-util", "http", "http-body", @@ -275,69 +294,22 @@ dependencies = [ "hyper", "hyper-util", "itoa", - "matchit 0.7.3", + "matchit", "memchr", "mime", "percent-encoding", "pin-project-lite", - "rustversion", - "serde", + "serde_core", "serde_json", "serde_path_to_error", "serde_urlencoded", - "sha1", + "sha1 0.10.7", "sync_wrapper", "tokio", - "tokio-tungstenite 0.24.0", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "axum" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" -dependencies = [ - "axum-core 0.5.6", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "itoa", - "matchit 0.8.4", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "serde_core", - "sync_wrapper", + "tokio-tungstenite 0.29.0", "tower", "tower-layer", "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper", - "tower-layer", - "tower-service", "tracing", ] @@ -357,17 +329,16 @@ dependencies = [ "sync_wrapper", "tower-layer", "tower-service", + "tracing", ] [[package]] -name = "backoff" -version = "0.4.0" +name = "backon" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" dependencies = [ - "getrandom 0.2.17", - "instant", - "rand 0.8.6", + "fastrand", ] [[package]] @@ -382,27 +353,36 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - [[package]] name = "better_any" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4372b9543397a4b86050cc5e7ee36953edf4bac9518e8a774c2da694977fb6e4" +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec 0.6.3", +] + [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec", + "bit-vec 0.8.0", ] +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bit-vec" version = "0.8.0" @@ -417,9 +397,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" dependencies = [ "serde_core", ] @@ -433,29 +413,36 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bon" -version = "3.9.1" +version = "3.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47dbe92550676ee653353c310dfb9cf6ba17ee70396e1f7cf0a2020ad49b2fe" +checksum = "214f5df094ce551a10a30ffb9c70243d61f121a3d985a6495933e181dee6a7d2" dependencies = [ "bon-macros", - "rustversion", ] [[package]] name = "bon-macros" -version = "3.9.1" +version = "3.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519bd3116aeeb42d5372c29d982d16d0170d3d4a5ed85fc7dd91642ffff3c67c" +checksum = "2706da6c749998cc555d04184909608956a69ad3f8ab1a076fbc867b4a3c3ce5" dependencies = [ "darling", "ident_case", - "prettyplease", + "prettyplease 0.3.0", "proc-macro2", "quote", - "rustversion", - "syn", + "syn 3.0.6", ] [[package]] @@ -479,18 +466,18 @@ dependencies = [ "schemars", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "subtle", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", "uuid", ] [[package]] name = "bstr" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7dc094d718f2e1c1559ad110e27eeaae14a5465d3d56dd6dbd793079fbd530" +checksum = "6bb31b46c14244e20ee9984b11bf5c992b91fb6939fea616e3512c8baecdbe5f" dependencies = [ "memchr", "regex-automata", @@ -499,9 +486,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "by_address" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytecount" @@ -529,15 +522,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - -[[package]] -name = "cassowary" -version = "0.3.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "castaway" @@ -550,9 +537,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.55" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +checksum = "f74872d07caf508b30a21f6836e7d7016a2eaf7d9ff4f48deaa58cd8a0407630" dependencies = [ "find-msvc-tools", "jobserver", @@ -562,9 +549,9 @@ dependencies = [ [[package]] name = "cel" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f93082a93da8fd78394852602ced1e2e7754ed8c29dc813fa80b01a1baf9032" +checksum = "2ae7daebcd4d032c9a5288790c2facde6fab3f9a9ff8d5028765e8b48a36eeb2" dependencies = [ "antlr4rust", "chrono", @@ -573,14 +560,14 @@ dependencies = [ "pastey", "regex", "serde", - "thiserror 2.0.18", + "thiserror 2.0.21", ] [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "cfg_aliases" @@ -590,18 +577,18 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", + "cpufeatures 0.3.1", "rand_core 0.10.1", ] @@ -617,17 +604,17 @@ dependencies = [ "schemars", "serde", "serde_json", - "sha2", - "thiserror 1.0.69", + "sha2 0.11.0", + "thiserror 2.0.21", "tokio", "uuid", ] [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -649,19 +636,20 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "crypto-common", + "block-buffer 0.12.1", + "crypto-common 0.2.2", "inout", ] [[package]] name = "clap" -version = "4.5.57" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" dependencies = [ "clap_builder", "clap_derive", @@ -669,9 +657,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.57" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" dependencies = [ "anstream", "anstyle", @@ -681,21 +669,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "clap_lex" -version = "0.7.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" [[package]] name = "cli" @@ -704,21 +692,21 @@ dependencies = [ "anyhow", "api", "async-trait", - "base64 0.22.1", + "base64 0.23.1", "clap", "crossterm", "dotenvy", - "engine", "futures-util", - "pulldown-cmark 0.10.3", + "harness", + "pulldown-cmark", "ratatui", "release-info", - "reqwest 0.13.4", + "reqwest", "serde", "serde_json", "tempfile", "tokio", - "unicode-width 0.2.0", + "unicode-width", "uuid", "vfs", ] @@ -732,6 +720,12 @@ dependencies = [ "cc", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "color_quant" version = "1.1.0" @@ -740,9 +734,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "combine" @@ -756,9 +750,9 @@ dependencies = [ [[package]] name = "compact_str" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab" dependencies = [ "castaway", "cfg-if", @@ -768,20 +762,11 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "convert_case" @@ -808,6 +793,18 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core_detect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" + +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -819,9 +816,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] @@ -841,15 +838,31 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" +[[package]] +name = "crc-fast" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75b2483e97a5a7da73ac68a05b629f9c53cff58d8ed1c77866079e18b00dba5" +dependencies = [ + "digest 0.10.7", + "spin 0.10.1", +] + [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "cron" version = "0.17.0" @@ -864,18 +877,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -883,40 +896,42 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.12" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crossterm" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", "crossterm_winapi", + "derive_more", + "document-features", "futures-core", "mio", "parking_lot", - "rustix 0.38.44", + "rustix", "signal-hook", "signal-hook-mio", "winapi", @@ -933,35 +948,65 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "getrandom 0.4.3", + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "csscolorparser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf" +dependencies = [ + "lab", + "phf 0.11.3", +] + [[package]] name = "ctr" -version = "0.9.2" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21" dependencies = [ "cipher", ] +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures 0.3.1", "curve25519-dalek-derive", - "digest", + "digest 0.11.3", "fiat-crypto", + "rand_core 0.10.1", "rustc_version", "subtle", "zeroize", @@ -975,14 +1020,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "darling" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec" dependencies = [ "darling_core", "darling_macro", @@ -990,53 +1035,45 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff" dependencies = [ "ident_case", "proc-macro2", "quote", "strsim", - "syn", + "syn 3.0.6", ] [[package]] name = "darling_macro" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" dependencies = [ "darling_core", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "data-encoding" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" [[package]] -name = "der" -version = "0.7.10" +name = "deltae" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] +checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" [[package]] name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", -] [[package]] name = "derive_more" @@ -1057,7 +1094,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 2.0.119", "unicode-xid", ] @@ -1067,10 +1104,20 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", + "crypto-common 0.1.6", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", "const-oid", - "crypto-common", - "subtle", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -1096,13 +1143,22 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", ] [[package]] @@ -1137,34 +1193,33 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ - "pkcs8", - "signature", + "signature 3.0.0", ] [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", - "rand_core 0.6.4", - "serde", - "sha2", + "rand_core 0.10.1", + "sha2 0.11.0", + "signature 3.0.0", "subtle", "zeroize", ] [[package]] name = "either" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" dependencies = [ "serde", ] @@ -1180,11 +1235,16 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.35" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +checksum = "8e985e0451871ad22fb8d2b6b076e2028a502a0d3950998c2c5c0a4f9b5d9679" dependencies = [ "cfg-if", + "core_detect", + "multiversion_no_op", + "rustversion", + "scopeguard", + "simdutf8", ] [[package]] @@ -1196,21 +1256,6 @@ dependencies = [ "encoding_rs", ] -[[package]] -name = "engine" -version = "0.1.0" -dependencies = [ - "async-trait", - "hex", - "schemars", - "serde", - "serde_json", - "sha2", - "thiserror 1.0.69", - "tokio", - "uuid", -] - [[package]] name = "enum-iterator" version = "2.3.0" @@ -1228,7 +1273,7 @@ checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1240,7 +1285,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1252,9 +1297,9 @@ dependencies = [ "futures-util", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", - "tokio-tungstenite 0.26.2", + "tokio-tungstenite 0.30.0", ] [[package]] @@ -1267,7 +1312,6 @@ dependencies = [ "clap", "dotenvy", "ed25519-dalek", - "engine", "environment-client", "environment-protocol", "flate2", @@ -1275,37 +1319,39 @@ dependencies = [ "glob", "grep-regex", "grep-searcher", + "harness", + "hex", "ignore", "libc", "portable-pty", - "rand 0.8.6", + "rand 0.10.3", "release-info", - "reqwest 0.13.4", - "rustix 1.1.3", + "reqwest", + "rustix", "rustls", "rustls-pki-types", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "store-fs", "tar", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", - "tokio-tungstenite 0.26.2", + "tokio-tungstenite 0.30.0", "tools", "vfs", - "webpki-roots 1.0.6", + "webpki-roots 1.0.9", ] [[package]] name = "environment-protocol" version = "0.1.0" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.21", ] [[package]] @@ -1314,20 +1360,20 @@ version = "0.3.0" dependencies = [ "anyhow", "async-trait", - "axum 0.7.9", + "axum", "clap", "dotenvy", "environment-protocol", "futures-util", "release-info", - "reqwest 0.13.4", + "reqwest", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", - "tokio-tungstenite 0.26.2", + "tokio-tungstenite 0.30.0", "uuid", ] @@ -1337,12 +1383,12 @@ version = "0.1.0" dependencies = [ "async-trait", "auth", - "engine", "environment-protocol", + "harness", "serde", "serde_json", - "sha2", - "thiserror 1.0.69", + "sha2 0.11.0", + "thiserror 2.0.21", "tokio", "uuid", ] @@ -1376,13 +1422,21 @@ dependencies = [ [[package]] name = "etcetera" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" dependencies = [ "cfg-if", - "home", - "windows-sys 0.48.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "euclid" +version = "0.22.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" +dependencies = [ + "num-traits", ] [[package]] @@ -1395,7 +1449,7 @@ dependencies = [ "async-trait", "clap", "dotenvy", - "engine", + "harness", "llm-clients", "llm-runtime", "serde", @@ -1408,31 +1462,40 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.4.1" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" dependencies = [ - "concurrent-queue", "parking", "pin-project-lite", ] [[package]] name = "fancy-regex" -version = "0.16.2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set 0.5.3", + "regex", +] + +[[package]] +name = "fancy-regex" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f" +checksum = "d301f5bf187b3c295fce6468d3875037a0bccc5f6b151c63cac2f85babf21912" dependencies = [ - "bit-set", + "bit-set 0.8.0", "regex-automata", "regex-syntax", ] [[package]] name = "fastrand" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "fdeflate" @@ -1445,9 +1508,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "filedescriptor" @@ -1472,9 +1535,21 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" + +[[package]] +name = "finl_unicode" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "80bb028c8b4148c9ee0cca68fcd9add6044e81d3619f48577ddf13a263d047a2" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "fixedbitset" @@ -1495,9 +1570,9 @@ dependencies = [ [[package]] name = "fluent-uri" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1918b65d96df47d3591bed19c5cca17e3fa5d0707318e4b5ef2eae01764df7e5" +checksum = "bc74ac4d8359ae70623506d512209619e5cf8f347124910440dbc221714b328e" dependencies = [ "borrow-or-share", "ref-cast", @@ -1506,13 +1581,13 @@ dependencies = [ [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ "futures-core", "futures-sink", - "spin", + "spin 0.9.9", ] [[package]] @@ -1544,12 +1619,12 @@ dependencies = [ [[package]] name = "fraction" -version = "0.15.4" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076045bb43dac435333ed5f04caf35c7463631d0dae2deb2638d94dd0a5b872" +checksum = "e246562084dde8ebbcc943b261c406ce4f68e5032ec28029a251a47d6a295500" dependencies = [ - "lazy_static", "num", + "num-bigint", ] [[package]] @@ -1569,9 +1644,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -1584,9 +1659,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -1594,15 +1669,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -1622,19 +1697,19 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -1650,21 +1725,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -1674,15 +1749,14 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1694,7 +1768,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "rustix 1.1.3", + "rustix", "windows-link", ] @@ -1704,7 +1778,7 @@ version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ - "unicode-width 0.2.0", + "unicode-width", ] [[package]] @@ -1736,25 +1810,24 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", + "wasm-bindgen", ] [[package]] name = "ghash" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" dependencies = [ - "opaque-debug", "polyval", ] @@ -1770,15 +1843,15 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "globset" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47d37d2ae4464254884b60ab7071be2b876a9c35b696bd018ddcc76847309cd" +checksum = "07c34a9410465b45bd9787443bc7370f37735bad04b0f0cd57ff1a3186c98988" dependencies = [ "aho-corasick", "bstr", @@ -1826,9 +1899,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" dependencies = [ "atomic-waker", "bytes", @@ -1843,14 +1916,27 @@ dependencies = [ "tracing", ] +[[package]] +name = "harness" +version = "0.1.0" +dependencies = [ + "async-trait", + "hex", + "schemars", + "serde", + "serde_json", + "sha2 0.11.0", + "thiserror 2.0.21", + "tokio", + "uuid", +] + [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "allocator-api2", - "equivalent", "foldhash 0.1.5", ] @@ -1870,14 +1956,19 @@ name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "hashlink" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.1", ] [[package]] @@ -1894,36 +1985,27 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.12" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "windows-sys 0.61.2", + "digest 0.11.3", ] [[package]] name = "http" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -1931,9 +2013,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -1941,9 +2023,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -1966,15 +2048,24 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.3.0" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" + +[[package]] +name = "hybrid-array" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "typenum", +] [[package]] name = "hyper" -version = "1.8.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" dependencies = [ "atomic-waker", "bytes", @@ -1987,7 +2078,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -1995,16 +2085,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53" dependencies = [ "http", "hyper", "hyper-util", "rustls", - "rustls-native-certs", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", @@ -2025,16 +2113,17 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "bytes", "futures-channel", "futures-util", "http", "http-body", + "httparse", "hyper", "ipnet", "libc", @@ -2072,12 +2161,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -2085,9 +2175,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -2098,9 +2188,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -2112,16 +2202,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -2132,15 +2223,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -2176,9 +2267,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -2186,9 +2277,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b17771570a2b94107741a7b033f19132c2eee21d59d21b24d2ced26500bd66e" +checksum = "00b69833ed729dc5aa7d19541d96d6cf8e9137194207a04916d658e43168402f" dependencies = [ "crossbeam-deque", "globset", @@ -2230,9 +2321,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown 0.17.1", @@ -2251,33 +2342,24 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] name = "instability" -version = "0.3.12" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971" +checksum = "4c3b5acc1e2fd9375041a388da33d1eb8aed5f7a8c0dd3543e3ea2805adfbe20" dependencies = [ "darling", "indoc", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", + "syn 3.0.6", ] [[package]] @@ -2291,19 +2373,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" +version = "2.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" -dependencies = [ - "memchr", - "serde", -] +checksum = "791930b43c0d5973160d90a8f3894509f2b273430f5c5c73b668636d0287c5c0" [[package]] name = "is_terminal_polyfill" @@ -2313,27 +2385,27 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jni" @@ -2347,7 +2419,7 @@ dependencies = [ "jni-sys", "log", "simd_cesu8", - "thiserror 2.0.18", + "thiserror 2.0.21", "walkdir", "windows-link", ] @@ -2362,7 +2434,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn", + "syn 2.0.119", ] [[package]] @@ -2381,7 +2453,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2390,70 +2462,115 @@ version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "7883d941dae510fb2d978fc3fe018c71c9e2892fd38854de3e8b92c2e5ad9cc5" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] [[package]] name = "jsonschema" -version = "0.33.0" +version = "0.58.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d46662859bc5f60a145b75f4632fbadc84e829e45df6c5de74cfc8e05acb96b5" +checksum = "ea18b8d5e1469b1bdd6b349169305141316a7c26da27f239773b65c830c0f5d6" dependencies = [ "ahash", - "base64 0.22.1", "bytecount", + "data-encoding", "email_address", - "fancy-regex", + "fancy-regex 0.19.2", "fraction", - "idna", + "getrandom 0.3.4", "itoa", + "jsonschema-regex", + "jsonschema-value", "num-cmp", "num-traits", - "once_cell", "percent-encoding", "referencing", "regex", - "regex-syntax", "serde", "serde_json", + "strum", + "unicode-general-category", "uuid-simd", ] +[[package]] +name = "jsonschema-regex" +version = "0.58.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e9e22c420535035e95eed240cbfb4a5f4b7da74d122d63144e0c31926dbfd" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "jsonschema-value" +version = "0.58.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3bfac11ac357ec620880025757d38c67da8fd5b9ef5024d19f0f360002b4ca" +dependencies = [ + "ahash", + "bytecount", + "fraction", + "getrandom 0.3.4", + "num-cmp", + "num-traits", + "serde_json", + "zmij", +] + [[package]] name = "jsonwebtoken" -version = "9.3.1" +version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "e75fe14a82d81e5f5af639997db37d8b96045938a7ac6ab18cdbe1c7467e05e1" dependencies = [ + "aws-lc-rs", "base64 0.22.1", + "getrandom 0.2.17", "js-sys", "pem", - "ring", "serde", "serde_json", + "signature 2.2.0", "simple_asn1", + "zeroize", ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "kasuari" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899" dependencies = [ - "spin", + "hashbrown 0.16.1", + "portable-atomic", + "thiserror 2.0.21", ] +[[package]] +name = "lab" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f" + +[[package]] +name = "lazy_static" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" + [[package]] name = "leb128fmt" version = "0.1.0" @@ -2462,9 +2579,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.180" +version = "0.2.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" [[package]] name = "libm" @@ -2474,56 +2591,62 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" dependencies = [ - "bitflags 2.10.0", "libc", - "plain", - "redox_syscall 0.7.5", ] [[package]] name = "libsqlite3-sys" -version = "0.30.1" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +checksum = "b1f111c8c41e7c61a49cd34e44c7619462967221a6443b0ec299e0ac30cfb9b1" dependencies = [ "pkg-config", "vcpkg", ] [[package]] -name = "linux-raw-sys" -version = "0.4.15" +name = "line-clipping" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "e752191d037c44ad111a8caa762921926658402f01cc1253f7bef2020ece4f5e" +dependencies = [ + "bitflags 2.13.2", +] [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "llm-clients" version = "0.1.0" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "bytes", "futures-util", "httpdate", - "reqwest 0.13.4", + "reqwest", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", ] @@ -2533,14 +2656,14 @@ version = "0.1.0" dependencies = [ "api-projection", "async-trait", - "base64 0.22.1", - "engine", + "base64 0.23.1", + "harness", "image", "llm-clients", "serde", "serde_json", "test-support", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", "tools", "tracing", @@ -2558,33 +2681,34 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "lru" -version = "0.12.5" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.17.1", ] [[package]] -name = "lru" -version = "0.16.4" +name = "lru-slab" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" -dependencies = [ - "hashbrown 0.16.1", -] +checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" [[package]] -name = "lru-slab" -version = "0.1.2" +name = "mac_address" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +checksum = "b367b50a9be9a5d3b5718c1da74e5d6b9c17647f89752ee2562a470cc3c4eb1a" +dependencies = [ + "nix 0.30.1", + "windows-sys 0.61.2", +] [[package]] name = "matchers" @@ -2595,12 +2719,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - [[package]] name = "matchit" version = "0.8.4" @@ -2613,29 +2731,29 @@ version = "0.1.0" dependencies = [ "async-trait", "auth", - "engine", + "harness", "serde", "serde_json", "strsim", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", ] [[package]] name = "md-5" -version = "0.10.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" dependencies = [ "cfg-if", - "digest", + "digest 0.11.3", ] [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "memmap2" @@ -2646,6 +2764,27 @@ dependencies = [ "libc", ] +[[package]] +name = "memmem" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "micromap" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a86d3146ed3995b5913c414f6664344b9617457320782e64f0bb44afd49d74" + [[package]] name = "mime" version = "0.3.17" @@ -2690,9 +2829,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" dependencies = [ "libc", "log", @@ -2723,14 +2862,14 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "moka" -version = "0.12.15" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046" +checksum = "4293f18e7567a1caf3c584855554377025c65e0aa445344d04171f5ad63d19b9" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -2759,6 +2898,12 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" +[[package]] +name = "multiversion_no_op" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d" + [[package]] name = "murmur3" version = "0.4.1" @@ -2774,27 +2919,64 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", "cfg-if", "cfg_aliases 0.1.1", "libc", ] [[package]] -name = "nom" -version = "7.1.3" +name = "nix" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "memchr", - "minimal-lexical", + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases 0.2.2", + "libc", ] [[package]] -name = "ntapi" -version = "0.4.3" +name = "nix" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases 0.2.2", + "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases 0.2.2", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" dependencies = [ "winapi", ] @@ -2824,28 +3006,12 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-bigint-dig" -version = "0.8.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ - "lazy_static", - "libm", "num-integer", - "num-iter", "num-traits", - "rand 0.8.6", - "smallvec", - "zeroize", ] [[package]] @@ -2869,22 +3035,32 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2907,7 +3083,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", ] [[package]] @@ -2920,11 +3104,11 @@ dependencies = [ "chrono", "getrandom 0.2.17", "http", - "rand 0.8.6", + "rand 0.8.8", "serde", "serde_json", "serde_path_to_error", - "sha2", + "sha2 0.10.9", "thiserror 1.0.69", "url", ] @@ -2935,7 +3119,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", ] [[package]] @@ -2950,14 +3134,16 @@ dependencies = [ [[package]] name = "object_store" -version = "0.13.2" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622acbc9100d3c10e2ee15804b0caa40e55c933d5aa53814cd520805b7958a49" +checksum = "f1796bc93603f78c5760a69f2d58badc9618d22adade0a95385bb2adbae4eb94" dependencies = [ "async-trait", - "base64 0.22.1", + "aws-lc-rs", + "base64 0.23.1", "bytes", "chrono", + "crc-fast", "form_urlencoded", "futures-channel", "futures-core", @@ -2966,31 +3152,33 @@ dependencies = [ "http-body-util", "humantime", "hyper", - "itertools 0.14.0", + "itertools 0.15.0", "md-5", + "nix 0.31.3", "parking_lot", "percent-encoding", "quick-xml", - "rand 0.10.1", - "reqwest 0.12.28", - "ring", + "rand 0.10.3", + "reqwest", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "thiserror 2.0.18", + "thiserror 2.0.21", "tokio", "tracing", "url", "walkdir", "wasm-bindgen-futures", "web-time", + "windows-sys 0.61.2", ] [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -2998,12 +3186,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl-probe" version = "0.2.1" @@ -3016,12 +3198,54 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + [[package]] name = "outref" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" +[[package]] +name = "palette" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddeed8580d347d2abf3dcf06a5f0b3dc020258338526b277847cd4248a70fc64" +dependencies = [ + "approx", + "libm", + "palette_derive", + "palette_math", +] + +[[package]] +name = "palette_derive" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88537020289b719d81be994ccf1bbf4990f477e2f69ee52fe3e45f43a02e56be" +dependencies = [ + "by_address", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "palette_math" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e6eb142958d64335fb0e345c5b9ead2ecd6fc438c307e9d7d3c4fd428dbaf12" +dependencies = [ + "libm", +] + [[package]] name = "parking" version = "2.2.1" @@ -3046,17 +3270,11 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pastey" version = "0.2.3" @@ -3096,19 +3314,52 @@ dependencies = [ ] [[package]] -name = "pem-rfc7468" -version = "0.7.0" +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pest" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d3aca230fad2e6f6317ca0a72724338c4960cb97168a85cdee66df4a9a21a8" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "284b60557f2c4a2e72ad3f2d34d42685a2fa4a6a61d0d2a10c0ae2a5e916c2cf" dependencies = [ - "base64ct", + "pest", + "pest_generator", ] [[package]] -name = "percent-encoding" -version = "2.3.2" +name = "pest_generator" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "1d9d1f08a115309ee99268cf85e5228e0e56aa9caf8841ec12866b6be07c3109" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pest_meta" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed93ba1a9ffcca32130a5188701c81c0c49cf00d4b7c5007d5148951d743adcb" +dependencies = [ + "pest", +] [[package]] name = "petgraph" @@ -3116,7 +3367,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ - "fixedbitset", + "fixedbitset 0.5.7", "hashbrown 0.15.5", "indexmap", ] @@ -3140,6 +3391,16 @@ dependencies = [ "phf_shared 0.12.1", ] +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared 0.11.3", +] + [[package]] name = "phf_generator" version = "0.11.3" @@ -3147,7 +3408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared 0.11.3", - "rand 0.8.6", + "rand 0.8.8", ] [[package]] @@ -3160,7 +3421,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -3207,53 +3468,20 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "png" @@ -3261,7 +3489,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", "crc32fast", "fdeflate", "flate2", @@ -3270,27 +3498,26 @@ dependencies = [ [[package]] name = "polyval" -version = "0.6.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +checksum = "f0fa31d631f2b2cb2a544d0aa321ce847a94764d701ca2becc411138b93d49cd" dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "opaque-debug", + "cpubits", + "cpufeatures 0.3.1", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -3308,7 +3535,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix", + "nix 0.28.0", "serial2", "shared_library", "shell-words", @@ -3318,9 +3545,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -3373,14 +3600,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.119", +] + +[[package]] +name = "prettyplease" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0" +dependencies = [ + "proc-macro2", + "syn 3.0.6", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -3393,7 +3630,7 @@ dependencies = [ "async-trait", "environment-protocol", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.21", ] [[package]] @@ -3407,14 +3644,14 @@ dependencies = [ "lazy_static", "memchr", "parking_lot", - "thiserror 2.0.18", + "thiserror 2.0.21", ] [[package]] name = "prost" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ "bytes", "prost-derive", @@ -3422,52 +3659,52 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ "heck", "itertools 0.14.0", "log", "multimap", "petgraph", - "prettyplease", + "prettyplease 0.2.37", "prost", "prost-types", - "pulldown-cmark 0.13.4", + "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn", + "syn 2.0.119", "tempfile", ] [[package]] name = "prost-derive" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", "itertools 0.14.0", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "prost-types" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" dependencies = [ "prost", ] [[package]] name = "prost-wkt" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3de5e9c9e84fcb5efa204b8e283d23e615a8bc8c777bf1d6622bb01dc61445" +checksum = "4bf89e78de037257a7be0177e894311c31bf7f0a02b752e74f402a5b324cc0fc" dependencies = [ "chrono", "inventory", @@ -3480,9 +3717,9 @@ dependencies = [ [[package]] name = "prost-wkt-build" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe500dc80e757a75e1e8fb7290e448d62dfba3105ece1d058579cb00b58151cd" +checksum = "cb5cd191fad9142d096efc97c64715db73db4adb60c38ebdf22f5b54cd6ea712" dependencies = [ "heck", "prost", @@ -3493,9 +3730,9 @@ dependencies = [ [[package]] name = "prost-wkt-types" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13807eaa7e15833d06e899008371926201cdcd11d74b6d490f49130cdb3f415e" +checksum = "9c46d9cbfee659aaabc63e8ab7d88e4814c2ad6eacdc09b404244ce3c7fbcdfc" dependencies = [ "chrono", "prost", @@ -3509,43 +3746,32 @@ dependencies = [ "serde_json", ] -[[package]] -name = "pulldown-cmark" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" -dependencies = [ - "bitflags 2.10.0", - "getopts", - "memchr", - "pulldown-cmark-escape", - "unicase", -] - [[package]] name = "pulldown-cmark" version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", + "getopts", "memchr", + "pulldown-cmark-escape", "unicase", ] [[package]] name = "pulldown-cmark-escape" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" [[package]] name = "pulldown-cmark-to-cmark" -version = "22.0.0" +version = "22.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" +checksum = "84bbb29c624230c4bd1047bbdb2aa47e41c860e9665ce62ba9504eebe91bf867" dependencies = [ - "pulldown-cmark 0.13.4", + "pulldown-cmark", ] [[package]] @@ -3562,9 +3788,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.39.2" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" dependencies = [ "memchr", "serde", @@ -3572,19 +3798,19 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "4051e23e9185c255a7e33ef59cdbca87a22d359052eecd22fc6b901fb37d9d11" dependencies = [ "bytes", - "cfg_aliases 0.2.1", + "cfg_aliases 0.2.2", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", "rustls", "socket2", - "thiserror 2.0.18", + "thiserror 2.0.21", "tokio", "tracing", "web-time", @@ -3592,21 +3818,22 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.13" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +checksum = "0e750cca55fe4f0439a15d0bb529da9651e79993e8e72c61a899a36d462befbe" dependencies = [ "aws-lc-rs", "bytes", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", - "rand 0.9.2", + "rand 0.10.3", + "rand_pcg", "ring", "rustc-hash", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror 2.0.21", "tinyvec", "tracing", "web-time", @@ -3614,23 +3841,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "af66907df18639dcf4db56ca65490cabc4b27a97dbadd96f2926cca73298f016" dependencies = [ - "cfg_aliases 0.2.1", + "cfg_aliases 0.2.2", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -3649,9 +3876,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -3660,9 +3887,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -3670,12 +3897,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af" dependencies = [ "chacha20", - "getrandom 0.4.2", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -3723,85 +3950,167 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "ratatui" -version = "0.29.0" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +checksum = "3274ba0a2c5e1bcad2a2005d20f4dc59dad26b2eb0940fb094500dba4099d57d" dependencies = [ - "bitflags 2.10.0", - "cassowary", - "compact_str", - "crossterm", - "indoc", "instability", - "itertools 0.13.0", - "lru 0.12.5", - "paste", + "ratatui-core", + "ratatui-crossterm", + "ratatui-macros", + "ratatui-termina", + "ratatui-termwiz", + "ratatui-widgets", + "serde", +] + +[[package]] +name = "ratatui-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbb175c433c8e28a809d1f5773a2ae96e68c0ce40db865cbab1020bf33ae479c" +dependencies = [ + "bitflags 2.13.2", + "compact_str", + "critical-section", + "hashbrown 0.17.1", + "itertools 0.14.0", + "kasuari", + "lru", + "palette", + "serde", "strum", + "thiserror 2.0.21", "unicode-segmentation", "unicode-truncate", - "unicode-width 0.2.0", + "unicode-width", ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "ratatui-crossterm" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "567584a3b0e6a8203c23de40b4861497266725eb5363dbfd18a1edd603cca9f0" +dependencies = [ + "cfg-if", + "crossterm", + "instability", + "ratatui-core", +] + +[[package]] +name = "ratatui-macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7dc68daa7498a43e4d68e0eb078427e10c38fbcfbb1e42d955f1fa2140d814" +dependencies = [ + "ratatui-core", + "ratatui-widgets", +] + +[[package]] +name = "ratatui-termina" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0bf912d9e66f057a759d92e386a280ea886b352ab757d6ac4d653c7ed2c43c2" +dependencies = [ + "instability", + "ratatui-core", + "termina", +] + +[[package]] +name = "ratatui-termwiz" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf03e0380b7744054d6cb74224fe3adf062a029754933f575ca1e3b4c2ce977" +dependencies = [ + "ratatui-core", + "termwiz", +] + +[[package]] +name = "ratatui-widgets" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66e3d19bcc9130ca376277d93b60767ff121ace3be06f5f95f81dd68956407d1" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", + "hashbrown 0.17.1", + "indoc", + "instability", + "itertools 0.14.0", + "line-clipping", + "ratatui-core", + "serde", + "strum", + "time", + "unicode-segmentation", + "unicode-width", ] [[package]] name = "redox_syscall" -version = "0.7.5" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", ] [[package]] name = "redox_users" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" dependencies = [ - "getrandom 0.2.17", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.21", ] [[package]] name = "ref-cast" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "referencing" -version = "0.33.0" +version = "0.58.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9c261f7ce75418b3beadfb3f0eb1299fe8eb9640deba45ffa2cb783098697d" +checksum = "590efadb0a669f1712c1e3ab810a55d4c3d20d0127c455f7236dd0710aba0346" dependencies = [ "ahash", "fluent-uri", - "once_cell", + "getrandom 0.3.4", + "hashbrown 0.17.1", + "itoa", + "micromap", "parking_lot", "percent-encoding", "serde_json", @@ -3809,9 +4118,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -3821,9 +4130,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -3832,66 +4141,28 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "release-info" version = "0.3.0" - -[[package]] -name = "reqwest" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams 0.4.2", - "web-sys", + "tempfile", ] [[package]] name = "reqwest" -version = "0.13.4" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +checksum = "16a1cfa75cc186dd73d5818e510e042e40927bccc9c236b061cea97e1eb08029" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "bytes", "futures-core", "futures-util", + "h2", "http", "http-body", "http-body-util", @@ -3920,7 +4191,7 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams 0.5.0", + "wasm-streams", "web-sys", ] @@ -3934,15 +4205,15 @@ dependencies = [ "cfg-if", "getrandom 0.2.17", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] [[package]] name = "ringbuf" -version = "0.4.8" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c" +checksum = "0b123165531e325df9079f56c036f2da4103a5d5abfef9e2fda4b9c34d1ef7aa" dependencies = [ "crossbeam-utils", "portable-atomic", @@ -3951,9 +4222,9 @@ dependencies = [ [[package]] name = "rmcp" -version = "3.1.4" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a15bc53261a9dc37e105df006e4656c598379a8f9581f8950debb130f27a7cf" +checksum = "fae7019994ae0fe4ada40b732f798f3ff26f0f04facb1477f1bf37eb4f18a2d3" dependencies = [ "async-trait", "base64 0.23.1", @@ -3964,43 +4235,23 @@ dependencies = [ "indexmap", "oauth2", "pin-project-lite", - "reqwest 0.13.4", + "reqwest", "serde", - "serde_json", - "sse-stream", - "thiserror 2.0.18", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", - "url", -] - -[[package]] -name = "rsa" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", + "serde_json", + "sse-stream", + "thiserror 2.0.21", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", + "url", ] [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -4013,35 +4264,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustix" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", "errno", "libc", - "linux-raw-sys 0.11.0", + "linux-raw-sys", "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" dependencies = [ "aws-lc-rs", "log", @@ -4055,9 +4293,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -4067,9 +4305,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "web-time", "zeroize", @@ -4077,9 +4315,9 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +checksum = "1167586491e2b18b8bfbb293e8180ec17c201c4f076d7cb3070ca964e7598f98" dependencies = [ "core-foundation", "core-foundation-sys", @@ -4098,27 +4336,27 @@ dependencies = [ [[package]] name = "rustls-platform-verifier-android" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +checksum = "eec689c0bc40ff2458a5977b6619cb718087084a18e02a131c599b62d05e1a5f" [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" @@ -4146,9 +4384,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" dependencies = [ "dyn-clone", "ref-cast", @@ -4160,14 +4398,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" +checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 3.0.6", ] [[package]] @@ -4178,11 +4416,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", "core-foundation", "core-foundation-sys", "libc", @@ -4207,9 +4445,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -4217,40 +4455,40 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "serde_derive_internals" -version = "0.29.1" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -4317,13 +4555,24 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", ] [[package]] @@ -4340,7 +4589,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", ] [[package]] @@ -4370,9 +4630,9 @@ checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook" @@ -4411,10 +4671,18 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "simd-adler32" version = "0.3.10" @@ -4445,15 +4713,15 @@ checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.18", + "thiserror 2.0.21", "time", ] [[package]] name = "siphasher" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" +checksum = "33f4fe9184a62d842c9ef383018f3306d8ba224fd9d836f56d7288308847c256" [[package]] name = "slab" @@ -4472,47 +4740,43 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.1" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" dependencies = [ "serde", ] [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] -name = "spki" -version = "0.7.3" +name = "spin" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] +checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" [[package]] name = "sqlx" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +checksum = "378620ccc25c62c89d8be1c819e76a88d59bdcc3304733330788948e619bfd71" dependencies = [ "sqlx-core", "sqlx-macros", @@ -4523,12 +4787,13 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +checksum = "05b44e85bf579a8eeb4ceaa77a3a523baf2bf0e9bac7e40f405d537b5d2d5ccb" dependencies = [ "base64 0.22.1", "bytes", + "cfg-if", "crc", "crossbeam-queue", "either", @@ -4537,18 +4802,17 @@ dependencies = [ "futures-intrusive", "futures-io", "futures-util", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "hashlink", "indexmap", "log", "memchr", - "once_cell", "percent-encoding", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.21", "tokio", "tokio-stream", "tracing", @@ -4558,94 +4822,78 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +checksum = "bd2b84f2bc39a5705ef27ec785a11c934a41bbd4a24941e257927cddc26b60bf" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn", + "syn 2.0.119", ] [[package]] name = "sqlx-macros-core" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +checksum = "fb8d96de5fdc85a5c4ec813432b523ec637e80ba98f046555f75f7908ddac7c3" dependencies = [ + "cfg-if", "dotenvy", "either", "heck", "hex", - "once_cell", "proc-macro2", "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn", + "syn 2.0.119", "tokio", "url", ] [[package]] name = "sqlx-mysql" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +checksum = "90b8020fe17c5f2c245bfa2505d7ef59c5604839527c740266ad2214acebea27" dependencies = [ - "atoi", - "base64 0.22.1", - "bitflags 2.10.0", + "bitflags 2.13.2", "byteorder", "bytes", "crc", - "digest", + "digest 0.11.3", "dotenvy", "either", - "futures-channel", "futures-core", - "futures-io", "futures-util", "generic-array", - "hex", - "hkdf", - "hmac", - "itoa", "log", - "md-5", - "memchr", - "once_cell", "percent-encoding", - "rand 0.8.6", - "rsa", "serde", - "sha1", - "sha2", - "smallvec", + "sha1 0.11.0", + "sha2 0.11.0", "sqlx-core", - "stringprep", - "thiserror 2.0.18", + "thiserror 2.0.21", "tracing", "uuid", - "whoami", ] [[package]] name = "sqlx-postgres" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +checksum = "87a2bdd6e83f6b3ea525ca9fee568030508b58355a43d0b2c1674d5f79dcd65e" dependencies = [ "atoi", "base64 0.22.1", - "bitflags 2.10.0", + "bitflags 2.13.2", "byteorder", "crc", "dotenvy", @@ -4656,20 +4904,18 @@ dependencies = [ "hex", "hkdf", "hmac", - "home", "itoa", "log", "md-5", "memchr", - "once_cell", - "rand 0.8.6", + "rand 0.10.3", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.18", + "thiserror 2.0.21", "tracing", "uuid", "whoami", @@ -4677,12 +4923,13 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +checksum = "488e99c397a62007e4229aec669a179816339afc6d2620ca6fa420dbee2e982c" dependencies = [ "atoi", "flume", + "form_urlencoded", "futures-channel", "futures-core", "futures-executor", @@ -4692,9 +4939,8 @@ dependencies = [ "log", "percent-encoding", "serde", - "serde_urlencoded", "sqlx-core", - "thiserror 2.0.18", + "thiserror 2.0.21", "tracing", "url", "uuid", @@ -4702,9 +4948,9 @@ dependencies = [ [[package]] name = "sse-stream" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c123f296ade4ec4b8b0f6162116e6629f5146922ca5ab40ca9d3c2e73ab4761e" +checksum = "c25ac7aff0abd1dbc474536e40416e1102c7dd9bfba0b9861c6d357f835dcfb4" dependencies = [ "bytes", "futures-util", @@ -4730,10 +4976,11 @@ name = "store-fs" version = "0.1.0" dependencies = [ "async-trait", - "engine", + "harness", + "hex", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "tempfile", "tokio", "vfs", @@ -4747,23 +4994,24 @@ dependencies = [ "api", "async-trait", "auth", - "base64 0.22.1", + "base64 0.23.1", "bots", "channels", - "engine", "environment-protocol", "environments", "futures-util", + "harness", + "hex", "mcp", "moka", "object_store", "profiles", - "rand 0.8.6", + "rand 0.10.3", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "sqlx", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", "tracing", "uuid", @@ -4789,24 +5037,23 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.26.4" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" dependencies = [ "heck", "proc-macro2", "quote", - "rustversion", - "syn", + "syn 2.0.119", ] [[package]] @@ -4817,9 +5064,31 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.114" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -4837,13 +5106,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -4878,19 +5147,19 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", - "rustix 1.1.3", + "rustix", "windows-sys 0.61.2", ] [[package]] -name = "temporal-server" +name = "temporal-runtime" version = "0.3.0" dependencies = [ "anyhow", @@ -4898,21 +5167,21 @@ dependencies = [ "api-projection", "async-trait", "auth", - "axum 0.7.9", - "base64 0.22.1", + "axum", + "base64 0.23.1", "bots", "channels", "chrono", "clap", "dotenvy", "ed25519-dalek", - "engine", "environment-client", "environment-daemon", "environment-protocol", "environments", "futures", "futures-util", + "harness", "http", "ipnet", "jsonschema", @@ -4921,13 +5190,13 @@ dependencies = [ "mcp", "object_store", "profiles", - "rand 0.8.6", + "rand 0.10.3", "release-info", - "reqwest 0.13.4", + "reqwest", "rmcp", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "sqlx", "sse-stream", "store-pg", @@ -4937,11 +5206,11 @@ dependencies = [ "temporalio-common", "temporalio-macros", "temporalio-sdk", - "temporalio-sdk-core", + "temporalio-workflow", "test-support", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", - "tokio-tungstenite 0.26.2", + "tokio-tungstenite 0.30.0", "tonic", "tools", "tracing", @@ -4960,35 +5229,36 @@ dependencies = [ "bots", "channels", "chrono", - "engine", "environment-protocol", "futures", "futures-util", + "harness", "hex", "jsonschema", "schemars", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "temporalio-client", "temporalio-common", "temporalio-macros", "temporalio-sdk", - "temporalio-sdk-core", + "temporalio-workflow", "tracing", + "url", "uuid", ] [[package]] name = "temporalio-client" -version = "0.4.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "798a49d1838935272b1f3a53c9ccc8ec65465be1a21f0e65c62d44cac765b1bc" +checksum = "37ca0a58c70ef0339e70ce03c273c5279f563266b48508fd883715bbd2a51396" dependencies = [ "anyhow", "async-trait", - "backoff", - "base64 0.22.1", + "backon", + "base64 0.23.1", "bon", "bytes", "derive_more", @@ -5000,10 +5270,12 @@ dependencies = [ "hyper", "hyper-util", "parking_lot", - "rand 0.10.1", + "rand 0.10.3", + "serde_json", "temporalio-common", - "thiserror 2.0.18", + "thiserror 2.0.21", "tokio", + "tokio-rustls", "tonic", "tower", "tracing", @@ -5013,13 +5285,12 @@ dependencies = [ [[package]] name = "temporalio-common" -version = "0.4.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad25c89ff8b626835e3dc1339b21387c7383c484ae585b67d34ceea074f1d65" +checksum = "5a8ed18abe448ad30def8136a2a04ca70a6e17ec234540c72f54da2cc9deadc7" dependencies = [ "anyhow", "async-trait", - "base64 0.22.1", "bon", "crc32fast", "derive_more", @@ -5031,22 +5302,18 @@ dependencies = [ "hyper", "hyper-util", "parking_lot", - "pbjson", - "pbjson-build", "prometheus", "prost", "prost-types", - "prost-wkt", - "prost-wkt-types", "ringbuf", "serde", "serde_json", - "thiserror 2.0.18", + "temporalio-common-wasm", + "temporalio-protos", + "thiserror 2.0.21", "tokio", "toml", "tonic", - "tonic-prost", - "tonic-prost-build", "tracing", "tracing-core", "tracing-subscriber", @@ -5054,22 +5321,71 @@ dependencies = [ "uuid", ] +[[package]] +name = "temporalio-common-wasm" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de457a7799583535a50d146fe6ae716932dad60818843b9b56c33b742b4451a8" +dependencies = [ + "anyhow", + "async-trait", + "bon", + "chrono", + "crc32fast", + "derive_more", + "erased-serde", + "futures", + "parking_lot", + "prost", + "prost-wkt-types", + "serde", + "serde_json", + "temporalio-protos", + "thiserror 2.0.21", + "tracing", + "tracing-core", + "tracing-subscriber", + "url", +] + [[package]] name = "temporalio-macros" -version = "0.4.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "657ca3d6e92c8ec1309af92042b691b6367fa25043a5ec59ee365da2fb8ae620" +checksum = "acdf4ae71d667c43439431128c6235986ee378224f491ca5b90f1a0b094d5821" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", +] + +[[package]] +name = "temporalio-protos" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf10c082ba2adf4073da05eb538146fce35734deb61f99d397ac3bd526c345d" +dependencies = [ + "anyhow", + "base64 0.23.1", + "derive_more", + "http", + "pbjson", + "pbjson-build", + "prost", + "prost-wkt-types", + "serde", + "serde_json", + "thiserror 2.0.21", + "tonic", + "tonic-prost", + "tonic-prost-build", ] [[package]] name = "temporalio-sdk" -version = "0.4.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6046cddb8288747e307a836516218fe5426bcaa704145fbabcd5db35fdd13560" +checksum = "6417808ea862d45f2b14c6aaa73aca8e240ac96371ef55fa199a2e092f67d88a" dependencies = [ "anyhow", "async-trait", @@ -5078,13 +5394,15 @@ dependencies = [ "futures-util", "gethostname", "parking_lot", + "prost", "prost-wkt-types", "serde", "temporalio-client", "temporalio-common", "temporalio-macros", "temporalio-sdk-core", - "thiserror 2.0.18", + "temporalio-workflow", + "thiserror 2.0.21", "tokio", "tokio-stream", "tokio-util", @@ -5094,13 +5412,13 @@ dependencies = [ [[package]] name = "temporalio-sdk-core" -version = "0.4.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e0eb803a4554e4a45fb4e9469e719536798c9f55807efde7824f679d6f8d96e" +checksum = "5785769756f53e970bfe0ae5ebac87a4781d6e4b4323e2b3cc358a9dd971e6fd" dependencies = [ "anyhow", "async-trait", - "backoff", + "backon", "bon", "crossbeam-channel", "crossbeam-utils", @@ -5111,14 +5429,14 @@ dependencies = [ "futures-util", "gethostname", "itertools 0.14.0", - "lru 0.16.4", + "lru", "mockall", "parking_lot", "pid", "pin-project", "prost", "prost-wkt-types", - "rand 0.10.1", + "rand 0.10.3", "serde", "serde_json", "siphasher", @@ -5127,7 +5445,7 @@ dependencies = [ "temporalio-client", "temporalio-common", "temporalio-macros", - "thiserror 2.0.18", + "thiserror 2.0.21", "tokio", "tokio-stream", "tokio-util", @@ -5137,21 +5455,121 @@ dependencies = [ "uuid", ] +[[package]] +name = "temporalio-workflow" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70b41ffbb9ae564fec8b218147b59cab1a890f2dcd3e0225d21a714c58f9ee66" +dependencies = [ + "anyhow", + "bon", + "derive_more", + "futures-channel", + "futures-util", + "prost", + "prost-wkt-types", + "rand 0.10.3", + "rand_pcg", + "serde", + "siphasher", + "temporalio-common-wasm", + "temporalio-macros", + "thiserror 2.0.21", + "uuid", + "wit-bindgen", +] + +[[package]] +name = "termina" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9048a889effe34a5cddee0af7f53285198b16dca3be510858d38dfdb3e62a04e" +dependencies = [ + "bitflags 2.13.2", + "parking_lot", + "rustix", + "signal-hook", + "windows-sys 0.61.2", +] + +[[package]] +name = "terminfo" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662" +dependencies = [ + "fnv", + "nom", + "phf 0.11.3", + "phf_codegen", +] + +[[package]] +name = "termios" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b" +dependencies = [ + "libc", +] + [[package]] name = "termtree" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +[[package]] +name = "termwiz" +version = "0.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7" +dependencies = [ + "anyhow", + "base64 0.22.1", + "bitflags 2.13.2", + "fancy-regex 0.11.0", + "filedescriptor", + "finl_unicode", + "fixedbitset 0.4.2", + "hex", + "lazy_static", + "libc", + "log", + "memmem", + "nix 0.29.0", + "num-derive", + "num-traits", + "ordered-float", + "pest", + "pest_derive", + "phf 0.11.3", + "sha2 0.10.9", + "signal-hook", + "siphasher", + "terminfo", + "termios", + "thiserror 1.0.69", + "ucd-trie", + "unicode-segmentation", + "vtparse", + "wezterm-bidi", + "wezterm-blob-leases", + "wezterm-color-types", + "wezterm-dynamic", + "wezterm-input-types", + "winapi", +] + [[package]] name = "test-support" version = "0.1.0" dependencies = [ "async-trait", - "engine", + "harness", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", "tools", "vfs", @@ -5168,11 +5586,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.21", ] [[package]] @@ -5183,38 +5601,39 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] [[package]] name = "time" -version = "0.3.47" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", - "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde_core", "time-core", @@ -5223,15 +5642,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -5239,9 +5658,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -5249,24 +5668,15 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" [[package]] name = "tokio" -version = "1.49.0" +version = "1.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "e95f91fcc7a621e8b030f6aa23c71fe9838ae2fb4d8118b75602a328f5144044" dependencies = [ "bytes", "libc", @@ -5281,20 +5691,20 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "tokio-rustls" -version = "0.26.4" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "c9cc2678c2cdd569ef8215e2afd7954ada2ae20b4fdd2c5fe6139a3b02d105db" dependencies = [ "rustls", "tokio", @@ -5302,9 +5712,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -5313,21 +5723,21 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.24.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.24.0", + "tungstenite 0.29.0", ] [[package]] name = "tokio-tungstenite" -version = "0.26.2" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" +checksum = "17a073bfed563fa236697a068031408a93cd9522e08abf9933ead3e73411bd71" dependencies = [ "futures-util", "log", @@ -5335,28 +5745,29 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls", - "tungstenite 0.26.2", + "tungstenite 0.30.0", "webpki-roots 0.26.11", ] [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "920602543f0911ab71da12c50d59701da54c196d1a2bf5cb4b75667f137a406a" dependencies = [ "indexmap", "serde_core", @@ -5364,7 +5775,7 @@ dependencies = [ "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] @@ -5378,18 +5789,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tonic" @@ -5398,9 +5809,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", - "axum 0.8.9", + "axum", "base64 0.22.1", "bytes", + "flate2", "h2", "http", "http-body", @@ -5428,10 +5840,10 @@ version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" dependencies = [ - "prettyplease", + "prettyplease 0.2.37", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -5451,12 +5863,12 @@ version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27" dependencies = [ - "prettyplease", + "prettyplease 0.2.37", "proc-macro2", "prost-build", "prost-types", "quote", - "syn", + "syn 2.0.119", "tempfile", "tonic-build", ] @@ -5467,19 +5879,19 @@ version = "0.1.0" dependencies = [ "api", "async-trait", - "engine", "environment-client", "environment-protocol", "futures-util", "glob", + "harness", "jsonschema", "regex", - "reqwest 0.13.4", + "reqwest", "serde", "serde_json", "serde_yaml", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", "uuid", "vfs", @@ -5506,20 +5918,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.2", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -5554,7 +5966,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -5618,39 +6030,36 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" dependencies = [ - "byteorder", "bytes", "data-encoding", "http", "httparse", "log", - "rand 0.8.6", - "sha1", - "thiserror 1.0.69", - "utf-8", + "rand 0.9.5", + "sha1 0.10.7", + "thiserror 2.0.21", ] [[package]] name = "tungstenite" -version = "0.26.2" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" +checksum = "e48ac77174b19c110a50ab2128b24215ac9cb40e0e12e093fb602d175c569d22" dependencies = [ "bytes", "data-encoding", "http", "httparse", "log", - "rand 0.9.2", + "rand 0.10.3", "rustls", "rustls-pki-types", - "sha1", - "thiserror 2.0.18", - "utf-8", + "sha1 0.11.0", + "thiserror 2.0.21", ] [[package]] @@ -5667,15 +6076,15 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "typetag" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a897b12c6c1151ad0b138b8db50252dc301f93bc3b027db05eec82aeed298c" +checksum = "c90e86058a30d42a1a928dfb4b49bb33c98c3a2b4909492e6b0881cd94798ec2" dependencies = [ "erased-serde", "inventory", @@ -5686,15 +6095,21 @@ dependencies = [ [[package]] name = "typetag-impl" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf808357c6ed7e13ba0f3277ec8d8f21b2d501274895104263985330c726c1c5" +checksum = "f153acc4e99a5f2a5aefa09fb078be54e26271b2813f6041200b224c098d8328" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "unicase" version = "2.9.0" @@ -5707,11 +6122,17 @@ version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" +[[package]] +name = "unicode-general-category" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" + [[package]] name = "unicode-ident" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "unicode-normalization" @@ -5730,32 +6151,26 @@ checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-truncate" -version = "1.1.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5" dependencies = [ - "itertools 0.13.0", + "itertools 0.14.0", "unicode-segmentation", - "unicode-width 0.1.14", + "unicode-width", ] [[package]] name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -5765,12 +6180,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ - "crypto-common", - "subtle", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -5779,6 +6194,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -5798,12 +6219,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -5818,11 +6233,12 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "97277d36b9c3ace13e58fa6e753f8b0bbbf302a18dd193240d70f9e29681059a" dependencies = [ - "getrandom 0.4.2", + "atomic", + "getrandom 0.4.3", "js-sys", "serde_core", "sha1_smol", @@ -5836,7 +6252,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" dependencies = [ "outref", - "uuid", "vsimd", ] @@ -5863,10 +6278,10 @@ name = "vfs" version = "0.1.0" dependencies = [ "async-trait", - "engine", + "harness", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.21", "tokio", ] @@ -5876,6 +6291,15 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" +[[package]] +name = "vtparse" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0" +dependencies = [ + "utf8parse", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -5903,33 +6327,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ "wit-bindgen", ] -[[package]] -name = "wasite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" - [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "9bb54f33acc68fd454578d9820b0bde1a1a3d17aa17bb7b6595806d02886d409" dependencies = [ "cfg-if", "once_cell", @@ -5940,23 +6349,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", + "tokio", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "2e29d0c35b16e224a7eeb5cd2d25e3e1968fbd65604117b44d3b789d00ee8535" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5964,31 +6370,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "6f501a8bc3719dba86ef8ae4728879c08001bea749eb1333ac5b91e040e2a6b7" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 3.0.6", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "23f0c9c52aa7cd7d77769a4cfe2a9adb1b331f489a41d912ce14513d5ab995c6" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-encoder" -version = "0.244.0" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +checksum = "30b6733b8b91d010a6ac5b0fb237dc46a19650bc4c67db66857e2e787d437204" dependencies = [ "leb128fmt", "wasmparser", @@ -5996,9 +6402,9 @@ dependencies = [ [[package]] name = "wasm-metadata" -version = "0.244.0" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +checksum = "665fe59e56cc9b419ca6fcca56673e3421d1a5011e3b65caf6b726fd9e041d10" dependencies = [ "anyhow", "indexmap", @@ -6006,19 +6412,6 @@ dependencies = [ "wasmparser", ] -[[package]] -name = "wasm-streams" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wasm-streams" version = "0.5.0" @@ -6034,21 +6427,21 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.244.0" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ - "bitflags 2.10.0", - "hashbrown 0.15.5", + "bitflags 2.13.2", + "hashbrown 0.17.1", "indexmap", "semver", ] [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" dependencies = [ "js-sys", "wasm-bindgen", @@ -6079,14 +6472,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.6", + "webpki-roots 1.0.9", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" dependencies = [ "rustls-pki-types", ] @@ -6098,15 +6491,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] -name = "whoami" -version = "1.6.1" +name = "wezterm-bidi" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec" dependencies = [ - "libredox", - "wasite", + "log", + "wezterm-dynamic", +] + +[[package]] +name = "wezterm-blob-leases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7" +dependencies = [ + "getrandom 0.3.4", + "mac_address", + "sha2 0.10.9", + "thiserror 1.0.69", + "uuid", +] + +[[package]] +name = "wezterm-color-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296" +dependencies = [ + "csscolorparser", + "deltae", + "lazy_static", + "wezterm-dynamic", +] + +[[package]] +name = "wezterm-dynamic" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac" +dependencies = [ + "log", + "ordered-float", + "strsim", + "thiserror 1.0.69", + "wezterm-dynamic-derive", +] + +[[package]] +name = "wezterm-dynamic-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c0cf2d539c645b448eaffec9ec494b8b19bd5077d9e58cb1ae7efece8d575b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wezterm-input-types" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e" +dependencies = [ + "bitflags 1.3.2", + "euclid", + "lazy_static", + "serde", + "wezterm-dynamic", ] +[[package]] +name = "whoami" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626c4bac6755d76ffc12cb01b2eac751db1996b9e0041de9aa02c8c211ddc82c" + [[package]] name = "winapi" version = "0.3.9" @@ -6191,7 +6652,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -6202,7 +6663,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -6239,31 +6700,13 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -6275,52 +6718,20 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -6332,144 +6743,54 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" version = "0.7.15" @@ -6481,9 +6802,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "winreg" @@ -6496,18 +6817,19 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" dependencies = [ + "bitflags 2.13.2", "wit-bindgen-rust-macro", ] [[package]] name = "wit-bindgen-core" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +checksum = "02dee27a2dc20d1008016c742ec9fc6ea498492994ba3750be7454cbc97ff04c" dependencies = [ "anyhow", "heck", @@ -6516,15 +6838,15 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +checksum = "b5007dae772945b7a5003d69d90a3a4a78929d41f19d004e980c4259a6af4484" dependencies = [ "anyhow", "heck", "indexmap", - "prettyplease", - "syn", + "prettyplease 0.2.37", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -6532,27 +6854,27 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +checksum = "af9237d678e3513ad24e96fe98beacdc0db6405284ba2a2400418cf0d42caa89" dependencies = [ "anyhow", - "prettyplease", + "prettyplease 0.2.37", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] [[package]] name = "wit-component" -version = "0.244.0" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" dependencies = [ "anyhow", - "bitflags 2.10.0", + "bitflags 2.13.2", "indexmap", "log", "serde", @@ -6566,11 +6888,12 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.244.0" +version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc" dependencies = [ "anyhow", + "hashbrown 0.17.1", "id-arena", "indexmap", "log", @@ -6584,15 +6907,15 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -6601,68 +6924,82 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "6df92bf3d9227be3d53173901ddbffac2babc27ae50f397776ffd6dc33f800cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "ac4f328cf2f05d084e496c3e9c3f33ed0a183656a16e1fcec4d464d8373aec82" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -6671,9 +7008,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -6682,26 +7019,26 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "zlib-rs" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" [[package]] name = "zmij" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zune-core" diff --git a/Cargo.toml b/Cargo.toml index 7d275eae5..e0be82444 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,13 +11,13 @@ members = [ "crates/bots", "crates/channels", "crates/environments", - "crates/engine", + "crates/harness", "crates/mcp", "crates/profiles", "crates/vfs", "crates/api-projection", "crates/temporal-workflow", - "crates/temporal-server", + "crates/temporal-runtime", "crates/test-support", "crates/llm-runtime", "crates/tools", diff --git a/clients/typescript/README.md b/clients/typescript/README.md index 578264c6e..0ad5ae723 100644 --- a/clients/typescript/README.md +++ b/clients/typescript/README.md @@ -1,6 +1,6 @@ -# Lightspeed TypeScript Client +# Lightspeed TypeScript SDK -Generated TypeScript client for the Lightspeed JSON-RPC gateway. +TypeScript SDK for Lightspeed, with a typed JSON-RPC client and workflow helpers. The public API types and typed method map are generated from the committed contract artifacts in `crates/api/contract/`. The hand-written code is limited to the @@ -14,17 +14,17 @@ Durable receivers and custom workers are covered in ## Install -Tagged Lightspeed releases publish `@lightspeed-ai/agent-client` to npm. In-tree +Tagged Lightspeed releases publish `@lightspeed-ai/sdk` to npm. In-tree consumers use the repository workspace directly. ```bash -npm install @lightspeed-ai/agent-client +npm install @lightspeed-ai/sdk ``` ## Use ```ts -import { LightspeedClient } from "@lightspeed-ai/agent-client"; +import { LightspeedClient } from "@lightspeed-ai/sdk"; const lightspeed = new LightspeedClient("http://127.0.0.1:18080/rpc"); @@ -56,13 +56,13 @@ from the generated schema types. ```bash npm install -npm run check --workspace @lightspeed-ai/agent-client +npm run check --workspace @lightspeed-ai/sdk ``` `npm run check:generated` regenerates `src/generated/*` and the packaged schemas, and fails if the committed generated output is stale. -Workflow receivers import `@lightspeed-ai/agent-client/workflow`. That subpath +Workflow receivers import `@lightspeed-ai/sdk/workflow`. That subpath contains generated emission/start-on-call types and manifest-owned constants, plus Temporal-sandbox-safe parsing, id derivation, workflow-id, recipe, and reply helpers. It has no Temporal package dependency. diff --git a/clients/typescript/examples/temporal-activity.ts b/clients/typescript/examples/temporal-activity.ts index ef3d769e1..b441e1dbf 100644 --- a/clients/typescript/examples/temporal-activity.ts +++ b/clients/typescript/examples/temporal-activity.ts @@ -1,5 +1,5 @@ import { Context } from "@temporalio/activity"; -import { LightspeedClient, type EventCursor } from "@lightspeed-ai/agent-client"; +import { LightspeedClient, type EventCursor } from "@lightspeed-ai/sdk"; export interface RunLightspeedStepInput { endpoint: string; diff --git a/clients/typescript/package-lock.json b/clients/typescript/package-lock.json index c4e0f9dd8..a34c75687 100644 --- a/clients/typescript/package-lock.json +++ b/clients/typescript/package-lock.json @@ -1,20 +1,20 @@ { - "name": "@lightspeed-ai/agent-client", + "name": "@lightspeed-ai/sdk", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@lightspeed-ai/agent-client", + "name": "@lightspeed-ai/sdk", "version": "0.0.0", "dependencies": { - "@noble/hashes": "2.2.0" + "@noble/hashes": "2.4.0" }, "devDependencies": { - "@types/node": "^24.0.0", - "json-schema-to-typescript": "^15.0.4", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "@types/node": "^24.19.1", + "json-schema-to-typescript": "^16.0.0", + "typescript": "^6.0.3", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" @@ -38,455 +38,57 @@ "url": "https://github.com/sponsors/philsturgeon" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", - "cpu": [ - "arm64" - ], + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", - "cpu": [ - "arm64" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } ], - "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", - "cpu": [ - "ia32" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, "node_modules/@jsdevtools/ono": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", @@ -495,9 +97,9 @@ "license": "MIT" }, "node_modules/@noble/hashes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", - "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.4.0.tgz", + "integrity": "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==", "license": "MIT", "engines": { "node": ">= 20.19.0" @@ -506,66 +108,39 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", - "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", - "cpu": [ - "arm" - ], + "node_modules/@oxc-project/types": { + "version": "0.152.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", + "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "peer": true, + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", - "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", + "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", "cpu": [ - "arm64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", - "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", - "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", - "cpu": [ - "x64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", - "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", + "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", "cpu": [ "arm64" ], @@ -573,69 +148,17 @@ "license": "MIT", "optional": true, "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", - "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", - "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", - "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", - "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", - "cpu": [ - "arm64" + "android" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", - "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", + "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", "cpu": [ "arm64" ], @@ -643,153 +166,197 @@ "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", - "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", + "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", "cpu": [ - "loong64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", - "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", + "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", "cpu": [ - "loong64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "freebsd" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", - "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", + "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", "cpu": [ - "ppc64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", - "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", + "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", "cpu": [ - "ppc64" + "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", - "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", + "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", "cpu": [ - "riscv64" + "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", - "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", + "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", "cpu": [ - "riscv64" + "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", - "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", + "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", - "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", + "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", - "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", + "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", - "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", - "cpu": [ - "x64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", - "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", + "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", "cpu": [ "arm64" ], @@ -798,12 +365,16 @@ "optional": true, "os": [ "openharmony" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", - "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", + "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", "cpu": [ "arm64" ], @@ -812,26 +383,16 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", - "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", - "cpu": [ - "ia32" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", - "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", + "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", "cpu": [ "x64" ], @@ -840,21 +401,19 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", - "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", - "cpu": [ - "x64" ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "peer": true }, "node_modules/@types/chai": { "version": "5.2.3", @@ -889,57 +448,40 @@ "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", - "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.25.tgz", + "integrity": "sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==", "dev": true, "license": "MIT" }, "node_modules/@types/node": { - "version": "24.13.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz", - "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/@vitest/expect": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.6.tgz", - "integrity": "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==", + "version": "24.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.1.tgz", + "integrity": "sha512-aS3/DG0oM05K0RIXXP+hKjinGG5IgSSVGzswZxW3O0sS3pH4/fycXundUC9XsszgKCk4gHXylTEK6hyFxVxnoQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "undici-types": ">=7.24.0 <7.24.7" } }, "node_modules/@vitest/mocker": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz", - "integrity": "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.3.tgz", + "integrity": "sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.6", + "@jridgewell/trace-mapping": "0.3.31", + "@vitest/spy": "5.0.3", "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" + "magic-string": "^1.2.3" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -950,336 +492,444 @@ } } }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz", - "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==", + "node_modules/@vitest/spy": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.3.tgz", + "integrity": "sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==", "dev": true, "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.6.tgz", - "integrity": "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", - "dependencies": { - "@vitest/utils": "3.2.6", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=12" } }, - "node_modules/@vitest/snapshot": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.6.tgz", - "integrity": "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==", + "node_modules/chai": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", "dev": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.6", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=18" } }, - "node_modules/@vitest/spy": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.6.tgz", - "integrity": "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==", + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=8" } }, - "node_modules/@vitest/utils": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.6.tgz", - "integrity": "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==", + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/estree": "^1.0.0" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, - "license": "Python-2.0" + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": ">=8" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "node_modules/js-yaml": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.2.tgz", + "integrity": "sha512-m+aqu+LwO1O6sIopafj8HUVl5aawITwZQe/yHpMCKjaWBaA/d07B/QdMb3529REftiU+RMMHL3Vlsw3hON7vWg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" + "argparse": "^2.0.1" }, - "engines": { - "node": ">=18" + "bin": { + "js-yaml": "bin/js-yaml.mjs" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "node_modules/json-schema-to-typescript": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-16.0.0.tgz", + "integrity": "sha512-Ah6kK4q6SjlMzWBH1eNOQkdRh5Qhr5T/RCFwfjQqWZA7UDW+N47A8wfyoiN0L884s4L4bAEI54IjIuN3/u0B/A==", "dev": true, "license": "MIT", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^11.9.3", + "@types/json-schema": "^7.0.15", + "@types/lodash": "^4.17.25", + "js-yaml": "^5.2.3", + "lodash": "^4.18.1", + "minimist": "^1.2.8", + "prettier": "^3.9.6", + "tinyglobby": "^0.2.17" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, "engines": { - "node": ">= 16" + "node": ">=16.0.0" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", "dev": true, - "license": "MIT", + "license": "MPL-2.0", + "peer": true, "dependencies": { - "ms": "^2.1.3" + "detect-libc": "^2.0.3" }, "engines": { - "node": ">=6.0" + "node": ">= 12.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": ">=6" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": ">=18" + "node": ">= 12.0.0" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=12.0.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" + "node": ">= 12.0.0" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], "dev": true, - "hasInstallScript": true, - "license": "MIT", + "libc": [ + "musl" + ], + "license": "MPL-2.0", "optional": true, "os": [ - "darwin" + "linux" ], + "peer": true, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" + "peer": true, + "engines": { + "node": ">= 12.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/json-schema-to-typescript": { - "version": "15.0.4", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-15.0.4.tgz", - "integrity": "sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ==", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.5.5", - "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.7", - "is-glob": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "minimist": "^1.2.8", - "prettier": "^3.2.5", - "tinyglobby": "^0.2.9" - }, - "bin": { - "json2ts": "dist/src/cli.js" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, "engines": { - "node": ">=16.0.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/lodash": { @@ -1289,21 +939,14 @@ "dev": true, "license": "MIT" }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.2.tgz", + "integrity": "sha512-vG+rjFRj1PqdIBozIxAGMjPlOhaVe+GXpbttY/iSK7rGcJRMlwNJO7dcUwmUqkymsFLJiNGI06t4D7Fr7yRC9g==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "@jridgewell/sourcemap-codec": "^1.6.0" } }, "node_modules/minimist": { @@ -1316,17 +959,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", "dev": true, "funding": [ { @@ -1335,6 +971,7 @@ } ], "license": "MIT", + "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1342,21 +979,18 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], "license": "MIT", "engines": { - "node": ">= 14.16" + "node": ">=12.20.0" } }, "node_modules/picocolors": { @@ -1364,15 +998,15 @@ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -1381,9 +1015,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", "dev": true, "funding": [ { @@ -1400,8 +1034,9 @@ } ], "license": "MIT", + "peer": true, "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.18", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -1410,9 +1045,9 @@ } }, "node_modules/prettier": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz", - "integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==", + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.9.tgz", + "integrity": "sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==", "dev": true, "license": "MIT", "bin": { @@ -1425,108 +1060,78 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/rollup": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", - "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "node_modules/rolldown": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", + "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@types/estree": "1.0.9" + "@oxc-project/types": "=0.152.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.61.1", - "@rollup/rollup-android-arm64": "4.61.1", - "@rollup/rollup-darwin-arm64": "4.61.1", - "@rollup/rollup-darwin-x64": "4.61.1", - "@rollup/rollup-freebsd-arm64": "4.61.1", - "@rollup/rollup-freebsd-x64": "4.61.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", - "@rollup/rollup-linux-arm-musleabihf": "4.61.1", - "@rollup/rollup-linux-arm64-gnu": "4.61.1", - "@rollup/rollup-linux-arm64-musl": "4.61.1", - "@rollup/rollup-linux-loong64-gnu": "4.61.1", - "@rollup/rollup-linux-loong64-musl": "4.61.1", - "@rollup/rollup-linux-ppc64-gnu": "4.61.1", - "@rollup/rollup-linux-ppc64-musl": "4.61.1", - "@rollup/rollup-linux-riscv64-gnu": "4.61.1", - "@rollup/rollup-linux-riscv64-musl": "4.61.1", - "@rollup/rollup-linux-s390x-gnu": "4.61.1", - "@rollup/rollup-linux-x64-gnu": "4.61.1", - "@rollup/rollup-linux-x64-musl": "4.61.1", - "@rollup/rollup-openbsd-x64": "4.61.1", - "@rollup/rollup-openharmony-arm64": "4.61.1", - "@rollup/rollup-win32-arm64-msvc": "4.61.1", - "@rollup/rollup-win32-ia32-msvc": "4.61.1", - "@rollup/rollup-win32-x64-gnu": "4.61.1", - "@rollup/rollup-win32-x64-msvc": "4.61.1", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm-eabi": "1.2.12", + "@rolldown/binding-android-arm64": "1.2.12", + "@rolldown/binding-darwin-arm64": "1.2.12", + "@rolldown/binding-darwin-x64": "1.2.12", + "@rolldown/binding-freebsd-x64": "1.2.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", + "@rolldown/binding-linux-arm64-gnu": "1.2.12", + "@rolldown/binding-linux-arm64-musl": "1.2.12", + "@rolldown/binding-linux-ppc64-gnu": "1.2.12", + "@rolldown/binding-linux-s390x-gnu": "1.2.12", + "@rolldown/binding-linux-x64-gnu": "1.2.12", + "@rolldown/binding-linux-x64-musl": "1.2.12", + "@rolldown/binding-openharmony-arm64": "1.2.12", + "@rolldown/binding-win32-arm64-msvc": "1.2.12", + "@rolldown/binding-win32-x64-msvc": "1.2.12" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", "dev": true, "license": "MIT" }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "node_modules/tinybench": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.0.tgz", + "integrity": "sha512-78U2TlB2CnVenajOFzf3BKSm0J6oz5L0NV7g32LCPccvYc0lbWvys4d3uUUCS2B1N8PAf2+aekR8i1KbC3HO7Q==", "dev": true, "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "engines": { + "node": ">=20.0.0" } }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.17", @@ -1545,40 +1150,10 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1590,26 +1165,25 @@ } }, "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "dev": true, "license": "MIT" }, "node_modules/vite": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", - "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.2.tgz", + "integrity": "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.11", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" @@ -1625,9 +1199,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", @@ -1640,13 +1215,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -1672,89 +1250,73 @@ } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/vitest": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz", - "integrity": "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.3.tgz", + "integrity": "sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.6", - "@vitest/mocker": "3.2.6", - "@vitest/pretty-format": "^3.2.6", - "@vitest/runner": "3.2.6", - "@vitest/snapshot": "3.2.6", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", - "why-is-node-running": "^2.3.0" + "@vitest/mocker": "5.0.3", + "chai": "^6.2.2", + "es-module-lexer": "^2.3.2", + "expect-type": "^1.4.0", + "magic-string": "^1.2.3", + "obug": "^2.1.4", + "picomatch": "^4.0.7", + "std-env": "^4.2.0", + "tinybench": "^6.1.4", + "tinyexec": "^1.3.0", + "tinyglobby": "^0.2.17", + "why-is-node-running": "3.2.1" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^22.12.0 || ^24.0.0 || >=26.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.6", - "@vitest/ui": "3.2.6", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "5.0.3", + "@vitest/browser-preview": "5.0.3", + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", + "@vitest/coverage-istanbul": "5.0.3", + "@vitest/coverage-v8": "5.0.3", + "@vitest/ui": "5.0.3", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@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": { @@ -1765,24 +1327,23 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-3.2.1.tgz", + "integrity": "sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==", "dev": true, "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, "bin": { "why-is-node-running": "cli.js" }, "engines": { - "node": ">=8" + "node": ">=20.11" } } } diff --git a/clients/typescript/package.json b/clients/typescript/package.json index 7946f694d..86f3d3b0a 100644 --- a/clients/typescript/package.json +++ b/clients/typescript/package.json @@ -1,9 +1,9 @@ { - "name": "@lightspeed-ai/agent-client", + "name": "@lightspeed-ai/sdk", "version": "0.0.0", "private": false, "type": "module", - "description": "TypeScript JSON-RPC client for the Lightspeed agent API.", + "description": "TypeScript SDK for the Lightspeed API and workflow integrations.", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { @@ -44,12 +44,12 @@ "check": "npm run check:generated && npm run typecheck && npm run test && npm run build" }, "dependencies": { - "@noble/hashes": "2.2.0" + "@noble/hashes": "2.4.0" }, "devDependencies": { - "@types/node": "^24.0.0", - "json-schema-to-typescript": "^15.0.4", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "@types/node": "^24.19.1", + "json-schema-to-typescript": "^16.0.0", + "typescript": "^6.0.3", + "vitest": "^5.0.3" } } diff --git a/clients/typescript/schema/api.schema.json b/clients/typescript/schema/api.schema.json index e63c99513..ef95aaa89 100644 --- a/clients/typescript/schema/api.schema.json +++ b/clients/typescript/schema/api.schema.json @@ -7560,7 +7560,7 @@ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -7915,7 +7915,7 @@ ] }, "ContextEntryView": { - "description": "A session context entry, faithful to the stored engine entry: keyed,\nkind-tagged, ref-backed. Keys are a stable extension point — clients\nreconstruct derived surfaces (e.g. the prompted instruction set via the\n`prompt_instructions/` key prefix) by filtering on `key` and fetching\noriginal bytes through `blobs/read`. `text` contains complete message and\nvisible reasoning text; tool and catalog bodies use bounded text previews.", + "description": "A session context entry, faithful to the stored harness entry: keyed,\nkind-tagged, ref-backed. Keys are a stable extension point — clients\nreconstruct derived surfaces (e.g. the prompted instruction set via the\n`prompt_instructions/` key prefix) by filtering on `key` and fetching\noriginal bytes through `blobs/read`. `text` contains complete message and\nvisible reasoning text; tool and catalog bodies use bounded text previews.", "properties": { "citations": { "description": "Sources this assistant message cites, derived from its own native\npayload. Empty for every other entry kind.", @@ -11048,7 +11048,7 @@ }, "LimitsConfig": { "additionalProperties": false, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", @@ -13197,7 +13197,7 @@ "type": "object" }, "RunFailureKindView": { - "description": "Why a run failed, as the engine classified it.", + "description": "Why a run failed, as the harness classified it.", "oneOf": [ { "enum": [ @@ -14502,7 +14502,7 @@ "type": "object" }, { - "description": "The run ended in failure. `kind` is the engine's classification;\n`message` is free text for display, and the provider's own message for\n`request_rejected`.", + "description": "The run ended in failure. `kind` is the harness's classification;\n`message` is free text for display, and the provider's own message for\n`request_rejected`.", "properties": { "kind": { "$ref": "#/definitions/RunFailureKindView" diff --git a/clients/typescript/schema/workflow.schema.json b/clients/typescript/schema/workflow.schema.json index 214d658c8..e21a7d918 100644 --- a/clients/typescript/schema/workflow.schema.json +++ b/clients/typescript/schema/workflow.schema.json @@ -384,7 +384,7 @@ ] }, "ContentRef": { - "description": "Durable content identity and encoding. The payload stays in CAS; consumers\nproject it outside the engine rather than assuming every output is text.", + "description": "Durable content identity and encoding. The payload stays in CAS; consumers\nproject it outside the harness rather than assuming every output is text.", "properties": { "content_ref": { "type": "string" @@ -551,7 +551,7 @@ { "properties": { "holder_workflow_id": { - "description": "Workflow id of the session that emitted the invocation — the\nendpoint a receiver signals its reply to. Supplied by the\nsubstrate adapter; the engine treats it as opaque.", + "description": "Workflow id of the session that emitted the invocation — the\nendpoint a receiver signals its reply to. Supplied by the\nsubstrate adapter; the harness treats it as opaque.", "type": "string" }, "invocation": { @@ -764,7 +764,7 @@ "type": "object" }, "PromiseId": { - "description": "Stable identifier for a promise: a session-scoped counter rendered as\n`promise_`, the same convention as `run_`, so the model copies a\nshort handle rather than a digest. The engine hands every tool batch a\nbase one past the session cursor (`ToolInvocationBatchRequest::\npromise_id_base`); the executor numbers the promises it creates from\nthat base, and the reducer accepts a creation only at or above the\nbatch's base and never twice. Producer correlation lives on\n`PromiseSource`, not in the id.", + "description": "Stable identifier for a promise: a session-scoped counter rendered as\n`promise_`, the same convention as `run_`, so the model copies a\nshort handle rather than a digest. The harness hands every tool batch a\nbase one past the session cursor (`ToolInvocationBatchRequest::\npromise_id_base`); the executor numbers the promises it creates from\nthat base, and the reducer accepts a creation only at or above the\nbatch's base and never twice. Producer correlation lives on\n`PromiseSource`, not in the id.", "type": "string" }, "PromiseResolution": { diff --git a/clients/typescript/scripts/generate.mjs b/clients/typescript/scripts/generate.mjs index 2a7ab21d9..66abb855e 100644 --- a/clients/typescript/scripts/generate.mjs +++ b/clients/typescript/scripts/generate.mjs @@ -212,7 +212,7 @@ const methodLines = [ await writeFile(path.join(generatedDir, "methods.ts"), methodLines.join("\n")); // Ship the canonical contract schema inside the package (exported as -// "@lightspeed-ai/agent-client/schema/api.schema.json") so downstream tooling +// "@lightspeed-ai/sdk/schema/api.schema.json") so downstream tooling // can derive references/validators from the exact schema version it pins. const schemaOutDir = path.join(clientDir, "schema"); await mkdir(schemaOutDir, { recursive: true }); diff --git a/clients/typescript/src/generated/types.ts b/clients/typescript/src/generated/types.ts index a9215e3c1..630fe1779 100644 --- a/clients/typescript/src/generated/types.ts +++ b/clients/typescript/src/generated/types.ts @@ -817,7 +817,7 @@ export type RunAcceptedSourceView = { */ export type ApprovalDecisionKind = "approve" | "reject"; /** - * Why a run failed, as the engine classified it. + * Why a run failed, as the harness classified it. * * This interface was referenced by `LightspeedAgentAPI`'s JSON-Schema * via the `definition` "RunFailureKindView". @@ -2024,7 +2024,7 @@ export interface ContextCompactionView { thresholdSource: string; } /** - * A session context entry, faithful to the stored engine entry: keyed, + * A session context entry, faithful to the stored harness entry: keyed, * kind-tagged, ref-backed. Keys are a stable extension point — clients * reconstruct derived surfaces (e.g. the prompted instruction set via the * `prompt_instructions/` key prefix) by filtering on `key` and fetching @@ -2231,7 +2231,7 @@ export interface SessionConfig { */ export interface ContextConfig { /** - * Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery. + * Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery. */ compaction?: CompactionPolicy | null; /** @@ -2559,7 +2559,7 @@ export interface GenerationConfig { toolChoice?: ToolChoice | null; } /** - * Run budget defaults enforced by the engine drive loop. + * Run budget defaults enforced by the harness drive loop. * * This interface was referenced by `LightspeedAgentAPI`'s JSON-Schema * via the `definition` "LimitsConfig". diff --git a/clients/typescript/src/generated/workflow-types.ts b/clients/typescript/src/generated/workflow-types.ts index 2f2607331..1cc85a0c9 100644 --- a/clients/typescript/src/generated/workflow-types.ts +++ b/clients/typescript/src/generated/workflow-types.ts @@ -121,7 +121,7 @@ export type EmissionBody = /** * Workflow id of the session that emitted the invocation — the * endpoint a receiver signals its reply to. Supplied by the - * substrate adapter; the engine treats it as opaque. + * substrate adapter; the harness treats it as opaque. */ holder_workflow_id: string; invocation: WorkflowToolInvocation; @@ -141,7 +141,7 @@ export type RunStatus = "active" | "parked" | "cancelling" | "completed" | "fail /** * Stable identifier for a promise: a session-scoped counter rendered as * `promise_`, the same convention as `run_`, so the model copies a - * short handle rather than a digest. The engine hands every tool batch a + * short handle rather than a digest. The harness hands every tool batch a * base one past the session cursor (`ToolInvocationBatchRequest:: * promise_id_base`); the executor numbers the promises it creates from * that base, and the reducer accepts a creation only at or above the @@ -352,7 +352,7 @@ export interface ChatActivation { } /** * Durable content identity and encoding. The payload stays in CAS; consumers - * project it outside the engine rather than assuming every output is text. + * project it outside the harness rather than assuming every output is text. * * This interface was referenced by `LightspeedWorkflowContract`'s JSON-Schema * via the `definition` "ContentRef". diff --git a/crates/api-projection/Cargo.toml b/crates/api-projection/Cargo.toml index 1a8fcaa4e..a655b73f2 100644 --- a/crates/api-projection/Cargo.toml +++ b/crates/api-projection/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] api = { path = "../api" } -engine = { path = "../engine" } +harness = { path = "../harness" } llm-clients = { path = "../llm-clients" } futures-util = "0.3" serde_json = "1" diff --git a/crates/api-projection/src/content.rs b/crates/api-projection/src/content.rs index a62abcd50..719a8070a 100644 --- a/crates/api-projection/src/content.rs +++ b/crates/api-projection/src/content.rs @@ -1,15 +1,15 @@ //! Read-only views of durable content. Provider payloads remain authoritative. use api::{AgentApiError, ContentRefView}; -use engine::{ContentRef, storage::BlobStore}; +use harness::{ContentRef, storage::BlobStore}; pub fn content_ref_to_api(content: &ContentRef) -> ContentRefView { ContentRefView { content_ref: content.content_ref.as_str().to_owned(), media_type: content.media_type.clone(), provider_kind: content.provider_kind.clone(), - media_handle: engine::media::is_media_content(content) - .then(|| engine::media::media_handle(&content.content_ref)), + media_handle: harness::media::is_media_content(content) + .then(|| harness::media::media_handle(&content.content_ref)), } } @@ -30,10 +30,10 @@ pub async fn project_content_text( return Ok(Some(text)); } let project = match content.provider_kind.as_deref() { - Some(engine::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND) => { + Some(harness::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND) => { llm_clients::content::anthropic_text_blocks } - Some(engine::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND) => { + Some(harness::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND) => { llm_clients::content::openai_response_message } Some(llm_clients::content::OPENAI_COMPLETIONS_MESSAGE_PROVIDER_KIND) => { @@ -66,14 +66,14 @@ pub async fn project_content_text( #[cfg(test)] mod tests { use super::*; - use engine::{ + use harness::{ ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, storage::InMemoryBlobStore, }; use llm_clients::content::*; use serde_json::json; - fn context_entry(input: engine::ContextEntryInput) -> ContextEntry { + fn context_entry(input: harness::ContextEntryInput) -> ContextEntry { ContextEntry { entry_id: ContextEntryId::new(1), key: None, @@ -107,10 +107,10 @@ mod tests { ] { let bytes = text.into_bytes(); let reference = blobs.put_bytes(bytes.clone()).await.unwrap(); - let source = engine::RunSource::Input { - input: vec![engine::ContextEntryInput { + let source = harness::RunSource::Input { + input: vec![harness::ContextEntryInput { kind: ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + role: harness::ContextMessageRole::User, }, content: ContentRef { content_ref: reference.clone(), @@ -145,9 +145,9 @@ mod tests { let full = "héllo 🦀\n".repeat(2000); for (kind, bytes) in [ (None, full.as_bytes().to_vec()), - (Some(engine::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND), + (Some(harness::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND), serde_json::to_vec(&json!([{"type":"text","text":full,"citations":[]}])).unwrap()), - (Some(engine::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND), + (Some(harness::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND), serde_json::to_vec(&json!({"type":"message","role":"assistant","content":[{"type":"output_text","text":full,"annotations":[]}]})).unwrap()), (Some(OPENAI_COMPLETIONS_MESSAGE_PROVIDER_KIND), serde_json::to_vec(&json!({"role":"assistant","content":full,"annotations":[]})).unwrap()), @@ -157,8 +157,8 @@ mod tests { media_type: Some(if kind.is_some() { "application/json" } else { "text/plain" }.into()), provider_kind: kind.map(str::to_owned), }; - let input = engine::ContextEntryInput { - kind: ContextEntryKind::Message { role: engine::ContextMessageRole::User }, + let input = harness::ContextEntryInput { + kind: ContextEntryKind::Message { role: harness::ContextMessageRole::User }, content: content.clone(), preview: Some("short preview".into()), origin: None, @@ -174,9 +174,9 @@ mod tests { vec![api::InputItem::Text { provenance_ref: None, origin: None, text: full.clone() }]); // The retained terminal output still resolves after its context is gone. - let source = engine::RunSource::Input { input: Vec::new() }; + let source = harness::RunSource::Input { input: Vec::new() }; let run = projector.project_run_with_metadata(crate::ProjectRun { - entries: &[], run_id: engine::RunId::new(1), status: api::RunStatus::Completed, + entries: &[], run_id: harness::RunId::new(1), status: api::RunStatus::Completed, output: Some(&content), source: &source, started_at_ms: None, completed_at_ms: Some(1), usage: None, }).await.unwrap(); @@ -195,13 +195,13 @@ mod tests { media_type: Some("image/png".into()), provider_kind: None, }; - let source = engine::RunSource::Input { input: Vec::new() }; + let source = harness::RunSource::Input { input: Vec::new() }; let projector = crate::CoreAgentProjector::new(&blobs); for output in [None, Some(&content)] { let run = projector .project_run_with_metadata(crate::ProjectRun { entries: &[], - run_id: engine::RunId::new(1), + run_id: harness::RunId::new(1), status: api::RunStatus::Completed, output, source: &source, @@ -220,9 +220,9 @@ mod tests { async fn tool_payloads_keep_bounded_previews_and_readable_original_blobs() { let blobs = InMemoryBlobStore::new(); let full = "tool output 🦀\n".repeat(2000); - let input = engine::ContextEntryInput { + let input = harness::ContextEntryInput { kind: ContextEntryKind::ToolResult { - call_id: engine::ToolCallId::new("call"), + call_id: harness::ToolCallId::new("call"), is_error: false, }, content: ContentRef::text(blobs.insert_text(&full).await), diff --git a/crates/api-projection/src/lib.rs b/crates/api-projection/src/lib.rs index 7476d79d3..94b1c59e9 100644 --- a/crates/api-projection/src/lib.rs +++ b/crates/api-projection/src/lib.rs @@ -22,7 +22,8 @@ use api::{ WorkflowToolDeclarationInput, WorkflowToolDefinitionInput, WorkflowToolKindInput, WorkflowToolSpecInput, WorkflowToolTargetInput, }; -use engine::{ +use futures_util::future::try_join_all; +use harness::{ ANTHROPIC_MESSAGES_SERVER_TOOL_RESULT_PROVIDER_KIND, ANTHROPIC_MESSAGES_SERVER_TOOL_USE_PROVIDER_KIND, ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND, CompactionPolicy, ContextCompactionStatus, ContextCompactionTrigger, ContextEntry, @@ -39,7 +40,6 @@ use engine::{ SessionStoreError, StoredSessionEntry, }, }; -use futures_util::future::try_join_all; use serde_json::Value; mod content; @@ -63,11 +63,11 @@ pub struct ProjectRun<'a> { pub entries: &'a [CoreAgentEntry], pub run_id: RunId, pub status: ApiRunStatus, - pub output: Option<&'a engine::ContentRef>, + pub output: Option<&'a harness::ContentRef>, pub source: &'a RunSource, pub started_at_ms: Option, pub completed_at_ms: Option, - pub usage: Option<&'a engine::LlmUsage>, + pub usage: Option<&'a harness::LlmUsage>, } pub struct CoreAgentProjector<'a> { @@ -77,9 +77,9 @@ pub struct CoreAgentProjector<'a> { /// One run in reducer state, whichever queue bucket holds it. #[derive(Clone, Copy)] pub enum RunStateRef<'a> { - Completed(&'a engine::RunRecord), - Active(&'a engine::ActiveRun), - Queued(&'a engine::AcceptedRun), + Completed(&'a harness::RunRecord), + Active(&'a harness::ActiveRun), + Queued(&'a harness::AcceptedRun), } impl RunStateRef<'_> { @@ -353,18 +353,18 @@ impl<'a> CoreAgentProjector<'a> { continue; }; match event { - engine::ApprovalEvent::Requested { approval } if approval.run_id == run_id => { + harness::ApprovalEvent::Requested { approval } if approval.run_id == run_id => { pending.insert( approval.approval_id.clone(), (entry.observed_at_ms, approval.subject.clone()), ); } - engine::ApprovalEvent::Decided { + harness::ApprovalEvent::Decided { approval_id, run_id: event_run_id, .. } - | engine::ApprovalEvent::Cancelled { + | harness::ApprovalEvent::Cancelled { approval_id, run_id: event_run_id, } if *event_run_id == run_id => { @@ -386,10 +386,10 @@ impl<'a> CoreAgentProjector<'a> { async fn approval_subject_to_api( &self, - subject: &engine::ApprovalSubject, + subject: &harness::ApprovalSubject, ) -> Result { match subject { - engine::ApprovalSubject::McpToolCall { + harness::ApprovalSubject::McpToolCall { server_id, server_label, tool_name, @@ -478,7 +478,7 @@ impl<'a> CoreAgentProjector<'a> { } /// Native identity is diagnostic; missing blobs or payload IDs do not invent one. - async fn native_item_id(&self, content: &engine::ContentRef) -> Option { + async fn native_item_id(&self, content: &harness::ContentRef) -> Option { if content.media_type.as_deref() != Some("application/json") || !content .provider_kind @@ -496,7 +496,7 @@ impl<'a> CoreAgentProjector<'a> { /// inline copy is a prefix of a longer body. async fn bounded_blob_text( &self, - content_ref: &engine::BlobRef, + content_ref: &harness::BlobRef, ) -> Result<(String, bool), AgentApiError> { let full = self.read_blob_text(content_ref).await?; let truncated = full.len() > MAX_INLINE_TEXT_BYTES; @@ -687,7 +687,7 @@ impl<'a> CoreAgentProjector<'a> { CoreAgentLifecycleEvent::Closed => Ok(SessionEventKindView::SessionClosed), }, CoreAgentEvent::WorkflowToolConfig(event) => match event { - engine::WorkflowToolConfigEvent::ManagedBindingsAdmitted { + harness::WorkflowToolConfigEvent::ManagedBindingsAdmitted { lifecycle_controller, creation_fingerprint, bindings, @@ -702,7 +702,7 @@ impl<'a> CoreAgentProjector<'a> { .map(|binding| binding.definition.tool_id.as_str().to_owned()) .collect(), }), - engine::WorkflowToolConfigEvent::SystemBindingAdmitted { binding } => { + harness::WorkflowToolConfigEvent::SystemBindingAdmitted { binding } => { Ok(SessionEventKindView::SystemWorkflowToolConfigured { tool_id: binding.definition.tool_id.as_str().to_owned(), binding_fingerprint: binding.binding_fingerprint.clone(), @@ -710,7 +710,7 @@ impl<'a> CoreAgentProjector<'a> { } }, CoreAgentEvent::WorkflowTool(event) => match event { - engine::WorkflowToolEvent::Emitted { invocation } => { + harness::WorkflowToolEvent::Emitted { invocation } => { Ok(SessionEventKindView::WorkflowToolEmitted { invocation_id: invocation.invocation_id.as_str().to_owned(), tool_id: invocation.tool_id.as_str().to_owned(), @@ -734,7 +734,7 @@ impl<'a> CoreAgentProjector<'a> { ), }) } - engine::WorkflowToolEvent::StartRequested { + harness::WorkflowToolEvent::StartRequested { invocation, execution_id, } => Ok(SessionEventKindView::WorkflowToolStartRequested { @@ -762,14 +762,14 @@ impl<'a> CoreAgentProjector<'a> { }) .unwrap_or_default(), }), - engine::WorkflowToolEvent::StartFailed { + harness::WorkflowToolEvent::StartFailed { invocation_id, error_ref, } => Ok(SessionEventKindView::WorkflowToolStartFailed { invocation_id: invocation_id.as_str().to_owned(), error_ref: error_ref.as_str().to_owned(), }), - engine::WorkflowToolEvent::DeliveryFailed { + harness::WorkflowToolEvent::DeliveryFailed { invocation_id, error_ref, } => Ok(SessionEventKindView::WorkflowToolDeliveryFailed { @@ -836,19 +836,19 @@ impl<'a> CoreAgentProjector<'a> { }), }, CoreAgentEvent::Approval(event) => match event { - engine::ApprovalEvent::Requested { approval } => { + harness::ApprovalEvent::Requested { approval } => { Ok(SessionEventKindView::ApprovalRequested { run_id: api_run_id(approval.run_id), approval_id: approval.approval_id.as_str().to_owned(), subject: self.approval_subject_to_api(&approval.subject).await?, }) } - engine::ApprovalEvent::RunParked { run_id } => { + harness::ApprovalEvent::RunParked { run_id } => { Ok(SessionEventKindView::ApprovalRunParked { run_id: api_run_id(*run_id), }) } - engine::ApprovalEvent::Decided { + harness::ApprovalEvent::Decided { approval_id, run_id, decision, @@ -858,13 +858,13 @@ impl<'a> CoreAgentProjector<'a> { run_id: api_run_id(*run_id), approval_id: approval_id.as_str().to_owned(), decision: match decision { - engine::ApprovalDecision::Approved => ApprovalDecisionKind::Approve, - engine::ApprovalDecision::Rejected => ApprovalDecisionKind::Reject, + harness::ApprovalDecision::Approved => ApprovalDecisionKind::Approve, + harness::ApprovalDecision::Rejected => ApprovalDecisionKind::Reject, }, note: note.clone(), decided_by: attribution(decided_by.as_ref()), }), - engine::ApprovalEvent::Cancelled { + harness::ApprovalEvent::Cancelled { approval_id, run_id, } => Ok(SessionEventKindView::ApprovalCancelled { @@ -873,32 +873,32 @@ impl<'a> CoreAgentProjector<'a> { }), }, CoreAgentEvent::Promise(event) => match event { - engine::PromiseEvent::Created { promise } => { + harness::PromiseEvent::Created { promise } => { Ok(SessionEventKindView::PromiseCreated { promise_id: promise.promise_id.as_str().to_owned(), source: promise_source_name(&promise.source).to_owned(), }) } - engine::PromiseEvent::Resolved { + harness::PromiseEvent::Resolved { promise_id, payload_ref, } => Ok(SessionEventKindView::PromiseResolved { promise_id: promise_id.as_str().to_owned(), payload_ref: payload_ref.as_ref().map(|ref_| ref_.as_str().to_owned()), }), - engine::PromiseEvent::Failed { + harness::PromiseEvent::Failed { promise_id, error_ref, } => Ok(SessionEventKindView::PromiseFailed { promise_id: promise_id.as_str().to_owned(), error_ref: error_ref.as_ref().map(|ref_| ref_.as_str().to_owned()), }), - engine::PromiseEvent::Cancelled { promise_id } => { + harness::PromiseEvent::Cancelled { promise_id } => { Ok(SessionEventKindView::PromiseCancelled { promise_id: promise_id.as_str().to_owned(), }) } - engine::PromiseEvent::Detached { promise_id } => { + harness::PromiseEvent::Detached { promise_id } => { Ok(SessionEventKindView::PromiseDetached { promise_id: promise_id.as_str().to_owned(), }) @@ -1046,12 +1046,12 @@ impl<'a> CoreAgentProjector<'a> { }), }, CoreAgentEvent::Environment(event) => match event { - engine::EnvironmentEvent::ActiveEnvironmentSet { environment_id } => { + harness::EnvironmentEvent::ActiveEnvironmentSet { environment_id } => { Ok(SessionEventKindView::ActiveEnvironmentChanged { environment_id: Some(environment_id.as_str().to_owned()), }) } - engine::EnvironmentEvent::ActiveEnvironmentCleared => { + harness::EnvironmentEvent::ActiveEnvironmentCleared => { Ok(SessionEventKindView::ActiveEnvironmentChanged { environment_id: None, }) @@ -1256,7 +1256,7 @@ impl<'a> CoreAgentProjector<'a> { call.started_at_ms = Some(entry.observed_at_ms); } } - // The durable per-call completion carries the engine's call + // The durable per-call completion carries the harness's call // status; it distinguishes `cancelled` from `failed`, which // the model-visible result entry alone cannot. ToolEvent::CallCompleted { @@ -1327,7 +1327,7 @@ impl<'a> CoreAgentProjector<'a> { ContextEntryKind::Message { role: ContextMessageRole::User, } if matches!(item.source, ContextEntrySource::Tool { .. }) - && engine::media::is_media_content(&item.content) => + && harness::media::is_media_content(&item.content) => { if let Some(call_id) = ¤t_call { media_by_call @@ -1387,7 +1387,7 @@ impl<'a> CoreAgentProjector<'a> { display(&value) } - async fn read_blob_text(&self, blob_ref: &engine::BlobRef) -> Result { + async fn read_blob_text(&self, blob_ref: &harness::BlobRef) -> Result { self.blobs .read_text(blob_ref) .await @@ -1580,7 +1580,7 @@ fn session_management_to_api(state: &CoreAgentState) -> Option Option { Some(WorkflowToolDeclarationInput { definition: WorkflowToolDefinitionInput { @@ -1590,7 +1590,7 @@ fn workflow_tool_declaration_to_api( tool: WorkflowToolSpecInput { name: binding.definition.tool.name.as_str().to_owned(), kind: match &binding.definition.tool.kind { - engine::ToolKind::Function(function) => WorkflowToolKindInput::Function { + harness::ToolKind::Function(function) => WorkflowToolKindInput::Function { description_ref: function .description_ref .as_ref() @@ -1612,23 +1612,23 @@ fn workflow_tool_declaration_to_api( }, }, target: match &binding.target { - engine::WorkflowToolTarget::Bound { receiver, dispatch } => { + harness::WorkflowToolTarget::Bound { receiver, dispatch } => { WorkflowToolTargetInput::Bound { receiver: WorkflowEndpointInput { workflow_id: receiver.workflow_id.clone(), workflow_kind: receiver.workflow_kind.clone(), }, dispatch: match dispatch { - engine::BoundWorkflowToolDispatch::Pull => { + harness::BoundWorkflowToolDispatch::Pull => { BoundWorkflowToolDispatchInput::Pull } - engine::BoundWorkflowToolDispatch::Push => { + harness::BoundWorkflowToolDispatch::Push => { BoundWorkflowToolDispatchInput::Push } }, } } - engine::WorkflowToolTarget::Start { start } => WorkflowToolTargetInput::Start { + harness::WorkflowToolTarget::Start { start } => WorkflowToolTargetInput::Start { start: WorkflowStartRefInput { recipe_format: start.recipe_format, revision: start.revision, @@ -1638,8 +1638,8 @@ fn workflow_tool_declaration_to_api( }, }, completion: match &binding.completion { - engine::WorkflowToolCompletion::Accepted => WorkflowToolCompletionInput::Accepted, - engine::WorkflowToolCompletion::Joined { + harness::WorkflowToolCompletion::Accepted => WorkflowToolCompletionInput::Accepted, + harness::WorkflowToolCompletion::Joined { reply_schema_ref, deadline_after_ms, } => WorkflowToolCompletionInput::Joined { @@ -1648,7 +1648,7 @@ fn workflow_tool_declaration_to_api( .map(|value| value.as_str().to_owned()), deadline_after_ms: *deadline_after_ms, }, - engine::WorkflowToolCompletion::Promises { + harness::WorkflowToolCompletion::Promises { reply_schema_ref, deadline_after_ms, max_promises, @@ -1660,21 +1660,21 @@ fn workflow_tool_declaration_to_api( deadline_after_ms: *deadline_after_ms, max_promises: *max_promises, key_source: match key_source { - engine::WorkflowToolCompletionKeySource::Reply => { + harness::WorkflowToolCompletionKeySource::Reply => { WorkflowToolCompletionKeySourceInput::Reply } - engine::WorkflowToolCompletionKeySource::StringArray { pointer } => { + harness::WorkflowToolCompletionKeySource::StringArray { pointer } => { WorkflowToolCompletionKeySourceInput::StringArray { pointer: pointer.clone(), } } - engine::WorkflowToolCompletionKeySource::ArrayItemField { pointer, field } => { + harness::WorkflowToolCompletionKeySource::ArrayItemField { pointer, field } => { WorkflowToolCompletionKeySourceInput::ArrayItemField { pointer: pointer.clone(), field: field.clone(), } } - engine::WorkflowToolCompletionKeySource::ArrayIndices { pointer, prefix } => { + harness::WorkflowToolCompletionKeySource::ArrayIndices { pointer, prefix } => { WorkflowToolCompletionKeySourceInput::ArrayIndices { pointer: pointer.clone(), prefix: prefix.clone(), @@ -1697,11 +1697,11 @@ struct ProjectedToolResult { fn tool_call_media_view(entry: &ContextEntry) -> ToolCallMediaView { let mime = entry.content.media_type.clone().unwrap_or_default(); ToolCallMediaView { - handle: engine::media::media_handle(&entry.content.content_ref), + handle: harness::media::media_handle(&entry.content.content_ref), blob_ref: entry.content.content_ref.as_str().to_owned(), kind: media_kind_for_mime(&mime), mime, - name: engine::media::media_preview_name(entry.preview.as_deref()), + name: harness::media::media_preview_name(entry.preview.as_deref()), } } @@ -1794,7 +1794,7 @@ pub fn replay_core_agent_state( ) -> Result { let mut state = CoreAgentState::new(); for entry in entries { - engine::apply_event(&mut state, entry) + harness::apply_event(&mut state, entry) .map_err(|error| AgentApiError::internal(error.to_string()))?; } Ok(state) @@ -1912,19 +1912,19 @@ pub fn api_run_id(run_id: RunId) -> String { format!("run_{}", run_id.as_u64()) } -fn promise_source_name(source: &engine::PromiseSource) -> &'static str { +fn promise_source_name(source: &harness::PromiseSource) -> &'static str { match source { - engine::PromiseSource::Timer { .. } => "timer", - engine::PromiseSource::Workflow { .. } => "workflow", + harness::PromiseSource::Timer { .. } => "timer", + harness::PromiseSource::Workflow { .. } => "workflow", } } -fn attribution(value: Option<&engine::Attribution>) -> Option { +fn attribution(value: Option<&harness::Attribution>) -> Option { Some(match value?.clone() { - engine::Attribution::Actor { id } => api::Attribution::Actor { id }, - engine::Attribution::Key { prefix } => api::Attribution::Key { prefix }, - engine::Attribution::Local => api::Attribution::Local, - engine::Attribution::Internal { component, cause } => { + harness::Attribution::Actor { id } => api::Attribution::Actor { id }, + harness::Attribution::Key { prefix } => api::Attribution::Key { prefix }, + harness::Attribution::Local => api::Attribution::Local, + harness::Attribution::Internal { component, cause } => { api::Attribution::Internal { component, cause } } }) @@ -2012,8 +2012,8 @@ fn context_compaction_to_api(state: &CoreAgentState) -> Option "providerStandalone", _ => "disabled", }; - let signed_window = state.context.entries.iter().any(|entry| entry.content.provider_kind.as_deref() == Some(engine::ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND) - && matches!(entry.kind, ContextEntryKind::ProviderOpaque) && matches!(&entry.source, ContextEntrySource::Runtime { label } if label == engine::STANDALONE_COMPACTION_SOURCE)); + let signed_window = state.context.entries.iter().any(|entry| entry.content.provider_kind.as_deref() == Some(harness::ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND) + && matches!(entry.kind, ContextEntryKind::ProviderOpaque) && matches!(&entry.source, ContextEntrySource::Runtime { label } if label == harness::STANDALONE_COMPACTION_SOURCE)); let effective = if requested == "providerTriggered" && signed_window { "providerStandalone" } else { @@ -2032,7 +2032,7 @@ fn context_compaction_to_api(state: &CoreAgentState) -> Option "modelSummary", _ => "nativePreferred", }; - let input_limit_tokens = engine::compaction_input_limit_tokens(state); + let input_limit_tokens = harness::compaction_input_limit_tokens(state); let override_threshold = match policy { Some( CompactionPolicy::ProviderTriggered { @@ -2149,11 +2149,11 @@ pub fn session_activity(state: &CoreAgentState) -> api::SessionActivity { } /// The stored list projection of a session's activity. -pub fn record_activity(record: &engine::storage::SessionRecord) -> api::SessionActivity { +pub fn record_activity(record: &harness::storage::SessionRecord) -> api::SessionActivity { match record.activity { - engine::storage::SessionActivity::Idle => api::SessionActivity::Idle, - engine::storage::SessionActivity::Working => api::SessionActivity::Working, - engine::storage::SessionActivity::Waiting => api::SessionActivity::Waiting, + harness::storage::SessionActivity::Idle => api::SessionActivity::Idle, + harness::storage::SessionActivity::Working => api::SessionActivity::Working, + harness::storage::SessionActivity::Waiting => api::SessionActivity::Waiting, } } @@ -2198,8 +2198,8 @@ fn tool_choice_to_api(choice: &ToolChoice) -> api::ToolChoice { } } -/// Sparse engine-doc to wire-doc mapping: a section that equals its engine -/// default projects to `None`; engine `Option` fields map 1:1. +/// Sparse harness-doc to wire-doc mapping: a section that equals its harness +/// default projects to `None`; harness `Option` fields map 1:1. pub fn session_config_to_api(config: &SessionConfig) -> Result { Ok(api::SessionConfig { model: Some(model_to_api(&config.model)), @@ -2225,22 +2225,22 @@ pub fn session_config_to_api(config: &SessionConfig) -> Result api::GenerationConfig { +fn generation_config_to_api(generation: &harness::GenerationConfig) -> api::GenerationConfig { api::GenerationConfig { max_output_tokens: generation.max_output_tokens, reasoning_effort: generation.reasoning_effort.clone(), tool_choice: generation.tool_choice.as_ref().map(tool_choice_to_api), parallel_tool_use: generation.parallel_tool_use, processing_tier: generation.processing_tier.map(|tier| match tier { - engine::ModelProcessingTier::Standard => api::ModelProcessingTier::Standard, - engine::ModelProcessingTier::Fast => api::ModelProcessingTier::Fast, - engine::ModelProcessingTier::Flex => api::ModelProcessingTier::Flex, + harness::ModelProcessingTier::Standard => api::ModelProcessingTier::Standard, + harness::ModelProcessingTier::Fast => api::ModelProcessingTier::Fast, + harness::ModelProcessingTier::Flex => api::ModelProcessingTier::Flex, }), } } fn features_config_to_api( - features: &engine::FeaturesConfig, + features: &harness::FeaturesConfig, ) -> Result { Ok(api::FeaturesConfig { vfs: features.vfs.as_ref().map(vfs_feature_to_api), @@ -2286,16 +2286,16 @@ fn features_config_to_api( }) } -pub fn environment_access_to_api(access: engine::EnvironmentAccess) -> api::EnvironmentAccess { +pub fn environment_access_to_api(access: harness::EnvironmentAccess) -> api::EnvironmentAccess { match access { - engine::EnvironmentAccess::Read => api::EnvironmentAccess::Read, - engine::EnvironmentAccess::Edit => api::EnvironmentAccess::Edit, - engine::EnvironmentAccess::Exec => api::EnvironmentAccess::Exec, - engine::EnvironmentAccess::Jobs => api::EnvironmentAccess::Jobs, + harness::EnvironmentAccess::Read => api::EnvironmentAccess::Read, + harness::EnvironmentAccess::Edit => api::EnvironmentAccess::Edit, + harness::EnvironmentAccess::Exec => api::EnvironmentAccess::Exec, + harness::EnvironmentAccess::Jobs => api::EnvironmentAccess::Jobs, } } -fn vfs_feature_to_api(vfs: &engine::VfsFeature) -> api::VfsFeature { +fn vfs_feature_to_api(vfs: &harness::VfsFeature) -> api::VfsFeature { api::VfsFeature { version: vfs.version, working_directory: vfs.working_directory.clone(), @@ -2304,10 +2304,10 @@ fn vfs_feature_to_api(vfs: &engine::VfsFeature) -> api::VfsFeature { .iter() .map(|attachment| { let (workspace_id, snapshot_ref) = match &attachment.target { - engine::WorkspaceAttachmentTarget::Workspace { workspace_id } => { + harness::WorkspaceAttachmentTarget::Workspace { workspace_id } => { (Some(workspace_id.clone()), None) } - engine::WorkspaceAttachmentTarget::Snapshot { snapshot_ref } => { + harness::WorkspaceAttachmentTarget::Snapshot { snapshot_ref } => { (None, Some(snapshot_ref.clone())) } }; @@ -2316,8 +2316,8 @@ fn vfs_feature_to_api(vfs: &engine::VfsFeature) -> api::VfsFeature { workspace_id, snapshot_ref, access: match attachment.access { - engine::WorkspaceAccess::Read => api::WorkspaceAccess::Read, - engine::WorkspaceAccess::Edit => api::WorkspaceAccess::Edit, + harness::WorkspaceAccess::Read => api::WorkspaceAccess::Read, + harness::WorkspaceAccess::Edit => api::WorkspaceAccess::Edit, }, } }) @@ -2331,7 +2331,7 @@ fn vfs_feature_to_api(vfs: &engine::VfsFeature) -> api::VfsFeature { } } -fn web_feature_to_api(web: &engine::WebFeature) -> api::WebFeature { +fn web_feature_to_api(web: &harness::WebFeature) -> api::WebFeature { api::WebFeature { version: web.version, fetch: web.fetch.as_ref().map(|_| api::WebFetchFeature {}), @@ -2343,7 +2343,7 @@ fn web_feature_to_api(web: &engine::WebFeature) -> api::WebFeature { } fn subagents_feature_to_api( - subagents: &engine::SubagentsFeature, + subagents: &harness::SubagentsFeature, ) -> Result { Ok(api::SubagentsFeature { version: subagents.version, @@ -2372,11 +2372,11 @@ fn subagents_feature_to_api( /// Project a session record's delegation provenance for API views. pub fn session_origin_to_api( - origin: &engine::storage::SessionOrigin, + origin: &harness::storage::SessionOrigin, ) -> Result { Ok(api::SessionOriginView { kind: match origin.kind { - engine::storage::SessionOriginKind::Subagent => api::SessionOriginKind::Subagent, + harness::storage::SessionOriginKind::Subagent => api::SessionOriginKind::Subagent, }, parent_session_id: origin.parent_session_id.as_str().to_owned(), parent_run_id: format!("run_{}", origin.parent_run_id), @@ -2396,7 +2396,7 @@ pub fn session_origin_to_api( }) } -pub fn subagent_limits_to_api(limits: engine::SubagentLimits) -> api::SubagentLimitsView { +pub fn subagent_limits_to_api(limits: harness::SubagentLimits) -> api::SubagentLimitsView { api::SubagentLimitsView { max_depth: limits.max_depth, max_descendants: limits.max_descendants, @@ -2405,7 +2405,7 @@ pub fn subagent_limits_to_api(limits: engine::SubagentLimits) -> api::SubagentLi } } -fn mcp_feature_to_api(mcp: &engine::McpFeature) -> api::McpFeature { +fn mcp_feature_to_api(mcp: &harness::McpFeature) -> api::McpFeature { api::McpFeature { version: mcp.version, servers: mcp @@ -2420,17 +2420,17 @@ fn mcp_feature_to_api(mcp: &engine::McpFeature) -> api::McpFeature { } fn remote_mcp_approval_to_api( - policy: &engine::RemoteMcpApprovalPolicy, + policy: &harness::RemoteMcpApprovalPolicy, ) -> api::RemoteMcpApprovalPolicy { match policy { - engine::RemoteMcpApprovalPolicy::Always => api::RemoteMcpApprovalPolicy::Always, - engine::RemoteMcpApprovalPolicy::Never => api::RemoteMcpApprovalPolicy::Never, + harness::RemoteMcpApprovalPolicy::Always => api::RemoteMcpApprovalPolicy::Always, + harness::RemoteMcpApprovalPolicy::Never => api::RemoteMcpApprovalPolicy::Never, } } fn active_tools_to_api( revision: u64, - tools: &BTreeMap, + tools: &BTreeMap, ) -> ActiveToolsView { ActiveToolsView { revision, @@ -2471,10 +2471,10 @@ fn tool_kind_to_api(kind: &ToolKind) -> ToolKindView { api_kind: api_kind_to_str(&native.api_kind).to_owned(), native_tool_ref: native.native_tool_ref.as_str().to_owned(), execution: match native.execution { - engine::ProviderNativeToolExecution::ProviderHosted => { + harness::ProviderNativeToolExecution::ProviderHosted => { ProviderNativeToolExecutionView::ProviderHosted } - engine::ProviderNativeToolExecution::ClientEffect => { + harness::ProviderNativeToolExecution::ClientEffect => { ProviderNativeToolExecutionView::ClientEffect } }, @@ -2596,7 +2596,7 @@ fn context_message_role_to_api(role: &ContextMessageRole) -> ContextMessageRoleV } } -fn token_estimate_to_api(estimate: &engine::TokenEstimate) -> TokenEstimateView { +fn token_estimate_to_api(estimate: &harness::TokenEstimate) -> TokenEstimateView { TokenEstimateView { tokens: estimate.tokens, quality: token_estimate_quality_to_api(estimate.quality), @@ -2604,12 +2604,12 @@ fn token_estimate_to_api(estimate: &engine::TokenEstimate) -> TokenEstimateView } fn token_estimate_quality_to_api( - quality: engine::TokenEstimateQuality, + quality: harness::TokenEstimateQuality, ) -> TokenEstimateQualityView { match quality { - engine::TokenEstimateQuality::Exact => TokenEstimateQualityView::Exact, - engine::TokenEstimateQuality::ProviderCounted => TokenEstimateQualityView::ProviderCounted, - engine::TokenEstimateQuality::Estimated => TokenEstimateQualityView::Estimated, + harness::TokenEstimateQuality::Exact => TokenEstimateQualityView::Exact, + harness::TokenEstimateQuality::ProviderCounted => TokenEstimateQualityView::ProviderCounted, + harness::TokenEstimateQuality::Estimated => TokenEstimateQualityView::Estimated, } } @@ -2755,11 +2755,11 @@ fn tool_attachments_for_run( .collect() } -fn tool_attachments_to_api(attachments: &[engine::Attachment]) -> Vec { +fn tool_attachments_to_api(attachments: &[harness::Attachment]) -> Vec { attachments .iter() .map(|attachment| match attachment { - engine::Attachment::Media(media) => api::ToolAttachmentView { + harness::Attachment::Media(media) => api::ToolAttachmentView { kind: api::ToolAttachmentKind::Media, handle: media.handle.clone(), content_ref: media.content_ref.to_string(), @@ -2767,7 +2767,7 @@ fn tool_attachments_to_api(attachments: &[engine::Attachment]) -> Vec api::ToolAttachmentView { + harness::Attachment::File(file) => api::ToolAttachmentView { kind: api::ToolAttachmentKind::File, handle: file.handle.clone(), content_ref: file.content_ref.to_string(), @@ -2786,10 +2786,10 @@ fn tool_attachments_to_api(attachments: &[engine::Attachment]) -> Vec Vec { +fn tool_effects_to_api(effects: &[harness::ToolEffect]) -> Vec { effects .iter() - .filter(|effect| effect.kind != engine::WORKFLOW_TOOL_EMIT_EFFECT_KIND) + .filter(|effect| effect.kind != harness::WORKFLOW_TOOL_EMIT_EFFECT_KIND) .map(|effect| ToolEffectView { kind: effect.kind.clone(), data: effect.data.clone(), @@ -3330,7 +3330,7 @@ fn superseded_by_map(entries: &[&ContextEntry]) -> BTreeMap LlmUsageView { +fn llm_usage_to_api(usage: &harness::LlmUsage) -> LlmUsageView { LlmUsageView { input_tokens: usage.input_tokens, output_tokens: usage.output_tokens, @@ -3343,7 +3343,7 @@ fn llm_usage_to_api(usage: &engine::LlmUsage) -> LlmUsageView { #[cfg(test)] mod tests { - use engine::{ + use harness::{ BlobRef, ContextEntryId, CoreAgentJoins, EventSeq, SessionPosition, TokenEstimate, TokenEstimateQuality, storage::{BlobStore, InMemoryBlobStore}, @@ -3363,7 +3363,7 @@ mod tests { generation: Default::default(), limits: Default::default(), features: Default::default(), - context: engine::ContextConfig { + context: harness::ContextConfig { compaction: Some(CompactionPolicy::ProviderTriggered { compact_threshold_tokens: None, }), @@ -3376,11 +3376,11 @@ mod tests { let mut retained = context_entry( 1, ContextEntrySource::Runtime { - label: engine::STANDALONE_COMPACTION_SOURCE.into(), + label: harness::STANDALONE_COMPACTION_SOURCE.into(), }, ); retained.content.provider_kind = - Some(engine::ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND.into()); + Some(harness::ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND.into()); state.context.entries.push(retained); assert_eq!( context_compaction_to_api(&state).unwrap().effective_mode, @@ -3597,7 +3597,7 @@ mod tests { fn managed_session_projection_exposes_controller_ownership() { let mut state = CoreAgentState::new(); state.workflow_tools.managed_declaration_version = Some(1); - state.workflow_tools.lifecycle_controller = Some(engine::WorkflowEndpointRef { + state.workflow_tools.lifecycle_controller = Some(harness::WorkflowEndpointRef { workflow_id: "channels/session-1".to_owned(), workflow_kind: "channelSessionWorkflowV1".to_owned(), }); @@ -3623,21 +3623,21 @@ mod tests { let universe_id = "00000000-0000-0000-0000-000000000001" .parse() .expect("universe id"); - let receiver = engine::WorkflowEndpointRef { + let receiver = harness::WorkflowEndpointRef { workflow_id: "channels/session-1".to_owned(), workflow_kind: "channels.session".to_owned(), }; let input_schema_ref = BlobRef::from_bytes(br#"{"type":"object"}"#); - let binding = engine::WorkflowToolBinding::admit( + let binding = harness::WorkflowToolBinding::admit( universe_id, - engine::WorkflowToolDefinition { - tool_id: engine::WorkflowToolId::new("message-send"), + harness::WorkflowToolDefinition { + tool_id: harness::WorkflowToolId::new("message-send"), revision: 1, semantic_type: "channels.message.send.v1".to_owned(), tool: ToolSpec { - name: engine::ToolName::new("message_send"), + name: harness::ToolName::new("message_send"), execution: Default::default(), - kind: ToolKind::Function(engine::FunctionToolSpec { + kind: ToolKind::Function(harness::FunctionToolSpec { description_ref: None, input_schema_ref, output_schema_ref: None, @@ -3647,22 +3647,22 @@ mod tests { parallelism: ToolParallelism::ParallelSafe, }, }, - engine::WorkflowToolTarget::Bound { + harness::WorkflowToolTarget::Bound { receiver: receiver.clone(), - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, - engine::WorkflowToolCompletion::Joined { + harness::WorkflowToolCompletion::Joined { reply_schema_ref: None, deadline_after_ms: 30_000, }, ) .expect("joined binding"); let mut system_definition = binding.definition.clone(); - system_definition.tool_id = engine::WorkflowToolId::new("subagent-run"); + system_definition.tool_id = harness::WorkflowToolId::new("subagent-run"); system_definition.semantic_type = "lightspeed.subagent.run.v1".to_owned(); - system_definition.tool.name = engine::ToolName::new("subagent.run"); + system_definition.tool.name = harness::ToolName::new("subagent.run"); system_definition.tool.kind = ToolKind::Builtin(Default::default()); - let system_binding = engine::WorkflowToolBinding::admit( + let system_binding = harness::WorkflowToolBinding::admit( universe_id, system_definition, binding.target.clone(), @@ -3735,14 +3735,14 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn content_projection_distinguishes_authored_json_native_json_and_media() { let blobs = InMemoryBlobStore::new(); - let authored = engine::ContentRef::text(blobs.insert_text("{\"answer\":42}").await); + let authored = harness::ContentRef::text(blobs.insert_text("{\"answer\":42}").await); assert_eq!( project_content_text(&blobs, &authored) .await .expect("authored JSON"), Some("{\"answer\":42}".to_owned()) ); - let mut content = engine::ContentRef { + let mut content = harness::ContentRef { content_ref: blobs.insert_text("{\"answer\":42}").await, media_type: Some("application/json".to_owned()), provider_kind: Some(ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND.to_owned()), @@ -3771,7 +3771,7 @@ mod tests { let projector = CoreAgentProjector::new(&blobs); let mut state = CoreAgentState::new(); for id in 1..=3 { - state.runs.completed.push(engine::RunRecord { + state.runs.completed.push(harness::RunRecord { run_id: RunId::new(id), status: RunStatus::Completed, submission_id: None, @@ -3819,7 +3819,7 @@ mod tests { metadata: Default::default(), session_id: session_id.clone(), display_name: None, - lifecycle_status: engine::storage::SessionLifecycleStatus::New, + lifecycle_status: harness::storage::SessionLifecycleStatus::New, closed_at_seq: None, closed_at_ms: None, activity: Default::default(), @@ -3890,7 +3890,7 @@ mod tests { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef::text(blob_ref.clone()), + content: harness::ContentRef::text(blob_ref.clone()), preview: Some("hello".to_owned()), origin: None, provenance_ref: None, @@ -3925,7 +3925,7 @@ mod tests { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: image_ref.clone(), media_type: Some("image/jpeg".to_owned()), provider_kind: None, @@ -3997,7 +3997,7 @@ mod tests { let blobs = InMemoryBlobStore::new(); let projector = CoreAgentProjector::new(&blobs); let universe_id = "00000000-0000-0000-0000-000000000001"; - let config_event: engine::WorkflowToolConfigEvent = + let config_event: harness::WorkflowToolConfigEvent = serde_json::from_value(serde_json::json!({ "managed_bindings_admitted": { "session_universe_id": universe_id, @@ -4033,7 +4033,7 @@ mod tests { let arguments_ref = BlobRef::from_bytes(br#"{"status":"complete"}"#); let error_ref = BlobRef::from_bytes(b"delivery failed"); let invocation_id = format!("wti:sha256:{}", "a".repeat(64)); - let emitted: engine::WorkflowToolEvent = serde_json::from_value(serde_json::json!({ + let emitted: harness::WorkflowToolEvent = serde_json::from_value(serde_json::json!({ "emitted": { "invocation": { "invocation_id": invocation_id, @@ -4073,8 +4073,8 @@ mod tests { } ); - let failed = engine::WorkflowToolEvent::DeliveryFailed { - invocation_id: engine::WorkflowToolInvocationId::new(invocation_id.clone()), + let failed = harness::WorkflowToolEvent::DeliveryFailed { + invocation_id: harness::WorkflowToolInvocationId::new(invocation_id.clone()), error_ref: error_ref.clone(), }; let projected = projector @@ -4094,18 +4094,18 @@ mod tests { run_id: RunId::new(2), turn_id: TurnId::new(3), batch_id: ToolBatchId::new(4), - result: engine::ToolCallResult { + result: harness::ToolCallResult { attachments: Vec::new(), duration_ms: None, output_bytes: None, truncated: false, - call_id: engine::ToolCallId::new("call-5"), - status: engine::ToolCallStatus::Succeeded, + call_id: harness::ToolCallId::new("call-5"), + status: harness::ToolCallStatus::Succeeded, output_ref: None, model_visible_context_entries: Vec::new(), error_ref: None, - effects: vec![engine::ToolEffect { - kind: engine::WORKFLOW_TOOL_EMIT_EFFECT_KIND.to_owned(), + effects: vec![harness::ToolEffect { + kind: harness::WORKFLOW_TOOL_EMIT_EFFECT_KIND.to_owned(), data: Default::default(), }], }, @@ -4134,7 +4134,7 @@ mod tests { run_id: RunId::new(7), turn_id: TurnId::new(8), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: BlobRef::from_bytes( br#"{"type":"compaction","id":"item_compaction_1"}"#, ), @@ -4213,7 +4213,7 @@ mod tests { run_id: RunId::new(7), turn_id: TurnId::new(8), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: content_ref.clone(), media_type: Some("application/json".to_owned()), provider_kind: Some(OPENAI_RESPONSES_MCP_CALL_PROVIDER_KIND.to_owned()), @@ -4288,7 +4288,7 @@ mod tests { run_id: RunId::new(7), turn_id: TurnId::new(8), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: Some(provider_kind.to_owned()), @@ -4562,10 +4562,10 @@ mod tests { provider_id: "openai".to_owned(), model: "gpt-5".to_owned(), }, - generation: engine::GenerationConfig::default(), - limits: engine::LimitsConfig::default(), - context: engine::ContextConfig::default(), - features: engine::FeaturesConfig::default(), + generation: harness::GenerationConfig::default(), + limits: harness::LimitsConfig::default(), + context: harness::ContextConfig::default(), + features: harness::FeaturesConfig::default(), }; let projected = session_config_to_api(&config).expect("project sparse config"); @@ -4594,78 +4594,78 @@ mod tests { provider_id: "anthropic".to_owned(), model: "claude".to_owned(), }, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(2048), reasoning_effort: Some("high".to_owned()), tool_choice: Some(ToolChoice::Specific { - tool_name: engine::ToolName::new("read_file"), + tool_name: harness::ToolName::new("read_file"), }), parallel_tool_use: Some(false), processing_tier: None, }, - limits: engine::LimitsConfig { + limits: harness::LimitsConfig { max_turns: Some(12), max_tool_rounds: Some(3), }, - context: engine::ContextConfig { + context: harness::ContextConfig { reported_input_limit_tokens: None, input_limit_tokens: None, - compaction: Some(engine::CompactionPolicy::ProviderStandalone { + compaction: Some(harness::CompactionPolicy::ProviderStandalone { compact_threshold_tokens: Some(20_000), target_tokens: Some(8_000), }), }, - features: engine::FeaturesConfig { - vfs: Some(engine::VfsFeature { + features: harness::FeaturesConfig { + vfs: Some(harness::VfsFeature { working_directory: None, - version: engine::CURRENT_FEATURE_VERSION, - workspaces: vec![engine::WorkspaceAttachment { + version: harness::CURRENT_FEATURE_VERSION, + workspaces: vec![harness::WorkspaceAttachment { path: "/workspace".to_owned(), - target: engine::WorkspaceAttachmentTarget::Workspace { + target: harness::WorkspaceAttachmentTarget::Workspace { workspace_id: "ws_1".to_owned(), }, - access: engine::WorkspaceAccess::Read, + access: harness::WorkspaceAccess::Read, }], - prompts: Some(engine::VfsPromptsConfig { + prompts: Some(harness::VfsPromptsConfig { roots: Some(vec!["/prompts".to_owned()]), }), - skills: Some(engine::VfsSkillsConfig { + skills: Some(harness::VfsSkillsConfig { roots: Some(vec!["/workspace/skills".into()]), }), }), - web: Some(engine::WebFeature { - version: engine::CURRENT_FEATURE_VERSION, - fetch: Some(engine::WebFetchFeature {}), - search: Some(engine::WebSearchFeature { + web: Some(harness::WebFeature { + version: harness::CURRENT_FEATURE_VERSION, + fetch: Some(harness::WebFetchFeature {}), + search: Some(harness::WebSearchFeature { allowed_domains: Some(vec!["example.com".to_owned()]), blocked_domains: vec!["blocked.example".to_owned()], }), }), - subagents: Some(engine::SubagentsFeature { - version: engine::CURRENT_FEATURE_VERSION, - agents: vec![engine::SubagentAgentConfig { + subagents: Some(harness::SubagentsFeature { + version: harness::CURRENT_FEATURE_VERSION, + agents: vec![harness::SubagentAgentConfig { profile_id: "researcher".to_owned(), }], - limits: engine::SubagentLimits { + limits: harness::SubagentLimits { max_depth: 3, max_descendants: 10, max_concurrent: 2, deadline_ms: 120_000, }, }), - timers: Some(engine::TimersFeature::default()), - environments: Some(engine::EnvironmentsFeature { - environments: vec![engine::EnvironmentAttachment { + timers: Some(harness::TimersFeature::default()), + environments: Some(harness::EnvironmentsFeature { + environments: vec![harness::EnvironmentAttachment { environment_id: "env_1".to_owned(), default: true, - access: engine::EnvironmentAccess::Exec, + access: harness::EnvironmentAccess::Exec, working_directory: Some("/srv".to_owned()), }], ..Default::default() }), - mcp: Some(engine::McpFeature { - version: engine::CURRENT_FEATURE_VERSION, - servers: vec![engine::McpServerAttachment { + mcp: Some(harness::McpFeature { + version: harness::CURRENT_FEATURE_VERSION, + servers: vec![harness::McpServerAttachment { server_id: "linear".to_owned(), tools: Some(vec!["search".to_owned()]), }], @@ -4769,16 +4769,16 @@ mod tests { #[test] fn session_origin_projects_lineage_and_pinned_limits() { - let origin = engine::storage::SessionOrigin { - kind: engine::storage::SessionOriginKind::Subagent, - parent_session_id: engine::SessionId::new("parent"), + let origin = harness::storage::SessionOrigin { + kind: harness::storage::SessionOriginKind::Subagent, + parent_session_id: harness::SessionId::new("parent"), parent_run_id: 7, - root_session_id: engine::SessionId::new("root"), + root_session_id: harness::SessionId::new("root"), depth: 2, invocation_id: "wti_1".to_owned(), profile_id: "reviewer".to_owned(), profile_revision: 4, - limits: engine::SubagentLimits::default(), + limits: harness::SubagentLimits::default(), }; let projected = session_origin_to_api(&origin).expect("project origin"); assert_eq!(projected.kind, api::SessionOriginKind::Subagent); @@ -4790,7 +4790,7 @@ mod tests { assert_eq!(projected.agent.revision, 4); assert_eq!( projected.limits, - subagent_limits_to_api(engine::SubagentLimits::default()) + subagent_limits_to_api(harness::SubagentLimits::default()) ); } @@ -4858,19 +4858,19 @@ mod tests { let pdf_ref = blobs.put_bytes(b"%PDF".to_vec()).await.unwrap(); let mut result = context_entry(1, tool_source.clone()); result.kind = ContextEntryKind::ToolResult { - call_id: engine::ToolCallId::new("call_1"), + call_id: harness::ToolCallId::new("call_1"), is_error: false, }; - result.content = engine::ContentRef::text(result_ref); + result.content = harness::ContentRef::text(result_ref); let mut image = context_entry(2, tool_source.clone()); - image.content = engine::ContentRef { + image.content = harness::ContentRef { content_ref: png_ref.clone(), media_type: Some("image/png".into()), provider_kind: None, }; image.preview = Some("[image]".into()); let mut pdf = context_entry(3, tool_source.clone()); - pdf.content = engine::ContentRef { + pdf.content = harness::ContentRef { content_ref: pdf_ref.clone(), media_type: Some("application/pdf".into()), provider_kind: None, @@ -4883,7 +4883,7 @@ mod tests { input_index: 0, }, ); - unrelated.content = engine::ContentRef { + unrelated.content = harness::ContentRef { content_ref: png_ref.clone(), media_type: Some("image/png".into()), provider_kind: None, @@ -4900,7 +4900,7 @@ mod tests { 2, "run-input media never attaches to a call" ); - assert_eq!(call.media[0].handle, engine::media::media_handle(&png_ref)); + assert_eq!(call.media[0].handle, harness::media::media_handle(&png_ref)); assert_eq!(call.media[0].kind, MediaKind::Image); assert_eq!(call.media[0].name, None); assert_eq!(call.media[1].mime, "application/pdf"); @@ -4908,7 +4908,7 @@ mod tests { assert_eq!(call.media[1].name.as_deref(), Some("report.pdf")); assert_eq!( content_ref_to_api(&image.content).media_handle, - Some(engine::media::media_handle(&png_ref)) + Some(harness::media::media_handle(&png_ref)) ); assert_eq!(content_ref_to_api(&result.content).media_handle, None); } @@ -4921,7 +4921,7 @@ mod tests { role: ContextMessageRole::User, }, source, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: BlobRef::default(), media_type: None, provider_kind: None, diff --git a/crates/api/Cargo.toml b/crates/api/Cargo.toml index 6e01c415e..22e205e59 100644 --- a/crates/api/Cargo.toml +++ b/crates/api/Cargo.toml @@ -9,9 +9,9 @@ async-trait = "0.1" schemars = { version = "1", features = ["uuid1"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" [dev-dependencies] -jsonschema = { version = "0.33", default-features = false } +jsonschema = { version = "0.58", default-features = false } serde_json = "1" tokio = { version = "1", features = ["macros", "rt"] } diff --git a/crates/api/contract/api.schema.json b/crates/api/contract/api.schema.json index e63c99513..ef95aaa89 100644 --- a/crates/api/contract/api.schema.json +++ b/crates/api/contract/api.schema.json @@ -7560,7 +7560,7 @@ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -7915,7 +7915,7 @@ ] }, "ContextEntryView": { - "description": "A session context entry, faithful to the stored engine entry: keyed,\nkind-tagged, ref-backed. Keys are a stable extension point — clients\nreconstruct derived surfaces (e.g. the prompted instruction set via the\n`prompt_instructions/` key prefix) by filtering on `key` and fetching\noriginal bytes through `blobs/read`. `text` contains complete message and\nvisible reasoning text; tool and catalog bodies use bounded text previews.", + "description": "A session context entry, faithful to the stored harness entry: keyed,\nkind-tagged, ref-backed. Keys are a stable extension point — clients\nreconstruct derived surfaces (e.g. the prompted instruction set via the\n`prompt_instructions/` key prefix) by filtering on `key` and fetching\noriginal bytes through `blobs/read`. `text` contains complete message and\nvisible reasoning text; tool and catalog bodies use bounded text previews.", "properties": { "citations": { "description": "Sources this assistant message cites, derived from its own native\npayload. Empty for every other entry kind.", @@ -11048,7 +11048,7 @@ }, "LimitsConfig": { "additionalProperties": false, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", @@ -13197,7 +13197,7 @@ "type": "object" }, "RunFailureKindView": { - "description": "Why a run failed, as the engine classified it.", + "description": "Why a run failed, as the harness classified it.", "oneOf": [ { "enum": [ @@ -14502,7 +14502,7 @@ "type": "object" }, { - "description": "The run ended in failure. `kind` is the engine's classification;\n`message` is free text for display, and the provider's own message for\n`request_rejected`.", + "description": "The run ended in failure. `kind` is the harness's classification;\n`message` is free text for display, and the provider's own message for\n`request_rejected`.", "properties": { "kind": { "$ref": "#/definitions/RunFailureKindView" diff --git a/crates/api/contract/openrpc.json b/crates/api/contract/openrpc.json index 162344b0c..5c68ae3a6 100644 --- a/crates/api/contract/openrpc.json +++ b/crates/api/contract/openrpc.json @@ -7560,7 +7560,7 @@ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -7915,7 +7915,7 @@ ] }, "ContextEntryView": { - "description": "A session context entry, faithful to the stored engine entry: keyed,\nkind-tagged, ref-backed. Keys are a stable extension point — clients\nreconstruct derived surfaces (e.g. the prompted instruction set via the\n`prompt_instructions/` key prefix) by filtering on `key` and fetching\noriginal bytes through `blobs/read`. `text` contains complete message and\nvisible reasoning text; tool and catalog bodies use bounded text previews.", + "description": "A session context entry, faithful to the stored harness entry: keyed,\nkind-tagged, ref-backed. Keys are a stable extension point — clients\nreconstruct derived surfaces (e.g. the prompted instruction set via the\n`prompt_instructions/` key prefix) by filtering on `key` and fetching\noriginal bytes through `blobs/read`. `text` contains complete message and\nvisible reasoning text; tool and catalog bodies use bounded text previews.", "properties": { "citations": { "description": "Sources this assistant message cites, derived from its own native\npayload. Empty for every other entry kind.", @@ -11048,7 +11048,7 @@ }, "LimitsConfig": { "additionalProperties": false, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", @@ -13197,7 +13197,7 @@ "type": "object" }, "RunFailureKindView": { - "description": "Why a run failed, as the engine classified it.", + "description": "Why a run failed, as the harness classified it.", "oneOf": [ { "enum": [ @@ -14502,7 +14502,7 @@ "type": "object" }, { - "description": "The run ended in failure. `kind` is the engine's classification;\n`message` is free text for display, and the provider's own message for\n`request_rejected`.", + "description": "The run ended in failure. `kind` is the harness's classification;\n`message` is free text for display, and the provider's own message for\n`request_rejected`.", "properties": { "kind": { "$ref": "#/components/schemas/RunFailureKindView" diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index f7944e68e..facbdcd92 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,6 +1,6 @@ //! Client-facing API contracts for Lightspeed agents. //! -//! This crate is intentionally independent of `engine` core types. Hosts +//! This crate is intentionally independent of `harness` core types. Hosts //! can implement these contracts from a local event-log runner, a Temporal //! workflow gateway, or another substrate while clients keep speaking the same //! session/run/item protocol. diff --git a/crates/api/src/sessions.rs b/crates/api/src/sessions.rs index 8244831df..b1350b13e 100644 --- a/crates/api/src/sessions.rs +++ b/crates/api/src/sessions.rs @@ -327,7 +327,7 @@ pub enum ToolChoice { Specific { tool_id: String }, } -/// Run budget defaults enforced by the engine drive loop. +/// Run budget defaults enforced by the harness drive loop. #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct LimitsConfig { @@ -343,7 +343,7 @@ pub struct ContextConfig { /// Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors. #[serde(default, skip_serializing_if = "Option::is_none")] pub input_limit_tokens: Option, - /// Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery. + /// Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery. #[serde(default, skip_serializing_if = "Option::is_none")] pub compaction: Option, } @@ -1452,7 +1452,7 @@ pub enum SessionEventKindView { run_id: RunId, output: Option, }, - /// The run ended in failure. `kind` is the engine's classification; + /// The run ended in failure. `kind` is the harness's classification; /// `message` is free text for display, and the provider's own message for /// `request_rejected`. RunFailed { @@ -1632,7 +1632,7 @@ pub enum SessionEventKindView { }, } -/// Why a run failed, as the engine classified it. +/// Why a run failed, as the harness classified it. #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum RunFailureKindView { diff --git a/crates/api/src/views.rs b/crates/api/src/views.rs index 7253206bc..5290efb24 100644 --- a/crates/api/src/views.rs +++ b/crates/api/src/views.rs @@ -515,7 +515,7 @@ pub enum TokenEstimateQualityView { Estimated, } -/// A session context entry, faithful to the stored engine entry: keyed, +/// A session context entry, faithful to the stored harness entry: keyed, /// kind-tagged, ref-backed. Keys are a stable extension point — clients /// reconstruct derived surfaces (e.g. the prompted instruction set via the /// `prompt_instructions/` key prefix) by filtering on `key` and fetching diff --git a/crates/api/tests/schema_artifacts.rs b/crates/api/tests/schema_artifacts.rs index f470bbcd0..6c0bf830d 100644 --- a/crates/api/tests/schema_artifacts.rs +++ b/crates/api/tests/schema_artifacts.rs @@ -60,7 +60,7 @@ fn assert_validates(bundle: &Value, definition: &str, instance: &Value) { let validator = jsonschema::validator_for(&schema).expect("schema compiles"); let errors: Vec = validator .iter_errors(instance) - .map(|error| format!("{} at {}", error, error.instance_path)) + .map(|error| format!("{} at {}", error, error.instance_path())) .collect(); assert!( errors.is_empty(), diff --git a/crates/auth/Cargo.toml b/crates/auth/Cargo.toml index 49b35cab7..81d3624e0 100644 --- a/crates/auth/Cargo.toml +++ b/crates/auth/Cargo.toml @@ -6,19 +6,19 @@ edition = "2024" [dependencies] api = { path = "../api" } async-trait = "0.1" -base64 = "0.22" -engine = { path = "../engine" } +base64 = "0.23" +harness = { path = "../harness" } futures-util = "0.3" hex = "0.4" -jsonwebtoken = "9" +jsonwebtoken = { version = "11", features = ["aws_lc_rs"] } oauth2 = { version = "5", default-features = false } -rand = "0.8" +rand = "0.10" reqwest = { version = "0.13", default-features = false, features = ["form", "json", "rustls", "stream"] } rmcp = { version = "3.1.4", default-features = false, features = ["auth", "client"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" -thiserror = "1" +sha2 = "0.11" +thiserror = "2" tokio = { version = "1", features = ["net", "sync", "time"] } [dev-dependencies] diff --git a/crates/auth/README.md b/crates/auth/README.md index 6711e0859..f7cc82169 100644 --- a/crates/auth/README.md +++ b/crates/auth/README.md @@ -5,7 +5,7 @@ Generic auth grant, secret, and token-broker substrate for Lightspeed. The crate defines the provider-independent records and traits; persistence and encryption live in store adapters (`store-pg` stores secrets AES-256-GCM encrypted at rest), and resolution happens only inside runtime activity -execution — never in the engine or the session log. +execution — never in the harness or the session log. ## What it provides @@ -60,13 +60,13 @@ execution — never in the engine or the session log. ## How it works -For MCP, sessions and the engine record only `SecretRef { namespace: +For MCP, sessions and the harness record only `SecretRef { namespace: "mcp_server", id: server_id }`; the universe server record owns the current grant binding. At LLM-call time the runtime reads that binding and asks the broker for a token for the admitted resource URL. The token is injected into the outgoing provider request at the last moment, while the persisted request blob keeps `"authorization": ""`. Plaintext tokens never enter -engine events, CAS blobs, Temporal history, API responses, or logs. The +harness events, CAS blobs, Temporal history, API responses, or logs. The three deliberate inbound-plaintext paths are `auth/grants/import` (bearer token), `auth/clients/create` (client secret), and `auth/providers/create` (GitHub App private key); all encrypt on receipt and redact `Debug` output. @@ -96,7 +96,7 @@ for testing. ```bash # 0. once: infra + env, gateway in its own terminal ./dev.sh infra && source scripts/dev/env.sh -cargo run -p temporal-server +cargo run -p temporal-runtime # separate terminal, env.sh sourced # 1. register the authenticated MCP server @@ -209,8 +209,8 @@ broker's automatic refresh path. ```bash # 0. infra + schema, env in every terminal; gateway in its own terminal ./dev.sh infra && source scripts/dev/env.sh -cargo run -p temporal-server -- migrate -cargo run -p temporal-server # separate terminal, env.sh sourced +cargo run -p temporal-runtime -- migrate +cargo run -p temporal-runtime # separate terminal, env.sh sourced # 1. register the MCP server under id gh cargo run -q -p cli -- mcp server put https://api.githubcopilot.com/mcp/ \ diff --git a/crates/auth/src/lib.rs b/crates/auth/src/lib.rs index 44a8cfc49..e510c9d88 100644 --- a/crates/auth/src/lib.rs +++ b/crates/auth/src/lib.rs @@ -6,7 +6,7 @@ //! drivers arrive in later milestones. Secret values only ever cross these //! boundaries wrapped in [`SecretValue`], whose `Debug` output is redacted. -use engine::{StringIdError, validate_general_string_id}; +use harness::{StringIdError, validate_general_string_id}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use std::fmt; use std::str::FromStr; @@ -217,10 +217,12 @@ pub enum AuthRegistryError { /// Generate a random id with the given prefix: `prefix` + 32 lowercase hex /// characters from the OS RNG (128 bits). pub fn random_auth_id(prefix: &str) -> String { - use rand::RngCore; + use rand::TryRng; let mut bytes = [0u8; 16]; - rand::rngs::OsRng.fill_bytes(&mut bytes); + rand::rngs::SysRng + .try_fill_bytes(&mut bytes) + .expect("OS random source unavailable"); format!("{prefix}{}", hex::encode(bytes)) } diff --git a/crates/auth/src/oauth.rs b/crates/auth/src/oauth.rs index 088c0a0a6..ade73954a 100644 --- a/crates/auth/src/oauth.rs +++ b/crates/auth/src/oauth.rs @@ -446,10 +446,12 @@ pub fn pkce_challenge_s256(verifier: &SecretValue) -> String { } fn random_url_safe(len: usize) -> String { - use rand::RngCore; + use rand::TryRng; let mut bytes = vec![0u8; len]; - rand::rngs::OsRng.fill_bytes(&mut bytes); + rand::rngs::SysRng + .try_fill_bytes(&mut bytes) + .expect("OS random source unavailable"); URL_SAFE_NO_PAD.encode(bytes) } diff --git a/crates/auth/src/secrets.rs b/crates/auth/src/secrets.rs index 3b91d9129..899e838cf 100644 --- a/crates/auth/src/secrets.rs +++ b/crates/auth/src/secrets.rs @@ -52,10 +52,12 @@ impl From<&str> for SecretValue { /// kinds have the same entropy, hashing, and display conventions. pub fn generate_prefixed_secret(prefix: &str) -> String { use base64::Engine as _; - use rand::RngCore; + use rand::TryRng; let mut bytes = [0u8; 32]; - rand::rngs::OsRng.fill_bytes(&mut bytes); + rand::rngs::SysRng + .try_fill_bytes(&mut bytes) + .expect("OS random source unavailable"); format!( "{prefix}{}", base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes) diff --git a/crates/bots/Cargo.toml b/crates/bots/Cargo.toml index 396bc3719..ef1b2be73 100644 --- a/crates/bots/Cargo.toml +++ b/crates/bots/Cargo.toml @@ -11,13 +11,13 @@ chrono = { version = "0.4", default-features = false, features = ["std", "clock" chrono-tz = "0.10" cron = "0.17" hex = "0.4" -hmac = "0.12" +hmac = "0.13" schemars = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" +sha2 = "0.11" subtle = "2" -thiserror = "1" +thiserror = "2" uuid = { version = "1", features = ["serde", "v4"] } [dev-dependencies] diff --git a/crates/bots/src/lib.rs b/crates/bots/src/lib.rs index e867ab837..7b3bafa42 100644 --- a/crates/bots/src/lib.rs +++ b/crates/bots/src/lib.rs @@ -3,7 +3,7 @@ //! //! Wire DTOs live in `api`; this crate adds what the runtime needs around //! them and nothing that does I/O. The Temporal workflows live in -//! `temporal-workflow`, the activities and service in `temporal-server`, the +//! `temporal-workflow`, the activities and service in `temporal-runtime`, the //! tables in `store-pg`. //! //! Module map: diff --git a/crates/bots/src/webhook.rs b/crates/bots/src/webhook.rs index daa1c419e..9120d8209 100644 --- a/crates/bots/src/webhook.rs +++ b/crates/bots/src/webhook.rs @@ -7,7 +7,7 @@ use std::collections::BTreeMap; use api::{WebhookPreset, WebhookVerification}; -use hmac::{Hmac, Mac}; +use hmac::{Hmac, KeyInit, Mac}; use serde_json::{Map, Value}; use sha2::Sha256; use subtle::ConstantTimeEq; diff --git a/crates/channels/Cargo.toml b/crates/channels/Cargo.toml index cc4548145..12a980863 100644 --- a/crates/channels/Cargo.toml +++ b/crates/channels/Cargo.toml @@ -12,8 +12,8 @@ hex = "0.4" schemars = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" -thiserror = "1" +sha2 = "0.11" +thiserror = "2" uuid = { version = "1", features = ["serde", "v4"] } [dev-dependencies] diff --git a/crates/channels/src/lib.rs b/crates/channels/src/lib.rs index 337d307f9..336849ec0 100644 --- a/crates/channels/src/lib.rs +++ b/crates/channels/src/lib.rs @@ -5,7 +5,7 @@ //! A chat connection is a bot trigger of kind `chat`; this crate holds //! what that trigger points at and the conversation-side logic. The //! conversation workflow lives in `temporal-workflow`, its activities and -//! the control plane in `temporal-server`, the tables in `store-pg`, and +//! the control plane in `temporal-runtime`, the tables in `store-pg`, and //! the provider bridges (Telegram, WhatsApp) in `platform/connectors`. //! //! Module map: diff --git a/crates/channels/src/state.rs b/crates/channels/src/state.rs index 979cb5341..637e92760 100644 --- a/crates/channels/src/state.rs +++ b/crates/channels/src/state.rs @@ -401,7 +401,7 @@ impl ReceivedInvocation { // ── Emissions ─────────────────────────────────────────────────────────────── /// The facts of a delivered emission the conversation cares about; the -/// substrate adapter projects the engine envelope onto this. +/// substrate adapter projects the harness envelope onto this. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ConversationEmission { diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index cc76bcf8c..6169c4615 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -6,18 +6,18 @@ edition = "2024" [dependencies] anyhow = "1" async-trait = "0.1" -base64 = "0.22" +base64 = "0.23" clap = { version = "4", features = ["derive", "env"] } -crossterm = { version = "0.28", features = ["bracketed-paste", "event-stream"] } +crossterm = { version = "0.29", features = ["bracketed-paste", "event-stream"] } dotenvy = "0.15" api = { path = "../api" } -engine = { path = "../engine" } +harness = { path = "../harness" } futures-util = "0.3" -pulldown-cmark = "0.10" +pulldown-cmark = "0.13" serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = { version = "1", features = ["macros", "rt", "signal", "sync", "time"] } -ratatui = "0.29" +ratatui = "0.30" reqwest = { version = "0.13", default-features = false, features = ["json", "rustls"] } release-info = { path = "../release-info" } unicode-width = "0.2" diff --git a/crates/cli/src/chat/tui/insert_history.rs b/crates/cli/src/chat/tui/insert_history.rs index 3952fe692..095701d9c 100644 --- a/crates/cli/src/chat/tui/insert_history.rs +++ b/crates/cli/src/chat/tui/insert_history.rs @@ -9,6 +9,7 @@ use crossterm::style::{ SetForegroundColor, }; use crossterm::terminal::{Clear, ClearType}; +use ratatui::backend::IntoCrossterm; use ratatui::style::{Color, Modifier}; use ratatui::text::{Line, Span}; @@ -186,11 +187,11 @@ fn write_history_line(writer: &mut W, line: &Line<'_>, wrap_width: usi SetColors(Colors::new( line.style .fg - .map(Into::into) + .map(IntoCrossterm::into_crossterm) .unwrap_or(CrosstermColor::Reset), line.style .bg - .map(Into::into) + .map(IntoCrossterm::into_crossterm) .unwrap_or(CrosstermColor::Reset), )), Clear(ClearType::UntilNewLine) @@ -232,7 +233,10 @@ where if next_fg != fg || next_bg != bg { queue!( writer, - SetColors(Colors::new(next_fg.into(), next_bg.into())) + SetColors(Colors::new( + next_fg.into_crossterm(), + next_bg.into_crossterm() + )) )?; fg = next_fg; bg = next_bg; diff --git a/crates/cli/src/chat/tui/markdown.rs b/crates/cli/src/chat/tui/markdown.rs index 6f1b2b403..0fe3a02eb 100644 --- a/crates/cli/src/chat/tui/markdown.rs +++ b/crates/cli/src/chat/tui/markdown.rs @@ -71,7 +71,9 @@ impl MarkdownWriter { match event { Event::Start(tag) => self.start_tag(tag), Event::End(tag) => self.end_tag(tag), - Event::Text(text) => self.text(text), + Event::Text(text) | Event::InlineMath(text) | Event::DisplayMath(text) => { + self.text(text) + } Event::Code(code) => self.code(code), Event::SoftBreak | Event::HardBreak => self.soft_break(), Event::Rule => self.rule(), @@ -84,7 +86,7 @@ impl MarkdownWriter { match tag { Tag::Paragraph => self.start_paragraph(), Tag::Heading { level, .. } => self.start_heading(level), - Tag::BlockQuote => self.start_blockquote(), + Tag::BlockQuote(_) => self.start_blockquote(), Tag::CodeBlock(kind) => self.start_code_block(kind), Tag::List(start) => self.list_stack.push(ListContext { next_number: start }), Tag::Item => self.start_item(), @@ -103,7 +105,12 @@ impl MarkdownWriter { | Tag::TableRow | Tag::TableCell | Tag::Image { .. } - | Tag::MetadataBlock(_) => {} + | Tag::MetadataBlock(_) + | Tag::DefinitionList + | Tag::DefinitionListTitle + | Tag::DefinitionListDefinition + | Tag::Superscript + | Tag::Subscript => {} } } @@ -118,7 +125,7 @@ impl MarkdownWriter { self.pop_inline_style(); self.needs_blank = true; } - TagEnd::BlockQuote => { + TagEnd::BlockQuote(_) => { self.flush_current(); self.block_stack.pop(); self.needs_blank = true; @@ -142,7 +149,12 @@ impl MarkdownWriter { | TagEnd::TableRow | TagEnd::TableCell | TagEnd::Image - | TagEnd::MetadataBlock(_) => {} + | TagEnd::MetadataBlock(_) + | TagEnd::DefinitionList + | TagEnd::DefinitionListTitle + | TagEnd::DefinitionListDefinition + | TagEnd::Superscript + | TagEnd::Subscript => {} } } diff --git a/crates/cli/src/vfs_transfer.rs b/crates/cli/src/vfs_transfer.rs index 5f1518b66..9da84a2ef 100644 --- a/crates/cli/src/vfs_transfer.rs +++ b/crates/cli/src/vfs_transfer.rs @@ -10,7 +10,7 @@ use api::{ }; use async_trait::async_trait; use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64}; -use engine::BlobRef; +use harness::BlobRef; use serde::Serialize; use vfs::{ VfsDirectory, VfsEntry, VfsFile, VfsPath, VfsSnapshotLimits, VfsSnapshotManifest, diff --git a/crates/environment-client/Cargo.toml b/crates/environment-client/Cargo.toml index a750b18ff..b868be79b 100644 --- a/crates/environment-client/Cargo.toml +++ b/crates/environment-client/Cargo.toml @@ -9,9 +9,9 @@ futures-util = "0.3" environment-protocol = { path = "../environment-protocol" } serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" tokio = { version = "1", features = ["net"] } -tokio-tungstenite = { version = "0.26", default-features = false, features = ["connect", "rustls-tls-webpki-roots"] } +tokio-tungstenite = { version = "0.30", default-features = false, features = ["connect", "rustls-tls-webpki-roots"] } [dev-dependencies] tokio = { version = "1", features = ["macros", "rt", "time"] } diff --git a/crates/environment-daemon/Cargo.toml b/crates/environment-daemon/Cargo.toml index cc76f7da5..c415affcf 100644 --- a/crates/environment-daemon/Cargo.toml +++ b/crates/environment-daemon/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition = "2024" [dependencies] +hex = "0.4" anyhow = "1" api = { path = "../api" } clap = { version = "4", features = ["derive", "env"] } @@ -20,14 +21,14 @@ portable-pty = "0.9" reqwest = { version = "0.13", default-features = false, features = ["json", "rustls", "stream"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" +sha2 = "0.11" tar = { version = "0.4", default-features = false } tempfile = "3" -thiserror = "1" +thiserror = "2" tokio = { version = "1", features = ["fs", "io-util", "macros", "net", "process", "rt", "signal", "sync", "time"] } -tokio-tungstenite = { version = "0.26", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] } -ed25519-dalek = { version = "2", features = ["rand_core"] } -rand = "0.8" +tokio-tungstenite = { version = "0.30", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] } +ed25519-dalek = { version = "3", features = ["rand_core"] } +rand = "0.10" rustls = { version = "0.23", default-features = false, features = ["aws_lc_rs", "std", "tls12", "logging"] } rustls-pki-types = { version = "1", features = ["std"] } webpki-roots = "1.0" @@ -42,7 +43,7 @@ libc = "0.2" async-trait = "0.1" store-fs = { path = "../store-fs" } vfs = { path = "../vfs" } -engine = { path = "../engine" } +harness = { path = "../harness" } environment-client = { path = "../environment-client" } tools = { path = "../tools" } diff --git a/crates/environment-daemon/src/filesystem/backend/mod.rs b/crates/environment-daemon/src/filesystem/backend/mod.rs index 64974f45e..d07fa92bc 100644 --- a/crates/environment-daemon/src/filesystem/backend/mod.rs +++ b/crates/environment-daemon/src/filesystem/backend/mod.rs @@ -58,7 +58,7 @@ pub(crate) fn valid_digest(value: &str) -> bool { }) } pub(crate) fn digest(hash: Sha256) -> String { - format!("sha256:{:x}", hash.finalize()) + format!("sha256:{}", hex::encode(hash.finalize())) } pub(crate) fn relative( root: &Path, diff --git a/crates/environment-daemon/src/filesystem/transfer/mod.rs b/crates/environment-daemon/src/filesystem/transfer/mod.rs index 97d19289a..712cf9f78 100644 --- a/crates/environment-daemon/src/filesystem/transfer/mod.rs +++ b/crates/environment-daemon/src/filesystem/transfer/mod.rs @@ -158,7 +158,7 @@ pub(super) async fn materialize( if bytes > quota.max_total_bytes { return Err(invalid("inline byte quota exceeded")); } - let digest = format!("sha256:{:x}", Sha256::digest(data.as_slice())); + let digest = format!("sha256:{}", hex::encode(Sha256::digest(data.as_slice()))); content.insert(digest.clone(), data.as_slice()); InventoryContent::File { digest, diff --git a/crates/environment-daemon/src/filesystem/transfer/session.rs b/crates/environment-daemon/src/filesystem/transfer/session.rs index b249c8364..72d99c2ed 100644 --- a/crates/environment-daemon/src/filesystem/transfer/session.rs +++ b/crates/environment-daemon/src/filesystem/transfer/session.rs @@ -1357,7 +1357,7 @@ mod tests { content: InventoryContent::File { size_bytes: bytes.len() as u64, executable: false, - digest: engine::BlobRef::from_bytes(bytes).to_string(), + digest: harness::BlobRef::from_bytes(bytes).to_string(), }, }); } diff --git a/crates/environment-daemon/src/filesystem/transfer/tests.rs b/crates/environment-daemon/src/filesystem/transfer/tests.rs index 334877a99..f87d22a20 100644 --- a/crates/environment-daemon/src/filesystem/transfer/tests.rs +++ b/crates/environment-daemon/src/filesystem/transfer/tests.rs @@ -1,14 +1,14 @@ use super::*; use async_trait::async_trait; -use engine::{ - BlobRef, - storage::{BlobSource, BlobStore, BlobStoreError}, -}; use environment_client::{EnvironmentClientResult, EnvironmentDataClient, JsonRpcTransport}; use environment_protocol::{ data::{inventory::*, transfer_session::*}, shared::EnvironmentPath, }; +use harness::{ + BlobRef, + storage::{BlobSource, BlobStore, BlobStoreError}, +}; use std::path::Path; use std::{ os::unix::fs::{PermissionsExt, symlink}, @@ -120,7 +120,7 @@ fn repeated_ref(size: u64) -> BlobRef { hash.update(&chunk[..n]); remaining -= n as u64; } - BlobRef::parse(format!("sha256:{:x}", hash.finalize())).unwrap() + BlobRef::parse(format!("sha256:{}", hex::encode(hash.finalize()))).unwrap() } #[tokio::test(flavor = "current_thread")] async fn rpc_vfs_roundtrip_streams_large_files_reuses_bytes_and_preserves_retry_receipt() { @@ -431,7 +431,7 @@ async fn rpc_materialize_creates_missing_parents_for_files_and_trees() { let environment = tempfile::tempdir().unwrap(); std::fs::write(environment.path().join("sibling"), b"preserved").unwrap(); let (remote, _, _) = remote(runtime(environment.path(), false)); - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let entry = vfs::VfsEntry::File(vfs::VfsFile { blob_ref: store.put_bytes(b"content".to_vec()).await.unwrap(), size_bytes: 7, @@ -584,7 +584,7 @@ async fn secure_replacement_rejects_links_and_uses_private_staging_without_readi .await .unwrap(); let (remote, _, _) = remote(runtime.clone()); - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob = store.put_bytes(b"new".to_vec()).await.unwrap(); let entry = vfs::VfsEntry::File(vfs::VfsFile { blob_ref: blob, @@ -932,7 +932,7 @@ async fn scan_installer_layouts_aliases_collisions_and_semantic_publication() { std::fs::write(home.join(".codex/skills/copy/SKILL.md"), doc).unwrap(); symlink(&canonical, root.join("project/.agents/skills/review")).unwrap(); symlink(&canonical, root.join("project/.agents/skills/alias")).unwrap(); - let config = engine::EnvironmentSkillsConfig { + let config = harness::EnvironmentSkillsConfig { roots: Some(vec![ root.join("project/.agents/skills") .to_string_lossy() @@ -980,8 +980,8 @@ async fn scan_installer_layouts_aliases_collisions_and_semantic_publication() { .unwrap() .ends_with("body two") ); - let blobs = engine::storage::InMemoryBlobStore::new(); - let Some(engine::CoreAgentCommand::UpsertContext { entry, .. }) = + let blobs = harness::storage::InMemoryBlobStore::new(); + let Some(harness::CoreAgentCommand::UpsertContext { entry, .. }) = publish_environment_skill_catalog(&blobs, None, &catalog) .await .unwrap() diff --git a/crates/environment-daemon/src/identity.rs b/crates/environment-daemon/src/identity.rs index c863174e3..bfe1ed4e5 100644 --- a/crates/environment-daemon/src/identity.rs +++ b/crates/environment-daemon/src/identity.rs @@ -53,7 +53,10 @@ impl DaemonIdentity { std::fs::create_dir_all(state_dir) .with_context(|| format!("create state dir {}", state_dir.display()))?; restrict_dir(state_dir)?; - let signing_key = SigningKey::generate(&mut rand::rngs::OsRng); + let mut seed = [0u8; 32]; + rand::TryRng::try_fill_bytes(&mut rand::rngs::SysRng, &mut seed) + .context("generate daemon identity seed")?; + let signing_key = SigningKey::from_bytes(&seed); let temp = state_dir.join(format!(".{DAEMON_KEY_FILE}.{}", std::process::id())); write_private(&temp, &encode_hex(&signing_key.to_bytes()))?; if let Err(error) = std::fs::rename(&temp, &path) { diff --git a/crates/environment-daemon/src/registration.rs b/crates/environment-daemon/src/registration.rs index fea3d546d..23b230f8c 100644 --- a/crates/environment-daemon/src/registration.rs +++ b/crates/environment-daemon/src/registration.rs @@ -467,8 +467,8 @@ impl TlsSettings { } fn jittered(base: Duration) -> Duration { - use rand::Rng as _; - let factor = rand::thread_rng().gen_range(0.75_f64..=1.25_f64); + use rand::RngExt as _; + let factor = rand::rng().random_range(0.75_f64..=1.25_f64); base.mul_f64(factor) } diff --git a/crates/environment-daemon/src/upgrade.rs b/crates/environment-daemon/src/upgrade.rs index 7a714ccfb..013539645 100644 --- a/crates/environment-daemon/src/upgrade.rs +++ b/crates/environment-daemon/src/upgrade.rs @@ -298,7 +298,7 @@ async fn download_archive( file.as_file_mut() .rewind() .context("rewind temporary envd archive")?; - Ok((file, format!("{:x}", sha.finalize()))) + Ok((file, hex::encode(sha.finalize()))) } fn extract_binary( @@ -539,7 +539,7 @@ mod tests { release_info::TARGET ); let archive = envd_archive(script.as_bytes()); - let archive_sha = format!("{:x}", Sha256::digest(&archive)); + let archive_sha = hex::encode(Sha256::digest(&archive)); let (origin, server) = serve_upgrade_with_document(archive, |origin| { discovery_json(origin, &archive_sha, &git_sha, 3) }) diff --git a/crates/environment-protocol/Cargo.toml b/crates/environment-protocol/Cargo.toml index f53f5df01..0fde6fb84 100644 --- a/crates/environment-protocol/Cargo.toml +++ b/crates/environment-protocol/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] -base64 = "0.22" +base64 = "0.23" serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" diff --git a/crates/environment-provider-incus/Cargo.toml b/crates/environment-provider-incus/Cargo.toml index b57a2c25b..6ac582bff 100644 --- a/crates/environment-provider-incus/Cargo.toml +++ b/crates/environment-provider-incus/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] anyhow = "1" async-trait = "0.1" -axum = { version = "0.7", features = ["ws"] } +axum = { version = "0.8", features = ["ws"] } clap = { version = "4", features = ["derive", "env"] } dotenvy = "0.15" futures-util = "0.3" @@ -15,10 +15,10 @@ reqwest = { version = "0.13", default-features = false, features = ["json", "rus release-info = { path = "../release-info" } serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" -thiserror = "1" +sha2 = "0.11" +thiserror = "2" tokio = { version = "1", features = ["fs", "macros", "net", "rt-multi-thread", "signal", "sync", "time"] } -tokio-tungstenite = { version = "0.26", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] } +tokio-tungstenite = { version = "0.30", default-features = false, features = ["connect", "handshake", "rustls-tls-webpki-roots"] } uuid = { version = "1", features = ["v4"] } [dev-dependencies] diff --git a/crates/environment-provider-incus/README.md b/crates/environment-provider-incus/README.md index 38a1d0dc6..1f48afeea 100644 --- a/crates/environment-provider-incus/README.md +++ b/crates/environment-provider-incus/README.md @@ -3,7 +3,7 @@ `lightspeed-provider-incus` is a stateless controller, passive data endpoint, optional application edge, and single-node/cluster Incus adapter. It depends on the public host -protocol crate, not Lightspeed's database, API implementation, engine, or +protocol crate, not Lightspeed's database, API implementation, harness, or Temporal runtime. Start from `config.example.json`. Application-level authentication for both diff --git a/crates/environment-provider-incus/src/edge.rs b/crates/environment-provider-incus/src/edge.rs index 0fb5194dc..e3812d70d 100644 --- a/crates/environment-provider-incus/src/edge.rs +++ b/crates/environment-provider-incus/src/edge.rs @@ -58,7 +58,7 @@ async fn authorize( async fn proxy( State(state): State>, - upgrade: Option, + upgrade: Result, method: Method, uri: Uri, headers: HeaderMap, @@ -78,7 +78,7 @@ async fn proxy( .path_and_query() .map(|value| value.as_str()) .unwrap_or("/"); - if let Some(upgrade) = upgrade { + if let Ok(upgrade) = upgrade { let endpoint = format!("ws://{}:{}{}", route.address, route.port, path); return upgrade .on_upgrade(move |socket| proxy_websocket(socket, endpoint)) @@ -154,9 +154,9 @@ async fn proxy_websocket(mut client: WebSocket, endpoint: String) { let close = matches!(message, axum::extract::ws::Message::Close(_)); let mapped = match message { axum::extract::ws::Message::Text(v) => UpstreamMessage::Text(v.to_string().into()), - axum::extract::ws::Message::Binary(v) => UpstreamMessage::Binary(v.to_vec().into()), - axum::extract::ws::Message::Ping(v) => UpstreamMessage::Ping(v.to_vec().into()), - axum::extract::ws::Message::Pong(v) => UpstreamMessage::Pong(v.to_vec().into()), + axum::extract::ws::Message::Binary(v) => UpstreamMessage::Binary(v), + axum::extract::ws::Message::Ping(v) => UpstreamMessage::Ping(v), + axum::extract::ws::Message::Pong(v) => UpstreamMessage::Pong(v), axum::extract::ws::Message::Close(_) => UpstreamMessage::Close(None), }; if upstream.send(mapped).await.is_err() || close { break } @@ -167,10 +167,10 @@ async fn proxy_websocket(mut client: WebSocket, endpoint: String) { Some(Ok(message)) => { let close = matches!(message, UpstreamMessage::Close(_)); let mapped = match message { - UpstreamMessage::Text(v) => axum::extract::ws::Message::Text(v.to_string()), - UpstreamMessage::Binary(v) => axum::extract::ws::Message::Binary(v.to_vec()), - UpstreamMessage::Ping(v) => axum::extract::ws::Message::Ping(v.to_vec()), - UpstreamMessage::Pong(v) => axum::extract::ws::Message::Pong(v.to_vec()), + UpstreamMessage::Text(v) => axum::extract::ws::Message::Text(v.to_string().into()), + UpstreamMessage::Binary(v) => axum::extract::ws::Message::Binary(v), + UpstreamMessage::Ping(v) => axum::extract::ws::Message::Ping(v), + UpstreamMessage::Pong(v) => axum::extract::ws::Message::Pong(v), UpstreamMessage::Close(_) => axum::extract::ws::Message::Close(None), UpstreamMessage::Frame(_) => continue, }; diff --git a/crates/environment-provider-incus/src/relay.rs b/crates/environment-provider-incus/src/relay.rs index 6f93e5a5e..6ac992bd1 100644 --- a/crates/environment-provider-incus/src/relay.rs +++ b/crates/environment-provider-incus/src/relay.rs @@ -97,19 +97,19 @@ enum Event { fn to_guest(message: AxumMessage) -> Option { Some(match message { AxumMessage::Text(value) => TungsteniteMessage::Text(value.to_string().into()), - AxumMessage::Binary(value) => TungsteniteMessage::Binary(value.to_vec().into()), - AxumMessage::Ping(value) => TungsteniteMessage::Ping(value.to_vec().into()), - AxumMessage::Pong(value) => TungsteniteMessage::Pong(value.to_vec().into()), + AxumMessage::Binary(value) => TungsteniteMessage::Binary(value), + AxumMessage::Ping(value) => TungsteniteMessage::Ping(value), + AxumMessage::Pong(value) => TungsteniteMessage::Pong(value), AxumMessage::Close(_) => TungsteniteMessage::Close(None), }) } fn to_lightspeed(message: TungsteniteMessage) -> Option { match message { - TungsteniteMessage::Text(value) => Some(AxumMessage::Text(value.to_string())), - TungsteniteMessage::Binary(value) => Some(AxumMessage::Binary(value.to_vec())), - TungsteniteMessage::Ping(value) => Some(AxumMessage::Ping(value.to_vec())), - TungsteniteMessage::Pong(value) => Some(AxumMessage::Pong(value.to_vec())), + TungsteniteMessage::Text(value) => Some(AxumMessage::Text(value.to_string().into())), + TungsteniteMessage::Binary(value) => Some(AxumMessage::Binary(value)), + TungsteniteMessage::Ping(value) => Some(AxumMessage::Ping(value)), + TungsteniteMessage::Pong(value) => Some(AxumMessage::Pong(value)), TungsteniteMessage::Close(_) => Some(AxumMessage::Close(None)), TungsteniteMessage::Frame(_) => None, } diff --git a/crates/environment-provider-incus/src/server.rs b/crates/environment-provider-incus/src/server.rs index c9380c777..f6090c2e3 100644 --- a/crates/environment-provider-incus/src/server.rs +++ b/crates/environment-provider-incus/src/server.rs @@ -49,7 +49,7 @@ pub async fn serve(config: Config, backend: B) -> anyhow::Resul .route("/health", get(health::)) .route("/control", get(upgrade::)) .route( - "/routes/:universe/:binding/:environment/:incarnation/:target", + "/routes/{universe}/{binding}/{environment}/{incarnation}/{target}", get(data_upgrade::), ) .with_state(App { @@ -125,7 +125,7 @@ async fn connection(app: App, mut socket: WebSocket) { Message::Text(text) => { let response = dispatch(&app, &text).await; if socket - .send(Message::Text(response.to_string())) + .send(Message::Text(response.to_string().into())) .await .is_err() { diff --git a/crates/environments/Cargo.toml b/crates/environments/Cargo.toml index 66426c821..b6d0c1e42 100644 --- a/crates/environments/Cargo.toml +++ b/crates/environments/Cargo.toml @@ -6,12 +6,12 @@ edition = "2024" [dependencies] async-trait = "0.1" auth = { path = "../auth" } -engine = { path = "../engine" } +harness = { path = "../harness" } environment-protocol = { path = "../environment-protocol" } serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" -thiserror = "1" +sha2 = "0.11" +thiserror = "2" uuid = { version = "1", features = ["serde", "v4"] } [dev-dependencies] diff --git a/crates/environments/src/lib.rs b/crates/environments/src/lib.rs index d166cc8bd..85001130d 100644 --- a/crates/environments/src/lib.rs +++ b/crates/environments/src/lib.rs @@ -8,13 +8,13 @@ use std::{collections::BTreeMap, fmt, str::FromStr}; use async_trait::async_trait; use auth::{AuthGrantId, AuthProviderId, SecretId, SecretValue}; -pub use engine::EnvironmentId; -use engine::{StringIdError, validate_general_string_id}; pub use environment_protocol::control::targets::PowerState; use environment_protocol::{ control::targets::EnvironmentTemplate, shared::{EnvironmentTransport, ProviderTargetId}, }; +pub use harness::EnvironmentId; +use harness::{StringIdError, validate_general_string_id}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use thiserror::Error; use uuid::Uuid; diff --git a/crates/environments/src/memory.rs b/crates/environments/src/memory.rs index c1a8cab32..fe9693f2e 100644 --- a/crates/environments/src/memory.rs +++ b/crates/environments/src/memory.rs @@ -619,7 +619,9 @@ impl EnvironmentStore for InMemoryEnvironmentRegistryStore { .as_ref() .is_none_or(|id| record.registration_key_id() == Some(id)) }) - .filter(|record| engine::storage::metadata_matches(&record.metadata, &request.metadata)) + .filter(|record| { + harness::storage::metadata_matches(&record.metadata, &request.metadata) + }) .cloned() .collect()) } diff --git a/crates/eval/Cargo.toml b/crates/eval/Cargo.toml index 6fccbf921..e9b630d30 100644 --- a/crates/eval/Cargo.toml +++ b/crates/eval/Cargo.toml @@ -8,7 +8,7 @@ anyhow = "1" async-trait = "0.1" clap = { version = "4", features = ["derive"] } dotenvy = "0.15" -engine = { path = "../engine" } +harness = { path = "../harness" } api = { path = "../api" } api-projection = { path = "../api-projection" } llm-runtime = { path = "../llm-runtime" } diff --git a/crates/eval/src/main.rs b/crates/eval/src/main.rs index 4b77b6081..0d5012678 100644 --- a/crates/eval/src/main.rs +++ b/crates/eval/src/main.rs @@ -13,7 +13,7 @@ use api_projection::{ use async_trait::async_trait; use casefile::{EvalCase, FileExpectation, SetupFile, load_cases}; use clap::{Parser, Subcommand}; -use engine::{ +use harness::{ ContextConfig, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextMessageRole, CoreAgentCommand, GenerationConfig, LimitsConfig, ModelSelection, ProviderApiKind, RunConfig, SessionConfig, SessionId, ToolName, ToolSpec, @@ -567,20 +567,20 @@ struct EvalRuntime { sessions: Arc, blobs: Arc, config: SessionConfig, - instructions_ref: engine::BlobRef, + instructions_ref: harness::BlobRef, tool_set: BTreeMap, tool_id_by_name: BTreeMap, diagnostics: Arc, } struct EvalRunProjection<'a> { - output: Option<&'a engine::ContentRef>, - run_id: engine::RunId, - status: engine::RunStatus, - source: &'a engine::RunSource, + output: Option<&'a harness::ContentRef>, + run_id: harness::RunId, + status: harness::RunStatus, + source: &'a harness::RunSource, started_at_ms: Option, completed_at_ms: Option, - usage: Option<&'a engine::LlmUsage>, + usage: Option<&'a harness::LlmUsage>, } impl EvalRuntime { @@ -635,11 +635,11 @@ impl EvalRuntime { let outcome = self .drive( session_id.clone(), - CoreAgentCommand::RequestRun(engine::RunRequestCommand { + CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: user_input(input_ref), }, run_config: RunConfig { @@ -939,12 +939,12 @@ fn session_config(case: &EvalCase, model: ModelSelection) -> SessionConfig { } } -fn user_input(content_ref: engine::BlobRef) -> Vec { +fn user_input(content_ref: harness::BlobRef) -> Vec { vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -956,10 +956,10 @@ fn user_input(content_ref: engine::BlobRef) -> Vec { }] } -fn instruction_context_input(content_ref: engine::BlobRef) -> ContextEntryInput { +fn instruction_context_input(content_ref: harness::BlobRef) -> ContextEntryInput { ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, diff --git a/crates/engine/Cargo.toml b/crates/harness/Cargo.toml similarity index 78% rename from crates/engine/Cargo.toml rename to crates/harness/Cargo.toml index c8ce3e175..012b17c3e 100644 --- a/crates/engine/Cargo.toml +++ b/crates/harness/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "engine" +name = "harness" version = "0.1.0" edition = "2024" @@ -8,14 +8,14 @@ async-trait = "0.1" serde = { version = "1", features = ["derive"] } serde_json = "1" hex = "0.4" -sha2 = "0.10" -thiserror = "1" +sha2 = "0.11" +thiserror = "2" uuid = { version = "1", features = ["serde"] } schemars = { version = "1", optional = true, features = ["uuid1"] } [features] # JSON Schema derives for the types exported in the workflow contract -# (`temporal-workflow`). A derive only; nothing about engine behaviour changes. +# (`temporal-workflow`). A derive only; nothing about harness behaviour changes. contract = ["dep:schemars"] [dev-dependencies] diff --git a/crates/engine/README.md b/crates/harness/README.md similarity index 83% rename from crates/engine/README.md rename to crates/harness/README.md index a658e1b60..2cea3c3c0 100644 --- a/crates/engine/README.md +++ b/crates/harness/README.md @@ -1,6 +1,6 @@ -# engine +# harness -`engine` is the deterministic Lightspeed-native agent engine. It defines the +`harness` is the deterministic core of the Lightspeed-native agent harness. It defines the session-scoped command, event, state, context, tooling, admission, projection, planning, workflow helpers, and the substrate-neutral CoreAgent drive machine used by local and Temporal substrates. @@ -18,6 +18,6 @@ Current architecture: Local verification: ```bash -cargo check -p engine -cargo test -p engine +cargo check -p harness +cargo test -p harness ``` diff --git a/crates/engine/fixtures/core_lifecycle_closed_stored_event.json b/crates/harness/fixtures/core_lifecycle_closed_stored_event.json similarity index 100% rename from crates/engine/fixtures/core_lifecycle_closed_stored_event.json rename to crates/harness/fixtures/core_lifecycle_closed_stored_event.json diff --git a/crates/engine/fixtures/core_tool_batch_completed_stored_entry.json b/crates/harness/fixtures/core_tool_batch_completed_stored_entry.json similarity index 100% rename from crates/engine/fixtures/core_tool_batch_completed_stored_entry.json rename to crates/harness/fixtures/core_tool_batch_completed_stored_entry.json diff --git a/crates/engine/fixtures/core_tool_batch_completed_stored_event.json b/crates/harness/fixtures/core_tool_batch_completed_stored_event.json similarity index 100% rename from crates/engine/fixtures/core_tool_batch_completed_stored_event.json rename to crates/harness/fixtures/core_tool_batch_completed_stored_event.json diff --git a/crates/engine/src/attachments.rs b/crates/harness/src/attachments.rs similarity index 97% rename from crates/engine/src/attachments.rs rename to crates/harness/src/attachments.rs index a0aeb149d..a033681bf 100644 --- a/crates/engine/src/attachments.rs +++ b/crates/harness/src/attachments.rs @@ -1,5 +1,5 @@ //! Portable immutable assets associated with tool results. -//! The engine records descriptors; adapters own admission and presentation. +//! The harness records descriptors; adapters own admission and presentation. use crate::{BlobRef, ContextEntryInput, media::MediaDescriptor}; use serde::{Deserialize, Serialize}; diff --git a/crates/engine/src/blob.rs b/crates/harness/src/blob.rs similarity index 97% rename from crates/engine/src/blob.rs rename to crates/harness/src/blob.rs index 7ed7ef78e..64c5d886e 100644 --- a/crates/engine/src/blob.rs +++ b/crates/harness/src/blob.rs @@ -15,7 +15,7 @@ const SHA256_REF_LEN: usize = SHA256_PREFIX.len() + SHA256_HEX_LEN; pub struct BlobRef(String); /// Durable content identity and encoding. The payload stays in CAS; consumers -/// project it outside the engine rather than assuming every output is text. +/// project it outside the harness rather than assuming every output is text. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "contract", derive(schemars::JsonSchema))] pub struct ContentRef { diff --git a/crates/engine/src/core/admit.rs b/crates/harness/src/core/admit.rs similarity index 100% rename from crates/engine/src/core/admit.rs rename to crates/harness/src/core/admit.rs diff --git a/crates/engine/src/core/apply.rs b/crates/harness/src/core/apply.rs similarity index 100% rename from crates/engine/src/core/apply.rs rename to crates/harness/src/core/apply.rs diff --git a/crates/engine/src/core/codec.rs b/crates/harness/src/core/codec.rs similarity index 100% rename from crates/engine/src/core/codec.rs rename to crates/harness/src/core/codec.rs diff --git a/crates/engine/src/core/components/approval.rs b/crates/harness/src/core/components/approval.rs similarity index 100% rename from crates/engine/src/core/components/approval.rs rename to crates/harness/src/core/components/approval.rs diff --git a/crates/engine/src/core/components/attribution.rs b/crates/harness/src/core/components/attribution.rs similarity index 88% rename from crates/engine/src/core/components/attribution.rs rename to crates/harness/src/core/components/attribution.rs index 8dcd180df..feaf6d987 100644 --- a/crates/engine/src/core/components/attribution.rs +++ b/crates/harness/src/core/components/attribution.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; /// Who asked for a change, as the API boundary attributed the request: an /// asserted actor, a key acting for itself, a local caller, or the runtime's -/// own work. The engine records it and never branches on it; the wire shape +/// own work. The harness records it and never branches on it; the wire shape /// matches the public attribution. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "contract", derive(schemars::JsonSchema))] diff --git a/crates/engine/src/core/components/command.rs b/crates/harness/src/core/components/command.rs similarity index 100% rename from crates/engine/src/core/components/command.rs rename to crates/harness/src/core/components/command.rs diff --git a/crates/engine/src/core/components/config.rs b/crates/harness/src/core/components/config.rs similarity index 99% rename from crates/engine/src/core/components/config.rs rename to crates/harness/src/core/components/config.rs index 2c332de16..f91550d15 100644 --- a/crates/engine/src/core/components/config.rs +++ b/crates/harness/src/core/components/config.rs @@ -19,7 +19,7 @@ pub const CURRENT_FEATURE_VERSION: u32 = 1; /// an absent feature is not granted (no tools, no access); a present feature /// is granted with the defaults documented on its struct. The stored document /// is this declaration itself; effective behavior is materialized outside the -/// engine. +/// harness. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct SessionConfig { pub model: ModelSelection, @@ -71,7 +71,7 @@ pub struct GenerationConfig { #[serde(default, skip_serializing_if = "Option::is_none")] pub max_output_tokens: Option, /// Reasoning effort tier as a provider-native string (e.g. "none", - /// "high", "xhigh", "max"). The engine carries it opaquely; the LLM + /// "high", "xhigh", "max"). The harness carries it opaquely; the LLM /// runtime validates it against the provider and materializes the /// request params. Never stored as provider JSON. #[serde(default, skip_serializing_if = "Option::is_none")] @@ -559,7 +559,7 @@ pub struct EnvironmentSkillsConfig { /// Grants remote MCP tools by declaring attached servers from the universe MCP /// catalog. Reconciliation into tool specs happens in the runtime -/// materialization layer, not in the engine. +/// materialization layer, not in the harness. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct McpFeature { #[serde(default = "default_feature_version")] diff --git a/crates/engine/src/core/components/context.rs b/crates/harness/src/core/components/context.rs similarity index 100% rename from crates/engine/src/core/components/context.rs rename to crates/harness/src/core/components/context.rs diff --git a/crates/engine/src/core/components/environment.rs b/crates/harness/src/core/components/environment.rs similarity index 100% rename from crates/engine/src/core/components/environment.rs rename to crates/harness/src/core/components/environment.rs diff --git a/crates/engine/src/core/components/error.rs b/crates/harness/src/core/components/error.rs similarity index 100% rename from crates/engine/src/core/components/error.rs rename to crates/harness/src/core/components/error.rs diff --git a/crates/engine/src/core/components/event.rs b/crates/harness/src/core/components/event.rs similarity index 100% rename from crates/engine/src/core/components/event.rs rename to crates/harness/src/core/components/event.rs diff --git a/crates/engine/src/core/components/ids.rs b/crates/harness/src/core/components/ids.rs similarity index 100% rename from crates/engine/src/core/components/ids.rs rename to crates/harness/src/core/components/ids.rs diff --git a/crates/engine/src/core/components/lifecycle.rs b/crates/harness/src/core/components/lifecycle.rs similarity index 100% rename from crates/engine/src/core/components/lifecycle.rs rename to crates/harness/src/core/components/lifecycle.rs diff --git a/crates/engine/src/core/components/llm.rs b/crates/harness/src/core/components/llm.rs similarity index 99% rename from crates/engine/src/core/components/llm.rs rename to crates/harness/src/core/components/llm.rs index f9a0166c1..0f8b9fda2 100644 --- a/crates/engine/src/core/components/llm.rs +++ b/crates/harness/src/core/components/llm.rs @@ -413,7 +413,7 @@ pub const LLM_COMPACTION_FINGERPRINT_PREFIX: &str = "compaction:sha256:"; /// the specific error text could not be materialized. Like /// [`crate::TOOL_RUNTIME_BOUNDARY_FAILURE_CONTENT`], every runtime must /// guarantee the matching blob exists via -/// [`crate::storage::ensure_engine_blobs`]. +/// [`crate::storage::ensure_harness_blobs`]. pub const LLM_RUNTIME_BOUNDARY_FAILURE_CONTENT: &str = "LLM call failed at the runtime boundary before its result could be recorded\n"; diff --git a/crates/engine/src/core/components/log.rs b/crates/harness/src/core/components/log.rs similarity index 100% rename from crates/engine/src/core/components/log.rs rename to crates/harness/src/core/components/log.rs diff --git a/crates/engine/src/core/components/mod.rs b/crates/harness/src/core/components/mod.rs similarity index 100% rename from crates/engine/src/core/components/mod.rs rename to crates/harness/src/core/components/mod.rs diff --git a/crates/engine/src/core/components/promise.rs b/crates/harness/src/core/components/promise.rs similarity index 98% rename from crates/engine/src/core/components/promise.rs rename to crates/harness/src/core/components/promise.rs index 6605f38ed..55ddcc50b 100644 --- a/crates/engine/src/core/components/promise.rs +++ b/crates/harness/src/core/components/promise.rs @@ -8,7 +8,7 @@ use crate::{BlobRef, CoreAgentState, DomainError, RunId}; /// Stable identifier for a promise: a session-scoped counter rendered as /// `promise_`, the same convention as `run_`, so the model copies a -/// short handle rather than a digest. The engine hands every tool batch a +/// short handle rather than a digest. The harness hands every tool batch a /// base one past the session cursor (`ToolInvocationBatchRequest:: /// promise_id_base`); the executor numbers the promises it creates from /// that base, and the reducer accepts a creation only at or above the @@ -39,7 +39,7 @@ impl PromiseId { } } - /// Trusted constructor for ids the engine minted itself; panics on a + /// Trusted constructor for ids the harness minted itself; panics on a /// malformed value. Untrusted input (model arguments, emissions) goes /// through `try_new`. pub fn new(value: impl Into) -> Self { @@ -126,7 +126,7 @@ impl PromiseIdAllocator { } /// What produces the resolution of a promise. Provider-native detail stays -/// opaque; the engine keeps only the facts needed for deterministic +/// opaque; the harness keeps only the facts needed for deterministic /// branching and outward cancellation. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case", tag = "kind")] @@ -193,7 +193,7 @@ pub struct Promise { pub payload_ref: Option, /// Failure detail (CAS ref); set only when `status == Failed`. pub error_ref: Option, - /// Engine-owned hard deadline, independent of any await. + /// Harness-owned hard deadline, independent of any await. pub deadline_ms: Option, } diff --git a/crates/engine/src/core/components/run.rs b/crates/harness/src/core/components/run.rs similarity index 100% rename from crates/engine/src/core/components/run.rs rename to crates/harness/src/core/components/run.rs diff --git a/crates/engine/src/core/components/state.rs b/crates/harness/src/core/components/state.rs similarity index 100% rename from crates/engine/src/core/components/state.rs rename to crates/harness/src/core/components/state.rs diff --git a/crates/engine/src/core/components/tooling.rs b/crates/harness/src/core/components/tooling.rs similarity index 99% rename from crates/engine/src/core/components/tooling.rs rename to crates/harness/src/core/components/tooling.rs index e721c30f1..0bac7ead3 100644 --- a/crates/engine/src/core/components/tooling.rs +++ b/crates/harness/src/core/components/tooling.rs @@ -356,7 +356,7 @@ pub enum ToolExecutionClass { /// Environment process execution; its deadline derives from the validated /// process timeout clamped to the deployment-owned ceiling. Process, - /// Bounded bulk data movement; progress and cancellation stay outside engine state. + /// Bounded bulk data movement; progress and cancellation stay outside harness state. Bulk, } @@ -1500,12 +1500,12 @@ fn planned_toolset_revision_for_turn( Ok(planned.toolset_revision) } -/// Model-visible content for tool calls the engine marks unavailable. +/// Model-visible content for tool calls the harness marks unavailable. /// /// The deterministic core cannot write blobs, so unavailable results reference /// this well-known constant content by hash. Every runtime that fulfills core /// actions must guarantee the matching blob exists (see -/// [`crate::storage::ensure_engine_blobs`]); content-addressed puts make that +/// [`crate::storage::ensure_harness_blobs`]); content-addressed puts make that /// idempotent. pub const UNAVAILABLE_TOOL_RESULT_CONTENT: &str = "tool unavailable: this tool cannot be invoked in this session\n"; @@ -1518,7 +1518,7 @@ pub fn unavailable_tool_result_ref() -> BlobRef { /// cancelled at the runtime boundary when the specific error text could not /// be materialized (e.g. the blob store itself is unavailable). Like /// [`UNAVAILABLE_TOOL_RESULT_CONTENT`], every runtime must guarantee the -/// matching blob exists via [`crate::storage::ensure_engine_blobs`]. +/// matching blob exists via [`crate::storage::ensure_harness_blobs`]. pub const TOOL_RUNTIME_BOUNDARY_FAILURE_CONTENT: &str = "tool call failed at the runtime boundary before its result could be recorded\n"; @@ -1526,10 +1526,10 @@ pub fn tool_runtime_boundary_failure_ref() -> BlobRef { BlobRef::from_bytes(TOOL_RUNTIME_BOUNDARY_FAILURE_CONTENT.as_bytes()) } -/// Model-visible content for tool calls the engine cancelled because their +/// Model-visible content for tool calls the harness cancelled because their /// run was cancelled before they completed. Like /// [`UNAVAILABLE_TOOL_RESULT_CONTENT`], every runtime must guarantee the -/// matching blob exists via [`crate::storage::ensure_engine_blobs`]. +/// matching blob exists via [`crate::storage::ensure_harness_blobs`]. pub const CANCELLED_TOOL_RESULT_CONTENT: &str = "tool call cancelled: the run was cancelled before this call completed\n"; diff --git a/crates/engine/src/core/components/turn.rs b/crates/harness/src/core/components/turn.rs similarity index 99% rename from crates/engine/src/core/components/turn.rs rename to crates/harness/src/core/components/turn.rs index 4bc7cadfe..2dafc0149 100644 --- a/crates/engine/src/core/components/turn.rs +++ b/crates/harness/src/core/components/turn.rs @@ -255,7 +255,7 @@ pub enum LlmGenerationStatus { Succeeded, Failed, /// The provider rejected the request instead of serving it. The runtime - /// supplies this classification; the engine only records it. + /// supplies this classification; the harness only records it. Rejected, Cancelled, } diff --git a/crates/engine/src/core/components/workflow_tool.rs b/crates/harness/src/core/components/workflow_tool.rs similarity index 99% rename from crates/engine/src/core/components/workflow_tool.rs rename to crates/harness/src/core/components/workflow_tool.rs index 745272e6a..c4e0632c9 100644 --- a/crates/engine/src/core/components/workflow_tool.rs +++ b/crates/harness/src/core/components/workflow_tool.rs @@ -87,7 +87,7 @@ impl WorkflowEndpointRef { /// Trusted, substrate-neutral reference to a workflow-start recipe for /// start-on-call tools. The recipe body (workflow type, task queue, ...) is -/// CAS-backed and resolved by a workflow-substrate adapter outside `engine`. +/// CAS-backed and resolved by a workflow-substrate adapter outside `harness`. /// `recipe_format` identifies the generic recipe codec, never a feature, /// service, or workflow plugin. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] diff --git a/crates/engine/src/core/drive.rs b/crates/harness/src/core/drive.rs similarity index 99% rename from crates/engine/src/core/drive.rs rename to crates/harness/src/core/drive.rs index f8c49922d..fc1f2d8bd 100644 --- a/crates/engine/src/core/drive.rs +++ b/crates/harness/src/core/drive.rs @@ -191,7 +191,7 @@ impl CoreAgentDrive { /// Accept one terminal call result of the active tool batch. /// - /// Per-call completion is the engine contract for progressive batches: + /// Per-call completion is the harness contract for progressive batches: /// each terminal result appends durably on its own, a failed call never /// re-runs a completed sibling, and the batch completes when its last /// call turns terminal. @@ -5890,7 +5890,7 @@ mod tests { } /// Cancelling a run whose generation is in flight resolves the - /// open turn as `cancelled` in the engine itself — no grace turn, no + /// open turn as `cancelled` in the harness itself — no grace turn, no /// `failed` record, and the runtime is never asked for work again. A late /// generation result for the abandoned turn is rejected. #[test] diff --git a/crates/engine/src/core/io.rs b/crates/harness/src/core/io.rs similarity index 100% rename from crates/engine/src/core/io.rs rename to crates/harness/src/core/io.rs diff --git a/crates/engine/src/core/mod.rs b/crates/harness/src/core/mod.rs similarity index 100% rename from crates/engine/src/core/mod.rs rename to crates/harness/src/core/mod.rs diff --git a/crates/engine/src/core/planning.rs b/crates/harness/src/core/planning.rs similarity index 100% rename from crates/engine/src/core/planning.rs rename to crates/harness/src/core/planning.rs diff --git a/crates/engine/src/core/session_graph.rs b/crates/harness/src/core/session_graph.rs similarity index 100% rename from crates/engine/src/core/session_graph.rs rename to crates/harness/src/core/session_graph.rs diff --git a/crates/engine/src/core/transition.rs b/crates/harness/src/core/transition.rs similarity index 100% rename from crates/engine/src/core/transition.rs rename to crates/harness/src/core/transition.rs diff --git a/crates/engine/src/emission.rs b/crates/harness/src/emission.rs similarity index 99% rename from crates/engine/src/emission.rs rename to crates/harness/src/emission.rs index 2cbf5989e..b86507acf 100644 --- a/crates/engine/src/emission.rs +++ b/crates/harness/src/emission.rs @@ -201,7 +201,7 @@ pub enum EmissionBody { invocation: WorkflowToolInvocation, /// Workflow id of the session that emitted the invocation — the /// endpoint a receiver signals its reply to. Supplied by the - /// substrate adapter; the engine treats it as opaque. + /// substrate adapter; the harness treats it as opaque. holder_workflow_id: String, }, /// Best-effort notice to a bound receiver that the session already diff --git a/crates/engine/src/lib.rs b/crates/harness/src/lib.rs similarity index 100% rename from crates/engine/src/lib.rs rename to crates/harness/src/lib.rs diff --git a/crates/engine/src/media.rs b/crates/harness/src/media.rs similarity index 100% rename from crates/engine/src/media.rs rename to crates/harness/src/media.rs diff --git a/crates/engine/src/session/codec.rs b/crates/harness/src/session/codec.rs similarity index 100% rename from crates/engine/src/session/codec.rs rename to crates/harness/src/session/codec.rs diff --git a/crates/engine/src/session/ids.rs b/crates/harness/src/session/ids.rs similarity index 100% rename from crates/engine/src/session/ids.rs rename to crates/harness/src/session/ids.rs diff --git a/crates/engine/src/session/log.rs b/crates/harness/src/session/log.rs similarity index 100% rename from crates/engine/src/session/log.rs rename to crates/harness/src/session/log.rs diff --git a/crates/engine/src/session/mod.rs b/crates/harness/src/session/mod.rs similarity index 100% rename from crates/engine/src/session/mod.rs rename to crates/harness/src/session/mod.rs diff --git a/crates/engine/src/session/stored.rs b/crates/harness/src/session/stored.rs similarity index 100% rename from crates/engine/src/session/stored.rs rename to crates/harness/src/session/stored.rs diff --git a/crates/engine/src/storage/blobs.rs b/crates/harness/src/storage/blobs.rs similarity index 99% rename from crates/engine/src/storage/blobs.rs rename to crates/harness/src/storage/blobs.rs index 97edf4e21..7cb43d5a9 100644 --- a/crates/engine/src/storage/blobs.rs +++ b/crates/harness/src/storage/blobs.rs @@ -34,7 +34,7 @@ pub const ENGINE_BLOB_CONTENTS: [&str; 4] = [ /// Refs of [`ENGINE_BLOB_CONTENTS`]. A long-running process may reference any /// of them at any moment, so blob collection pins them: they are never /// candidates for a sweep regardless of holders or age. -pub fn engine_blob_refs() -> Vec { +pub fn harness_blob_refs() -> Vec { ENGINE_BLOB_CONTENTS .iter() .map(|content| BlobRef::from_bytes(content.as_bytes())) @@ -45,13 +45,13 @@ pub fn engine_blob_refs() -> Vec { /// /// Runtimes that fulfill core actions must call this before driving sessions; /// content-addressed puts make repeated calls idempotent. -pub async fn ensure_engine_blobs(blobs: &dyn BlobStore) -> Result<(), BlobStoreError> { +pub async fn ensure_harness_blobs(blobs: &dyn BlobStore) -> Result<(), BlobStoreError> { for content in ENGINE_BLOB_CONTENTS { let blob_ref = blobs.put_bytes(content.as_bytes().to_vec()).await?; debug_assert_eq!(blob_ref, BlobRef::from_bytes(content.as_bytes())); } debug_assert_eq!( - engine_blob_refs(), + harness_blob_refs(), vec![ crate::unavailable_tool_result_ref(), crate::tool_runtime_boundary_failure_ref(), @@ -1023,9 +1023,9 @@ mod tests { } #[test] - fn engine_blob_refs_match_the_core_constants() { + fn harness_blob_refs_match_the_core_constants() { assert_eq!( - engine_blob_refs(), + harness_blob_refs(), vec![ crate::unavailable_tool_result_ref(), crate::tool_runtime_boundary_failure_ref(), diff --git a/crates/engine/src/storage/mod.rs b/crates/harness/src/storage/mod.rs similarity index 94% rename from crates/engine/src/storage/mod.rs rename to crates/harness/src/storage/mod.rs index 63699a22a..983605a77 100644 --- a/crates/engine/src/storage/mod.rs +++ b/crates/harness/src/storage/mod.rs @@ -14,7 +14,7 @@ pub use crate::session::{ pub use blobs::{ BlobCacheLimits, BlobCacheStats, BlobEdge, BlobGraphStore, BlobInfo, BlobSource, BlobStore, BlobStoreError, CachedBlobStore, ENGINE_BLOB_CONTENTS, InMemoryBlobCache, InMemoryBlobStore, - collect_blob_refs, engine_blob_refs, ensure_engine_blobs, record_contains_edges, + collect_blob_refs, ensure_harness_blobs, harness_blob_refs, record_contains_edges, }; pub use session::{ AdvanceSessionCheckpoint, AppendSessionEvents, AppendSessionEventsResult, CreateClonedSession, diff --git a/crates/engine/src/storage/session.rs b/crates/harness/src/storage/session.rs similarity index 99% rename from crates/engine/src/storage/session.rs rename to crates/harness/src/storage/session.rs index f060cdda6..5ea263996 100644 --- a/crates/engine/src/storage/session.rs +++ b/crates/harness/src/storage/session.rs @@ -1282,7 +1282,7 @@ pub fn validate_fork_point( }); } for range in core_run_ranges(entries).values() { - let end_exclusive = range.terminal_seq.map_or(head.saturating_add(1), |seq| seq); + let end_exclusive = range.terminal_seq.unwrap_or(head.saturating_add(1)); if source_seq_u64 >= range.first_seq && source_seq_u64 < end_exclusive { return Err(SessionStoreError::InvalidForkPoint { session_id: session_id.clone(), diff --git a/crates/engine/src/string_id.rs b/crates/harness/src/string_id.rs similarity index 100% rename from crates/engine/src/string_id.rs rename to crates/harness/src/string_id.rs diff --git a/crates/llm-clients/Cargo.toml b/crates/llm-clients/Cargo.toml index a031c682c..887ba7a4e 100644 --- a/crates/llm-clients/Cargo.toml +++ b/crates/llm-clients/Cargo.toml @@ -10,8 +10,8 @@ httpdate = "1" reqwest = { version = "0.13", default-features = false, features = ["json", "multipart", "query", "rustls", "stream"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" [dev-dependencies] -base64 = "0.22" +base64 = "0.23" tokio = { version = "1", features = ["io-util", "macros", "net", "rt", "sync"] } diff --git a/crates/llm-runtime/Cargo.toml b/crates/llm-runtime/Cargo.toml index 81d6b491b..224f44dab 100644 --- a/crates/llm-runtime/Cargo.toml +++ b/crates/llm-runtime/Cargo.toml @@ -5,13 +5,13 @@ edition = "2024" [dependencies] async-trait = "0.1" -base64 = "0.22" -engine = { path = "../engine" } +base64 = "0.23" +harness = { path = "../harness" } image = { version = "0.25", default-features = false, features = ["gif", "jpeg", "png", "webp"] } llm-clients = { path = "../llm-clients" } serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" tokio = { version = "1", features = ["rt"] } tracing = "0.1" tools = { path = "../tools" } diff --git a/crates/llm-runtime/src/anthropic_messages.rs b/crates/llm-runtime/src/anthropic_messages.rs index b1d5223f5..26077cecc 100644 --- a/crates/llm-runtime/src/anthropic_messages.rs +++ b/crates/llm-runtime/src/anthropic_messages.rs @@ -1,6 +1,6 @@ //! Anthropic Messages adapter. //! -//! Lowers the engine's provider-neutral [`LlmRequest`] intent into native +//! Lowers the harness's provider-neutral [`LlmRequest`] intent into native //! Anthropic Messages API requests and maps responses back into context //! entries and reducer facts, mirroring the OpenAI Responses adapter. //! @@ -11,7 +11,7 @@ use std::sync::Arc; use async_trait::async_trait; -use engine::{ +use harness::{ ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND, ANTHROPIC_MESSAGES_MCP_TOOL_RESULT_PROVIDER_KIND, ANTHROPIC_MESSAGES_MCP_TOOL_USE_PROVIDER_KIND, ANTHROPIC_MESSAGES_SERVER_TOOL_RESULT_PROVIDER_KIND, @@ -1694,7 +1694,7 @@ async fn result_from_compact_response_with_strategy( failure_ref: None, context_entries: vec![ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: put_json(blobs, &blocks[0]).await?, media_type: Some(MEDIA_TYPE_JSON.into()), provider_kind: Some(ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND.into()), @@ -1759,7 +1759,7 @@ async fn result_from_compact_response_with_strategy( kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_TEXT.to_owned()), provider_kind: Some(ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND.to_owned()), @@ -1806,7 +1806,7 @@ async fn text_run_context_entries( kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: put_json(blobs, &Value::Array(blocks)).await?, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND.to_owned()), @@ -1850,7 +1850,7 @@ async fn tool_use_context( call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: native_call_ref.clone(), media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(PROVIDER_KIND_TOOL_USE.to_owned()), @@ -1890,7 +1890,7 @@ async fn thinking_context_entry( }; Ok(ContextEntryInput { kind: ContextEntryKind::ReasoningState, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(PROVIDER_KIND_THINKING.to_owned()), @@ -1931,7 +1931,7 @@ async fn opaque_context_entry( let content_ref = put_json(blobs, &raw_block).await?; Ok(ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(provider_kind.to_owned()), @@ -2069,7 +2069,7 @@ mod tests { use std::collections::{BTreeMap, VecDeque}; use std::sync::{Arc, Mutex}; - use engine::{ + use harness::{ BlobRef, ContextEntryId, ContextEntrySource, ContextSnapshot, CoreAgentLlm, FunctionToolSpec, ModelSelection, ProviderParams, RunId, SessionId, ToolParallelism, TurnId, storage::InMemoryBlobStore, @@ -2580,7 +2580,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -2638,11 +2638,11 @@ mod tests { .await .expect("provider options"); let instructions_item = ContextEntry { - key: Some(engine::ContextEntryKey::new("instructions.000.test")), + key: Some(harness::ContextEntryKey::new("instructions.000.test")), entry_id: ContextEntryId::new(1), kind: ContextEntryKind::Instructions, source: ContextEntrySource::ContextEdit, - content: engine::ContentRef::text(instructions_ref), + content: harness::ContentRef::text(instructions_ref), preview: None, origin: None, provenance_ref: None, @@ -2779,7 +2779,7 @@ mod tests { run_id: RunId::new(1), turn_id: TurnId::new(1), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: thinking_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(PROVIDER_KIND_THINKING.to_owned()), @@ -2800,7 +2800,7 @@ mod tests { run_id: RunId::new(1), turn_id: TurnId::new(1), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: assistant_ref, media_type: Some("text/plain".to_owned()), provider_kind: Some("anthropic.messages.text".to_owned()), @@ -2815,14 +2815,14 @@ mod tests { key: None, entry_id: ContextEntryId::new(4), kind: ContextEntryKind::ToolCall { - call_id: engine::ToolCallId::new("toolu_1"), + call_id: harness::ToolCallId::new("toolu_1"), name: ToolName::new("read_file"), }, source: ContextEntrySource::AssistantOutput { run_id: RunId::new(1), turn_id: TurnId::new(1), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: tool_use_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(PROVIDER_KIND_TOOL_USE.to_owned()), @@ -2837,7 +2837,7 @@ mod tests { key: None, entry_id: ContextEntryId::new(5), kind: ContextEntryKind::ToolResult { - call_id: engine::ToolCallId::new("toolu_1"), + call_id: harness::ToolCallId::new("toolu_1"), is_error: false, }, source: ContextEntrySource::Tool { @@ -2845,7 +2845,7 @@ mod tests { turn_id: TurnId::new(1), batch_id: None, }, - content: engine::ContentRef::text(tool_result_ref), + content: harness::ContentRef::text(tool_result_ref), preview: None, origin: None, provenance_ref: None, @@ -2908,11 +2908,11 @@ mod tests { .expect("raw message blob"); let followup_ref = text_blob(&blobs, "What marker?").await; let raw_entry = ContextEntry { - key: Some(engine::ContextEntryKey::new("client.anthropic.raw.note")), + key: Some(harness::ContextEntryKey::new("client.anthropic.raw.note")), entry_id: ContextEntryId::new(1), kind: ContextEntryKind::ProviderOpaque, source: ContextEntrySource::ContextEdit, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: raw_message_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(ANTHROPIC_MESSAGES_INPUT_MESSAGE_PROVIDER_KIND.to_owned()), @@ -3160,7 +3160,7 @@ mod tests { exposure: RemoteMcpExposure::Inject, approval: RemoteMcpApprovalPolicy::Never, defer_loading: None, - auth_ref: Some(engine::SecretRef { + auth_ref: Some(harness::SecretRef { namespace: "mcp_server".to_string(), id: "echo".to_string(), }), @@ -4536,7 +4536,7 @@ mod tests { source: ContextEntrySource::Runtime { label: "inserted-skill".to_string(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: skill_text_ref, media_type: None, provider_kind: None, @@ -4583,7 +4583,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("image/jpeg".to_owned()), provider_kind: None, @@ -4607,7 +4607,7 @@ mod tests { announcement["text"], json!(format!( "[image · {} · image/jpeg]", - engine::media::media_handle(&entry.content.content_ref) + harness::media::media_handle(&entry.content.content_ref) )) ); let block = &blocks[1]; @@ -4639,7 +4639,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("application/pdf".to_owned()), provider_kind: None, @@ -4662,7 +4662,7 @@ mod tests { announcement["text"], json!(format!( "[document: offer.pdf · {} · application/pdf]", - engine::media::media_handle(&entry.content.content_ref) + harness::media::media_handle(&entry.content.content_ref) )) ); let block = &blocks[1]; @@ -4690,7 +4690,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/markdown".to_owned()), provider_kind: None, @@ -4738,7 +4738,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, @@ -4759,13 +4759,13 @@ mod tests { fn catalog_entry(id: u64, content_ref: BlobRef, supersedes: Option) -> ContextEntry { ContextEntry { - key: Some(engine::ContextEntryKey::new("bot:directory")), + key: Some(harness::ContextEntryKey::new("bot:directory")), entry_id: ContextEntryId::new(id), kind: ContextEntryKind::Catalog { title: "Bot directory".to_string(), }, source: ContextEntrySource::ContextEdit, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/markdown".to_string()), provider_kind: None, @@ -4802,7 +4802,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -4880,11 +4880,11 @@ mod tests { .await .expect("schema"); let instructions_item = ContextEntry { - key: Some(engine::ContextEntryKey::new("instructions.000.test")), + key: Some(harness::ContextEntryKey::new("instructions.000.test")), entry_id: ContextEntryId::new(1), kind: ContextEntryKind::Instructions, source: ContextEntrySource::ContextEdit, - content: engine::ContentRef::text(instructions_ref), + content: harness::ContentRef::text(instructions_ref), preview: None, origin: None, provenance_ref: None, @@ -4986,7 +4986,7 @@ mod tests { .expect("store pdf"); let make = |id: u64, kind: ContextEntryKind, - content: engine::ContentRef, + content: harness::ContentRef, preview: Option<&str>| { ContextEntry { entry_id: ContextEntryId::new(id), @@ -5008,7 +5008,7 @@ mod tests { call_id: ToolCallId::try_new("call_1").expect("call id"), is_error: false, }, - engine::ContentRef::text(result_ref), + harness::ContentRef::text(result_ref), None, ), make( @@ -5016,7 +5016,7 @@ mod tests { ContextEntryKind::Message { role: ContextMessageRole::User, }, - engine::ContentRef { + harness::ContentRef { content_ref: image_ref, media_type: Some("image/png".to_owned()), provider_kind: None, @@ -5028,7 +5028,7 @@ mod tests { ContextEntryKind::Message { role: ContextMessageRole::User, }, - engine::ContentRef { + harness::ContentRef { content_ref: pdf_ref, media_type: Some("application/pdf".to_owned()), provider_kind: None, diff --git a/crates/llm-runtime/src/blob_io.rs b/crates/llm-runtime/src/blob_io.rs index 0cadb754f..64a314218 100644 --- a/crates/llm-runtime/src/blob_io.rs +++ b/crates/llm-runtime/src/blob_io.rs @@ -1,4 +1,4 @@ -use engine::{BlobRef, storage::BlobStore}; +use harness::{BlobRef, storage::BlobStore}; use serde::Serialize; use serde_json::Value; @@ -17,18 +17,18 @@ pub fn image_media_type(media_type: Option<&str>) -> Option<&str> { /// True for entries a tool appended (results and their media companions), /// as opposed to deliberate run input or steering. -pub fn is_tool_sourced(entry: &engine::ContextEntry) -> bool { - matches!(entry.source, engine::ContextEntrySource::Tool { .. }) +pub fn is_tool_sourced(entry: &harness::ContextEntry) -> bool { + matches!(entry.source, harness::ContextEntrySource::Tool { .. }) } /// The text block written immediately before a media entry's provider-native /// block, naming it for the model: `[image · media:3f9a2c1d4e7b · image/png]`. -pub fn media_announcement(entry: &engine::ContextEntry) -> String { - engine::media::media_announcement(&entry.content, entry.preview.as_deref()) +pub fn media_announcement(entry: &harness::ContextEntry) -> String { + harness::media::media_announcement(&entry.content, entry.preview.as_deref()) } /// The text a text-only dialect materializes in place of tool-produced media. -pub fn text_only_omission(entry: &engine::ContextEntry) -> String { +pub fn text_only_omission(entry: &harness::ContextEntry) -> String { let announcement = media_announcement(entry); let inner = announcement .strip_prefix('[') diff --git a/crates/llm-runtime/src/catalog_prompts.rs b/crates/llm-runtime/src/catalog_prompts.rs index bae43f628..9d30d7ae9 100644 --- a/crates/llm-runtime/src/catalog_prompts.rs +++ b/crates/llm-runtime/src/catalog_prompts.rs @@ -1,12 +1,12 @@ //! Shared rendering for catalog context entries. //! -//! A catalog that changes is not rewritten in place: the engine keeps the +//! A catalog that changes is not rewritten in place: the harness keeps the //! earlier version active and appends the new one with `supersedes` set, so //! the rendered prefix never moves and the provider prompt cache holds. The //! earlier version must therefore render byte-for-byte as it always did — //! only the successor announces the update. -use engine::{BlobRef, ContextEntry, ContextEntryKind, storage::BlobStore}; +use harness::{BlobRef, ContextEntry, ContextEntryKind, storage::BlobStore}; use crate::error::LlmAdapterResult; @@ -43,7 +43,7 @@ pub(crate) async fn stored_catalog_text( #[cfg(test)] mod tests { use super::*; - use engine::{ContextEntryId, ContextEntrySource}; + use harness::{ContextEntryId, ContextEntrySource}; fn entry(supersedes: Option) -> ContextEntry { ContextEntry { @@ -53,7 +53,7 @@ mod tests { title: "Bot directory".to_owned(), }, source: ContextEntrySource::ContextEdit, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: BlobRef::from_bytes(b"body"), media_type: None, provider_kind: None, @@ -80,7 +80,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn stored_body_is_verbatim_and_never_requires_source_decoding() { - let blobs = engine::storage::InMemoryBlobStore::new(); + let blobs = harness::storage::InMemoryBlobStore::new(); let body = " publisher text\n\n"; let body_ref = blobs.put_bytes(body.as_bytes().to_vec()).await.unwrap(); let mut original = entry(None); diff --git a/crates/llm-runtime/src/compaction.rs b/crates/llm-runtime/src/compaction.rs index c41af0ce4..5b6257d37 100644 --- a/crates/llm-runtime/src/compaction.rs +++ b/crates/llm-runtime/src/compaction.rs @@ -1,6 +1,6 @@ //! Bounded standalone compaction shared by native and summary adapters. use crate::{LlmAdapterError, LlmAdapterResult, LlmCompactionAdapter}; -use engine::{ +use harness::{ ContextCompactionRequest, ContextCompactionResult, ContextCompactionStatus, ContextEntry, ContextEntryInput, ContextEntryKind, ContextEntrySource, }; @@ -47,7 +47,7 @@ fn safe_cuts(entries: &[ContextEntry]) -> Vec { let same_native_window = index > 0 && matches!((&entries[index - 1].source, &entry.source), (ContextEntrySource::Runtime { label: previous }, ContextEntrySource::Runtime { label }) - if previous == engine::STANDALONE_COMPACTION_SOURCE && label == previous); + if previous == harness::STANDALONE_COMPACTION_SOURCE && label == previous); if index > 0 && !same_native_window && (turn != previous || turn.is_none()) @@ -109,7 +109,7 @@ pub(crate) async fn compact( let mut window: Vec = Vec::new(); let mut calls = 0; let mut spent = 0u64; - let mut usage: Option = None; + let mut usage: Option = None; while start < prefix.len() { let mut end = prefix.len(); loop { @@ -246,7 +246,7 @@ async fn estimate( fn synthetic_entry(input: ContextEntryInput, id: u64) -> ContextEntry { ContextEntry { - entry_id: engine::ContextEntryId::new(id), + entry_id: harness::ContextEntryId::new(id), key: None, source: ContextEntrySource::Runtime { label: "rolling_compaction".into(), @@ -261,7 +261,7 @@ fn synthetic_entry(input: ContextEntryInput, id: u64) -> ContextEntry { } } -fn add_usage(total: &mut Option, value: engine::LlmUsage) { +fn add_usage(total: &mut Option, value: harness::LlmUsage) { if let Some(total) = total { for (target, value) in [ (&mut total.input_tokens, value.input_tokens), @@ -291,7 +291,7 @@ fn add_usage(total: &mut Option, value: engine::LlmUsage) { mod tests { use super::*; use async_trait::async_trait; - use engine::{ + use harness::{ BlobRef, ContentRef, ContextCompactionTask, ContextEntryId, ContextMessageRole, ContextSnapshot, ModelSelection, ProviderApiKind, SessionId, TokenEstimate, TokenEstimateQuality, ToolCallId, ToolName, @@ -336,7 +336,7 @@ mod tests { status: ContextCompactionStatus::Succeeded, failure_ref: None, calls: 1, - usage: Some(engine::LlmUsage { + usage: Some(harness::LlmUsage { input_tokens: Some(10), output_tokens: Some(2), total_tokens: Some(12), @@ -491,7 +491,7 @@ mod tests { let mut entries: Vec<_> = (1..=4).map(entry).collect(); for entry in &mut entries[..3] { entry.source = ContextEntrySource::Runtime { - label: engine::STANDALONE_COMPACTION_SOURCE.into(), + label: harness::STANDALONE_COMPACTION_SOURCE.into(), }; } assert_eq!(safe_cuts(&entries), vec![0, 3, 4]); diff --git a/crates/llm-runtime/src/error.rs b/crates/llm-runtime/src/error.rs index cdfd1e4bd..bfd36dd40 100644 --- a/crates/llm-runtime/src/error.rs +++ b/crates/llm-runtime/src/error.rs @@ -1,4 +1,4 @@ -use engine::{BlobRef, ContextEntryId, ProviderApiKind}; +use harness::{BlobRef, ContextEntryId, ProviderApiKind}; use thiserror::Error; pub type LlmAdapterResult = Result; @@ -54,8 +54,8 @@ pub enum LlmAdapterError { }, } -impl From for LlmAdapterError { - fn from(error: engine::storage::BlobStoreError) -> Self { +impl From for LlmAdapterError { + fn from(error: harness::storage::BlobStoreError) -> Self { Self::BlobStore { message: error.to_string(), } diff --git a/crates/llm-runtime/src/executor.rs b/crates/llm-runtime/src/executor.rs index 6f8ea122a..652dd0e96 100644 --- a/crates/llm-runtime/src/executor.rs +++ b/crates/llm-runtime/src/executor.rs @@ -1,7 +1,7 @@ use std::{collections::BTreeMap, sync::Arc}; use async_trait::async_trait; -use engine::{ +use harness::{ ContextCompactionRequest, ContextCompactionResult, CoreAgentIoError, CoreAgentLlm, LlmGenerationRequest, LlmGenerationResult, ProviderApiKind, }; @@ -21,7 +21,7 @@ pub trait LlmGenerationAdapter: Send + Sync { #[async_trait] pub trait LlmCompactionAdapter: Send + Sync { - fn blobs(&self) -> Option<&dyn engine::storage::BlobStore> { + fn blobs(&self) -> Option<&dyn harness::storage::BlobStore> { None } async fn compact_context( @@ -207,7 +207,7 @@ impl CoreAgentLlm for LlmRuntime { mod tests { use super::*; use crate::error::LlmAdapterError; - use engine::{ContextSnapshot, LlmRequest, ModelSelection, RunId, SessionId, TurnId}; + use harness::{ContextSnapshot, LlmRequest, ModelSelection, RunId, SessionId, TurnId}; struct FailingAdapter { error: llm_clients::LlmApiError, diff --git a/crates/llm-runtime/src/lib.rs b/crates/llm-runtime/src/lib.rs index 14e9702fc..9595f6af9 100644 --- a/crates/llm-runtime/src/lib.rs +++ b/crates/llm-runtime/src/lib.rs @@ -1,6 +1,6 @@ //! LLM runtime adapters for Lightspeed-native agent sessions. //! -//! This crate connects `engine` LLM request records to provider-native +//! This crate connects `harness` LLM request records to provider-native //! `llm-clients` clients without making the deterministic agent core depend on //! provider clients or HTTP configuration. diff --git a/crates/llm-runtime/src/mcp.rs b/crates/llm-runtime/src/mcp.rs index 27054ac58..5e960f22c 100644 --- a/crates/llm-runtime/src/mcp.rs +++ b/crates/llm-runtime/src/mcp.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use engine::{RemoteMcpToolSpec, ToolName}; +use harness::{RemoteMcpToolSpec, ToolName}; use serde_json::Value; use crate::{LlmAdapterError, LlmAdapterResult}; @@ -100,7 +100,7 @@ impl McpInventoryResolver for UnconfiguredMcpInventoryResolver { #[cfg(test)] mod tests { use super::*; - use engine::{RemoteMcpApprovalPolicy, RemoteMcpExecution, RemoteMcpExposure}; + use harness::{RemoteMcpApprovalPolicy, RemoteMcpExecution, RemoteMcpExposure}; use serde_json::json; struct Inventory(Result, McpInventoryError>); diff --git a/crates/llm-runtime/src/media.rs b/crates/llm-runtime/src/media.rs index e77f48c40..4b783167d 100644 --- a/crates/llm-runtime/src/media.rs +++ b/crates/llm-runtime/src/media.rs @@ -22,7 +22,7 @@ use std::io::Cursor; use std::sync::{Mutex, OnceLock}; use base64::Engine as _; -use engine::{BlobRef, ContextEntry, ContextEntryId, ContextEntryKind, storage::BlobStore}; +use harness::{BlobRef, ContextEntry, ContextEntryId, ContextEntryKind, storage::BlobStore}; use image::codecs::jpeg::JpegEncoder; use image::codecs::png::{CompressionType, FilterType as PngFilter, PngEncoder}; use image::imageops::FilterType; @@ -214,7 +214,7 @@ impl ModelImage { /// The media announcement written before the image block, extended with /// the dimensions the model sees when the image was downscaled, so /// coordinate-based work can scale back to the source. - pub fn announcement(&self, entry: &engine::ContextEntry) -> String { + pub fn announcement(&self, entry: &harness::ContextEntry) -> String { let announcement = crate::blob_io::media_announcement(entry); match (&self.resize, announcement.strip_suffix(']')) { (Some(resize), Some(head)) => format!( @@ -476,18 +476,18 @@ mod tests { bytes } - fn image_entry(content_ref: BlobRef) -> engine::ContextEntry { - engine::ContextEntry { - entry_id: engine::ContextEntryId::new(1), + fn image_entry(content_ref: BlobRef) -> harness::ContextEntry { + harness::ContextEntry { + entry_id: harness::ContextEntryId::new(1), key: None, - kind: engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + kind: harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User, }, - source: engine::ContextEntrySource::RunInput { - run_id: engine::RunId::new(1), + source: harness::ContextEntrySource::RunInput { + run_id: harness::RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("image/png".to_owned()), provider_kind: None, @@ -616,7 +616,7 @@ mod tests { image.announcement(&entry), format!( "[image · {} · image/png · shown at 2000×1400 of 4000×2800]", - engine::media::media_handle(&blob_ref) + harness::media::media_handle(&blob_ref) ) ); } @@ -648,7 +648,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn request_media_omits_the_oldest_and_keeps_the_rest_prepared() { - let blobs = engine::storage::InMemoryBlobStore::new(); + let blobs = harness::storage::InMemoryBlobStore::new(); let png = { let mut bytes = Vec::new(); PngEncoder::new(&mut bytes) diff --git a/crates/llm-runtime/src/openai_completions.rs b/crates/llm-runtime/src/openai_completions.rs index 81aba46ea..44bbc7256 100644 --- a/crates/llm-runtime/src/openai_completions.rs +++ b/crates/llm-runtime/src/openai_completions.rs @@ -1,13 +1,13 @@ //! OpenAI Chat Completions adapter. //! //! Chat Completions has a message-oriented wire format distinct from the -//! Responses API. This adapter lowers engine context directly into native +//! Responses API. This adapter lowers harness context directly into native //! messages and preserves native tool-call objects for exact replay. use std::{collections::BTreeMap, sync::Arc}; use async_trait::async_trait; -use engine::{ +use harness::{ CompactionPolicy, ContextCompactionRequest, ContextCompactionResult, ContextCompactionStatus, ContextCompactionTask, ContextEntry, ContextEntryInput, ContextEntryKind, ContextEntrySource, ContextMessageRole, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, @@ -1112,7 +1112,7 @@ pub async fn result_from_response( kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(OPENAI_COMPLETIONS_MESSAGE_PROVIDER_KIND.to_owned()), @@ -1132,7 +1132,7 @@ pub async fn result_from_response( let content_ref = put_json(blobs, &reasoning_state).await?; context_entries.push(ContextEntryInput { kind: ContextEntryKind::ReasoningState, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(OPENAI_COMPLETIONS_REASONING_PROVIDER_KIND.to_owned()), @@ -1276,7 +1276,7 @@ pub async fn result_from_compact_response( kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_TEXT.to_owned()), provider_kind: Some(OPENAI_COMPLETIONS_COMPACTION_PROVIDER_KIND.to_owned()), @@ -1400,7 +1400,7 @@ async fn tool_call_context( call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: native_call_ref.clone(), media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: Some(OPENAI_COMPLETIONS_TOOL_CALL_PROVIDER_KIND.to_owned()), @@ -1470,10 +1470,10 @@ fn u64_to_u32(value: u64) -> u32 { #[cfg(test)] mod tests { - use engine::ToolSpec; + use harness::ToolSpec; use std::sync::{Arc, Mutex}; - use engine::{ + use harness::{ BlobRef, ContextEntryId, ContextSnapshot, FunctionToolSpec, ModelSelection, ProviderParams, RunId, SessionId, ToolParallelism, TurnId, storage::{BlobStore, InMemoryBlobStore}, @@ -1489,7 +1489,7 @@ mod tests { impl McpInventoryResolver for StaticMcpInventory { async fn list_tools( &self, - _spec: &engine::RemoteMcpToolSpec, + _spec: &harness::RemoteMcpToolSpec, ) -> Result, crate::McpInventoryError> { Ok(vec![crate::NativeMcpTool { remote_name: "lookup".to_owned(), @@ -1510,7 +1510,7 @@ mod tests { &tools::runtime::ToolTarget::api_kind(ProviderApiKind::OpenAiCompletions), &[ToolSpec { name: ToolName::try_new("mcp_internal").expect("name"), - kind: ToolKind::RemoteMcp(engine::RemoteMcpToolSpec { + kind: ToolKind::RemoteMcp(harness::RemoteMcpToolSpec { server_id: "internal".to_owned(), record_revision: 2, server_label: "internal".to_owned(), @@ -1519,7 +1519,7 @@ mod tests { allowed_tools: None, execution: RemoteMcpExecution::Native, exposure: RemoteMcpExposure::Inject, - approval: engine::RemoteMcpApprovalPolicy::Never, + approval: harness::RemoteMcpApprovalPolicy::Never, defer_loading: None, auth_ref: None, auth_required: false, @@ -1639,7 +1639,7 @@ mod tests { key: None, kind, source, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_TEXT.to_owned()), provider_kind: None, @@ -1763,7 +1763,7 @@ mod tests { request.output_limit = Some(321); request.reasoning_effort = Some("max".to_owned()); request.parallel_tool_use = Some(false); - request.processing_tier = Some(engine::ModelProcessingTier::Fast); + request.processing_tier = Some(harness::ModelProcessingTier::Fast); request.tool_choice = Some(ToolChoice::RequiredAny); request.params = Some(ProviderParams::new( ProviderApiKind::OpenAiCompletions, @@ -2016,7 +2016,7 @@ mod tests { parts[0]["text"], format!( "[image · {} · image/png]", - engine::media::media_handle(&BlobRef::from_bytes(&[1, 2, 3])) + harness::media::media_handle(&BlobRef::from_bytes(&[1, 2, 3])) ) ); assert_eq!(parts[1]["type"], "image_url"); @@ -2493,8 +2493,8 @@ mod tests { assert!(replay[0].extra.is_empty()); assert!(replay[0].refusal.is_none()); let view = api_projection::CoreAgentProjector::new(&blobs) - .project_event_kind(&engine::CoreAgentEvent::Context( - engine::ContextEvent::EntriesApplied { + .project_event_kind(&harness::CoreAgentEvent::Context( + harness::ContextEvent::EntriesApplied { base_revision: 0, entries: vec![entry], }, @@ -2747,7 +2747,7 @@ mod tests { .expect("store pdf"); let make = |id: u64, kind: ContextEntryKind, - content: engine::ContentRef, + content: harness::ContentRef, preview: Option<&str>| { ContextEntry { entry_id: ContextEntryId::new(id), @@ -2769,7 +2769,7 @@ mod tests { call_id: ToolCallId::try_new("call_1").expect("call id"), is_error: false, }, - engine::ContentRef::text(result_ref), + harness::ContentRef::text(result_ref), None, ), make( @@ -2777,7 +2777,7 @@ mod tests { ContextEntryKind::Message { role: ContextMessageRole::User, }, - engine::ContentRef { + harness::ContentRef { content_ref: image_ref, media_type: Some("image/png".to_owned()), provider_kind: None, @@ -2789,7 +2789,7 @@ mod tests { ContextEntryKind::Message { role: ContextMessageRole::User, }, - engine::ContentRef { + harness::ContentRef { content_ref: pdf_ref, media_type: Some("application/pdf".to_owned()), provider_kind: None, diff --git a/crates/llm-runtime/src/openai_responses.rs b/crates/llm-runtime/src/openai_responses.rs index 0ff944df1..5f9d759e9 100644 --- a/crates/llm-runtime/src/openai_responses.rs +++ b/crates/llm-runtime/src/openai_responses.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use async_trait::async_trait; -use engine::{ +use harness::{ ApprovalContinuation, ApprovalSubject, BlobRef, CompactionPolicy, ContextCompactionRequest, ContextCompactionResult, ContextCompactionStatus, ContextCompactionTask, ContextEntry, ContextEntryInput, ContextEntryKind, ContextMessageRole, LlmFinish, LlmGenerationFacts, @@ -317,7 +317,7 @@ impl OpenAiResponsesLlmAdapter { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: crate::blob_io::put_text(self.blobs.as_ref(), &text).await?, media_type: Some(MEDIA_TYPE_TEXT.into()), provider_kind: Some("openai.responses.compaction_summary_text".into()), @@ -1223,7 +1223,7 @@ pub async fn result_from_compact_response( } else { context_entries.push(ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: put_json(blobs, &raw_item).await?, media_type: Some(MEDIA_TYPE_JSON.into()), provider_kind: Some("openai.responses.compacted_window_item".into()), @@ -1368,7 +1368,7 @@ async fn assistant_context_entries( kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: if native { put_json(blobs, &raw_item).await? } else { @@ -1440,7 +1440,7 @@ async fn function_call_context( call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: native_call_ref.clone(), media_type: Some(MEDIA_TYPE_JSON.to_string()), provider_kind: Some(PROVIDER_KIND_FUNCTION_CALL.to_string()), @@ -1471,7 +1471,7 @@ async fn reasoning_context_entry( let content_ref = put_json(blobs, &raw_item).await?; Ok(Some(ContextEntryInput { kind: ContextEntryKind::ReasoningState, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_string()), provider_kind: Some( @@ -1499,7 +1499,7 @@ async fn compaction_context_entry( let content_ref = put_json(blobs, &raw_item).await?; Ok(ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_string()), provider_kind: Some(OPENAI_RESPONSES_COMPACTION_PROVIDER_KIND.to_string()), @@ -1518,7 +1518,7 @@ async fn web_search_call_context_entry( let content_ref = put_json(blobs, &raw_item).await?; Ok(ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_string()), provider_kind: Some(OPENAI_RESPONSES_WEB_SEARCH_CALL_PROVIDER_KIND.to_string()), @@ -1548,7 +1548,7 @@ async fn mcp_context_entry( let content_ref = put_json(blobs, &raw_item).await?; Ok(ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(MEDIA_TYPE_JSON.to_string()), provider_kind: Some(provider_kind.to_string()), @@ -1650,7 +1650,7 @@ mod tests { use std::collections::BTreeMap; use std::sync::{Arc, Mutex}; - use engine::{ + use harness::{ ContextCompactionTask, ContextEntryId, ContextEntrySource, ContextSnapshot, CoreAgentLlm, FunctionToolSpec, LlmGenerationRequest, LlmRequest, ModelSelection, ProviderParams, RunId, SessionId, ToolParallelism, TurnId, storage::InMemoryBlobStore, @@ -1960,11 +1960,11 @@ mod tests { .await .expect("provider options"); let instructions_item = ContextEntry { - key: Some(engine::ContextEntryKey::new("instructions.000.test")), + key: Some(harness::ContextEntryKey::new("instructions.000.test")), entry_id: ContextEntryId::new(1), kind: ContextEntryKind::Instructions, source: ContextEntrySource::ContextEdit, - content: engine::ContentRef::text(instructions_ref), + content: harness::ContentRef::text(instructions_ref), preview: None, origin: None, provenance_ref: None, @@ -1981,7 +1981,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -2013,7 +2013,7 @@ mod tests { request.compaction = Some(CompactionPolicy::ProviderTriggered { compact_threshold_tokens: Some(120_000), }); - request.processing_tier = Some(engine::ModelProcessingTier::Flex); + request.processing_tier = Some(harness::ModelProcessingTier::Flex); request.params = Some(openai_params(&OpenAiResponsesParams { reasoning: Some(OpenAiReasoningConfig { effort: Some("medium".to_string()), @@ -2093,17 +2093,17 @@ mod tests { .expect("enabled web search"); let mut request = intent_request(Vec::new()); - request.tools = vec![engine::ToolSpec { - name: engine::ToolName::new("web_search"), - kind: engine::ToolKind::ProviderNative(engine::ProviderNativeToolSpec { + request.tools = vec![harness::ToolSpec { + name: harness::ToolName::new("web_search"), + kind: harness::ToolKind::ProviderNative(harness::ProviderNativeToolSpec { api_kind: ProviderApiKind::OpenAiResponses, native_tool_ref: blobs .put_bytes(serde_json::to_vec(&native).expect("native json")) .await .expect("native definition"), - execution: engine::ProviderNativeToolExecution::ProviderHosted, + execution: harness::ProviderNativeToolExecution::ProviderHosted, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, execution: Default::default(), }]; request.tool_choice = Some(ToolChoice::Auto); @@ -2222,9 +2222,9 @@ mod tests { }, source: ContextEntrySource::ApprovalDecision { run_id: RunId::new(1), - approval_id: engine::ApprovalId::try_new("approval_1").expect("approval id"), + approval_id: harness::ApprovalId::try_new("approval_1").expect("approval id"), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: response_ref, media_type: Some(MEDIA_TYPE_JSON.to_owned()), provider_kind: None, @@ -2259,7 +2259,7 @@ mod tests { exposure: RemoteMcpExposure::Inject, approval: RemoteMcpApprovalPolicy::Never, defer_loading: None, - auth_ref: Some(engine::SecretRef { + auth_ref: Some(harness::SecretRef { namespace: "mcp_server".to_string(), id: "echo".to_string(), }), @@ -2562,7 +2562,7 @@ mod tests { source: ContextEntrySource::Runtime { label: "runtime.catalog.skills.vfs".to_string(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: catalog_ref, media_type: None, provider_kind: None, @@ -2583,7 +2583,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -2603,7 +2603,7 @@ mod tests { source: ContextEntrySource::Runtime { label: "inserted-skill".to_string(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: skill_text_ref, media_type: None, provider_kind: None, @@ -2653,7 +2653,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -2822,7 +2822,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -3401,15 +3401,15 @@ mod tests { } assert_eq!( result.context_entries[0].content.provider_kind.as_deref(), - Some(engine::OPENAI_RESPONSES_MCP_LIST_TOOLS_PROVIDER_KIND) + Some(harness::OPENAI_RESPONSES_MCP_LIST_TOOLS_PROVIDER_KIND) ); assert_eq!( result.context_entries[1].content.provider_kind.as_deref(), - Some(engine::OPENAI_RESPONSES_MCP_CALL_PROVIDER_KIND) + Some(harness::OPENAI_RESPONSES_MCP_CALL_PROVIDER_KIND) ); assert_eq!( result.context_entries[2].content.provider_kind.as_deref(), - Some(engine::OPENAI_RESPONSES_MCP_APPROVAL_REQUEST_PROVIDER_KIND) + Some(harness::OPENAI_RESPONSES_MCP_APPROVAL_REQUEST_PROVIDER_KIND) ); assert_eq!( result.context_entries[1].preview.as_deref(), @@ -3480,7 +3480,7 @@ mod tests { run_id: RunId::new(1), input_index: id as u32 - 1, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: media_type.map(str::to_owned), provider_kind: None, @@ -3536,7 +3536,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: pdf_ref, media_type: Some("application/pdf".to_owned()), provider_kind: None, @@ -3558,7 +3558,7 @@ mod tests { value["content"][0]["text"], json!(format!( "[document: offer.pdf · {} · application/pdf]", - engine::media::media_handle(&BlobRef::from_bytes(b"%PDF-1.4 fake")) + harness::media::media_handle(&BlobRef::from_bytes(b"%PDF-1.4 fake")) )) ); assert_eq!(value["content"][1]["type"], json!("input_file")); @@ -3584,7 +3584,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: doc_ref, media_type: Some("text/markdown".to_owned()), provider_kind: None, @@ -3770,7 +3770,7 @@ mod tests { run_id: RunId::new(1), turn_id: TurnId::new(1), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -3816,7 +3816,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("image/png".to_owned()), provider_kind: None, @@ -3839,7 +3839,7 @@ mod tests { value["content"][0]["text"], json!(format!( "[image: photo.png · {} · image/png]", - engine::media::media_handle(&entry.content.content_ref) + harness::media::media_handle(&entry.content.content_ref) )) ); assert_eq!(value["content"][1]["type"], json!("input_image")); @@ -3857,13 +3857,13 @@ mod tests { fn catalog_entry(id: u64, content_ref: BlobRef, supersedes: Option) -> ContextEntry { ContextEntry { - key: Some(engine::ContextEntryKey::new("bot:directory")), + key: Some(harness::ContextEntryKey::new("bot:directory")), entry_id: ContextEntryId::new(id), kind: ContextEntryKind::Catalog { title: "Bot directory".to_string(), }, source: ContextEntrySource::ContextEdit, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/markdown".to_string()), provider_kind: None, @@ -3900,7 +3900,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -3973,7 +3973,7 @@ mod tests { .expect("store pdf"); let make = |id: u64, kind: ContextEntryKind, - content: engine::ContentRef, + content: harness::ContentRef, preview: Option<&str>| { ContextEntry { entry_id: ContextEntryId::new(id), @@ -3995,7 +3995,7 @@ mod tests { call_id: ToolCallId::try_new("call_1").expect("call id"), is_error: false, }, - engine::ContentRef::text(result_ref), + harness::ContentRef::text(result_ref), None, ), make( @@ -4003,7 +4003,7 @@ mod tests { ContextEntryKind::Message { role: ContextMessageRole::User, }, - engine::ContentRef { + harness::ContentRef { content_ref: image_ref, media_type: Some("image/png".to_owned()), provider_kind: None, @@ -4015,7 +4015,7 @@ mod tests { ContextEntryKind::Message { role: ContextMessageRole::User, }, - engine::ContentRef { + harness::ContentRef { content_ref: pdf_ref, media_type: Some("application/pdf".to_owned()), provider_kind: None, @@ -4072,7 +4072,7 @@ mod tests { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef::text(text.clone()), + content: harness::ContentRef::text(text.clone()), preview: None, origin: None, provenance_ref: None, diff --git a/crates/llm-runtime/src/params.rs b/crates/llm-runtime/src/params.rs index c98a23475..8f27a75dd 100644 --- a/crates/llm-runtime/src/params.rs +++ b/crates/llm-runtime/src/params.rs @@ -1,7 +1,7 @@ //! Typed provider request parameters. //! -//! The engine carries provider request settings as opaque -//! [`engine::ProviderParams`] (`api_kind` + versioned JSON body). This module +//! The harness carries provider request settings as opaque +//! [`harness::ProviderParams`] (`api_kind` + versioned JSON body). This module //! owns the typed schemas for those bodies: admission boundaries validate //! incoming params against them, and adapters parse them when materializing //! provider-native wire requests. The deterministic core never sees these @@ -9,7 +9,7 @@ use std::collections::BTreeMap; -use engine::{ModelProcessingTier, ProviderApiKind, ProviderParams}; +use harness::{ModelProcessingTier, ProviderApiKind, ProviderParams}; use serde::{Deserialize, Serialize}; use serde_json::Value; diff --git a/crates/llm-runtime/src/prompt_cache.rs b/crates/llm-runtime/src/prompt_cache.rs index 51e8bfc04..29e9349cc 100644 --- a/crates/llm-runtime/src/prompt_cache.rs +++ b/crates/llm-runtime/src/prompt_cache.rs @@ -5,7 +5,7 @@ //! long-lived session are best-effort. The session id is the natural key: //! every turn of a session shares its prefix, and nothing else does. -use engine::{BlobRef, SessionId}; +use harness::{BlobRef, SessionId}; /// OpenAI accepts short opaque keys; longer session ids are hashed so the /// key stays stable and within bounds. diff --git a/crates/llm-runtime/src/provider_keys.rs b/crates/llm-runtime/src/provider_keys.rs index 5084760fd..a01ceb391 100644 --- a/crates/llm-runtime/src/provider_keys.rs +++ b/crates/llm-runtime/src/provider_keys.rs @@ -12,7 +12,7 @@ use std::collections::BTreeMap; use async_trait::async_trait; -use engine::{ModelSelection, ProviderApiKind}; +use harness::{ModelSelection, ProviderApiKind}; use llm_clients::EndpointOverride; use thiserror::Error; @@ -143,7 +143,7 @@ pub(crate) async fn resolve_model_provider( }) } -/// Resolve a protocol route without extending the engine's generation model enum. +/// Resolve a protocol route without extending the harness's generation model enum. /// Only built-in providers may use deployment transport defaults. pub async fn resolve_provider_route( resolver: &dyn ModelProviderResolver, diff --git a/crates/llm-runtime/src/result.rs b/crates/llm-runtime/src/result.rs index c1a440cff..aa0af4df2 100644 --- a/crates/llm-runtime/src/result.rs +++ b/crates/llm-runtime/src/result.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use engine::{ +use harness::{ BlobRef, ContextEntryId, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, LlmGenerationStatus, RunId, TurnId, storage::BlobStore, }; @@ -129,14 +129,14 @@ pub fn truncation_failure_text( /// replay-safe. pub async fn partial_output_entries( blobs: &dyn BlobStore, - entries: Vec, -) -> LlmAdapterResult> { + entries: Vec, +) -> LlmAdapterResult> { let mut partial = Vec::new(); for mut entry in entries { if !matches!( entry.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::Assistant + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::Assistant } ) { continue; @@ -144,10 +144,10 @@ pub async fn partial_output_entries( if entry.content.media_type.as_deref() == Some("application/json") { let raw = crate::blob_io::read_json(blobs, &entry.content.content_ref).await?; let text = match entry.content.provider_kind.as_deref() { - Some(engine::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND) => { + Some(harness::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND) => { llm_clients::content::anthropic_text_blocks(&raw) } - Some(engine::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND) => { + Some(harness::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND) => { llm_clients::content::openai_response_message(&raw) } Some(llm_clients::content::OPENAI_COMPLETIONS_MESSAGE_PROVIDER_KIND) => { diff --git a/crates/llm-runtime/src/secrets.rs b/crates/llm-runtime/src/secrets.rs index 3f22e8c6d..0a32c92fb 100644 --- a/crates/llm-runtime/src/secrets.rs +++ b/crates/llm-runtime/src/secrets.rs @@ -12,7 +12,7 @@ use std::collections::BTreeMap; use std::fmt; use async_trait::async_trait; -use engine::SecretRef; +use harness::SecretRef; use thiserror::Error; pub const SECRET_NAMESPACE_ENV: &str = "env"; diff --git a/crates/llm-runtime/src/testing.rs b/crates/llm-runtime/src/testing.rs index 069ed153a..6f471ebdd 100644 --- a/crates/llm-runtime/src/testing.rs +++ b/crates/llm-runtime/src/testing.rs @@ -1,4 +1,4 @@ -use engine::{ContextEntry, ContextSnapshot, ProviderApiKind, TokenEstimate}; +use harness::{ContextEntry, ContextSnapshot, ProviderApiKind, TokenEstimate}; pub fn context_snapshot( api_kind: ProviderApiKind, diff --git a/crates/llm-runtime/src/tool_catalog.rs b/crates/llm-runtime/src/tool_catalog.rs index 78fd838dd..e877806c2 100644 --- a/crates/llm-runtime/src/tool_catalog.rs +++ b/crates/llm-runtime/src/tool_catalog.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet}; -use engine::{ +use harness::{ LlmGenerationResult, ProviderApiKind, ProviderNativeToolExecution, RemoteMcpToolSpec, ToolChoice, ToolKind, ToolName, ToolSpec, storage::BlobStore, }; @@ -192,7 +192,7 @@ impl ToolCatalog { /// The exact function namespace advertised in this request, including expanded /// MCP functions and provider-hosted helpers. Only client functions can route -/// back into the engine. +/// back into the harness. #[derive(Default)] pub(crate) struct AdvertisedNames { exposed: BTreeSet, @@ -229,7 +229,7 @@ pub(crate) fn valid_exposed_name(name: &str) -> bool { #[cfg(test)] mod tests { use super::*; - use engine::{ + use harness::{ BlobRef, BuiltinToolSpec, FunctionToolSpec, LlmFinish, LlmGenerationFacts, LlmGenerationStatus, ObservedToolCall, RunId, ToolCallId, ToolParallelism, TurnId, storage::InMemoryBlobStore, @@ -462,7 +462,7 @@ mod tests { .unwrap(); let native = ToolSpec { name: ToolName::new("custom"), - kind: ToolKind::ProviderNative(engine::ProviderNativeToolSpec { + kind: ToolKind::ProviderNative(harness::ProviderNativeToolSpec { api_kind: ProviderApiKind::OpenAiResponses, native_tool_ref, execution: ProviderNativeToolExecution::ClientEffect, diff --git a/crates/llm-runtime/tests/anthropic_messages_caching_live.rs b/crates/llm-runtime/tests/anthropic_messages_caching_live.rs index 1bf787dc4..8d65bc624 100644 --- a/crates/llm-runtime/tests/anthropic_messages_caching_live.rs +++ b/crates/llm-runtime/tests/anthropic_messages_caching_live.rs @@ -5,7 +5,7 @@ use std::sync::Arc; -use engine::{ +use harness::{ BlobRef, ContextEntry, ContextEntryId, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmGenerationRequest, LlmGenerationStatus, LlmRequest, LlmUsage, ModelSelection, ProviderApiKind, RunId, SessionId, @@ -44,7 +44,7 @@ fn entry( entry_id: ContextEntryId::new(id), kind, source, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -183,7 +183,7 @@ async fn generate( (usage, execution.result.context_entries) } -async fn assert_succeeded(blobs: &InMemoryBlobStore, result: &engine::LlmGenerationResult) { +async fn assert_succeeded(blobs: &InMemoryBlobStore, result: &harness::LlmGenerationResult) { let failure = match result.failure_ref.as_ref() { Some(reference) => blobs.read_text(reference).await.expect("failure details"), None => format!("finish={:?}", result.facts.finish), @@ -282,17 +282,17 @@ async fn anthropic_caching_live_tool_round_trip_keeps_the_prefix_warm() { .await .expect("schema blob"); let description_ref = text_blob(&blobs, "Get current weather for a city").await; - let tool = engine::ToolSpec { + let tool = harness::ToolSpec { name: ToolName::new("get_weather"), execution: Default::default(), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: Some(description_ref), input_schema_ref: schema_ref, output_schema_ref: None, strict: None, provider_options_ref: None, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, }; let mut request = intent_request( diff --git a/crates/llm-runtime/tests/anthropic_messages_compaction_live.rs b/crates/llm-runtime/tests/anthropic_messages_compaction_live.rs index 9f548bdcc..5071d3fe1 100644 --- a/crates/llm-runtime/tests/anthropic_messages_compaction_live.rs +++ b/crates/llm-runtime/tests/anthropic_messages_compaction_live.rs @@ -1,11 +1,11 @@ -//! Live engine-loop compaction tests for the Anthropic Messages adapter. +//! Live harness-loop compaction tests for the Anthropic Messages adapter. //! //! Provider-triggered tests exercise native summaries, pruning, and recall. -//! Standalone tests exercise summarization requests planned by the engine. +//! Standalone tests exercise summarization requests planned by the harness. use std::sync::Arc; -use engine::{ +use harness::{ ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND, BlobRef, CompactionPolicy, ContextCompactionStatus, ContextCompactionTrigger, ContextConfig, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextMessageRole, ContextRemovalReason, CoreAgentCommand, @@ -31,7 +31,7 @@ const LIVE_MARKER: &str = "LIGHTSPEED-ANTHROPIC-COMPACTION-LIVE-4217"; #[tokio::test(flavor = "current_thread")] #[ignore = "requires ANTHROPIC_API_KEY and a compaction-capable Anthropic model (costs real money)"] -async fn anthropic_messages_live_engine_prunes_and_reuses_provider_compaction() { +async fn anthropic_messages_live_harness_prunes_and_reuses_provider_compaction() { const NEWSLETTER_TITLE: &str = "Spring Garden Notes: April Edition"; let session_id = SessionId::new("session-live-anthropic-provider-compaction"); let (runner, blobs) = live_runner(&session_id).await; @@ -164,16 +164,16 @@ async fn anthropic_messages_live_engine_prunes_and_reuses_provider_compaction() } fn provider_compaction_run(content_ref: BlobRef) -> CoreAgentCommand { - CoreAgentCommand::RequestRun(engine::RunRequestCommand { + CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -300,16 +300,16 @@ async fn anthropic_messages_live_manual_standalone_compaction_preserves_marker() .drive_command(DriveCommand { session_id, observed_at_ms: 40, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: question_ref, media_type: None, provider_kind: None, @@ -457,7 +457,7 @@ fn standalone_session_config( ) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(2048), reasoning_effort: None, tool_choice: None, @@ -509,7 +509,7 @@ fn anthropic_raw_context_input( ) -> ContextEntryInput { ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("application/json".to_owned()), provider_kind: Some(ANTHROPIC_MESSAGES_INPUT_MESSAGE_PROVIDER_KIND.to_owned()), @@ -524,7 +524,7 @@ fn anthropic_raw_context_input( } } -fn compaction_summary_entries(state: &engine::CoreAgentState) -> Vec<&engine::ContextEntry> { +fn compaction_summary_entries(state: &harness::CoreAgentState) -> Vec<&harness::ContextEntry> { state .context .entries @@ -536,7 +536,7 @@ fn compaction_summary_entries(state: &engine::CoreAgentState) -> Vec<&engine::Co .collect() } -fn active_context_contains_ref(state: &engine::CoreAgentState, content_ref: &BlobRef) -> bool { +fn active_context_contains_ref(state: &harness::CoreAgentState, content_ref: &BlobRef) -> bool { state .context .entries @@ -545,13 +545,13 @@ fn active_context_contains_ref(state: &engine::CoreAgentState, content_ref: &Blo } fn has_compaction_requested( - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], expected_trigger: ContextCompactionTrigger, ) -> bool { entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::CompactionRequested { + CoreAgentEvent::Context(harness::ContextEvent::CompactionRequested { trigger, .. }) if *trigger == expected_trigger @@ -560,13 +560,13 @@ fn has_compaction_requested( } fn has_compaction_finished( - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], expected_status: ContextCompactionStatus, ) -> bool { entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::CompactionFinished { + CoreAgentEvent::Context(harness::ContextEvent::CompactionFinished { status, .. }) if *status == expected_status @@ -574,11 +574,11 @@ fn has_compaction_finished( }) } -fn has_provider_compacted_removal(entries: &[engine::CoreAgentEntry]) -> bool { +fn has_provider_compacted_removal(entries: &[harness::CoreAgentEntry]) -> bool { entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::EntriesRemoved { + CoreAgentEvent::Context(harness::ContextEvent::EntriesRemoved { reason: ContextRemovalReason::ProviderCompacted, .. }) @@ -586,10 +586,10 @@ fn has_provider_compacted_removal(entries: &[engine::CoreAgentEntry]) -> bool { }) } -async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> String { +async fn assistant_text(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> String { let mut text = String::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { @@ -610,10 +610,10 @@ async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry async fn compaction_failure_text( blobs: &dyn BlobStore, - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], ) -> String { for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::CompactionFinished { + if let CoreAgentEvent::Context(harness::ContextEvent::CompactionFinished { status: ContextCompactionStatus::Failed, failure_ref: Some(failure_ref), .. @@ -628,7 +628,7 @@ async fn compaction_failure_text( "compaction did not finish with a failure ref".to_owned() } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.last() else { return "run did not complete".to_owned(); }; @@ -683,7 +683,7 @@ async fn anthropic_messages_live_chunked_compaction_keeps_tail_and_transitions_t kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, @@ -728,8 +728,8 @@ async fn anthropic_messages_live_chunked_compaction_keeps_tail_and_transitions_t .filter(|entry| { matches!( entry.source, - engine::ContextEntrySource::AssistantOutput { .. } - | engine::ContextEntrySource::Reasoning { .. } + harness::ContextEntrySource::AssistantOutput { .. } + | harness::ContextEntrySource::Reasoning { .. } ) }) .collect(); @@ -760,9 +760,9 @@ async fn anthropic_messages_live_chunked_compaction_keeps_tail_and_transitions_t .emitted_entries .iter() .find_map(|entry| match entry.event { - CoreAgentEvent::Context(engine::ContextEvent::CompactionFinished { calls, .. }) => { - Some(calls) - } + CoreAgentEvent::Context(harness::ContextEvent::CompactionFinished { + calls, .. + }) => Some(calls), _ => None, }) .unwrap(); diff --git a/crates/llm-runtime/tests/anthropic_messages_live.rs b/crates/llm-runtime/tests/anthropic_messages_live.rs index 7d6ab3337..2f9c222b9 100644 --- a/crates/llm-runtime/tests/anthropic_messages_live.rs +++ b/crates/llm-runtime/tests/anthropic_messages_live.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use engine::{ +use harness::{ ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND, ANTHROPIC_MESSAGES_SERVER_TOOL_RESULT_PROVIDER_KIND, ANTHROPIC_MESSAGES_SERVER_TOOL_USE_PROVIDER_KIND, ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND, @@ -46,7 +46,7 @@ fn user_entry(entry_id: u64, content_ref: BlobRef) -> ContextEntry { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -158,18 +158,18 @@ fn retained_context_entry(index: usize, item: &ContextEntryInput) -> ContextEntr } } -fn weather_tool_spec(schema_ref: BlobRef, description_ref: BlobRef) -> engine::ToolSpec { - engine::ToolSpec { +fn weather_tool_spec(schema_ref: BlobRef, description_ref: BlobRef) -> harness::ToolSpec { + harness::ToolSpec { name: ToolName::new("get_weather"), execution: Default::default(), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: Some(description_ref), input_schema_ref: schema_ref, output_schema_ref: None, strict: None, provider_options_ref: None, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, } } @@ -346,7 +346,7 @@ async fn anthropic_messages_live_adapter_uses_hosted_web_search() { let tool = tools::definitions::register( "web.search", Default::default(), - engine::ToolParallelism::ParallelSafe, + harness::ToolParallelism::ParallelSafe, Default::default(), ); let input_ref = text_blob( @@ -411,7 +411,7 @@ async fn anthropic_messages_live_adapter_uses_hosted_web_fetch() { let tool = tools::definitions::register( "web.fetch", Default::default(), - engine::ToolParallelism::ParallelSafe, + harness::ToolParallelism::ParallelSafe, Default::default(), ); let input_ref = text_blob( @@ -711,7 +711,7 @@ async fn anthropic_messages_live_adapter_runs_tool_round_trip() { turn_id: TurnId::new(1), batch_id: None, }, - content: engine::ContentRef::text(tool_output_ref), + content: harness::ContentRef::text(tool_output_ref), preview: None, origin: None, provenance_ref: None, @@ -986,7 +986,7 @@ async fn anthropic_messages_live_adapter_thinks_across_tool_round_trip() { turn_id: TurnId::new(1), batch_id: None, }, - content: engine::ContentRef::text(tool_output_ref), + content: harness::ContentRef::text(tool_output_ref), preview: None, origin: None, provenance_ref: None, @@ -1757,7 +1757,7 @@ async fn anthropic_messages_live_adapter_sees_oversized_image() { #[tokio::test(flavor = "current_thread")] #[ignore = "requires ANTHROPIC_API_KEY (costs real money)"] async fn anthropic_messages_live_runtime_reports_provider_rejections() { - use engine::{CoreAgentIoError, CoreAgentLlm as _}; + use harness::{CoreAgentIoError, CoreAgentLlm as _}; let blobs = Arc::new(InMemoryBlobStore::new()); let mut corrupt = b"\x89PNG\r\n\x1a\n".to_vec(); corrupt.extend(std::iter::repeat_n(0x5a, 4096)); diff --git a/crates/llm-runtime/tests/anthropic_messages_mcp_live.rs b/crates/llm-runtime/tests/anthropic_messages_mcp_live.rs index 76820d254..ee36a2628 100644 --- a/crates/llm-runtime/tests/anthropic_messages_mcp_live.rs +++ b/crates/llm-runtime/tests/anthropic_messages_mcp_live.rs @@ -1,12 +1,12 @@ -//! Live engine-loop test for direct remote MCP through the Anthropic MCP -//! connector: the engine session carries a `RemoteMcp` tool spec, the adapter +//! Live harness-loop test for direct remote MCP through the Anthropic MCP +//! connector: the harness session carries a `RemoteMcp` tool spec, the adapter //! lowers it into the request-level `mcp_servers` field, and the connector's //! `mcp_tool_use`/`mcp_tool_result` blocks come back as provider-opaque //! context without any Lightspeed tool events. use std::{collections::BTreeMap, sync::Arc}; -use engine::{ +use harness::{ ContextConfig, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentEvent, ModelSelection, ProviderApiKind, RemoteMcpApprovalPolicy, RemoteMcpToolSpec, RunConfig, RunStatus, SessionConfig, SessionId, ToolKind, ToolName, ToolParallelism, ToolSpec, @@ -109,16 +109,16 @@ async fn anthropic_messages_live_core_session_uses_public_remote_mcp() { .drive_command(DriveCommand { session_id: session_id.clone(), observed_at_ms: 20, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -196,8 +196,8 @@ fn remote_mcp_tools() -> BTreeMap { server_url: MCP_TEST_SERVER_URL.to_string(), description_ref: None, allowed_tools: Some(vec![MCP_TEST_TOOL.to_string()]), - execution: engine::RemoteMcpExecution::Provider, - exposure: engine::RemoteMcpExposure::Inject, + execution: harness::RemoteMcpExecution::Provider, + exposure: harness::RemoteMcpExposure::Inject, approval: RemoteMcpApprovalPolicy::Never, defer_loading: Some(true), auth_ref: None, @@ -212,7 +212,7 @@ fn remote_mcp_tools() -> BTreeMap { fn session_config(model: ModelSelection) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(4096), reasoning_effort: None, tool_choice: None, @@ -244,17 +244,17 @@ fn run_config() -> RunConfig { } } -async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> String { +async fn assistant_text(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> String { let mut text = String::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::Assistant + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::Assistant } ) { text.push_str(&support::content_text(blobs, &item.content).await); @@ -268,19 +268,19 @@ async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry async fn mcp_context_items( blobs: &dyn BlobStore, - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], ) -> Vec { let mut items = Vec::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.content.provider_kind.as_deref(), Some( - engine::ANTHROPIC_MESSAGES_MCP_TOOL_USE_PROVIDER_KIND - | engine::ANTHROPIC_MESSAGES_MCP_TOOL_RESULT_PROVIDER_KIND + harness::ANTHROPIC_MESSAGES_MCP_TOOL_USE_PROVIDER_KIND + | harness::ANTHROPIC_MESSAGES_MCP_TOOL_RESULT_PROVIDER_KIND ) ) { let bytes = blobs @@ -297,19 +297,19 @@ async fn mcp_context_items( async fn tool_search_context_items( blobs: &dyn BlobStore, - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], ) -> Vec { let mut items = Vec::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.content.provider_kind.as_deref(), Some( - engine::ANTHROPIC_MESSAGES_SERVER_TOOL_USE_PROVIDER_KIND - | engine::ANTHROPIC_MESSAGES_SERVER_TOOL_RESULT_PROVIDER_KIND + harness::ANTHROPIC_MESSAGES_SERVER_TOOL_USE_PROVIDER_KIND + | harness::ANTHROPIC_MESSAGES_SERVER_TOOL_RESULT_PROVIDER_KIND ) ) { let bytes = blobs @@ -324,7 +324,7 @@ async fn tool_search_context_items( items } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.first() else { return "run did not complete".to_owned(); }; diff --git a/crates/llm-runtime/tests/anthropic_messages_prompts_live.rs b/crates/llm-runtime/tests/anthropic_messages_prompts_live.rs index 3b3470cca..707f28942 100644 --- a/crates/llm-runtime/tests/anthropic_messages_prompts_live.rs +++ b/crates/llm-runtime/tests/anthropic_messages_prompts_live.rs @@ -1,4 +1,4 @@ -//! Live engine-loop test proving VFS prompt instructions flow into the +//! Live harness-loop test proving VFS prompt instructions flow into the //! Anthropic Messages request as the system prompt. use std::{ @@ -7,7 +7,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ ContextConfig, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentEvent, ModelSelection, ProviderApiKind, RunConfig, RunStatus, SessionConfig, SessionId, WorkspaceAccess, WorkspaceAttachment, WorkspaceAttachmentTarget, @@ -226,16 +226,16 @@ async fn anthropic_messages_live_uses_vfs_prompt_instructions() { .drive_command(DriveCommand { session_id, observed_at_ms: 20, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -284,7 +284,7 @@ fn session_config( ) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(4096), reasoning_effort: None, tool_choice: None, @@ -297,13 +297,13 @@ fn session_config( input_limit_tokens: None, compaction: None, }, - features: engine::FeaturesConfig { - vfs: Some(engine::VfsFeature { + features: harness::FeaturesConfig { + vfs: Some(harness::VfsFeature { workspaces: workspace_attachments, - prompts: Some(engine::VfsPromptsConfig::default()), - ..engine::VfsFeature::default() + prompts: Some(harness::VfsPromptsConfig::default()), + ..harness::VfsFeature::default() }), - ..engine::FeaturesConfig::default() + ..harness::FeaturesConfig::default() }, } } @@ -323,17 +323,17 @@ fn run_config() -> RunConfig { } } -async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> String { +async fn assistant_text(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> String { let mut text = String::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::Assistant + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::Assistant } ) { text.push_str(&support::content_text(blobs, &item.content).await); @@ -345,7 +345,7 @@ async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry text } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.first() else { return "run did not complete".to_owned(); }; diff --git a/crates/llm-runtime/tests/anthropic_messages_skills_live.rs b/crates/llm-runtime/tests/anthropic_messages_skills_live.rs index 69c55759b..9f64ff384 100644 --- a/crates/llm-runtime/tests/anthropic_messages_skills_live.rs +++ b/crates/llm-runtime/tests/anthropic_messages_skills_live.rs @@ -1,4 +1,4 @@ -//! Live engine-loop test proving the skill catalog flow works end to end on +//! Live harness-loop test proving the skill catalog flow works end to end on //! the Anthropic Messages adapter: the catalog lowers as a user message, the //! model picks the matching skill, reads its SKILL.md through the fs file //! tool, and follows its migration preparation instructions. @@ -9,7 +9,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, ContextConfig, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentEvent, ModelSelection, ProviderApiKind, RunConfig, RunStatus, SessionConfig, SessionId, WorkspaceAccess, WorkspaceAttachment, WorkspaceAttachmentTarget, @@ -265,16 +265,16 @@ async fn anthropic_messages_live_selects_and_reads_the_matching_skill() { .drive_command(DriveCommand { session_id, observed_at_ms: 20, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -307,7 +307,7 @@ async fn anthropic_messages_live_selects_and_reads_the_matching_skill() { .emitted_entries .iter() .find_map(|entry| { - let CoreAgentEvent::Tool(engine::ToolEvent::BatchStarted { calls, .. }) = &entry.event + let CoreAgentEvent::Tool(harness::ToolEvent::BatchStarted { calls, .. }) = &entry.event else { return None; }; @@ -341,7 +341,7 @@ fn session_config( ) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(4096), reasoning_effort: None, tool_choice: None, @@ -354,9 +354,9 @@ fn session_config( input_limit_tokens: None, compaction: None, }, - features: engine::FeaturesConfig { - vfs: Some(engine::VfsFeature { - skills: Some(engine::VfsSkillsConfig { + features: harness::FeaturesConfig { + vfs: Some(harness::VfsFeature { + skills: Some(harness::VfsSkillsConfig { roots: Some( workspace_attachments .iter() @@ -365,9 +365,9 @@ fn session_config( ), }), workspaces: workspace_attachments, - ..engine::VfsFeature::default() + ..harness::VfsFeature::default() }), - ..engine::FeaturesConfig::default() + ..harness::FeaturesConfig::default() }, } } @@ -389,10 +389,10 @@ fn run_config() -> RunConfig { async fn selected_skill_read_call_id( blobs: &dyn BlobStore, - entries: &[engine::CoreAgentEntry], -) -> Option { + entries: &[harness::CoreAgentEntry], +) -> Option { for entry in entries { - let CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { result, .. }) = &entry.event + let CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { result, .. }) = &entry.event else { continue; }; @@ -407,10 +407,10 @@ async fn selected_skill_read_call_id( None } -async fn read_paths(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> Vec { +async fn read_paths(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> Vec { let mut paths = Vec::new(); for entry in entries { - let CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { result, .. }) = &entry.event + let CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { result, .. }) = &entry.event else { continue; }; @@ -429,17 +429,17 @@ async fn read_file_result(blobs: &dyn BlobStore, output_ref: &BlobRef) -> Option serde_json::from_slice(&bytes).ok() } -async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> String { +async fn assistant_text(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> String { let mut text = String::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::Assistant + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::Assistant } ) { text.push_str(&support::content_text(blobs, &item.content).await); @@ -451,7 +451,7 @@ async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry text } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.first() else { return "run did not complete".to_owned(); }; diff --git a/crates/llm-runtime/tests/builtin_catalog_parity.rs b/crates/llm-runtime/tests/builtin_catalog_parity.rs index f4dca1171..486efdce1 100644 --- a/crates/llm-runtime/tests/builtin_catalog_parity.rs +++ b/crates/llm-runtime/tests/builtin_catalog_parity.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ ContextSnapshot, LlmRequest, ModelSelection, ProviderApiKind, ToolChoice, ToolSpec, storage::InMemoryBlobStore, }; @@ -49,7 +49,7 @@ fn registered(case: &str, api: &ProviderApiKind) -> Vec { let tool = tools::definitions::register( id, Default::default(), - engine::ToolParallelism::ParallelSafe, + harness::ToolParallelism::ParallelSafe, Default::default(), ); registered.tools.insert(tool.name.clone(), tool); diff --git a/crates/llm-runtime/tests/content_materialization.rs b/crates/llm-runtime/tests/content_materialization.rs index 43754cc9a..ddf0470bd 100644 --- a/crates/llm-runtime/tests/content_materialization.rs +++ b/crates/llm-runtime/tests/content_materialization.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ ContentRef, ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmRequest, ModelSelection, ProviderApiKind, storage::{BlobStore, InMemoryBlobStore}, diff --git a/crates/llm-runtime/tests/openai_completions_caching_live.rs b/crates/llm-runtime/tests/openai_completions_caching_live.rs index 71d4ac581..a0190235b 100644 --- a/crates/llm-runtime/tests/openai_completions_caching_live.rs +++ b/crates/llm-runtime/tests/openai_completions_caching_live.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use std::time::Duration; -use engine::{ +use harness::{ BlobRef, ContextEntry, ContextEntryId, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmGenerationRequest, LlmGenerationStatus, LlmRequest, LlmUsage, ModelSelection, ProviderApiKind, RunId, SessionId, @@ -41,7 +41,7 @@ fn entry( entry_id: ContextEntryId::new(id), kind, source, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -156,7 +156,7 @@ async fn generate( ) -> ( LlmUsage, Vec, - Vec, + Vec, ) { let execution = adapter .generate(generation_request(turn_id, request)) @@ -220,14 +220,14 @@ async fn weather_tool(blobs: &InMemoryBlobStore) -> ToolSpec { ToolSpec { name: ToolName::new("get_weather"), execution: Default::default(), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: Some(description_ref), input_schema_ref: schema_ref, output_schema_ref: None, strict: None, provider_options_ref: None, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, } } diff --git a/crates/llm-runtime/tests/openai_completions_compaction_live.rs b/crates/llm-runtime/tests/openai_completions_compaction_live.rs index 0604910fb..afbe4674c 100644 --- a/crates/llm-runtime/tests/openai_completions_compaction_live.rs +++ b/crates/llm-runtime/tests/openai_completions_compaction_live.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; -use engine::{ +use harness::{ ContextCompactionRequest, ContextCompactionStatus, ContextCompactionTask, ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmGenerationRequest, LlmGenerationStatus, LlmRequest, ModelSelection, @@ -32,14 +32,14 @@ fn entry( id: u64, role: ContextMessageRole, source: ContextEntrySource, - content_ref: engine::BlobRef, + content_ref: harness::BlobRef, ) -> ContextEntry { ContextEntry { entry_id: ContextEntryId::new(id), key: None, kind: ContextEntryKind::Message { role }, source, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, diff --git a/crates/llm-runtime/tests/openai_completions_live.rs b/crates/llm-runtime/tests/openai_completions_live.rs index 69dbc1e64..6580f9e84 100644 --- a/crates/llm-runtime/tests/openai_completions_live.rs +++ b/crates/llm-runtime/tests/openai_completions_live.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; -use engine::{ +use harness::{ BlobRef, ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, FunctionToolSpec, LlmFinish, LlmGenerationRequest, LlmGenerationStatus, LlmRequest, ModelSelection, ProviderApiKind, RunId, SessionId, ToolChoice, @@ -45,7 +45,7 @@ fn entry( key: None, kind, source, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -194,7 +194,7 @@ async fn openai_completions_runtime_live_fast_mode_reports_effective_service_tie env_or_dotenv_var("OPENAI_FAST_MODE_MODEL").unwrap_or_else(|_| "gpt-5.6-sol".to_owned()); request.request.reasoning_effort = Some("none".to_owned()); request.request.output_limit = Some(64); - request.request.processing_tier = Some(engine::ModelProcessingTier::Fast); + request.request.processing_tier = Some(harness::ModelProcessingTier::Fast); request.request.params = Some(openai_completions_params(&OpenAiCompletionsParams { store: Some(false), stream: Some(false), diff --git a/crates/llm-runtime/tests/openai_completions_prompts_live.rs b/crates/llm-runtime/tests/openai_completions_prompts_live.rs index 926298e6d..ca143ed09 100644 --- a/crates/llm-runtime/tests/openai_completions_prompts_live.rs +++ b/crates/llm-runtime/tests/openai_completions_prompts_live.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use engine::{ +use harness::{ ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmGenerationRequest, LlmRequest, ModelSelection, ProviderApiKind, RunId, SessionId, TurnId, @@ -21,7 +21,7 @@ use support::{ retrying_openai_completions_client, }; -fn entry(id: u64, kind: ContextEntryKind, content_ref: engine::BlobRef) -> ContextEntry { +fn entry(id: u64, kind: ContextEntryKind, content_ref: harness::BlobRef) -> ContextEntry { ContextEntry { entry_id: ContextEntryId::new(id), key: None, @@ -29,7 +29,7 @@ fn entry(id: u64, kind: ContextEntryKind, content_ref: engine::BlobRef) -> Conte source: ContextEntrySource::Runtime { label: "live-prompt".to_owned(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, diff --git a/crates/llm-runtime/tests/openai_completions_replay.rs b/crates/llm-runtime/tests/openai_completions_replay.rs index ad788fc7a..1f0c07707 100644 --- a/crates/llm-runtime/tests/openai_completions_replay.rs +++ b/crates/llm-runtime/tests/openai_completions_replay.rs @@ -1,6 +1,6 @@ -//! Exercise response replay through actual engine-assigned context provenance. +//! Exercise response replay through actual harness-assigned context provenance. -use engine::{ +use harness::{ BlobRef, ContextEntry, ContextEntryId, ContextEntryInput, ContextEntryKind, ContextEntrySource, ContextMessageRole, ModelSelection, ProviderApiKind, RunId, SessionId, ToolCallId, TurnId, storage::InMemoryBlobStore, @@ -20,7 +20,7 @@ fn entry( key: None, kind, source, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/plain".to_owned()), provider_kind: None, @@ -34,9 +34,9 @@ fn entry( } #[tokio::test(flavor = "current_thread")] -async fn engine_completion_history_reconstructs_one_message_and_preserves_request_prefixes() { - fn commit(drive: &mut engine::CoreAgentDrive, action: engine::CoreAgentAction) { - let engine::CoreAgentAction::AppendEvents { +async fn harness_completion_history_reconstructs_one_message_and_preserves_request_prefixes() { + fn commit(drive: &mut harness::CoreAgentDrive, action: harness::CoreAgentAction) { + let harness::CoreAgentAction::AppendEvents { expected_head, events, } = action @@ -49,9 +49,9 @@ async fn engine_completion_history_reconstructs_one_message_and_preserves_reques events .into_iter() .enumerate() - .map(|(index, event)| engine::session::StoredSessionEntry { - position: engine::session::SessionPosition { - seq: engine::session::EventSeq::new(first + index as u64), + .map(|(index, event)| harness::session::StoredSessionEntry { + position: harness::session::SessionPosition { + seq: harness::session::EventSeq::new(first + index as u64), }, observed_at_ms: event.observed_at_ms, joins: event.joins, @@ -63,15 +63,15 @@ async fn engine_completion_history_reconstructs_one_message_and_preserves_reques } let blobs = InMemoryBlobStore::new(); - let mut drive = engine::CoreAgentDrive::from_replayed( + let mut drive = harness::CoreAgentDrive::from_replayed( SessionId::new("completion-replay"), - engine::CoreAgentState::new(), + harness::CoreAgentState::new(), None, ); let action = drive .admit_command( - engine::CoreAgentCommand::OpenSession { - config: engine::SessionConfig { + harness::CoreAgentCommand::OpenSession { + config: harness::SessionConfig { model: ModelSelection { api_kind: ProviderApiKind::OpenAiCompletions, provider_id: "openai".to_owned(), @@ -79,7 +79,7 @@ async fn engine_completion_history_reconstructs_one_message_and_preserves_reques }, generation: Default::default(), limits: Default::default(), - context: engine::ContextConfig { + context: harness::ContextConfig { reported_input_limit_tokens: None, input_limit_tokens: None, compaction: None, @@ -93,17 +93,17 @@ async fn engine_completion_history_reconstructs_one_message_and_preserves_reques commit(&mut drive, action); let action = drive .admit_command( - engine::CoreAgentCommand::RequestRun(engine::RunRequestCommand { + harness::CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, submission_id: None, notify_on_terminal: Vec::new(), run_config: Default::default(), - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef::text( + content: harness::ContentRef::text( blobs.insert_text("Inspect the workspace").await, ), preview: None, @@ -120,7 +120,7 @@ async fn engine_completion_history_reconstructs_one_message_and_preserves_reques let mut generation = None; for tick in 3..30 { match drive.next_action(tick, 64).expect("drive") { - engine::CoreAgentAction::GenerateLlm { request } => { + harness::CoreAgentAction::GenerateLlm { request } => { generation = Some(request); break; } @@ -137,7 +137,7 @@ async fn engine_completion_history_reconstructs_one_message_and_preserves_reques // The request policy deliberately lowers visible content to text and // excludes response metadata. Reasoning/signatures and calls must still - // rejoin that message exactly, using provenance assigned by the engine. + // rejoin that message exactly, using provenance assigned by the harness. for (content, refusal, expected_content, with_tools) in [ (json!("Checking"), Value::Null, json!("Checking"), true), ( @@ -181,11 +181,11 @@ async fn engine_completion_history_reconstructs_one_message_and_preserves_reques .await .expect("convert"); let proposals = - engine::generation_result_proposals(drive.state(), result).expect("engine provenance"); + harness::generation_result_proposals(drive.state(), result).expect("engine provenance"); let retained = proposals .into_iter() .find_map(|proposal| match proposal.event { - engine::CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { + harness::CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) => Some(entries), diff --git a/crates/llm-runtime/tests/openai_completions_skills_live.rs b/crates/llm-runtime/tests/openai_completions_skills_live.rs index 722c6214a..21f6e1f3a 100644 --- a/crates/llm-runtime/tests/openai_completions_skills_live.rs +++ b/crates/llm-runtime/tests/openai_completions_skills_live.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use tools::skills::SkillId; -use engine::{ +use harness::{ ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmGenerationRequest, LlmRequest, ModelSelection, ProviderApiKind, RunId, SessionId, TurnId, @@ -21,7 +21,7 @@ use support::{ retrying_openai_completions_client, }; -fn entry(id: u64, kind: ContextEntryKind, content_ref: engine::BlobRef) -> ContextEntry { +fn entry(id: u64, kind: ContextEntryKind, content_ref: harness::BlobRef) -> ContextEntry { ContextEntry { entry_id: ContextEntryId::new(id), key: None, @@ -29,7 +29,7 @@ fn entry(id: u64, kind: ContextEntryKind, content_ref: engine::BlobRef) -> Conte source: ContextEntrySource::Runtime { label: "live-skill".to_owned(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, diff --git a/crates/llm-runtime/tests/openai_responses_caching_live.rs b/crates/llm-runtime/tests/openai_responses_caching_live.rs index af93adc12..b4fd09f7d 100644 --- a/crates/llm-runtime/tests/openai_responses_caching_live.rs +++ b/crates/llm-runtime/tests/openai_responses_caching_live.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use std::time::Duration; -use engine::{ +use harness::{ BlobRef, ContextEntry, ContextEntryId, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmGenerationRequest, LlmGenerationStatus, LlmRequest, LlmUsage, ModelSelection, ProviderApiKind, RunId, SessionId, @@ -43,7 +43,7 @@ fn entry( entry_id: ContextEntryId::new(id), kind, source, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, diff --git a/crates/llm-runtime/tests/openai_responses_compaction_live.rs b/crates/llm-runtime/tests/openai_responses_compaction_live.rs index 1e2daf485..5886726b1 100644 --- a/crates/llm-runtime/tests/openai_responses_compaction_live.rs +++ b/crates/llm-runtime/tests/openai_responses_compaction_live.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use engine::{ +use harness::{ BlobRef, CompactionPolicy, ContextCompactionStatus, ContextCompactionTrigger, ContextConfig, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextMessageRole, ContextRemovalReason, CoreAgentCommand, CoreAgentEvent, ModelSelection, OPENAI_RESPONSES_COMPACTION_PROVIDER_KIND, @@ -28,7 +28,7 @@ fn live_compaction_model() -> String { #[tokio::test(flavor = "current_thread")] #[ignore = "requires OPENAI_API_KEY and a compaction-capable OpenAI Responses model (costs real money)"] -async fn openai_responses_live_engine_prunes_and_reuses_provider_compaction() { +async fn openai_responses_live_harness_prunes_and_reuses_provider_compaction() { let sessions = Arc::new(InMemorySessionStore::new()); let blobs = Arc::new(InMemoryBlobStore::new()); let session_id = SessionId::new("session-live-compaction-engine"); @@ -80,11 +80,11 @@ async fn openai_responses_live_engine_prunes_and_reuses_provider_compaction() { .drive_command(DriveCommand { session_id: session_id.clone(), observed_at_ms: 20, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: user_input(first_input_ref.clone()), }, run_config: run_config(), @@ -104,7 +104,7 @@ async fn openai_responses_live_engine_prunes_and_reuses_provider_compaction() { assert!( first.emitted_entries.iter().any(|entry| matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::EntriesRemoved { + CoreAgentEvent::Context(harness::ContextEvent::EntriesRemoved { reason: ContextRemovalReason::ProviderCompacted, .. }) @@ -136,11 +136,11 @@ async fn openai_responses_live_engine_prunes_and_reuses_provider_compaction() { .drive_command(DriveCommand { session_id, observed_at_ms: 30, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: user_input(second_input_ref), }, run_config: run_config(), @@ -164,7 +164,7 @@ async fn openai_responses_live_engine_prunes_and_reuses_provider_compaction() { assert_eq!(output.media_type.as_deref(), Some("application/json")); assert_eq!( output.provider_kind.as_deref(), - Some(engine::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND) + Some(harness::OPENAI_RESPONSES_MESSAGE_PROVIDER_KIND) ); let assistant_text = support::content_text(blobs.as_ref(), output).await; assert!( @@ -364,7 +364,7 @@ fn live_model_selection() -> ModelSelection { fn session_config(model: ModelSelection) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(1024), reasoning_effort: None, tool_choice: None, @@ -389,7 +389,7 @@ fn standalone_session_config( ) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(1024), reasoning_effort: None, tool_choice: None, @@ -435,7 +435,7 @@ fn user_input(content_ref: BlobRef) -> Vec { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -464,7 +464,7 @@ fn openai_raw_context_input( ) -> ContextEntryInput { ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("application/json".to_owned()), provider_kind: Some("openai.responses.input_message".to_owned()), @@ -491,7 +491,7 @@ fn first_prompt() -> String { ) } -fn provider_compaction_entries(state: &engine::CoreAgentState) -> Vec<&engine::ContextEntry> { +fn provider_compaction_entries(state: &harness::CoreAgentState) -> Vec<&harness::ContextEntry> { state .context .entries @@ -503,7 +503,7 @@ fn provider_compaction_entries(state: &engine::CoreAgentState) -> Vec<&engine::C .collect() } -fn active_context_contains_ref(state: &engine::CoreAgentState, content_ref: &BlobRef) -> bool { +fn active_context_contains_ref(state: &harness::CoreAgentState, content_ref: &BlobRef) -> bool { state .context .entries @@ -512,13 +512,13 @@ fn active_context_contains_ref(state: &engine::CoreAgentState, content_ref: &Blo } fn has_compaction_requested( - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], expected_trigger: ContextCompactionTrigger, ) -> bool { entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::CompactionRequested { + CoreAgentEvent::Context(harness::ContextEvent::CompactionRequested { trigger, .. }) if *trigger == expected_trigger @@ -527,13 +527,13 @@ fn has_compaction_requested( } fn has_compaction_finished( - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], expected_status: ContextCompactionStatus, ) -> bool { entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::CompactionFinished { + CoreAgentEvent::Context(harness::ContextEvent::CompactionFinished { status, .. }) if *status == expected_status @@ -541,11 +541,11 @@ fn has_compaction_finished( }) } -fn has_provider_compacted_removal(entries: &[engine::CoreAgentEntry]) -> bool { +fn has_provider_compacted_removal(entries: &[harness::CoreAgentEntry]) -> bool { entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::EntriesRemoved { + CoreAgentEvent::Context(harness::ContextEvent::EntriesRemoved { reason: ContextRemovalReason::ProviderCompacted, .. }) @@ -555,10 +555,10 @@ fn has_provider_compacted_removal(entries: &[engine::CoreAgentEntry]) -> bool { async fn compaction_failure_text( blobs: &dyn BlobStore, - entries: &[engine::CoreAgentEntry], + entries: &[harness::CoreAgentEntry], ) -> String { for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::CompactionFinished { + if let CoreAgentEvent::Context(harness::ContextEvent::CompactionFinished { status: ContextCompactionStatus::Failed, failure_ref: Some(failure_ref), .. @@ -573,7 +573,7 @@ async fn compaction_failure_text( "compaction did not finish with a failure ref".to_owned() } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.last() else { return "run did not complete".to_owned(); }; @@ -617,11 +617,11 @@ async fn openai_responses_live_provider_triggered_without_threshold_override() { session_id, observed_at_ms: 20, max_steps: Some(64), - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: vec![], submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: user_input(input), }, run_config: run_config(), @@ -632,7 +632,7 @@ async fn openai_responses_live_provider_triggered_without_threshold_override() { assert_eq!(result.quiescence, RunnerQuiescence::Idle); assert_eq!( result.state.runs.completed.last().unwrap().status, - engine::RunStatus::Completed, + harness::RunStatus::Completed, "{}", run_failure_text(blobs.as_ref(), &result.state).await ); diff --git a/crates/llm-runtime/tests/openai_responses_live.rs b/crates/llm-runtime/tests/openai_responses_live.rs index e925eca75..e87ccead8 100644 --- a/crates/llm-runtime/tests/openai_responses_live.rs +++ b/crates/llm-runtime/tests/openai_responses_live.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use engine::{ +use harness::{ BlobRef, CompactionPolicy, ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, ContextMessageRole, ContextSnapshot, LlmFinish, LlmGenerationRequest, LlmGenerationStatus, LlmRequest, ModelSelection, OPENAI_RESPONSES_COMPACTION_PROVIDER_KIND, @@ -85,7 +85,7 @@ async fn openai_responses_live_fast_mode_reports_effective_service_tier() { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -103,7 +103,7 @@ async fn openai_responses_live_fast_mode_reports_effective_service_tier() { output_limit: Some(64), reasoning_effort: Some("none".to_owned()), parallel_tool_use: None, - processing_tier: Some(engine::ModelProcessingTier::Fast), + processing_tier: Some(harness::ModelProcessingTier::Fast), provider_response_id: None, compaction: None, params: Some(openai_params(&OpenAiResponsesParams { @@ -166,7 +166,7 @@ async fn openai_responses_live_adapter_describes_image_input() { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: image_ref, media_type: Some("image/png".to_owned()), provider_kind: None, @@ -187,7 +187,7 @@ async fn openai_responses_live_adapter_describes_image_input() { run_id: RunId::new(1), input_index: 1, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: question_ref, media_type: None, provider_kind: None, @@ -322,7 +322,7 @@ async fn openai_responses_live_adapter_reads_pdf_document_input() { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: pdf_ref, media_type: Some("application/pdf".to_owned()), provider_kind: None, @@ -343,7 +343,7 @@ async fn openai_responses_live_adapter_reads_pdf_document_input() { run_id: RunId::new(1), input_index: 1, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: question_ref, media_type: None, provider_kind: None, @@ -438,7 +438,7 @@ async fn openai_responses_live_adapter_generates_result() { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -565,7 +565,7 @@ async fn openai_responses_live_adapter_captures_provider_triggered_compaction() run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -671,7 +671,7 @@ async fn openai_responses_live_adapter_captures_web_search_call_and_citations() run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -704,17 +704,17 @@ async fn openai_responses_live_adapter_captures_web_search_call_and_citations() entries: vec![context_entry], token_estimate: None, }, - tools: vec![engine::ToolSpec { - name: engine::ToolName::new("web_search"), - kind: engine::ToolKind::ProviderNative(engine::ProviderNativeToolSpec { + tools: vec![harness::ToolSpec { + name: harness::ToolName::new("web_search"), + kind: harness::ToolKind::ProviderNative(harness::ProviderNativeToolSpec { api_kind: ProviderApiKind::OpenAiResponses, native_tool_ref: blobs .put_bytes(serde_json::to_vec(&native).expect("native json")) .await .expect("native definition"), - execution: engine::ProviderNativeToolExecution::ProviderHosted, + execution: harness::ProviderNativeToolExecution::ProviderHosted, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, execution: Default::default(), }], tool_choice: Some(ToolChoice::RequiredAny), @@ -849,7 +849,7 @@ async fn openai_responses_live_adapter_captures_web_search_call_and_citations() run_id: RunId::new(2), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: text_blob(&blobs, "Reply with exactly: replay ok").await, media_type: None, provider_kind: None, @@ -930,7 +930,7 @@ async fn openai_responses_live_adapter_sees_tool_media() { run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef::text(input_ref), + content: harness::ContentRef::text(input_ref), preview: None, origin: None, provenance_ref: None, @@ -1024,7 +1024,7 @@ fn user_message(entry_id: u64, content_ref: BlobRef, media_type: Option<&str>) - run_id: RunId::new(1), input_index: 0, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: media_type.map(str::to_owned), provider_kind: None, @@ -1133,7 +1133,7 @@ async fn openai_responses_live_adapter_sees_oversized_image() { assert_eq!(execution.result.status, LlmGenerationStatus::Succeeded); let sent = support::content_text( blobs.as_ref(), - &engine::ContentRef::text(dumps(&execution).provider_request_ref.clone()), + &harness::ContentRef::text(dumps(&execution).provider_request_ref.clone()), ) .await; let sent: Value = serde_json::from_str(&sent).expect("provider request json"); diff --git a/crates/llm-runtime/tests/openai_responses_mcp_live.rs b/crates/llm-runtime/tests/openai_responses_mcp_live.rs index 198c73ef9..315b81034 100644 --- a/crates/llm-runtime/tests/openai_responses_mcp_live.rs +++ b/crates/llm-runtime/tests/openai_responses_mcp_live.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; -use engine::{ +use harness::{ ContextConfig, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentEvent, ModelSelection, ProviderApiKind, RemoteMcpApprovalPolicy, RemoteMcpToolSpec, RunConfig, RunStatus, SessionConfig, SessionId, ToolKind, ToolName, ToolParallelism, ToolSpec, @@ -95,16 +95,16 @@ async fn openai_responses_live_core_session_uses_public_remote_mcp() { .drive_command(DriveCommand { session_id: session_id.clone(), observed_at_ms: 20, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -164,8 +164,8 @@ fn remote_mcp_tools() -> BTreeMap { server_url: MCP_TEST_SERVER_URL.to_string(), description_ref: None, allowed_tools: Some(vec![MCP_TEST_TOOL.to_string()]), - execution: engine::RemoteMcpExecution::Provider, - exposure: engine::RemoteMcpExposure::Inject, + execution: harness::RemoteMcpExecution::Provider, + exposure: harness::RemoteMcpExposure::Inject, approval: RemoteMcpApprovalPolicy::Never, defer_loading: None, auth_ref: None, @@ -180,7 +180,7 @@ fn remote_mcp_tools() -> BTreeMap { fn session_config(model: ModelSelection) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(1024), reasoning_effort: None, tool_choice: None, @@ -217,17 +217,17 @@ fn run_config() -> RunConfig { } } -async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> String { +async fn assistant_text(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> String { let mut text = String::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::Assistant + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::Assistant } ) { text.push_str(&support::content_text(blobs, &item.content).await); @@ -239,15 +239,15 @@ async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry text } -async fn mcp_call_items(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> Vec { +async fn mcp_call_items(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> Vec { let mut items = Vec::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if item.content.provider_kind.as_deref() - == Some(engine::OPENAI_RESPONSES_MCP_CALL_PROVIDER_KIND) + == Some(harness::OPENAI_RESPONSES_MCP_CALL_PROVIDER_KIND) { let bytes = blobs .read_bytes(&item.content.content_ref) @@ -261,7 +261,7 @@ async fn mcp_call_items(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry items } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.first() else { return "run did not complete".to_owned(); }; diff --git a/crates/llm-runtime/tests/openai_responses_prompts_live.rs b/crates/llm-runtime/tests/openai_responses_prompts_live.rs index 31e9ff73d..5563872fa 100644 --- a/crates/llm-runtime/tests/openai_responses_prompts_live.rs +++ b/crates/llm-runtime/tests/openai_responses_prompts_live.rs @@ -4,7 +4,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ ContextConfig, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentEvent, ModelSelection, ProviderApiKind, RunConfig, RunStatus, SessionConfig, SessionId, WorkspaceAccess, WorkspaceAttachment, WorkspaceAttachmentTarget, @@ -231,16 +231,16 @@ async fn openai_responses_live_uses_vfs_prompt_instructions() { .drive_command(DriveCommand { session_id, observed_at_ms: 20, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -276,7 +276,7 @@ async fn openai_responses_live_uses_vfs_prompt_instructions() { assert!(outcome.emitted_entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::KeyPrefixReplaced { + CoreAgentEvent::Context(harness::ContextEvent::KeyPrefixReplaced { key_prefix, entries, .. @@ -299,7 +299,7 @@ fn session_config( ) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(1024), reasoning_effort: None, tool_choice: None, @@ -312,13 +312,13 @@ fn session_config( input_limit_tokens: None, compaction: None, }, - features: engine::FeaturesConfig { - vfs: Some(engine::VfsFeature { + features: harness::FeaturesConfig { + vfs: Some(harness::VfsFeature { workspaces: workspace_attachments, - prompts: Some(engine::VfsPromptsConfig::default()), - ..engine::VfsFeature::default() + prompts: Some(harness::VfsPromptsConfig::default()), + ..harness::VfsFeature::default() }), - ..engine::FeaturesConfig::default() + ..harness::FeaturesConfig::default() }, } } @@ -343,17 +343,17 @@ fn run_config() -> RunConfig { } } -async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> String { +async fn assistant_text(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> String { let mut text = String::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::Assistant + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::Assistant } ) { text.push_str(&support::content_text(blobs, &item.content).await); @@ -365,7 +365,7 @@ async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry text } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.first() else { return "run did not complete".to_owned(); }; diff --git a/crates/llm-runtime/tests/openai_responses_skills_live.rs b/crates/llm-runtime/tests/openai_responses_skills_live.rs index 8282b3a8a..12c72e391 100644 --- a/crates/llm-runtime/tests/openai_responses_skills_live.rs +++ b/crates/llm-runtime/tests/openai_responses_skills_live.rs @@ -4,7 +4,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, ContextConfig, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentEvent, ModelSelection, ProviderApiKind, RunConfig, RunStatus, SessionConfig, SessionId, WorkspaceAccess, WorkspaceAttachment, WorkspaceAttachmentTarget, @@ -257,16 +257,16 @@ async fn openai_responses_live_selects_and_reads_the_matching_skill() { .drive_command(DriveCommand { session_id, observed_at_ms: 20, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: input_ref, media_type: None, provider_kind: None, @@ -299,7 +299,7 @@ async fn openai_responses_live_selects_and_reads_the_matching_skill() { .emitted_entries .iter() .find_map(|entry| { - let CoreAgentEvent::Tool(engine::ToolEvent::BatchStarted { calls, .. }) = &entry.event + let CoreAgentEvent::Tool(harness::ToolEvent::BatchStarted { calls, .. }) = &entry.event else { return None; }; @@ -333,7 +333,7 @@ fn session_config( ) -> SessionConfig { SessionConfig { model, - generation: engine::GenerationConfig { + generation: harness::GenerationConfig { max_output_tokens: Some(1024), reasoning_effort: None, tool_choice: None, @@ -346,9 +346,9 @@ fn session_config( input_limit_tokens: None, compaction: None, }, - features: engine::FeaturesConfig { - vfs: Some(engine::VfsFeature { - skills: Some(engine::VfsSkillsConfig { + features: harness::FeaturesConfig { + vfs: Some(harness::VfsFeature { + skills: Some(harness::VfsSkillsConfig { roots: Some( workspace_attachments .iter() @@ -357,9 +357,9 @@ fn session_config( ), }), workspaces: workspace_attachments, - ..engine::VfsFeature::default() + ..harness::VfsFeature::default() }), - ..engine::FeaturesConfig::default() + ..harness::FeaturesConfig::default() }, } } @@ -386,10 +386,10 @@ fn run_config() -> RunConfig { async fn selected_skill_read_call_id( blobs: &dyn BlobStore, - entries: &[engine::CoreAgentEntry], -) -> Option { + entries: &[harness::CoreAgentEntry], +) -> Option { for entry in entries { - let CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { result, .. }) = &entry.event + let CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { result, .. }) = &entry.event else { continue; }; @@ -404,10 +404,10 @@ async fn selected_skill_read_call_id( None } -async fn read_paths(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> Vec { +async fn read_paths(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> Vec { let mut paths = Vec::new(); for entry in entries { - let CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { result, .. }) = &entry.event + let CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { result, .. }) = &entry.event else { continue; }; @@ -426,17 +426,17 @@ async fn read_file_result(blobs: &dyn BlobStore, output_ref: &BlobRef) -> Option serde_json::from_slice(&bytes).ok() } -async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry]) -> String { +async fn assistant_text(blobs: &dyn BlobStore, entries: &[harness::CoreAgentEntry]) -> String { let mut text = String::new(); for entry in entries { - if let CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) = + if let CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) = &entry.event { for item in entries { if matches!( item.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::Assistant + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::Assistant } ) { text.push_str(&support::content_text(blobs, &item.content).await); @@ -448,7 +448,7 @@ async fn assistant_text(blobs: &dyn BlobStore, entries: &[engine::CoreAgentEntry text } -async fn run_failure_text(blobs: &dyn BlobStore, state: &engine::CoreAgentState) -> String { +async fn run_failure_text(blobs: &dyn BlobStore, state: &harness::CoreAgentState) -> String { let Some(run) = state.runs.completed.first() else { return "run did not complete".to_owned(); }; diff --git a/crates/llm-runtime/tests/support/mod.rs b/crates/llm-runtime/tests/support/mod.rs index 405223ddf..d43c7ad0b 100644 --- a/crates/llm-runtime/tests/support/mod.rs +++ b/crates/llm-runtime/tests/support/mod.rs @@ -16,7 +16,7 @@ pub mod media; pub mod tool_media; use async_trait::async_trait; -use engine::{ProviderApiKind, ProviderParams}; +use harness::{ProviderApiKind, ProviderParams}; use llm_clients::{ ApiResponse, LlmApiError, anthropic::messages::{self as am}, @@ -214,8 +214,8 @@ fn retry_delay(error: &LlmApiError, attempt: usize) -> Duration { #[allow(dead_code)] pub async fn content_text( - blobs: &dyn engine::storage::BlobStore, - content: &engine::ContentRef, + blobs: &dyn harness::storage::BlobStore, + content: &harness::ContentRef, ) -> String { api_projection::project_content_text(blobs, content) .await diff --git a/crates/llm-runtime/tests/support/tool_media.rs b/crates/llm-runtime/tests/support/tool_media.rs index 429363928..9b6b06887 100644 --- a/crates/llm-runtime/tests/support/tool_media.rs +++ b/crates/llm-runtime/tests/support/tool_media.rs @@ -2,7 +2,7 @@ //! result hands the model two images and one PDF as media entries, and the //! answer shape every provider must produce from them. -use engine::{ +use harness::{ BlobRef, ContextEntry, ContextEntryId, ContextEntryKind, ContextEntrySource, ContextMessageRole, FunctionToolSpec, RunId, ToolCallId, ToolExecutionSpec, ToolKind, ToolName, ToolParallelism, ToolSpec, TurnId, @@ -162,7 +162,7 @@ pub async fn tool_media_entries_for( turn_id: TurnId::new(1), batch_id: None, }; - let commit = |id: u64, input: engine::ContextEntryInput| ContextEntry { + let commit = |id: u64, input: harness::ContextEntryInput| ContextEntry { key: None, entry_id: ContextEntryId::new(id), kind: input.kind, @@ -182,7 +182,7 @@ pub async fn tool_media_entries_for( is_error: false, }, source: source.clone(), - content: engine::ContentRef::text(visible_ref), + content: harness::ContentRef::text(visible_ref), preview: None, origin: None, provenance_ref: None, @@ -190,7 +190,7 @@ pub async fn tool_media_entries_for( supersedes: None, }]; let mut next_id = first_entry_id + 1; - let mut push = |entries: &mut Vec, input: engine::ContextEntryInput| { + let mut push = |entries: &mut Vec, input: harness::ContextEntryInput| { entries.push(commit(next_id, input)); next_id += 1; }; @@ -276,7 +276,7 @@ pub fn assert_tool_media_answer(text: &str, fixture: &ToolMediaFixture) { } } -pub fn assistant_entry(execution: &llm_runtime::LlmGenerationExecution) -> engine::ContentRef { +pub fn assistant_entry(execution: &llm_runtime::LlmGenerationExecution) -> harness::ContentRef { execution .result .context_entries @@ -291,7 +291,7 @@ pub fn assistant_entry(execution: &llm_runtime::LlmGenerationExecution) -> engin } /// Commit a generation's output entries as retained assistant context. -pub fn retained(first_entry_id: u64, outputs: &[engine::ContextEntryInput]) -> Vec { +pub fn retained(first_entry_id: u64, outputs: &[harness::ContextEntryInput]) -> Vec { outputs .iter() .enumerate() diff --git a/crates/mcp/Cargo.toml b/crates/mcp/Cargo.toml index b2f1f21a9..f74570e99 100644 --- a/crates/mcp/Cargo.toml +++ b/crates/mcp/Cargo.toml @@ -6,11 +6,11 @@ edition = "2024" [dependencies] async-trait = "0.1" auth = { path = "../auth" } -engine = { path = "../engine" } +harness = { path = "../harness" } serde = { version = "1", features = ["derive"] } serde_json = "1" strsim = "0.11.1" -thiserror = "1" +thiserror = "2" [dev-dependencies] tokio = { version = "1", features = ["macros", "rt"] } diff --git a/crates/mcp/src/lib.rs b/crates/mcp/src/lib.rs index 73734c7f8..26a9855ea 100644 --- a/crates/mcp/src/lib.rs +++ b/crates/mcp/src/lib.rs @@ -13,7 +13,7 @@ use std::sync::{Arc, RwLock}; use async_trait::async_trait; use auth::AuthGrantId; -use engine::{StringIdError, validate_general_string_id}; +use harness::{StringIdError, validate_general_string_id}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use thiserror::Error; diff --git a/crates/profiles/Cargo.toml b/crates/profiles/Cargo.toml index 194fe351e..b424e2a6c 100644 --- a/crates/profiles/Cargo.toml +++ b/crates/profiles/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" api = { path = "../api" } async-trait = "0.1" environment-protocol = { path = "../environment-protocol" } -thiserror = "1" +thiserror = "2" [dev-dependencies] serde_json = "1" diff --git a/crates/profiles/src/lib.rs b/crates/profiles/src/lib.rs index aed0900d7..0b88113b7 100644 --- a/crates/profiles/src/lib.rs +++ b/crates/profiles/src/lib.rs @@ -195,7 +195,7 @@ pub fn validate_profile_document(document: &ProfileDocument) -> Result<(), Profi /// The profile-level attachment rules: each attachment names exactly one /// machine (an id or `inherit`) and at most one attachment inherits. The -/// engine validates the concrete list (unique ids, one default, absolute +/// harness validates the concrete list (unique ids, one default, absolute /// working directories) once the document is applied to a session. pub fn validate_environment_attachments( attachments: &[EnvironmentAttachment], diff --git a/crates/release-info/Cargo.toml b/crates/release-info/Cargo.toml index 38afc3e28..1aed43333 100644 --- a/crates/release-info/Cargo.toml +++ b/crates/release-info/Cargo.toml @@ -3,3 +3,6 @@ name = "release-info" version.workspace = true edition = "2024" build = "build.rs" + +[dev-dependencies] +tempfile = "3" diff --git a/crates/release-info/build.rs b/crates/release-info/build.rs index 39da92737..2f123ab93 100644 --- a/crates/release-info/build.rs +++ b/crates/release-info/build.rs @@ -4,7 +4,24 @@ fn main() { println!("cargo:rerun-if-env-changed=LIGHTSPEED_GIT_SHA"); println!("cargo:rerun-if-env-changed=LIGHTSPEED_RELEASE_VERSION"); println!("cargo:rerun-if-env-changed=LIGHTSPEED_ENVD_TARGETS"); - println!("cargo:rerun-if-changed=../../.git/HEAD"); + // Resolve Git's own paths so linked worktrees and packed refs work too. + // HEAD alone does not change when a commit advances the current branch. + for name in [ + Some("HEAD".to_owned()), + command_output("git", &["symbolic-ref", "-q", "HEAD"]), + ] + .into_iter() + .flatten() + { + if let Some(path) = command_output("git", &["rev-parse", "--git-path", &name]) { + println!("cargo:rerun-if-changed={path}"); + } + } + if let Some(path) = command_output("git", &["rev-parse", "--git-path", "packed-refs"]) + && std::path::Path::new(&path).exists() + { + println!("cargo:rerun-if-changed={path}"); + } let git_sha = std::env::var("LIGHTSPEED_GIT_SHA") .ok() diff --git a/crates/release-info/tests/build_identity.rs b/crates/release-info/tests/build_identity.rs new file mode 100644 index 000000000..10e900581 --- /dev/null +++ b/crates/release-info/tests/build_identity.rs @@ -0,0 +1,95 @@ +use std::{fs, path::Path, process::Command}; + +fn run(directory: &Path, program: &str, args: &[&str]) -> String { + let output = Command::new(program) + .args(args) + .current_dir(directory) + .env_remove("LIGHTSPEED_GIT_SHA") + .env_remove("LIGHTSPEED_RELEASE_VERSION") + .env_remove("LIGHTSPEED_ENVD_TARGETS") + .env_remove("CARGO_TARGET_DIR") + .output() + .expect("execute fixture command"); + assert!( + output.status.success(), + "{program} {args:?}: {}", + String::from_utf8_lossy(&output.stderr) + ); + String::from_utf8(output.stdout).unwrap().trim().to_owned() +} + +fn commit(directory: &Path, message: &str) -> String { + run(directory, "git", &["add", "."]); + run( + directory, + "git", + &[ + "-c", + "user.name=Build Test", + "-c", + "user.email=build@example.test", + "-c", + "commit.gpgsign=false", + "commit", + "--allow-empty", + "-qm", + message, + ], + ); + run(directory, "git", &["rev-parse", "HEAD"]) +} + +fn built_sha(directory: &Path) -> String { + run(directory, env!("CARGO"), &["run", "--quiet", "--offline"]) +} + +#[test] +fn cached_build_identity_tracks_branch_commits_packed_refs_and_worktrees() { + let root = tempfile::tempdir().unwrap(); + let repo = root.path().join("repo"); + fs::create_dir_all(repo.join("src")).unwrap(); + fs::write( + repo.join("Cargo.toml"), + "[package]\nname = \"build-identity-fixture\"\nversion = \"0.1.0\"\nedition = \"2024\"\n[workspace]\n", + ) + .unwrap(); + fs::write(repo.join("build.rs"), include_str!("../build.rs")).unwrap(); + fs::write( + repo.join("src/main.rs"), + "fn main() { println!(\"{}\", env!(\"LIGHTSPEED_BUILD_GIT_SHA\")); }\n", + ) + .unwrap(); + fs::write(repo.join(".gitignore"), "/target\n/Cargo.lock\n").unwrap(); + run(&repo, "git", &["init", "-q", "-b", "main"]); + + let first = commit(&repo, "first"); + assert_eq!(built_sha(&repo), first); + let second = commit(&repo, "advance branch without source changes"); + assert_ne!(first, second); + assert_eq!(built_sha(&repo), second); + + run(&repo, "git", &["pack-refs", "--all", "--prune"]); + assert_eq!(built_sha(&repo), second); + let third = commit(&repo, "advance a packed branch"); + assert_eq!(built_sha(&repo), third); + + run(&repo, "git", &["checkout", "-q", "--detach", &first]); + assert_eq!(built_sha(&repo), first); + + let worktree = root.path().join("worktree"); + run( + &repo, + "git", + &[ + "worktree", + "add", + "-q", + "-b", + "linked", + worktree.to_str().unwrap(), + ], + ); + assert_eq!(built_sha(&worktree), first); + let linked = commit(&worktree, "advance linked worktree"); + assert_eq!(built_sha(&worktree), linked); +} diff --git a/crates/store-fs/Cargo.toml b/crates/store-fs/Cargo.toml index ea75048f5..2697b696c 100644 --- a/crates/store-fs/Cargo.toml +++ b/crates/store-fs/Cargo.toml @@ -4,11 +4,12 @@ version = "0.1.0" edition = "2024" [dependencies] -engine = { path = "../engine" } +hex = "0.4" +harness = { path = "../harness" } async-trait = "0.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -sha2 = "0.10" +sha2 = "0.11" tempfile = "3" tokio = { version = "1", features = ["fs", "io-util", "sync"] } vfs = { path = "../vfs" } diff --git a/crates/store-fs/src/blob.rs b/crates/store-fs/src/blob.rs index 8cc89e7ab..0023d17f7 100644 --- a/crates/store-fs/src/blob.rs +++ b/crates/store-fs/src/blob.rs @@ -5,7 +5,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, storage::{BlobInfo, BlobStore, BlobStoreError}, }; @@ -117,7 +117,7 @@ impl BlobStore for FsBlobStore { &self, expected: &BlobRef, size: u64, - source: &mut dyn engine::storage::BlobSource, + source: &mut dyn harness::storage::BlobSource, ) -> Result { use sha2::{Digest, Sha256}; use tokio::io::AsyncWriteExt; @@ -155,7 +155,8 @@ impl BlobStore for FsBlobStore { .await .map_err(|e| blob_io_error("write blob spool", &paths.dir, e))?; } - if length != size || format!("sha256:{:x}", hash.finalize()) != expected.as_str() { + if length != size || format!("sha256:{}", hex::encode(hash.finalize())) != expected.as_str() + { return Err(BlobStoreError::Store { message: "blob stream length/digest mismatch".into(), }); @@ -246,7 +247,7 @@ fn blob_io_error(action: &str, path: &Path, error: io::Error) -> BlobStoreError #[cfg(test)] mod tests { use super::*; - use engine::storage::BlobStore; + use harness::storage::BlobStore; #[tokio::test(flavor = "current_thread")] async fn fs_blob_store_persists_bytes() { diff --git a/crates/store-fs/src/lib.rs b/crates/store-fs/src/lib.rs index ca5d63860..bc30a4a7f 100644 --- a/crates/store-fs/src/lib.rs +++ b/crates/store-fs/src/lib.rs @@ -1,6 +1,6 @@ //! Filesystem-backed storage adapters. //! -//! This crate keeps durable filesystem I/O outside `engine` while +//! This crate keeps durable filesystem I/O outside `harness` while //! implementing the core storage contracts. //! //! Project-backed stores use `.lightspeed` by convention: diff --git a/crates/store-fs/src/session.rs b/crates/store-fs/src/session.rs index b531ef97d..96c72b590 100644 --- a/crates/store-fs/src/session.rs +++ b/crates/store-fs/src/session.rs @@ -6,7 +6,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ session::{EventSeq, SessionId, SessionPosition, StoredSessionEntry}, storage::{ AppendSessionEvents, AppendSessionEventsResult, CreateSession, DeleteClosedSessions, @@ -616,8 +616,8 @@ fn session_io_error(action: &str, path: &Path, error: io::Error) -> SessionStore #[cfg(test)] mod tests { use super::*; - use engine::session::{StoredEvent, StoredJoins, UncommittedStoredEvent}; - use engine::storage::SessionStore; + use harness::session::{StoredEvent, StoredJoins, UncommittedStoredEvent}; + use harness::storage::SessionStore; fn open_event(at_ms: u64) -> UncommittedStoredEvent { UncommittedStoredEvent { @@ -662,8 +662,8 @@ mod tests { session_id: session_id.clone(), expected_head: None, events: vec![ - lifecycle_event(10, engine::CORE_AGENT_LIFECYCLE_OPENED_EVENT_KIND), - lifecycle_event(20, engine::CORE_AGENT_LIFECYCLE_CLOSED_EVENT_KIND), + lifecycle_event(10, harness::CORE_AGENT_LIFECYCLE_OPENED_EVENT_KIND), + lifecycle_event(20, harness::CORE_AGENT_LIFECYCLE_CLOSED_EVENT_KIND), ], }) .await diff --git a/crates/store-fs/src/vfs.rs b/crates/store-fs/src/vfs.rs index 356e537bc..ca36994c0 100644 --- a/crates/store-fs/src/vfs.rs +++ b/crates/store-fs/src/vfs.rs @@ -5,7 +5,7 @@ use std::{ }; use async_trait::async_trait; -use engine::BlobRef; +use harness::BlobRef; use serde::{Serialize, de::DeserializeOwned}; use tokio::{fs, sync::Mutex}; diff --git a/crates/store-pg/Cargo.toml b/crates/store-pg/Cargo.toml index 8d5190489..e2d42aa48 100644 --- a/crates/store-pg/Cargo.toml +++ b/crates/store-pg/Cargo.toml @@ -4,27 +4,28 @@ version = "0.1.0" edition = "2024" [dependencies] -aes-gcm = "0.10" +hex = "0.4" +aes-gcm = "0.11" api = { path = "../api" } auth = { path = "../auth" } -base64 = "0.22" +base64 = "0.23" bots = { path = "../bots" } channels = { path = "../channels" } -engine = { path = "../engine" } +harness = { path = "../harness" } moka = { version = "0.12", features = ["sync"] } environments = { path = "../environments" } environment-protocol = { path = "../environment-protocol" } futures-util = "0.3" async-trait = "0.1" mcp = { path = "../mcp" } -object_store = { version = "0.13.1", features = ["aws"] } +object_store = { version = "0.14", features = ["aws"] } profiles = { path = "../profiles" } -rand = "0.8" -sha2 = "0.10" +rand = "0.10" +sha2 = "0.11" serde = { version = "1", features = ["derive"] } serde_json = "1" -sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio", "postgres", "uuid", "json"] } -thiserror = "1" +sqlx = { version = "0.9", default-features = false, features = ["runtime-tokio", "postgres", "uuid", "json"] } +thiserror = "2" tracing = "0.1" tokio = { version = "1", features = ["rt"] } uuid = { version = "1", features = ["v4"] } diff --git a/crates/store-pg/src/access.rs b/crates/store-pg/src/access.rs index 8eb5d9432..58b97ba4f 100644 --- a/crates/store-pg/src/access.rs +++ b/crates/store-pg/src/access.rs @@ -5,6 +5,7 @@ //! a bot's session follows its bot, which is shared. Lineage is written only //! by the runtime, so decisions may read it. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use api::{Attribution, ResourceAccessSummary, ResourceRef, Visibility}; use serde_json::json; use sqlx::{PgPool, Row}; @@ -94,7 +95,7 @@ pub(crate) fn created_by_from_row( } /// `column` holds the attribution of the actor bound at `$bind`. -pub(crate) fn actor_match(column: &str, bind: usize) -> String { +pub(crate) fn actor_match(column: &'static str, bind: usize) -> String { format!("{column} = jsonb_build_object('kind', 'actor', 'id', ${bind}::text)") } @@ -177,9 +178,9 @@ impl PgAccessStore { resource: &ResourceRef, ) -> Result { let (table, id_column) = content_table(resource); - sqlx::query_scalar(&format!( + sqlx::query_scalar(sqlx::AssertSqlSafe(format!( "SELECT EXISTS(SELECT 1 FROM {table} WHERE universe_id=$1 AND {id_column}=$2)" - )) + ))) .bind(universe) .bind(resource.id()) .fetch_one(&self.pool) @@ -240,12 +241,12 @@ impl PgAccessStore { session: &str, ) -> Result, AccessStoreError> { let summary = session_summary_columns(); - let row = sqlx::query(&format!( + let row = sqlx::query(sqlx::AssertSqlSafe(format!( "SELECT s.origin_parent_session_id, COALESCE(s.origin_root_session_id, s.session_id) AS root_session_id, {SESSION_BOT} AS root_bot_id, {summary} FROM sessions s {SESSION_ROOT_JOIN} WHERE s.universe_id = $1 AND s.session_id = $2" - )) + ))) .bind(universe) .bind(session) .fetch_optional(&self.pool) diff --git a/crates/store-pg/src/api_keys.rs b/crates/store-pg/src/api_keys.rs index 3943ae272..105dbe872 100644 --- a/crates/store-pg/src/api_keys.rs +++ b/crates/store-pg/src/api_keys.rs @@ -4,6 +4,7 @@ //! universe resolution. A key's authority is its row: scope, groups and the //! actor flag. Rotation replaces only the secret and its display prefix. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use std::collections::BTreeSet; use api::{AccessScope, MethodGroup}; @@ -70,9 +71,9 @@ impl PgApiKeyStore { Err(error) => return Err(error), } } - let row = sqlx::query(&format!( + let row = sqlx::query(sqlx::AssertSqlSafe(format!( "SELECT {KEY_COLUMNS} FROM api_keys WHERE key_hash = $1" - )) + ))) .bind(&key.key_hash) .fetch_optional(&self.pool) .await @@ -97,9 +98,9 @@ impl PgApiKeyStore { key_hash: &str, observed_at_ms: u64, ) -> Result, ApiKeyError> { - let Some(row) = sqlx::query(&format!( + let Some(row) = sqlx::query(sqlx::AssertSqlSafe(format!( "SELECT {KEY_COLUMNS} FROM api_keys WHERE key_hash = $1 AND revoked_at_ms IS NULL" - )) + ))) .bind(key_hash) .fetch_optional(&self.pool) .await @@ -134,11 +135,11 @@ impl PgApiKeyStore { None => (false, None), Some(scope) => (true, scope.universe_id()), }; - sqlx::query(&format!( + sqlx::query(sqlx::AssertSqlSafe(format!( "SELECT {KEY_COLUMNS} FROM api_keys WHERE NOT $1 OR universe_id IS NOT DISTINCT FROM $2 ORDER BY created_at_ms, key_prefix" - )) + ))) .bind(filtered) .bind(universe_id) .fetch_all(&self.pool) @@ -162,10 +163,10 @@ impl PgApiKeyStore { if new_prefix == key_prefix { continue; } - let result = sqlx::query(&format!( + let result = sqlx::query(sqlx::AssertSqlSafe(format!( "UPDATE api_keys SET key_hash = $2, key_prefix = $3, last_used_at_ms = NULL WHERE key_prefix = $1 AND revoked_at_ms IS NULL RETURNING {KEY_COLUMNS}" - )) + ))) .bind(key_prefix) .bind(&key_hash) .bind(&new_prefix) @@ -196,10 +197,10 @@ impl PgApiKeyStore { key_prefix: &str, now_ms: u64, ) -> Result, ApiKeyError> { - sqlx::query(&format!( + sqlx::query(sqlx::AssertSqlSafe(format!( "UPDATE api_keys SET revoked_at_ms = COALESCE(revoked_at_ms, $2) WHERE key_prefix = $1 RETURNING {KEY_COLUMNS}" - )) + ))) .bind(key_prefix) .bind(ms_to_i64(now_ms)?) .fetch_optional(&self.pool) diff --git a/crates/store-pg/src/auth.rs b/crates/store-pg/src/auth.rs index 164cfc303..f97f23b03 100644 --- a/crates/store-pg/src/auth.rs +++ b/crates/store-pg/src/auth.rs @@ -5,6 +5,7 @@ //! be swapped or relabeled without failing decryption. Plaintext exists only //! inside [`auth::SecretValue`] wrappers in adapter memory. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use ::auth::{ AuthGrantExposure, AuthGrantId, AuthGrantRecord, AuthGrantStatus, AuthGrantStore, AuthGrantTokenRefresh, AuthProviderKind, AuthRegistryError, CreateAuthGrantRecord, @@ -12,10 +13,10 @@ use ::auth::{ SecretValue, }; use aes_gcm::aead::{Aead, Payload}; -use aes_gcm::{Aes256Gcm, Key, KeyInit, Nonce}; +use aes_gcm::{Aes256Gcm, KeyInit, Nonce}; use api::Attribution; use async_trait::async_trait; -use rand::RngCore; +use rand::TryRng; use sqlx::Row; use crate::PgStore; @@ -32,7 +33,7 @@ impl PgStore { }); }; Ok(( - Aes256Gcm::new(Key::::from_slice(key.bytes())), + Aes256Gcm::new_from_slice(key.bytes()).expect("32-byte master key"), LOCAL_KEY_ID, )) } @@ -54,10 +55,12 @@ fn seal_secret( value: &SecretValue, ) -> Result<(Vec, Vec), AuthRegistryError> { let mut nonce = [0u8; NONCE_LEN]; - rand::rngs::OsRng.fill_bytes(&mut nonce); + rand::rngs::SysRng + .try_fill_bytes(&mut nonce) + .expect("OS random source unavailable"); let ciphertext = cipher .encrypt( - Nonce::from_slice(&nonce), + &nonce.into(), Payload { msg: value.expose().as_bytes(), aad, @@ -82,7 +85,7 @@ fn open_secret( } let plaintext = cipher .decrypt( - Nonce::from_slice(nonce), + &Nonce::try_from(nonce).expect("nonce length validated"), Payload { msg: ciphertext, aad, @@ -273,7 +276,7 @@ impl AuthGrantStore for PgStore { RETURNING {GRANT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.grant_id.as_str()) .bind(&record.provider_id) @@ -320,7 +323,7 @@ impl AuthGrantStore for PgStore { WHERE universe_id = $1 AND grant_id = $2 "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(grant_id.as_str()) .fetch_optional(&self.pool) @@ -349,7 +352,7 @@ impl AuthGrantStore for PgStore { ORDER BY grant_id "# ); - sqlx::query(&query) + sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(grant_status_to_str(status)) .fetch_all(&self.pool) @@ -364,7 +367,7 @@ impl AuthGrantStore for PgStore { ORDER BY grant_id "# ); - sqlx::query(&query) + sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -389,7 +392,7 @@ impl AuthGrantStore for PgStore { RETURNING {GRANT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(grant_id.as_str()) .bind(grant_status_to_str(status)) @@ -422,7 +425,7 @@ impl AuthGrantStore for PgStore { RETURNING {GRANT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(grant_id.as_str()) .bind(refresh.access_token_secret.as_str()) @@ -455,7 +458,7 @@ impl AuthGrantStore for PgStore { RETURNING {GRANT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(grant_id.as_str()) .bind(leased_at_ms) @@ -486,7 +489,7 @@ impl AuthGrantStore for PgStore { RETURNING {GRANT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(grant_id.as_str()) .bind(expires_at_ms) @@ -514,7 +517,7 @@ impl AuthGrantStore for PgStore { RETURNING {GRANT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(grant_id.as_str()) .fetch_optional(&self.pool) @@ -724,3 +727,59 @@ pub(crate) fn auth_sql_error(action: &str, error: sqlx::Error) -> AuthRegistryEr message: format!("{action}: {error}"), } } + +#[cfg(test)] +mod tests { + use base64::Engine as _; + + use super::*; + + #[test] + fn persisted_aes_gcm_ciphertext_remains_readable_and_bound_to_its_aad() { + let key = std::array::from_fn::<_, 32, _>(|i| i as u8); + let cipher = Aes256Gcm::new_from_slice(&key).expect("32-byte key"); + let nonce = std::array::from_fn::<_, NONCE_LEN, _>(|i| i as u8); + let aad = b"universe/secret/oauth_client_secret"; + // Independent AES-256-GCM fixture: ciphertext followed by the 16-byte tag, + // produced with Node's crypto implementation and the key, nonce, and AAD above. + let ciphertext = base64::engine::general_purpose::STANDARD + .decode("N2ekaKyWtn7pbOTu0psdGW/9S3b73k/9ObzTEmBK3xs=") + .expect("fixture base64"); + let secret = open_secret(&cipher, aad, &nonce, &ciphertext).expect("persisted secret"); + assert_eq!(secret.expose(), "persisted-secret"); + assert!(matches!( + open_secret( + &cipher, + b"another/secret/oauth_client_secret", + &nonce, + &ciphertext + ), + Err(AuthRegistryError::Store { .. }) + )); + let mut tampered = ciphertext; + tampered[0] ^= 1; + assert!(matches!( + open_secret(&cipher, aad, &nonce, &tampered), + Err(AuthRegistryError::Store { .. }) + )); + } + + #[test] + fn sealed_secrets_use_distinct_nonces_and_round_trip() { + let cipher = Aes256Gcm::new_from_slice(&[7; 32]).expect("32-byte key"); + let secret = SecretValue::new("secret".to_owned()); + let aad = b"universe/secret/oauth_client_secret"; + let first = seal_secret(&cipher, aad, &secret).expect("first encryption"); + let second = seal_secret(&cipher, aad, &secret).expect("second encryption"); + assert_ne!(first.0, second.0); + for (nonce, ciphertext) in [first, second] { + assert_eq!(nonce.len(), NONCE_LEN); + assert_eq!( + open_secret(&cipher, aad, &nonce, &ciphertext) + .expect("decrypt") + .expose(), + secret.expose() + ); + } + } +} diff --git a/crates/store-pg/src/blob.rs b/crates/store-pg/src/blob.rs index c72cb0ef9..6b2863b53 100644 --- a/crates/store-pg/src/blob.rs +++ b/crates/store-pg/src/blob.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, storage::{BlobEdge, BlobGraphStore, BlobInfo, BlobStore, BlobStoreError}, }; @@ -275,7 +275,7 @@ impl BlobStore for PgStore { &self, expected: &BlobRef, size: u64, - source: &mut dyn engine::storage::BlobSource, + source: &mut dyn harness::storage::BlobSource, ) -> Result { let digest = sha256_hex(expected)?; // Admission renews existing content without downloading or re-uploading it. diff --git a/crates/store-pg/src/blob_cache.rs b/crates/store-pg/src/blob_cache.rs index 806a10245..f1015d9d9 100644 --- a/crates/store-pg/src/blob_cache.rs +++ b/crates/store-pg/src/blob_cache.rs @@ -17,7 +17,7 @@ use std::sync::Arc; -use engine::BlobRef; +use harness::BlobRef; use uuid::Uuid; #[derive(Clone, Debug, Hash, PartialEq, Eq)] diff --git a/crates/store-pg/src/bots.rs b/crates/store-pg/src/bots.rs index 1ea875d51..55669db5e 100644 --- a/crates/store-pg/src/bots.rs +++ b/crates/store-pg/src/bots.rs @@ -3,6 +3,7 @@ //! tables are the read model plus what admission needs (the `#N` counter, //! trigger secrets and incidents, write-once outcomes). +// Formatted SQL uses internal schema fragments; request values use bind parameters. use ::bots::{ BotError, BotEventCursor, BotEventOutcomeWrite, BotEventRateScope, BotEventRecord, BotEventStore, BotRecord, BotRosterRow, BotStore, BotTriggerRecord, BotTriggerStore, @@ -61,7 +62,7 @@ fn event_columns() -> String { /// `table.col AS col, ...` for embedding the event columns beside /// other tables' columns. -fn prefixed_event_columns(table: &str, prefix: &str) -> String { +fn prefixed_event_columns(table: &'static str, prefix: &'static str) -> String { EVENT_COLUMN_NAMES .iter() .map(|column| format!("{table}.{column} AS {prefix}{column}")) @@ -124,7 +125,7 @@ impl PgStore { ORDER BY b.bot_id "# ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(created_by) .fetch_all(&self.pool) @@ -206,7 +207,7 @@ impl BotStore for PgStore { RETURNING {BOT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(json_value("serialize bot document", &document)?) @@ -296,7 +297,7 @@ impl BotStore for PgStore { async fn read_bot(&self, bot_id: &BotId) -> Result { let query = format!("SELECT {BOT_COLUMNS} FROM bots WHERE universe_id = $1 AND bot_id = $2"); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .fetch_optional(&self.pool) @@ -313,7 +314,7 @@ impl BotStore for PgStore { async fn list_bots(&self) -> Result, BotError> { let query = format!("SELECT {BOT_COLUMNS} FROM bots WHERE universe_id = $1 ORDER BY bot_id"); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -343,7 +344,7 @@ impl BotStore for PgStore { ORDER BY bot_id "# ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(profile_id.as_str()) .fetch_all(&self.pool) @@ -364,7 +365,7 @@ impl BotStore for PgStore { RETURNING {BOT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(now_ms) @@ -418,7 +419,7 @@ impl BotStore for PgStore { let query = format!( "DELETE FROM bots WHERE universe_id = $1 AND bot_id = $2 RETURNING {BOT_COLUMNS}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .fetch_optional(&self.pool) @@ -476,7 +477,7 @@ impl PgStore { RETURNING {BOT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(u64_to_i64(revision, "revision")?) @@ -594,7 +595,7 @@ impl BotTriggerStore for PgStore { "SELECT {TRIGGER_COLUMNS} FROM bot_triggers \ WHERE universe_id = $1 AND bot_id = $2 AND trigger_id = $3" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(trigger_id.as_str()) @@ -615,7 +616,7 @@ impl BotTriggerStore for PgStore { "SELECT {TRIGGER_COLUMNS} FROM bot_triggers \ WHERE universe_id = $1 AND bot_id = $2 ORDER BY trigger_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .fetch_all(&self.pool) @@ -632,7 +633,7 @@ impl BotTriggerStore for PgStore { "SELECT {TRIGGER_COLUMNS} FROM bot_triggers \ WHERE universe_id = $1 AND kind = $2 ORDER BY bot_id, trigger_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(kind.as_str()) .fetch_all(&self.pool) @@ -651,7 +652,7 @@ impl BotTriggerStore for PgStore { WHERE universe_id = $1 AND bot_id = $2 AND trigger_id = $3 \ RETURNING {TRIGGER_COLUMNS}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(trigger_id.as_str()) @@ -686,7 +687,7 @@ impl BotTriggerStore for PgStore { RETURNING {TRIGGER_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(trigger_id.as_str()) @@ -723,7 +724,7 @@ impl BotTriggerStore for PgStore { RETURNING {TRIGGER_COLUMNS} "# ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(disabled_reason_to_str(reason)) @@ -832,7 +833,7 @@ impl PgStore { RETURNING {TRIGGER_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(write.trigger_id.as_str()) @@ -874,7 +875,7 @@ impl PgStore { RETURNING {TRIGGER_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(replaced.bot_id.as_str()) .bind(replaced.trigger_id.as_str()) @@ -932,7 +933,7 @@ impl BotEventStore for PgStore { "# ); let row = - sqlx::query(&query) + sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.bot_id.as_str()) .bind(record.event_id.as_str()) @@ -997,7 +998,7 @@ impl BotEventStore for PgStore { let digests = refs .iter() .map(|value| { - engine::BlobRef::parse(value) + harness::BlobRef::parse(value) .map(|blob| blob.as_str()[7..].to_owned()) .map_err(|error| { BotError::invalid(format!("invalid bot event blob ref: {error}")) @@ -1053,7 +1054,7 @@ impl BotEventStore for PgStore { let query = format!( "SELECT {columns} FROM bot_events WHERE universe_id = $1 AND bot_id = $2 AND seq = $3" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(u64_to_i64(seq, "seq")?) @@ -1079,7 +1080,7 @@ impl BotEventStore for PgStore { "SELECT {columns} FROM bot_events \ WHERE universe_id = $1 AND bot_id = $2 AND event_id = $3" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(event_id) @@ -1109,7 +1110,7 @@ impl BotEventStore for PgStore { WHERE universe_id = $1 AND bot_id = $2 AND event_id = ANY($3::text[]) \ ORDER BY seq" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(event_ids.to_vec()) @@ -1135,7 +1136,7 @@ impl BotEventStore for PgStore { AND (received_at_ms, seq) < ($3, $4) \ ORDER BY received_at_ms DESC, seq DESC LIMIT $5" ); - sqlx::query(&query) + sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(cursor.received_at_ms) @@ -1150,7 +1151,7 @@ impl BotEventStore for PgStore { WHERE universe_id = $1 AND bot_id = $2 \ ORDER BY received_at_ms DESC, seq DESC LIMIT $3" ); - sqlx::query(&query) + sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(bot_id.as_str()) .bind(limit) diff --git a/crates/store-pg/src/cas_sweep.rs b/crates/store-pg/src/cas_sweep.rs index a7475ed58..721862c20 100644 --- a/crates/store-pg/src/cas_sweep.rs +++ b/crates/store-pg/src/cas_sweep.rs @@ -5,7 +5,8 @@ //! them on a later pass. Pages bound rows examined, including live rows. //! Objects have incarnation-specific keys and are removed after catalog commit. -use engine::{BlobRef, storage::BlobStoreError}; +// Formatted SQL uses internal schema fragments; request values use bind parameters. +use harness::{BlobRef, storage::BlobStoreError}; use object_store::{ObjectStoreExt, path::Path as ObjectPath}; use sqlx::{PgPool, Postgres, Row, Transaction, pool::PoolConnection}; use thiserror::Error; @@ -160,7 +161,7 @@ impl PgStore { "# ); let mut tx = sweep_transaction(&self.pool).await?; - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(cutoff_to_i64(cutoff_ms)?) .bind(digests(pinned)?) @@ -231,7 +232,7 @@ impl PgStore { "# ); let mut tx = sweep_transaction(&self.pool).await?; - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(cutoff_to_i64(cutoff_ms)?) .bind(digests(pinned)?) diff --git a/crates/store-pg/src/channels.rs b/crates/store-pg/src/channels.rs index 92af34b88..377e386e9 100644 --- a/crates/store-pg/src/channels.rs +++ b/crates/store-pg/src/channels.rs @@ -2,6 +2,7 @@ //! Accounts are what a `chat` bot trigger points at; pairings record which //! conversations that trigger admitted. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use ::channels::{ ChannelAccountRecord, ChannelAccountStore, ChannelError, ChannelPairingFilter, ChannelPairingRecord, ChannelPairingStore, validate_account_document, @@ -46,7 +47,7 @@ impl ChannelAccountStore for PgStore { RETURNING {ACCOUNT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(account_id.as_str()) .bind(document.provider.as_str()) @@ -139,7 +140,7 @@ impl ChannelAccountStore for PgStore { "SELECT {ACCOUNT_COLUMNS} FROM channel_accounts \ WHERE universe_id = $1 AND account_id = $2" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(account_id.as_str()) .fetch_optional(&self.pool) @@ -162,7 +163,7 @@ impl ChannelAccountStore for PgStore { WHERE universe_id = $1 AND ($2::text IS NULL OR provider = $2) \ ORDER BY account_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(provider.as_ref().map(ChannelProvider::as_str)) .fetch_all(&self.pool) @@ -179,7 +180,7 @@ impl ChannelAccountStore for PgStore { "DELETE FROM channel_accounts WHERE universe_id = $1 AND account_id = $2 \ RETURNING {ACCOUNT_COLUMNS}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(account_id.as_str()) .fetch_optional(&self.pool) @@ -218,7 +219,7 @@ impl PgStore { RETURNING {ACCOUNT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(account_id.as_str()) .bind(document.provider.as_str()) @@ -259,7 +260,7 @@ impl ChannelPairingStore for PgStore { RETURNING {PAIRING_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.account_id.as_str()) .bind(record.chat_id.as_str()) @@ -282,7 +283,7 @@ impl ChannelPairingStore for PgStore { "SELECT {PAIRING_COLUMNS} FROM channel_pairings \ WHERE universe_id = $1 AND account_id = $2 AND chat_id = $3" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(account_id.as_str()) .bind(chat_id) @@ -305,7 +306,7 @@ impl ChannelPairingStore for PgStore { AND ($5::text IS NULL OR chat_id = $5) \ ORDER BY paired_at_ms DESC, account_id, chat_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(filter.account_id.as_ref().map(ChannelAccountId::as_str)) .bind(filter.bot_id.as_ref().map(BotId::as_str)) @@ -327,7 +328,7 @@ impl ChannelPairingStore for PgStore { WHERE universe_id = $1 AND account_id = $2 AND chat_id = $3 \ RETURNING {PAIRING_COLUMNS}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(account_id.as_str()) .bind(chat_id) @@ -360,7 +361,7 @@ pub async fn list_channel_accounts_all( AND ($2 OR COALESCE((document_json->>'enabled')::boolean, true)) \ ORDER BY universe_id, account_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(provider.as_ref().map(ChannelProvider::as_str)) .bind(include_disabled) .fetch_all(pool) diff --git a/crates/store-pg/src/deployment.rs b/crates/store-pg/src/deployment.rs index 1aeee290b..76d812c8a 100644 --- a/crates/store-pg/src/deployment.rs +++ b/crates/store-pg/src/deployment.rs @@ -5,6 +5,7 @@ //! of universes, so no per-universe store applies. Stats are cheap aggregates //! computed at read time, approximate under concurrent writes by design. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use sqlx::{PgPool, Row}; use uuid::Uuid; @@ -90,7 +91,7 @@ pub async fn read_universe_stats( universe_id: Uuid, ) -> Result, PgStoreError> { let query = format!("{UNIVERSE_STATS_SELECT} WHERE u.universe_id = $1"); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(universe_id) .fetch_optional(pool) .await?; @@ -99,7 +100,9 @@ pub async fn read_universe_stats( pub async fn list_universe_stats(pool: &PgPool) -> Result, PgStoreError> { let query = format!("{UNIVERSE_STATS_SELECT} ORDER BY u.created_at_ms, u.universe_id"); - let rows = sqlx::query(&query).fetch_all(pool).await?; + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) + .fetch_all(pool) + .await?; rows.iter().map(universe_stats_from_row).collect() } diff --git a/crates/store-pg/src/environment.rs b/crates/store-pg/src/environment.rs index 63660f7bd..61d20da40 100644 --- a/crates/store-pg/src/environment.rs +++ b/crates/store-pg/src/environment.rs @@ -1,3 +1,4 @@ +// Formatted SQL uses internal schema fragments; request values use bind parameters. use async_trait::async_trait; use auth::{AuthGrantId, AuthProviderId, SecretId}; use environment_protocol::shared::ProviderTargetId; @@ -88,7 +89,7 @@ impl EnvironmentProviderStore for PgStore { RETURNING {PROVIDER_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(record.provider_id.as_str()) .bind(record.display_name.as_deref()) .bind(json_value( @@ -110,7 +111,7 @@ impl EnvironmentProviderStore for PgStore { ) -> Result { let query = format!("SELECT {PROVIDER_COLUMNS} FROM environment_providers WHERE provider_id = $1"); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(provider_id.as_str()) .fetch_optional(&self.pool) .await @@ -125,7 +126,7 @@ impl EnvironmentProviderStore for PgStore { ) -> Result, EnvironmentRegistryError> { let query = format!("SELECT {PROVIDER_COLUMNS} FROM environment_providers ORDER BY provider_id"); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .fetch_all(&self.pool) .await .map_err(|error| sql_error("list environment providers", error))?; @@ -149,7 +150,7 @@ impl EnvironmentProviderStore for PgStore { let query = format!( "DELETE FROM environment_providers WHERE provider_id = $1 RETURNING {PROVIDER_COLUMNS}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(provider_id.as_str()) .fetch_optional(&self.pool) .await @@ -213,7 +214,7 @@ impl EnvironmentProviderBindingStore for PgStore { RETURNING {BINDING_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(request.universe_id) .bind(request.binding_id.as_str()) .bind(request.provider_id.as_str()) @@ -241,7 +242,7 @@ impl EnvironmentProviderBindingStore for PgStore { let query = format!( "SELECT {BINDING_COLUMNS} FROM environment_provider_bindings WHERE universe_id = $1 AND binding_id = $2" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(universe_id) .bind(binding_id.as_str()) .fetch_optional(&self.pool) @@ -258,7 +259,7 @@ impl EnvironmentProviderBindingStore for PgStore { let query = format!( "SELECT {BINDING_COLUMNS} FROM environment_provider_bindings WHERE universe_id = $1 ORDER BY binding_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(universe_id) .fetch_all(&self.pool) .await @@ -281,7 +282,7 @@ impl EnvironmentProviderBindingStore for PgStore { let query = format!( "DELETE FROM environment_provider_bindings WHERE universe_id = $1 AND binding_id = $2 RETURNING {BINDING_COLUMNS}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(universe_id) .bind(binding_id.as_str()) .fetch_optional(&self.pool) @@ -328,7 +329,7 @@ impl EnvironmentStore for PgStore { let query = format!( "SELECT {BINDING_COLUMNS} FROM environment_provider_bindings WHERE universe_id = $1 AND binding_id = $2 FOR UPDATE" ); - let binding_row = sqlx::query(&query) + let binding_row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.binding_id.as_str()) .fetch_optional(&mut *tx) @@ -435,7 +436,7 @@ impl EnvironmentStore for PgStore { let query = format!( "SELECT {BINDING_COLUMNS} FROM environment_provider_bindings WHERE universe_id = $1 AND binding_id = $2 FOR UPDATE" ); - let binding_row = sqlx::query(&query) + let binding_row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.binding_id.as_str()) .fetch_optional(&mut *tx) @@ -707,7 +708,7 @@ impl EnvironmentStore for PgStore { let query = format!( "SELECT {ENVIRONMENT_COLUMNS} {ENVIRONMENT_JOIN} WHERE e.universe_id = $1 AND e.daemon_public_key = $2" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(daemon_public_key) .fetch_optional(&self.pool) @@ -776,7 +777,7 @@ impl EnvironmentStore for PgStore { let query = format!( "SELECT {ENVIRONMENT_COLUMNS} {ENVIRONMENT_JOIN} WHERE e.universe_id = $1 AND e.source_kind = 'registered' AND e.status NOT IN ('closing','closed') ORDER BY e.environment_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -840,7 +841,7 @@ impl EnvironmentStore for PgStore { query.push_str(&format!(" AND e.metadata_json @> ${next}")); } query.push_str(" ORDER BY e.environment_id"); - let mut sql = sqlx::query(&query).bind(self.config.universe_id); + let mut sql = sqlx::query(sqlx::AssertSqlSafe(query)).bind(self.config.universe_id); if let Some(id) = request.provider_id { sql = sql.bind(id.to_string()); } @@ -869,7 +870,7 @@ impl EnvironmentStore for PgStore { let query = format!( "SELECT {ENVIRONMENT_COLUMNS} {ENVIRONMENT_JOIN} WHERE e.universe_id = $1 AND (e.status IN ('provisioning','booting','closing','unknown') OR {POWER_DIVERGES_SQL}) ORDER BY e.updated_at_ms, e.environment_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -883,7 +884,7 @@ impl EnvironmentStore for PgStore { let query = format!( "SELECT {ENVIRONMENT_COLUMNS} {ENVIRONMENT_JOIN} WHERE e.universe_id = $1 AND e.status = 'ready' AND e.idle_policy_json IS NOT NULL ORDER BY e.updated_at_ms, e.environment_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -1072,7 +1073,7 @@ impl EnvironmentCredentialStore for PgStore { updated_at_ms=EXCLUDED.updated_at_ms RETURNING {CREDENTIAL_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.environment_id.as_str()) .bind(&record.env_name) @@ -1094,7 +1095,7 @@ impl EnvironmentCredentialStore for PgStore { let query = format!( "SELECT {CREDENTIAL_COLUMNS} FROM environment_credentials WHERE universe_id=$1 AND environment_id=$2 ORDER BY env_name" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.environment_id.as_str()) .fetch_all(&self.pool) @@ -1111,7 +1112,7 @@ impl EnvironmentCredentialStore for PgStore { let query = format!( "DELETE FROM environment_credentials WHERE universe_id=$1 AND environment_id=$2 AND env_name=$3 RETURNING {CREDENTIAL_COLUMNS}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(environment_id.as_str()) .bind(env_name) @@ -1131,14 +1132,14 @@ impl EnvironmentCredentialStore for PgStore { async fn read_environment_on( pool: &sqlx::PgPool, universe_id: Uuid, - predicate: &str, + predicate: &'static str, value: &str, action: &str, ) -> Result { let query = format!( "SELECT {ENVIRONMENT_COLUMNS} {ENVIRONMENT_JOIN} WHERE e.universe_id = $1 AND {predicate}" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(universe_id) .bind(value) .fetch_optional(pool) diff --git a/crates/store-pg/src/environment_registration.rs b/crates/store-pg/src/environment_registration.rs index 37f490703..0aa704097 100644 --- a/crates/store-pg/src/environment_registration.rs +++ b/crates/store-pg/src/environment_registration.rs @@ -3,6 +3,7 @@ //! universe: a presented secret selects the universe of its key, and a //! known daemon public key selects the universe of its environment. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use async_trait::async_trait; use environments::{ CreateEnvironmentRegistrationKey, EnvironmentRegistrationKeyId, @@ -44,7 +45,7 @@ impl EnvironmentRegistrationKeyStore for PgStore { RETURNING {KEY_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.registration_key_id.as_str()) .bind(&record.display_name) @@ -77,7 +78,7 @@ impl EnvironmentRegistrationKeyStore for PgStore { let query = format!( "SELECT {KEY_COLUMNS} FROM environment_registration_keys WHERE universe_id = $1 AND registration_key_id = $2" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(registration_key_id.as_str()) .fetch_optional(&self.pool) @@ -93,7 +94,7 @@ impl EnvironmentRegistrationKeyStore for PgStore { let query = format!( "SELECT {KEY_COLUMNS} FROM environment_registration_keys WHERE universe_id = $1 ORDER BY created_at_ms, registration_key_id" ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -116,7 +117,7 @@ impl EnvironmentRegistrationKeyStore for PgStore { RETURNING {KEY_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.registration_key_id.as_str()) .bind(request.revoked_at_ms) @@ -136,7 +137,7 @@ impl EnvironmentRegistrationKeyStore for PgStore { let query = format!( "SELECT {KEY_COLUMNS} FROM environment_registration_keys WHERE universe_id = $1 AND secret_hash = $2" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(secret_hash) .fetch_optional(&self.pool) @@ -189,7 +190,7 @@ pub(crate) async fn lock_registration_key( let query = format!( "SELECT {KEY_COLUMNS} FROM environment_registration_keys WHERE universe_id = $1 AND registration_key_id = $2 FOR UPDATE" ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(universe_id) .bind(registration_key_id.as_str()) .fetch_optional(&mut **tx) diff --git a/crates/store-pg/src/lib.rs b/crates/store-pg/src/lib.rs index 73ab8cdc7..4bf23ff2e 100644 --- a/crates/store-pg/src/lib.rs +++ b/crates/store-pg/src/lib.rs @@ -42,8 +42,8 @@ pub use model_defaults::ModelDefaultsStoreError; /// A session page with the access summary each view carries. #[derive(Clone, Debug)] pub struct SessionListPageWithAccess { - pub sessions: Vec<(engine::storage::SessionRecord, api::ResourceAccessSummary)>, - pub next_cursor: Option, + pub sessions: Vec<(harness::storage::SessionRecord, api::ResourceAccessSummary)>, + pub next_cursor: Option, } pub const CORE_SCHEMA_SQL: &str = include_str!("../migrations/001_core.sql"); @@ -223,7 +223,7 @@ pub enum PgStoreError { Store { message: String }, #[error( - "database schema revision {current_revision} is stale; revision {required_revision} is required (run `lightspeed-server migrate`)" + "database schema revision {current_revision} is stale; revision {required_revision} is required (run `lightspeed-runtime migrate`)" )] MigrationRequired { current_revision: i64, @@ -231,7 +231,7 @@ pub enum PgStoreError { }, #[error( - "found unledgered Lightspeed tables {relations:?}; refusing to baseline an existing schema (reset the full Lightspeed schema or database before running `lightspeed-server migrate`)" + "found unledgered Lightspeed tables {relations:?}; refusing to baseline an existing schema (reset the full Lightspeed schema or database before running `lightspeed-runtime migrate`)" )] UnledgeredSchema { relations: Vec }, diff --git a/crates/store-pg/src/migrations.rs b/crates/store-pg/src/migrations.rs index a8ac3f92b..c9d186252 100644 --- a/crates/store-pg/src/migrations.rs +++ b/crates/store-pg/src/migrations.rs @@ -1,7 +1,7 @@ //! Embedded, immutable PostgreSQL schema migrations. //! //! Production processes verify this ledger at startup. Only the explicit -//! `lightspeed-server migrate` command applies migrations. +//! `lightspeed-runtime migrate` command applies migrations. use std::collections::BTreeMap; @@ -356,7 +356,7 @@ async fn apply_one( } fn checksum(sql: &str) -> String { - format!("{:x}", Sha256::digest(sql.as_bytes())) + hex::encode(Sha256::digest(sql.as_bytes())) } #[cfg(test)] diff --git a/crates/store-pg/src/oauth.rs b/crates/store-pg/src/oauth.rs index cad8ddbeb..c11a345a1 100644 --- a/crates/store-pg/src/oauth.rs +++ b/crates/store-pg/src/oauth.rs @@ -7,6 +7,7 @@ //! lock keyed by universe and grant, so refresh single-flight holds across //! worker processes. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use api::Attribution; use async_trait::async_trait; use auth::{ @@ -102,7 +103,7 @@ impl OAuthClientStore for PgStore { RETURNING {OAUTH_CLIENT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.client_id.as_str()) .bind(&record.provider_id) @@ -144,7 +145,7 @@ impl OAuthClientStore for PgStore { WHERE universe_id = $1 AND client_id = $2 "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(client_id.as_str()) .fetch_optional(&self.pool) @@ -168,7 +169,7 @@ impl OAuthClientStore for PgStore { ORDER BY client_id "# ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -187,7 +188,7 @@ impl OAuthClientStore for PgStore { RETURNING {OAUTH_CLIENT_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(client_id.as_str()) .fetch_optional(&self.pool) @@ -240,7 +241,7 @@ impl AuthFlowStore for PgStore { RETURNING {AUTH_FLOW_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.flow_id.as_str()) .bind(record.client_id.as_str()) @@ -277,7 +278,7 @@ impl AuthFlowStore for PgStore { WHERE universe_id = $1 AND flow_id = $2 "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(flow_id.as_str()) .fetch_optional(&self.pool) @@ -303,7 +304,7 @@ impl AuthFlowStore for PgStore { WHERE universe_id = $1 AND state_hash = $2 "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(state_hash) .fetch_optional(&self.pool) @@ -328,7 +329,7 @@ impl AuthFlowStore for PgStore { RETURNING {AUTH_FLOW_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(flow_id.as_str()) .bind(now_ms) @@ -370,7 +371,7 @@ impl AuthFlowStore for PgStore { RETURNING {AUTH_FLOW_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(flow_id.as_str()) .bind(outcome.grant_id.as_ref().map(AuthGrantId::as_str)) diff --git a/crates/store-pg/src/object.rs b/crates/store-pg/src/object.rs index fe73282b9..dffb9a880 100644 --- a/crates/store-pg/src/object.rs +++ b/crates/store-pg/src/object.rs @@ -1,5 +1,5 @@ -use engine::{BlobRef, storage::BlobStoreError}; use futures_util::TryStreamExt as _; +use harness::{BlobRef, storage::BlobStoreError}; use object_store::{ObjectStore, ObjectStoreExt, PutPayload, path::Path as ObjectPath}; use uuid::Uuid; @@ -117,7 +117,7 @@ pub(crate) async fn put_streamed_object( key: &str, expected: &BlobRef, size: u64, - source: &mut dyn engine::storage::BlobSource, + source: &mut dyn harness::storage::BlobSource, ) -> Result { use sha2::{Digest, Sha256}; struct Guard(Option>); @@ -178,7 +178,8 @@ pub(crate) async fn put_streamed_object( part = Vec::with_capacity(part_size + 256 * 1024); } } - if length != size || format!("sha256:{:x}", hash.finalize()) != expected.as_str() { + if length != size || format!("sha256:{}", hex::encode(hash.finalize())) != expected.as_str() + { return Err(BlobStoreError::Store { message: "blob stream length/digest mismatch".into(), }); @@ -223,7 +224,7 @@ mod tests { remaining: u64, } #[async_trait::async_trait] - impl engine::storage::BlobSource for Source { + impl harness::storage::BlobSource for Source { async fn read_chunk(&mut self, max_bytes: usize) -> Result, BlobStoreError> { assert!(max_bytes <= 256 * 1024); let count = self.remaining.min(max_bytes as u64) as usize; diff --git a/crates/store-pg/src/providers.rs b/crates/store-pg/src/providers.rs index cd4a89b30..992ef8577 100644 --- a/crates/store-pg/src/providers.rs +++ b/crates/store-pg/src/providers.rs @@ -6,6 +6,7 @@ //! `auth_secrets` (ON DELETE RESTRICT), so a provider's private key cannot //! be deleted out from under it. +// Formatted SQL uses internal schema fragments; request values use bind parameters. use async_trait::async_trait; use auth::{ AuthProviderConfig, AuthProviderId, AuthProviderRecord, AuthProviderStatus, AuthProviderStore, @@ -57,7 +58,7 @@ impl AuthProviderStore for PgStore { RETURNING {AUTH_PROVIDER_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(record.provider_id.as_str()) .bind(provider_kind_to_str(record.provider_kind)) @@ -89,7 +90,7 @@ impl AuthProviderStore for PgStore { WHERE universe_id = $1 AND provider_id = $2 "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(provider_id.as_str()) .fetch_optional(&self.pool) @@ -113,7 +114,7 @@ impl AuthProviderStore for PgStore { ORDER BY provider_id "# ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -132,7 +133,7 @@ impl AuthProviderStore for PgStore { RETURNING {AUTH_PROVIDER_COLUMNS} "# ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(provider_id.as_str()) .fetch_optional(&self.pool) diff --git a/crates/store-pg/src/session.rs b/crates/store-pg/src/session.rs index 8dd05e0f9..3db76e991 100644 --- a/crates/store-pg/src/session.rs +++ b/crates/store-pg/src/session.rs @@ -1,8 +1,9 @@ +// Formatted SQL uses internal schema fragments; request values use bind parameters. use std::collections::{BTreeMap, BTreeSet}; use async_trait::async_trait; -use engine::storage::SessionActivity; -use engine::{ +use harness::storage::SessionActivity; +use harness::{ BlobRef, session::{EventSeq, SessionId, SessionPosition, StoredSessionEntry, UncommittedStoredEvent}, storage::{ @@ -69,7 +70,7 @@ impl PgStore { FOR UPDATE "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.session_id.as_str()) .fetch_optional(&mut *tx) @@ -486,7 +487,7 @@ impl PgStore { LIMIT $5 "#, ); - let sql = sqlx::query(&query) + let sql = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(cursor_updated_at_ms) .bind(cursor_session_id) @@ -635,7 +636,7 @@ impl SessionStore for PgStore { RETURNING {SESSION_COLUMNS}, {SESSION_ACTIVITY} "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.session_id.as_str()) .bind(request.display_name.as_deref()) @@ -676,7 +677,7 @@ impl SessionStore for PgStore { WHERE universe_id = $1 AND session_id = $2 "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(session_id.as_str()) .fetch_optional(&self.pool) @@ -716,7 +717,7 @@ impl SessionStore for PgStore { RETURNING {SESSION_COLUMNS}, {SESSION_ACTIVITY} "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(session_id.as_str()) .bind(display_name.as_deref()) @@ -745,7 +746,7 @@ impl SessionStore for PgStore { RETURNING {SESSION_COLUMNS}, {SESSION_ACTIVITY} "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(session_id.as_str()) .bind(metadata_json(&metadata)?) @@ -797,7 +798,7 @@ impl SessionStore for PgStore { RETURNING {SESSION_COLUMNS}, {SESSION_ACTIVITY} "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(session_id.as_str()) .bind(optional_u64_to_i64( @@ -835,7 +836,7 @@ impl SessionStore for PgStore { LIMIT $3 "#, ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(u64_to_i64(now_ms, "retention now_ms")?) .bind(usize_to_session_i64(limit, "retention limit")?) @@ -929,7 +930,7 @@ impl SessionStore for PgStore { FOR UPDATE "#, ); - let rows = sqlx::query(&query) + let rows = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(&selected_ids) .fetch_all(&mut *tx) @@ -1024,7 +1025,7 @@ impl SessionStore for PgStore { RETURNING {SESSION_COLUMNS}, {SESSION_ACTIVITY} "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.session_id.as_str()) .bind(request.source_session_id.as_str()) @@ -1142,7 +1143,7 @@ impl SessionStore for PgStore { RETURNING {SESSION_COLUMNS}, {SESSION_ACTIVITY} "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(self.config.universe_id) .bind(request.session_id.as_str()) .bind(session_lifecycle_status_str(lifecycle_status)) @@ -1270,7 +1271,7 @@ impl SessionStore for PgStore { .try_get("state_digest") .map_err(|error| session_sql_error("decode checkpoint digest", error))?; let state_ref = - engine::BlobRef::parse(format!("sha256:{state_digest}")).map_err(|error| { + harness::BlobRef::parse(format!("sha256:{state_digest}")).map_err(|error| { SessionStoreError::Store { message: format!("decode checkpoint blob ref: {error}"), } @@ -1675,7 +1676,7 @@ async fn lock_session( FOR UPDATE "#, ); - let row = sqlx::query(&query) + let row = sqlx::query(sqlx::AssertSqlSafe(query)) .bind(universe_id) .bind(session_id.as_str()) .fetch_optional(&mut **tx) diff --git a/crates/store-pg/src/shared.rs b/crates/store-pg/src/shared.rs index ba11fabfe..fce110de5 100644 --- a/crates/store-pg/src/shared.rs +++ b/crates/store-pg/src/shared.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ BlobRef, session::{EventSeq, SessionPosition}, storage::{BlobStoreError, SessionStoreError}, diff --git a/crates/store-pg/src/vfs.rs b/crates/store-pg/src/vfs.rs index 1bd733423..6849252d6 100644 --- a/crates/store-pg/src/vfs.rs +++ b/crates/store-pg/src/vfs.rs @@ -1,5 +1,6 @@ +// Formatted SQL uses internal schema fragments; request values use bind parameters. use async_trait::async_trait; -use engine::BlobRef; +use harness::BlobRef; use sqlx::Row; use crate::{PgStore, shared::sha256_hex}; @@ -101,7 +102,7 @@ impl VfsWorkspaceStore for PgStore { .as_ref() .map(catalog_digest) .transpose()?; - let row = sqlx::query(&format!( + let row = sqlx::query(sqlx::AssertSqlSafe(format!( r#" INSERT INTO vfs_workspaces ( universe_id, @@ -119,7 +120,7 @@ impl VfsWorkspaceStore for PgStore { ON CONFLICT (universe_id, workspace_id) DO NOTHING RETURNING {WORKSPACE_COLUMNS} "# - )) + ))) .bind(self.config.universe_id) .bind(record.workspace_id.as_str()) .bind(record.display_name.as_deref()) @@ -145,13 +146,13 @@ impl VfsWorkspaceStore for PgStore { &self, workspace_id: &VfsWorkspaceId, ) -> Result { - let row = sqlx::query(&format!( + let row = sqlx::query(sqlx::AssertSqlSafe(format!( r#" SELECT {WORKSPACE_COLUMNS} FROM vfs_workspaces WHERE universe_id = $1 AND workspace_id = $2 "# - )) + ))) .bind(self.config.universe_id) .bind(workspace_id.as_str()) .fetch_optional(&self.pool) @@ -168,14 +169,14 @@ impl VfsWorkspaceStore for PgStore { } async fn list_workspaces(&self) -> Result, VfsCatalogError> { - let rows = sqlx::query(&format!( + let rows = sqlx::query(sqlx::AssertSqlSafe(format!( r#" SELECT {WORKSPACE_COLUMNS} FROM vfs_workspaces WHERE universe_id = $1 ORDER BY updated_at_ms DESC, workspace_id "# - )) + ))) .bind(self.config.universe_id) .fetch_all(&self.pool) .await @@ -193,14 +194,14 @@ impl VfsWorkspaceStore for PgStore { .begin() .await .map_err(|error| catalog_sql_error("begin vfs workspace transaction", error))?; - let row = sqlx::query(&format!( + let row = sqlx::query(sqlx::AssertSqlSafe(format!( r#" SELECT {WORKSPACE_COLUMNS} FROM vfs_workspaces WHERE universe_id = $1 AND workspace_id = $2 FOR UPDATE "# - )) + ))) .bind(self.config.universe_id) .bind(request.workspace_id.as_str()) .fetch_optional(&mut *tx) @@ -233,7 +234,7 @@ impl VfsWorkspaceStore for PgStore { current.workspace_id ), })?; - let row = sqlx::query(&format!( + let row = sqlx::query(sqlx::AssertSqlSafe(format!( r#" UPDATE vfs_workspaces SET @@ -246,7 +247,7 @@ impl VfsWorkspaceStore for PgStore { WHERE universe_id = $1 AND workspace_id = $2 RETURNING {WORKSPACE_COLUMNS} "# - )) + ))) .bind(self.config.universe_id) .bind(current.workspace_id.as_str()) .bind(request.display_name.as_deref()) @@ -271,13 +272,13 @@ impl VfsWorkspaceStore for PgStore { self.ensure_universe() .await .map_err(|error| catalog_store_error("ensure universe", error))?; - let row = sqlx::query(&format!( + let row = sqlx::query(sqlx::AssertSqlSafe(format!( r#" DELETE FROM vfs_workspaces WHERE universe_id = $1 AND workspace_id = $2 RETURNING {WORKSPACE_COLUMNS} "# - )) + ))) .bind(self.config.universe_id) .bind(workspace_id.as_str()) .fetch_optional(&self.pool) diff --git a/crates/store-pg/tests/api_keys_live.rs b/crates/store-pg/tests/api_keys_live.rs index 2785e95de..15aa0a646 100644 --- a/crates/store-pg/tests/api_keys_live.rs +++ b/crates/store-pg/tests/api_keys_live.rs @@ -22,7 +22,9 @@ async fn keys_persist_their_scope_groups_and_actor_flag() { .expect("connect to live Postgres"); let schema = format!("lightspeed_api_keys_test_{}", Uuid::new_v4().simple()); admin - .execute(format!("CREATE SCHEMA \"{schema}\"").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "CREATE SCHEMA \"{schema}\"" + )))) .await .expect("create isolated schema"); let pool = PgPoolOptions::new() @@ -37,7 +39,9 @@ async fn keys_persist_their_scope_groups_and_actor_flag() { let outcome = AssertUnwindSafe(exercise(&pool)).catch_unwind().await; pool.close().await; admin - .execute(format!("DROP SCHEMA \"{schema}\" CASCADE").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "DROP SCHEMA \"{schema}\" CASCADE" + )))) .await .expect("drop isolated schema"); admin.close().await; diff --git a/crates/store-pg/tests/audience_live.rs b/crates/store-pg/tests/audience_live.rs index 77c31fa7d..ec470e198 100644 --- a/crates/store-pg/tests/audience_live.rs +++ b/crates/store-pg/tests/audience_live.rs @@ -2,13 +2,13 @@ use std::{panic::AssertUnwindSafe, str::FromStr}; use api::{Attribution, ResourceRef, Visibility}; -use engine::StoredEvent; -use engine::storage::{ +use futures_util::FutureExt as _; +use harness::StoredEvent; +use harness::storage::{ AppendSessionEvents, CreateSession, ListSessions, SessionActivity, SessionOrigin, SessionOriginKind, SessionStore as _, UncommittedStoredEvent, }; -use engine::{SessionId, SubagentLimits}; -use futures_util::FutureExt as _; +use harness::{SessionId, SubagentLimits}; use sqlx::{ Executor as _, postgres::{PgConnectOptions, PgPoolOptions}, @@ -28,7 +28,9 @@ async fn sessions_record_their_creator_and_children_follow_their_root() { .unwrap(); let schema = format!("lightspeed_audience_test_{}", Uuid::new_v4().simple()); admin - .execute(format!("CREATE SCHEMA \"{schema}\"").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "CREATE SCHEMA \"{schema}\"" + )))) .await .unwrap(); let options = PgConnectOptions::from_str(&url) @@ -42,7 +44,9 @@ async fn sessions_record_their_creator_and_children_follow_their_root() { let outcome = AssertUnwindSafe(exercise(&pool)).catch_unwind().await; pool.close().await; admin - .execute(format!("DROP SCHEMA \"{schema}\" CASCADE").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "DROP SCHEMA \"{schema}\" CASCADE" + )))) .await .unwrap(); admin.close().await; diff --git a/crates/store-pg/tests/bots_pg.rs b/crates/store-pg/tests/bots_pg.rs index 0d45c2826..38742047d 100644 --- a/crates/store-pg/tests/bots_pg.rs +++ b/crates/store-pg/tests/bots_pg.rs @@ -17,7 +17,7 @@ use channels::{ ChannelAccountStore, ChannelError, ChannelPairingFilter, ChannelPairingRecord, ChannelPairingStore, }; -use engine::{BlobRef, storage::BlobStore}; +use harness::{BlobRef, storage::BlobStore}; use sqlx::postgres::PgPoolOptions; use store_pg::{PgStore, PgStoreConfig}; use uuid::Uuid; diff --git a/crates/store-pg/tests/migrations_live.rs b/crates/store-pg/tests/migrations_live.rs index 4d05b5e37..e382666b2 100644 --- a/crates/store-pg/tests/migrations_live.rs +++ b/crates/store-pg/tests/migrations_live.rs @@ -19,7 +19,9 @@ async fn embedded_migrations_are_locked_idempotent_and_checksum_guarded() { .expect("connect to live Postgres"); let schema = format!("lightspeed_migration_test_{}", Uuid::new_v4().simple()); admin - .execute(format!(r#"CREATE SCHEMA "{schema}""#).as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + r#"CREATE SCHEMA "{schema}""# + )))) .await .expect("create isolated migration schema"); @@ -35,7 +37,9 @@ async fn embedded_migrations_are_locked_idempotent_and_checksum_guarded() { let result = exercise_migrator(&pool).await; pool.close().await; admin - .execute(format!(r#"DROP SCHEMA "{schema}" CASCADE"#).as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + r#"DROP SCHEMA "{schema}" CASCADE"# + )))) .await .expect("drop isolated migration schema"); result.unwrap_or_else(|message| panic!("migration acceptance failed: {message}")); diff --git a/crates/store-pg/tests/model_defaults_live.rs b/crates/store-pg/tests/model_defaults_live.rs index eddc318b4..249dbaa2d 100644 --- a/crates/store-pg/tests/model_defaults_live.rs +++ b/crates/store-pg/tests/model_defaults_live.rs @@ -19,7 +19,9 @@ async fn universe_defaults_are_revision_safe_and_isolated() { .expect("connect to live Postgres"); let schema = format!("lightspeed_model_defaults_test_{}", Uuid::new_v4().simple()); admin - .execute(format!("CREATE SCHEMA \"{schema}\"").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "CREATE SCHEMA \"{schema}\"" + )))) .await .expect("create isolated schema"); let pool = PgPoolOptions::new() @@ -34,7 +36,9 @@ async fn universe_defaults_are_revision_safe_and_isolated() { let outcome = AssertUnwindSafe(exercise(&pool)).catch_unwind().await; pool.close().await; admin - .execute(format!("DROP SCHEMA \"{schema}\" CASCADE").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "DROP SCHEMA \"{schema}\" CASCADE" + )))) .await .expect("drop isolated schema"); admin.close().await; diff --git a/crates/store-pg/tests/session_lifecycle_live.rs b/crates/store-pg/tests/session_lifecycle_live.rs index db1f7c929..aa84a5b40 100644 --- a/crates/store-pg/tests/session_lifecycle_live.rs +++ b/crates/store-pg/tests/session_lifecycle_live.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ CORE_AGENT_LIFECYCLE_CLOSED_EVENT_KIND, CORE_AGENT_LIFECYCLE_OPENED_EVENT_KIND, CoreAgentCodec, CoreAgentEvent, CoreAgentJoins, StoredEvent, UncommittedCoreAgentEvent, WorkflowEndpointRef, WorkflowToolConfigEvent, diff --git a/crates/store-pg/tests/store_pg_live.rs b/crates/store-pg/tests/store_pg_live.rs index 42945e7f1..4b01d250d 100644 --- a/crates/store-pg/tests/store_pg_live.rs +++ b/crates/store-pg/tests/store_pg_live.rs @@ -7,7 +7,16 @@ use auth::{ OAuthClientStore, PutSecretRecord, SECRET_KIND_STATIC_BEARER, SecretId, SecretStore, SecretValue, TokenEndpointAuthMethod, state_hash, }; -use engine::{ +use environment_protocol::shared::{EnvironmentTransport, ProviderTargetId}; +use environments::{ + BeginCloseEnvironment, CreateEnvironment, EnvironmentConnectionSpec, EnvironmentId, + EnvironmentIncarnationId, EnvironmentProviderBindingId, EnvironmentProviderBindingStatus, + EnvironmentProviderBindingStore, EnvironmentProviderId, EnvironmentProviderStore, + EnvironmentProvisionRequestId, EnvironmentStatus, EnvironmentStore, EnvironmentTemplateId, + ListEnvironmentProviders, ListEnvironments, ObserveProvisionedEnvironment, + PutEnvironmentProvider, PutEnvironmentProviderBinding, +}; +use harness::{ BlobRef, CORE_AGENT_LIFECYCLE_CLOSED_EVENT_KIND, session::{ EventSeq, SessionId, SessionPosition, StoredEvent, StoredJoins, UncommittedStoredEvent, @@ -16,18 +25,10 @@ use engine::{ AdvanceSessionCheckpoint, AppendSessionEvents, BlobEdge, BlobGraphStore, BlobStore, CreateClonedSession, CreateForkedSession, CreateSession, DeleteClosedSessions, ListSessions, ReadSessionEventRange, ReadSessionEvents, SessionCheckpoint, SessionOrigin, - SessionOriginKind, SessionStore, SessionStoreError, engine_blob_refs, ensure_engine_blobs, + SessionOriginKind, SessionStore, SessionStoreError, ensure_harness_blobs, + harness_blob_refs, }, }; -use environment_protocol::shared::{EnvironmentTransport, ProviderTargetId}; -use environments::{ - BeginCloseEnvironment, CreateEnvironment, EnvironmentConnectionSpec, EnvironmentId, - EnvironmentIncarnationId, EnvironmentProviderBindingId, EnvironmentProviderBindingStatus, - EnvironmentProviderBindingStore, EnvironmentProviderId, EnvironmentProviderStore, - EnvironmentProvisionRequestId, EnvironmentStatus, EnvironmentStore, EnvironmentTemplateId, - ListEnvironmentProviders, ListEnvironments, ObserveProvisionedEnvironment, - PutEnvironmentProvider, PutEnvironmentProviderBinding, -}; use mcp::{ ListMcpServers, McpApprovalPolicy, McpRegistryError, McpRegistryStore, McpServerAuthPolicy, McpServerId, McpServerStatus, PutMcpServerRecord, RemoteMcpTransport, @@ -228,7 +229,7 @@ async fn pg_live_session_ranges_are_fenced_and_checkpoint_pointers_only_advance( #[tokio::test(flavor = "current_thread")] #[ignore = "requires ./dev.sh infra or compatible Postgres + MinIO env"] async fn pg_live_session_list_pages_newest_first_and_rename_persists() { - use engine::storage::{ListSessions, SessionListCursor}; + use harness::storage::{ListSessions, SessionListCursor}; let store = live_store("session-list", 64).await; let other = live_store("session-list-other", 64).await; @@ -325,7 +326,7 @@ async fn pg_live_session_list_pages_newest_first_and_rename_persists() { store .set_session_display_name(&SessionId::new("missing"), None) .await, - Err(engine::storage::SessionStoreError::SessionNotFound { .. }) + Err(harness::storage::SessionStoreError::SessionNotFound { .. }) )); } @@ -407,7 +408,7 @@ async fn pg_live_clone_copies_resources_and_links_sessions() { .expect("count workspaces"); assert_eq!(workspace_count, 1); // Sub-agent lineage: the child row is the root-scoped reservation. - let limits = engine::SubagentLimits { + let limits = harness::SubagentLimits { max_depth: 1, max_descendants: 2, max_concurrent: 1, @@ -476,7 +477,7 @@ async fn pg_live_clone_copies_resources_and_links_sessions() { assert!(matches!( refused, SessionStoreError::OriginLimitExceeded { - limit: engine::storage::SessionOriginLimit::MaxConcurrent, + limit: harness::storage::SessionOriginLimit::MaxConcurrent, .. } )); @@ -495,7 +496,7 @@ async fn pg_live_clone_copies_resources_and_links_sessions() { assert!(matches!( too_deep, SessionStoreError::OriginLimitExceeded { - limit: engine::storage::SessionOriginLimit::MaxDepth, + limit: harness::storage::SessionOriginLimit::MaxDepth, .. } )); @@ -801,7 +802,7 @@ async fn pg_live_blobs_use_inline_and_object_storage() { #[tokio::test(flavor = "current_thread")] #[ignore = "requires ./dev.sh infra or compatible Postgres + MinIO env"] async fn pg_live_streamed_blobs_verify_ranges_reuse_and_reject_corruption() { - use engine::storage::{BlobSource, BlobStoreError}; + use harness::storage::{BlobSource, BlobStoreError}; struct Source { bytes: Vec, @@ -1124,8 +1125,8 @@ async fn pg_live_put_of_existing_content_touches_without_rewriting() { async fn pg_live_sweep_frees_only_unreachable_blobs_after_grace() { let store = live_store("sweep", 8).await; let universe_id = store.config().universe_id; - let pinned = engine_blob_refs(); - ensure_engine_blobs(&store).await.expect("engine blobs"); + let pinned = harness_blob_refs(); + ensure_harness_blobs(&store).await.expect("engine blobs"); // Holders of every kind. Payloads exceed the 8-byte inline threshold so // the object phase is exercised too. @@ -1428,7 +1429,7 @@ async fn pg_live_sweep_frees_only_unreachable_blobs_after_grace() { #[ignore = "requires ./dev.sh infra or compatible Postgres + MinIO env"] async fn pg_live_sweep_follows_fork_trees_and_clone_roots() { let store = live_store("sweep-lineage", 8).await; - let pinned = engine_blob_refs(); + let pinned = harness_blob_refs(); let config_blob = store .put_bytes(b"session config blob shared by lineage".to_vec()) .await @@ -2936,7 +2937,7 @@ async fn pg_live_environment_credentials_round_trip() { #[tokio::test(flavor = "current_thread")] #[ignore = "requires ./dev.sh infra or compatible Postgres + MinIO env"] async fn pg_live_session_metadata_filters_by_containment_and_put_replaces() { - use engine::storage::{ListSessions, SessionListPage}; + use harness::storage::{ListSessions, SessionListPage}; use std::collections::BTreeMap; let store = live_store("session-metadata", 64).await; @@ -3081,7 +3082,8 @@ async fn live_store(test_name: &str, inline_threshold_bytes: usize) -> PgStore { fn random_master_key() -> SecretsMasterKey { let mut bytes = [0u8; 32]; - rand::RngCore::fill_bytes(&mut rand::rngs::OsRng, &mut bytes); + rand::TryRng::try_fill_bytes(&mut rand::rngs::SysRng, &mut bytes) + .expect("OS random source unavailable"); SecretsMasterKey::from_bytes(bytes) } @@ -3344,7 +3346,7 @@ async fn pg_live_admission_touch_refreshes_grace_and_rejects_missing_refs() { let missing = BlobRef::from_bytes(b"missing input"); assert!( matches!(store.touch_blob_refs(std::slice::from_ref(&missing)).await, - Err(engine::storage::BlobStoreError::NotFound { blob_ref }) if blob_ref == missing) + Err(harness::storage::BlobStoreError::NotFound { blob_ref }) if blob_ref == missing) ); } diff --git a/crates/store-pg/tests/universe_slugs_live.rs b/crates/store-pg/tests/universe_slugs_live.rs index 92d29f82e..838c987f9 100644 --- a/crates/store-pg/tests/universe_slugs_live.rs +++ b/crates/store-pg/tests/universe_slugs_live.rs @@ -19,7 +19,9 @@ async fn host_provisioning_fills_missing_slugs_without_renaming() { .expect("connect to live Postgres"); let schema = format!("lightspeed_universe_slug_test_{}", Uuid::new_v4().simple()); admin - .execute(format!("CREATE SCHEMA \"{schema}\"").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "CREATE SCHEMA \"{schema}\"" + )))) .await .expect("create isolated schema"); let pool = PgPoolOptions::new() @@ -34,7 +36,9 @@ async fn host_provisioning_fills_missing_slugs_without_renaming() { let outcome = AssertUnwindSafe(exercise(&pool)).catch_unwind().await; pool.close().await; admin - .execute(format!("DROP SCHEMA \"{schema}\" CASCADE").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "DROP SCHEMA \"{schema}\" CASCADE" + )))) .await .expect("drop isolated schema"); admin.close().await; diff --git a/crates/temporal-server/Cargo.toml b/crates/temporal-runtime/Cargo.toml similarity index 75% rename from crates/temporal-server/Cargo.toml rename to crates/temporal-runtime/Cargo.toml index 804819705..90366b61f 100644 --- a/crates/temporal-server/Cargo.toml +++ b/crates/temporal-runtime/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "temporal-server" +name = "temporal-runtime" version.workspace = true edition = "2024" [dependencies] temporal-workflow = { path = "../temporal-workflow" } -jsonschema = { version = "0.33", default-features = false } +jsonschema = { version = "0.58", default-features = false } ipnet = "2" api = { path = "../api" } api-projection = { path = "../api-projection" } -engine = { path = "../engine" } +harness = { path = "../harness" } environments = { path = "../environments" } environment-client = { path = "../environment-client" } environment-protocol = { path = "../environment-protocol" } @@ -19,12 +19,12 @@ async-trait = "0.1" auth = { path = "../auth" } bots = { path = "../bots" } channels = { path = "../channels" } -axum = { version = "0.7", features = ["ws"] } -base64 = "0.22" +axum = { version = "0.8", features = ["ws"] } +base64 = "0.23" chrono = { version = "0.4", default-features = false, features = ["std", "clock"] } -ed25519-dalek = "2" -rand = "0.8" -sha2 = "0.10" +ed25519-dalek = "3" +rand = "0.10" +sha2 = "0.11" clap = { version = "4", features = ["derive", "env"] } dotenvy = "0.15" futures-util = "0.3" @@ -33,29 +33,30 @@ http = "1" llm-clients = { path = "../llm-clients" } llm-runtime = { path = "../llm-runtime" } mcp = { path = "../mcp" } -object_store = "0.13.1" -sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio", "postgres", "uuid"] } +object_store = "0.14" +sqlx = { version = "0.9", default-features = false, features = ["runtime-tokio", "postgres", "uuid"] } profiles = { path = "../profiles" } release-info = { path = "../release-info" } reqwest = { version = "0.13", default-features = false, features = ["json", "rustls", "stream"] } rmcp = { version = "3.1.4", default-features = false, features = ["client", "transport-streamable-http-client"] } serde = { version = "1", features = ["derive"] } serde_json = "1" +# rmcp exposes sse-stream 0.2 types in its transport trait. sse-stream = "0.2.5" store-pg = { path = "../store-pg" } -temporalio-common = "0.4.0" -temporalio-client = "0.4.0" -temporalio-macros = "0.4.0" -temporalio-sdk = "0.4.0" -temporalio-sdk-core = "0.4.0" +temporalio-common = "1" +temporalio-client = "1" +temporalio-macros = "1" +temporalio-sdk = "1" +temporalio-workflow = "1" tempfile = "3" tokio = { version = "1", features = ["fs", "macros", "net", "process", "rt-multi-thread", "signal", "time"] } tonic = "0.14" -tokio-tungstenite = { version = "0.26", default-features = false, features = ["connect", "rustls-tls-webpki-roots"] } +tokio-tungstenite = { version = "0.30", default-features = false, features = ["connect", "rustls-tls-webpki-roots"] } tools = { path = "../tools" } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } -thiserror = "1" +thiserror = "2" uuid = { version = "1", features = ["v4"] } url = "2" @@ -67,5 +68,5 @@ futures-util = "0.3" tempfile = "3" [[bin]] -name = "lightspeed-server" +name = "lightspeed-runtime" path = "src/main.rs" diff --git a/crates/temporal-server/build.rs b/crates/temporal-runtime/build.rs similarity index 86% rename from crates/temporal-server/build.rs rename to crates/temporal-runtime/build.rs index c5863beb8..67bceeaee 100644 --- a/crates/temporal-server/build.rs +++ b/crates/temporal-runtime/build.rs @@ -3,7 +3,7 @@ fn main() { let profile = std::env::var("PROFILE").unwrap_or_default(); if target_os == "macos" && profile == "debug" { // Apple's compact-unwind table is limited to 16 MiB. The debug - // Temporal server and live-test binaries exceed that limit, so ask the + // Temporal runtime and live-test binaries exceed that limit, so ask the // linker to retain the equivalent DWARF unwind data directly instead // of attempting (and warning about) a compact table it cannot encode. println!("cargo:rustc-link-arg=-Wl,-no_compact_unwind"); diff --git a/crates/temporal-server/src/bots/admission.rs b/crates/temporal-runtime/src/bots/admission.rs similarity index 93% rename from crates/temporal-server/src/bots/admission.rs rename to crates/temporal-runtime/src/bots/admission.rs index 3e16e1587..d9a18b136 100644 --- a/crates/temporal-server/src/bots/admission.rs +++ b/crates/temporal-runtime/src/bots/admission.rs @@ -22,19 +22,17 @@ use bots::{ render::{DEFAULT_PROMPT_BUDGET, render_event_prompt}, validate::{effective_coalesce, effective_route}, }; -use engine::storage::BlobStore; +use harness::storage::BlobStore; use serde_json::Value; use temporal_workflow::bots::BotControllerArgs; -use temporalio_client::{UntypedWorkflow, WorkflowStartOptions, WorkflowStartSignal}; +use temporalio_client::{UntypedSignal, UntypedWorkflow, WorkflowStartOptions}; use temporalio_common::data_converters::{PayloadConverter, RawValue}; -use temporalio_common::protos::{ - coresdk::AsJsonPayloadExt as _, temporal::api::common::v1::Payloads, -}; +use temporalio_common::protos::coresdk::AsJsonPayloadExt as _; use super::now_ms; use crate::gateway::GatewayAgentApi; -/// Workflow type name of the bot controller (`#[workflow(name = …)]`). +/// Workflow type name of the bot controller (`#[run(name = …)]`). pub const BOT_CONTROLLER_WORKFLOW_TYPE: &str = "BotControllerWorkflow"; /// What an admission stores for one event. @@ -217,16 +215,15 @@ impl GatewayAgentApi { let config = BotControllerConfig::from_record(self.universe_id(), bot); let workflow_id = bot_controller_workflow_id(self.universe_id(), &bot.bot_id); let payload = event.as_json_payload()?; - let options = WorkflowStartOptions::new(self.bot_task_queue().to_owned(), workflow_id) - .start_signal( - WorkflowStartSignal::new(bots::BOT_EVENT_SIGNAL) - .input(Payloads { - payloads: vec![payload], - }) - .build(), - ) - .build(); - self.start_bot_controller(config, options).await + let options = + WorkflowStartOptions::new(self.bot_task_queue().to_owned(), workflow_id).build(); + self.start_bot_controller( + config, + options, + bots::BOT_EVENT_SIGNAL, + RawValue::new(vec![payload]), + ) + .await } /// Start (or signal-with-start) the controller workflow by type name so @@ -235,6 +232,8 @@ impl GatewayAgentApi { &self, config: BotControllerConfig, options: WorkflowStartOptions, + signal_name: &str, + signal_input: RawValue, ) -> anyhow::Result<()> { let input = RawValue::from_value( &BotControllerArgs { @@ -244,9 +243,11 @@ impl GatewayAgentApi { &PayloadConverter::default(), ); self.temporal_client() - .start_workflow( + .signal_with_start_workflow( UntypedWorkflow::new(BOT_CONTROLLER_WORKFLOW_TYPE), input, + UntypedSignal::new(signal_name), + signal_input, options, ) .await @@ -261,16 +262,15 @@ impl GatewayAgentApi { let config = BotControllerConfig::from_record(self.universe_id(), bot); let workflow_id = bot_controller_workflow_id(self.universe_id(), &bot.bot_id); let payload = config.as_json_payload()?; - let options = WorkflowStartOptions::new(self.bot_task_queue().to_owned(), workflow_id) - .start_signal( - WorkflowStartSignal::new(bots::BOT_CONFIG_SIGNAL) - .input(Payloads { - payloads: vec![payload], - }) - .build(), - ) - .build(); - self.start_bot_controller(config, options).await + let options = + WorkflowStartOptions::new(self.bot_task_queue().to_owned(), workflow_id).build(); + self.start_bot_controller( + config, + options, + bots::BOT_CONFIG_SIGNAL, + RawValue::new(vec![payload]), + ) + .await } /// The trigger pipeline: filter, route, idle-close policy, coalesce, delivery diff --git a/crates/temporal-server/src/bots/fires.rs b/crates/temporal-runtime/src/bots/fires.rs similarity index 99% rename from crates/temporal-server/src/bots/fires.rs rename to crates/temporal-runtime/src/bots/fires.rs index 437b9afb2..48d5aa120 100644 --- a/crates/temporal-server/src/bots/fires.rs +++ b/crates/temporal-runtime/src/bots/fires.rs @@ -154,7 +154,7 @@ async fn drop_schedule(api: &GatewayAgentApi, bot: &BotRecord, trigger: &BotTrig .await { tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", bot_id = %bot.bot_id, trigger_id = %trigger.trigger_id, %error, @@ -452,7 +452,7 @@ pub async fn poll_trigger( .await .map_err(retryable)?; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", bot_id = %bot.bot_id, trigger_id = %trigger.trigger_id, items = items.len(), @@ -508,7 +508,7 @@ async fn note_poll_failure( let now = now_ms(); let (state, disable) = poll_failure_state(trigger.cursor.as_ref(), now); tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", bot_id = %bot.bot_id, trigger_id = %trigger.trigger_id, consecutive_failures = state.consecutive_failures, diff --git a/crates/temporal-server/src/bots/hooks.rs b/crates/temporal-runtime/src/bots/hooks.rs similarity index 100% rename from crates/temporal-server/src/bots/hooks.rs rename to crates/temporal-runtime/src/bots/hooks.rs diff --git a/crates/temporal-server/src/bots/mod.rs b/crates/temporal-runtime/src/bots/mod.rs similarity index 100% rename from crates/temporal-server/src/bots/mod.rs rename to crates/temporal-runtime/src/bots/mod.rs diff --git a/crates/temporal-server/src/bots/receipts.rs b/crates/temporal-runtime/src/bots/receipts.rs similarity index 99% rename from crates/temporal-server/src/bots/receipts.rs rename to crates/temporal-runtime/src/bots/receipts.rs index b9b35d245..c36750ec9 100644 --- a/crates/temporal-server/src/bots/receipts.rs +++ b/crates/temporal-runtime/src/bots/receipts.rs @@ -182,7 +182,7 @@ pub async fn send_delivery_receipts( // there): the delivery never waits on it. Err(error) => { tracing::debug!( - target: "temporal_server", + target: "temporal_runtime", bot_id = %request.bot_id, workflow_id = %target.workflow_id, %error, @@ -272,7 +272,7 @@ pub async fn send_bot_receipts( } /// Put the `bot:directory` catalog into a session before a delivery: the -/// bots whose inbox accepts this one. A same-content append is an engine +/// bots whose inbox accepts this one. A same-content append is an harness /// no-op, so calling it before every delivery is cheap and keeps the prefix /// cache intact. pub async fn publish_directory( diff --git a/crates/temporal-server/src/bots/schedules.rs b/crates/temporal-runtime/src/bots/schedules.rs similarity index 99% rename from crates/temporal-server/src/bots/schedules.rs rename to crates/temporal-runtime/src/bots/schedules.rs index da3530a6d..314f744a9 100644 --- a/crates/temporal-server/src/bots/schedules.rs +++ b/crates/temporal-runtime/src/bots/schedules.rs @@ -266,7 +266,7 @@ impl GatewayAgentApi { let handle = self .temporal_client() .get_schedule_handle(schedule_id.clone()); - match handle.delete().await { + match handle.delete(Default::default()).await { Ok(()) => Ok(()), Err(ScheduleError::Rpc(status)) if status.code() == tonic::Code::NotFound => Ok(()), Err(error) => Err(anyhow::anyhow!("delete schedule {schedule_id}: {error}")), diff --git a/crates/temporal-server/src/bots/sessions.rs b/crates/temporal-runtime/src/bots/sessions.rs similarity index 99% rename from crates/temporal-server/src/bots/sessions.rs rename to crates/temporal-runtime/src/bots/sessions.rs index b8f62199a..f2b30f802 100644 --- a/crates/temporal-server/src/bots/sessions.rs +++ b/crates/temporal-runtime/src/bots/sessions.rs @@ -29,7 +29,7 @@ use bots::{ }, views::{delivery_input_items, steer_input_items}, }; -use engine::{ +use harness::{ BlobRef, storage::{BlobStore, BlobStoreError}, }; @@ -95,7 +95,7 @@ fn is_declaration_mismatch(error: &AgentApiError) -> bool { .contains("managed-session controller, receiver, or tool declaration conflicts")) } -/// The engine refused the profile's config for this session in a way no +/// The harness refused the profile's config for this session in a way no /// retry fixes: an invalid document, or a command rejection of the /// provider-compatibility kind (the rejection kind leads the message). fn is_profile_unapplicable(error: &AgentApiError) -> bool { @@ -497,7 +497,7 @@ pub async fn ensure_session( // A profile that moved to another provider or kind is valid for a fresh session // but not for this one: report that as unapplicable so the // controller rotates, rather than retrying into a degraded bot. - // Checked structurally first; the engine's rejection is the backstop. + // Checked structurally first; the harness's rejection is the backstop. if let Some(proposed) = proposed_provider_route(&resolved) { let current = read_session_view(api, &request.session_id) .await diff --git a/crates/temporal-server/src/bots/tools.rs b/crates/temporal-runtime/src/bots/tools.rs similarity index 99% rename from crates/temporal-server/src/bots/tools.rs rename to crates/temporal-runtime/src/bots/tools.rs index 2d56f7ea8..76e13e961 100644 --- a/crates/temporal-server/src/bots/tools.rs +++ b/crates/temporal-runtime/src/bots/tools.rs @@ -30,7 +30,7 @@ use bots::{ resolve_inbox, trigger_tool_view, }, }; -use engine::{ +use harness::{ BlobRef, storage::{BlobStore, BlobStoreError}, }; @@ -190,7 +190,7 @@ pub async fn execute_tool( }), Err(ToolError::Failed(failure)) => { tracing::info!( - target: "temporal_server", + target: "temporal_runtime", bot_id = %request.bot_id, tool_id = %request.tool_id, invocation_id = %request.invocation_id, diff --git a/crates/temporal-server/src/channels/activities.rs b/crates/temporal-runtime/src/channels/activities.rs similarity index 99% rename from crates/temporal-server/src/channels/activities.rs rename to crates/temporal-runtime/src/channels/activities.rs index d7dd68544..288439b83 100644 --- a/crates/temporal-server/src/channels/activities.rs +++ b/crates/temporal-runtime/src/channels/activities.rs @@ -28,7 +28,7 @@ use channels::{ state::ChatHandle, tools::{CHANNEL_TOOL_DESCRIPTIONS, CHANNEL_TOOL_SCHEMAS, channel_workflow_tool_declarations}, }; -use engine::{ +use harness::{ BlobRef, storage::{BlobStore, BlobStoreError}, }; @@ -186,7 +186,7 @@ pub async fn chat_tool_declarations( .chain(description_refs.values()) .map(|value| parse_blob_ref(value)) .collect::, _>>()?; - engine::storage::record_contains_edges(Some(api.store().as_ref()), &tools_ref, children) + harness::storage::record_contains_edges(Some(api.store().as_ref()), &tools_ref, children) .await .map_err(|error| blob_error("record channel declaration edges", error))?; Ok(ChatToolDeclarationsResult { @@ -645,7 +645,7 @@ pub async fn emit_chat_event( let tools_ref = parse_blob_ref(&request.tools_ref)?; match store.touch_blob_refs(&[tools_ref]).await { Ok(()) => {} - Err(engine::storage::BlobStoreError::NotFound { .. }) => { + Err(harness::storage::BlobStoreError::NotFound { .. }) => { request.tools_ref = chat_tool_declarations( api, ChatToolDeclarationsRequest { @@ -916,7 +916,7 @@ mod tests { BotDocument, BotId, BotTriggerDocument, BotTriggerId, ChannelMediaKind, ChatAccess, ChatActivation, ProfileId, }; - use engine::WorkflowEndpointRef; + use harness::WorkflowEndpointRef; use uuid::Uuid; fn conversation(thread_id: Option<&str>) -> ConversationRef { diff --git a/crates/temporal-server/src/channels/control_plane.rs b/crates/temporal-runtime/src/channels/control_plane.rs similarity index 97% rename from crates/temporal-server/src/channels/control_plane.rs rename to crates/temporal-runtime/src/channels/control_plane.rs index 1a48695c4..c3bfb743e 100644 --- a/crates/temporal-server/src/channels/control_plane.rs +++ b/crates/temporal-runtime/src/channels/control_plane.rs @@ -20,12 +20,12 @@ use channels::{ }; use temporal_workflow::channels::{CHAT_INBOUND_SIGNAL, CHAT_STATE_QUERY, ChannelConversationArgs}; use temporalio_client::{ - UntypedQuery, UntypedWorkflow, WorkflowQueryOptions, WorkflowStartOptions, WorkflowStartSignal, + UntypedQuery, UntypedSignal, UntypedWorkflow, WorkflowQueryOptions, WorkflowStartOptions, errors::WorkflowQueryError, }; use temporalio_common::{ data_converters::{PayloadConverter, RawValue}, - protos::{coresdk::AsJsonPayloadExt as _, temporal::api::common::v1::Payloads}, + protos::coresdk::AsJsonPayloadExt as _, }; use super::map_channel_error; @@ -337,23 +337,18 @@ impl GatewayAgentApi { let payload = admitted .as_json_payload() .map_err(|error| AgentApiError::internal(format!("encode inbound: {error}")))?; - let options = WorkflowStartOptions::new(self.channel_task_queue.clone(), workflow_id) - .start_signal( - WorkflowStartSignal::new(CHAT_INBOUND_SIGNAL) - .input(Payloads { - payloads: vec![payload], - }) - .build(), - ) - .build(); + let options = + WorkflowStartOptions::new(self.channel_task_queue.clone(), workflow_id).build(); let input = RawValue::from_value( &ChannelConversationArgs { start, carry: None }, &PayloadConverter::default(), ); self.temporal_client() - .start_workflow( + .signal_with_start_workflow( UntypedWorkflow::new(CHANNEL_CONVERSATION_WORKFLOW_TYPE), input, + UntypedSignal::new(CHAT_INBOUND_SIGNAL), + RawValue::new(vec![payload]), options, ) .await diff --git a/crates/temporal-server/src/channels/mod.rs b/crates/temporal-runtime/src/channels/mod.rs similarity index 100% rename from crates/temporal-server/src/channels/mod.rs rename to crates/temporal-runtime/src/channels/mod.rs diff --git a/crates/temporal-server/src/checkpoint.rs b/crates/temporal-runtime/src/checkpoint.rs similarity index 96% rename from crates/temporal-server/src/checkpoint.rs rename to crates/temporal-runtime/src/checkpoint.rs index 1ff8f5633..4da5630d3 100644 --- a/crates/temporal-server/src/checkpoint.rs +++ b/crates/temporal-runtime/src/checkpoint.rs @@ -2,7 +2,7 @@ //! activities. Checkpoints are disposable accelerators; every rejected or //! unreadable pointer falls back to the authoritative event log. -use engine::{ +use harness::{ EventSeq, SessionId, storage::{ AdvanceSessionCheckpoint, BlobStore, ReadSessionEventRange, SessionCheckpoint, @@ -26,8 +26,8 @@ const CHECKPOINT_READ_PAGE: usize = 512; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] struct CheckpointReduction { - core_state: engine::CoreAgentState, - run_submissions: std::collections::BTreeMap>, + core_state: harness::CoreAgentState, + run_submissions: std::collections::BTreeMap>, } impl From for ReducedSession { @@ -199,7 +199,7 @@ async fn read_entries_through( session_id: &SessionId, mut after: EventSeq, through: EventSeq, -) -> Result, anyhow::Error> { +) -> Result, anyhow::Error> { let mut entries = Vec::new(); while after < through { let page = sessions @@ -254,7 +254,7 @@ pub(crate) fn checkpoint_due(loaded: &LoadedReduction) -> bool { /// the general tail thresholds fire. Sequence-span length matches the range a /// run-detail read must fetch, including the accepted and terminal entries. pub(crate) fn terminal_runs_checkpoint_due( - state: &engine::CoreAgentState, + state: &harness::CoreAgentState, checkpoint_through_seq: Option, newly_terminal_seqs: &[EventSeq], ) -> bool { @@ -331,7 +331,7 @@ pub(crate) async fn write_checkpoint( Ok(advanced) } -fn encoded_entry_bytes(entries: &[engine::storage::StoredSessionEntry]) -> u64 { +fn encoded_entry_bytes(entries: &[harness::storage::StoredSessionEntry]) -> u64 { entries .iter() .map(|entry| serde_json::to_vec(entry).map_or(0, |bytes| bytes.len() as u64)) @@ -356,7 +356,7 @@ fn checkpoint_rejection_reason(error: &anyhow::Error) -> &'static str { #[cfg(test)] mod tests { use super::*; - use engine::{ + use harness::{ CoreAgentCodec, CoreAgentEvent, CoreAgentJoins, CoreAgentLifecycleEvent, ModelSelection, ProviderApiKind, UncommittedCoreAgentEvent, storage::{ @@ -368,7 +368,7 @@ mod tests { fn stored_event( event: CoreAgentEvent, observed_at_ms: u64, - ) -> engine::storage::UncommittedStoredEvent { + ) -> harness::storage::UncommittedStoredEvent { CoreAgentCodec .encode_uncommitted(&UncommittedCoreAgentEvent { observed_at_ms, @@ -470,13 +470,13 @@ mod tests { assert_eq!(checkpointed.reduced.run_submissions, full.run_submissions); } - fn terminal_run(id: u64, first_seq: u64, terminal_seq: u64) -> engine::RunRecord { - engine::RunRecord { - run_id: engine::RunId::new(id), - status: engine::RunStatus::Completed, + fn terminal_run(id: u64, first_seq: u64, terminal_seq: u64) -> harness::RunRecord { + harness::RunRecord { + run_id: harness::RunId::new(id), + status: harness::RunStatus::Completed, submission_id: None, submission_digest: None, - source: engine::RunSource::Input { input: Vec::new() }, + source: harness::RunSource::Input { input: Vec::new() }, first_seq: EventSeq::new(first_seq), terminal_seq: EventSeq::new(terminal_seq), accepted_at_ms: first_seq, @@ -507,7 +507,7 @@ mod tests { #[test] fn terminal_runs_checkpoint_every_ten_since_the_pointer() { - let mut state = engine::CoreAgentState::default(); + let mut state = harness::CoreAgentState::default(); for id in 1..=9 { state .runs @@ -530,7 +530,7 @@ mod tests { #[test] fn newly_terminal_run_over_one_hundred_events_checkpoints_immediately() { - let mut state = engine::CoreAgentState::default(); + let mut state = harness::CoreAgentState::default(); state.runs.completed.push(terminal_run(1, 1, 100)); assert!(!terminal_runs_checkpoint_due( &state, diff --git a/crates/temporal-server/src/config.rs b/crates/temporal-runtime/src/config.rs similarity index 99% rename from crates/temporal-server/src/config.rs rename to crates/temporal-runtime/src/config.rs index dedebbb4a..597d6e445 100644 --- a/crates/temporal-server/src/config.rs +++ b/crates/temporal-runtime/src/config.rs @@ -353,7 +353,7 @@ async fn verify_runtime_schema(pool: &PgPool, allow_unledgered: bool) -> anyhow: evaluate_schema_verification(store_pg::verify_schema(pool).await, allow_unledgered)? { tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", tables = ?relations, "running with an externally managed, unledgered PostgreSQL schema; Lightspeed cannot verify its compatibility" ); diff --git a/crates/temporal-server/src/credential_injection.rs b/crates/temporal-runtime/src/credential_injection.rs similarity index 100% rename from crates/temporal-server/src/credential_injection.rs rename to crates/temporal-runtime/src/credential_injection.rs diff --git a/crates/temporal-server/src/environments/credentials.rs b/crates/temporal-runtime/src/environments/credentials.rs similarity index 100% rename from crates/temporal-server/src/environments/credentials.rs rename to crates/temporal-runtime/src/environments/credentials.rs diff --git a/crates/temporal-server/src/environments/gateway.rs b/crates/temporal-runtime/src/environments/gateway.rs similarity index 100% rename from crates/temporal-server/src/environments/gateway.rs rename to crates/temporal-runtime/src/environments/gateway.rs diff --git a/crates/temporal-server/src/environments/lifecycle.rs b/crates/temporal-runtime/src/environments/lifecycle.rs similarity index 99% rename from crates/temporal-server/src/environments/lifecycle.rs rename to crates/temporal-runtime/src/environments/lifecycle.rs index b88a7d538..e7f7c8f54 100644 --- a/crates/temporal-server/src/environments/lifecycle.rs +++ b/crates/temporal-runtime/src/environments/lifecycle.rs @@ -686,11 +686,11 @@ impl ReconcileFailureLog { *last == message && now.duration_since(*at) < Self::REPEAT_INTERVAL }); if repeat { - tracing::debug!(target: "temporal_server", %universe_id, error = %message, "environment lifecycle reconcile pass still failing"); + tracing::debug!(target: "temporal_runtime", %universe_id, error = %message, "environment lifecycle reconcile pass still failing"); return; } self.last.insert(universe_id, (message.clone(), now)); - tracing::warn!(target: "temporal_server", %universe_id, error = %message, "environment lifecycle reconcile pass failed (repeats suppressed for 60s)"); + tracing::warn!(target: "temporal_runtime", %universe_id, error = %message, "environment lifecycle reconcile pass failed (repeats suppressed for 60s)"); } /// Record a successful pass so the next failure logs immediately. diff --git a/crates/temporal-server/src/environments/mod.rs b/crates/temporal-runtime/src/environments/mod.rs similarity index 100% rename from crates/temporal-server/src/environments/mod.rs rename to crates/temporal-runtime/src/environments/mod.rs diff --git a/crates/temporal-server/src/environments/power.rs b/crates/temporal-runtime/src/environments/power.rs similarity index 99% rename from crates/temporal-server/src/environments/power.rs rename to crates/temporal-runtime/src/environments/power.rs index 9f2f0c2d8..1932f8816 100644 --- a/crates/temporal-server/src/environments/power.rs +++ b/crates/temporal-runtime/src/environments/power.rs @@ -97,7 +97,7 @@ impl EnvironmentService { .map_err(map_environments_error)?; stats.powered_down += 1; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", environment_id = %environment.environment_id, idle_for_ms = report.idle_for_ms, %desired_power, @@ -120,7 +120,7 @@ impl EnvironmentService { Err(error) => return Err(map_environments_error(error)), } tracing::info!( - target: "temporal_server", + target: "temporal_runtime", environment_id = %environment.environment_id, idle_for_ms = report.idle_for_ms, "idle policy closed environment" diff --git a/crates/temporal-server/src/environments/prompts.rs b/crates/temporal-runtime/src/environments/prompts.rs similarity index 97% rename from crates/temporal-server/src/environments/prompts.rs rename to crates/temporal-runtime/src/environments/prompts.rs index 4fe0285ed..f87168c1c 100644 --- a/crates/temporal-server/src/environments/prompts.rs +++ b/crates/temporal-runtime/src/environments/prompts.rs @@ -1,6 +1,6 @@ //! Idle-boundary environment prompt refresh, independent of VFS instruction ownership. use crate::environments::sources::{Discovery, PhaseTimer}; -use engine::{ +use harness::{ ContextEntryInput, ContextEntryKey, storage::{BlobStore, BlobStoreError}, }; @@ -47,8 +47,8 @@ pub(crate) async fn refresh( #[cfg(test)] mod tests { use super::*; - use engine::storage::{BlobStore, InMemoryBlobStore}; - use engine::{EnvironmentId, EnvironmentsFeature, SessionId}; + use harness::storage::{BlobStore, InMemoryBlobStore}; + use harness::{EnvironmentId, EnvironmentsFeature, SessionId}; use tools::prompts::environment::{ ENVIRONMENT_PROMPT_CONTEXT_KEY, EnvironmentPromptReport, assemble, publication, }; diff --git a/crates/temporal-server/src/environments/provider_controllers.rs b/crates/temporal-runtime/src/environments/provider_controllers.rs similarity index 99% rename from crates/temporal-server/src/environments/provider_controllers.rs rename to crates/temporal-runtime/src/environments/provider_controllers.rs index 896fc5779..dd91f8b39 100644 --- a/crates/temporal-server/src/environments/provider_controllers.rs +++ b/crates/temporal-runtime/src/environments/provider_controllers.rs @@ -99,7 +99,7 @@ impl ProviderControllerConnector for WebSocketProviderControllerConnector { &connection.endpoint, WebSocketConnectOptions { bearer_token: None, - user_agent: Some("lightspeed-temporal-server".to_owned()), + user_agent: Some("lightspeed-temporal-runtime".to_owned()), headers: Vec::new(), }, ) @@ -123,7 +123,7 @@ impl ProviderControllerConnector for WebSocketProviderControllerConnector { let initialized = controller .initialize(&ControllerInitializeParams { protocol_version: CURRENT_PROTOCOL_VERSION, - client_name: "lightspeed-temporal-server".to_owned(), + client_name: "lightspeed-temporal-runtime".to_owned(), }) .await; let initialized = match initialized { diff --git a/crates/temporal-server/src/environments/providers.rs b/crates/temporal-runtime/src/environments/providers.rs similarity index 100% rename from crates/temporal-server/src/environments/providers.rs rename to crates/temporal-runtime/src/environments/providers.rs diff --git a/crates/temporal-server/src/environments/registration.rs b/crates/temporal-runtime/src/environments/registration.rs similarity index 98% rename from crates/temporal-server/src/environments/registration.rs rename to crates/temporal-runtime/src/environments/registration.rs index 132926b06..9317b8276 100644 --- a/crates/temporal-server/src/environments/registration.rs +++ b/crates/temporal-runtime/src/environments/registration.rs @@ -87,7 +87,7 @@ impl EnvironmentService { .await .map_err(map_environments_error)?; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", registration_key_id = %record.registration_key_id, display_name = %record.display_name, identity_mode = record.identity_mode.as_str(), @@ -177,7 +177,7 @@ impl EnvironmentService { } } tracing::info!( - target: "temporal_server", + target: "temporal_runtime", registration_key_id = %record.registration_key_id, closed = closed_environment_ids.len(), "environment registration key revoked" @@ -222,7 +222,7 @@ impl EnvironmentService { None => {} Some(RegisteredSweepAction::MarkOffline) => { tracing::info!( - target: "temporal_server", + target: "temporal_runtime", environment = %environment.environment_id, "registered environment heartbeat is stale; marking offline" ); @@ -241,7 +241,7 @@ impl EnvironmentService { } Some(RegisteredSweepAction::Close) => { tracing::info!( - target: "temporal_server", + target: "temporal_runtime", environment = %environment.environment_id, registration_key_id = %key.registration_key_id, "ephemeral registered environment exceeded its disconnect grace; closing" diff --git a/crates/temporal-server/src/environments/resolver.rs b/crates/temporal-runtime/src/environments/resolver.rs similarity index 98% rename from crates/temporal-server/src/environments/resolver.rs rename to crates/temporal-runtime/src/environments/resolver.rs index 97e42e271..9b9f24a18 100644 --- a/crates/temporal-server/src/environments/resolver.rs +++ b/crates/temporal-runtime/src/environments/resolver.rs @@ -294,11 +294,11 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn environment_discovery_shares_connection_preserves_freshness_and_never_wakes() { - use engine::{ + use futures_util::{SinkExt, StreamExt}; + use harness::{ CoreAgentCommand, storage::{BlobStore, InMemoryBlobStore}, }; - use futures_util::{SinkExt, StreamExt}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use tools::skills::environment::{EnvironmentSkillAvailability, EnvironmentSkillCatalog}; let (resolver, environment_id) = resolver().await; @@ -433,13 +433,13 @@ mod tests { ) }; let blobs = InMemoryBlobStore::new(); - let session_id = engine::SessionId::new(uuid::Uuid::new_v4().to_string()); - let feature = engine::EnvironmentsFeature { + let session_id = harness::SessionId::new(uuid::Uuid::new_v4().to_string()); + let feature = harness::EnvironmentsFeature { skills: Some(Default::default()), - environments: vec![engine::EnvironmentAttachment { + environments: vec![harness::EnvironmentAttachment { environment_id: environment_id.as_str().to_owned(), default: false, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }], ..Default::default() @@ -508,7 +508,7 @@ mod tests { both.prompts = Some(Default::default()); std::fs::create_dir_all(root.join(".agents/prompts")).unwrap(); let prompt_path = root.join(".agents/prompts/instructions.md"); - let prompt_key = engine::ContextEntryKey::new( + let prompt_key = harness::ContextEntryKey::new( tools::prompts::environment::ENVIRONMENT_PROMPT_CONTEXT_KEY, ); let refresh_sources = async |config, current| { @@ -542,7 +542,7 @@ mod tests { ); } let before = counts(); - let prompts_only = engine::EnvironmentsFeature { + let prompts_only = harness::EnvironmentsFeature { prompts: Some(Default::default()), environments: feature.environments.clone(), ..Default::default() @@ -556,7 +556,7 @@ mod tests { ); let before = counts(); - let disabled_feature = engine::EnvironmentsFeature::default(); + let disabled_feature = harness::EnvironmentsFeature::default(); let disabled = refresh_sources(&disabled_feature, None).await; assert!(disabled.skill_command.is_none()); assert!(disabled.prompt_entries.is_empty()); diff --git a/crates/temporal-server/src/environments/runtime.rs b/crates/temporal-runtime/src/environments/runtime.rs similarity index 97% rename from crates/temporal-server/src/environments/runtime.rs rename to crates/temporal-runtime/src/environments/runtime.rs index 2fb323b33..cd453e6de 100644 --- a/crates/temporal-server/src/environments/runtime.rs +++ b/crates/temporal-runtime/src/environments/runtime.rs @@ -103,7 +103,7 @@ pub struct SessionEnvironmentManager { } impl SessionEnvironmentManager { - pub fn new(_blobs: std::sync::Arc) -> Self { + pub fn new(_blobs: std::sync::Arc) -> Self { Self::default() } @@ -143,13 +143,13 @@ impl SessionEnvironmentManager { mod tests { use std::{collections::BTreeMap, sync::Arc}; - use engine::storage::InMemoryBlobStore; use environment_protocol::shared::ProviderTargetId; use environments::{ EnvironmentIncarnationId, EnvironmentIncarnationRecord, EnvironmentProviderBindingId, EnvironmentProviderId, EnvironmentProvisionRequestId, EnvironmentSource, EnvironmentStatus, EnvironmentTemplateId, }; + use harness::storage::InMemoryBlobStore; use tools::fs::{FsPath, FsToolContext, InMemoryFileSystem}; use super::*; @@ -157,7 +157,7 @@ mod tests { fn resource() -> EnvironmentRecord { let target_id = ProviderTargetId::new("target-a"); EnvironmentRecord { - environment_id: engine::EnvironmentId::new("environment-a"), + environment_id: harness::EnvironmentId::new("environment-a"), request_id: EnvironmentProvisionRequestId::new("request-a"), source: EnvironmentSource::Provisioned { provider_id: EnvironmentProviderId::new("provider-a"), diff --git a/crates/temporal-server/src/environments/skills.rs b/crates/temporal-runtime/src/environments/skills.rs similarity index 99% rename from crates/temporal-server/src/environments/skills.rs rename to crates/temporal-runtime/src/environments/skills.rs index 5efc7f4af..a9037fa40 100644 --- a/crates/temporal-server/src/environments/skills.rs +++ b/crates/temporal-runtime/src/environments/skills.rs @@ -1,6 +1,6 @@ //! Workflow activity discovery at eligible idle boundaries. Never wakes a machine. use crate::environments::sources::{Discovery, PhaseTimer}; -use engine::{ +use harness::{ ContextEntryInput, CoreAgentCommand, SessionId, storage::{BlobStore, BlobStoreError}, }; @@ -157,7 +157,7 @@ async fn unavailable_observation( #[cfg(test)] mod tests { use super::*; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; #[tokio::test(flavor = "current_thread")] async fn failed_discovery_preserves_only_the_same_persisted_scope() { diff --git a/crates/temporal-server/src/environments/sources.rs b/crates/temporal-runtime/src/environments/sources.rs similarity index 99% rename from crates/temporal-server/src/environments/sources.rs rename to crates/temporal-runtime/src/environments/sources.rs index 51fa015e4..8de5fd1e9 100644 --- a/crates/temporal-server/src/environments/sources.rs +++ b/crates/temporal-runtime/src/environments/sources.rs @@ -3,11 +3,6 @@ use crate::{ environments::gateway::EnvironmentGatewayClientConfig, environments::resolver::EnvironmentResolver, }; -use engine::{ - ContextEntryInput, ContextEntryKey, CoreAgentCommand, EnvironmentId, EnvironmentsFeature, - SessionId, - storage::{BlobStore, BlobStoreError}, -}; use environment_client::{EnvironmentDataClient, JsonRpcTransport, WebSocketTransport}; use environment_protocol::{ data::{ @@ -16,6 +11,11 @@ use environment_protocol::{ }, shared::{CURRENT_PROTOCOL_VERSION, EnvironmentPath}, }; +use harness::{ + ContextEntryInput, ContextEntryKey, CoreAgentCommand, EnvironmentId, EnvironmentsFeature, + SessionId, + storage::{BlobStore, BlobStoreError}, +}; use std::{ collections::BTreeMap, time::{Duration, Instant}, diff --git a/crates/temporal-server/src/gateway/authentication.rs b/crates/temporal-runtime/src/gateway/authentication.rs similarity index 99% rename from crates/temporal-server/src/gateway/authentication.rs rename to crates/temporal-runtime/src/gateway/authentication.rs index d41728d9f..54616f4c0 100644 --- a/crates/temporal-server/src/gateway/authentication.rs +++ b/crates/temporal-runtime/src/gateway/authentication.rs @@ -75,7 +75,7 @@ pub async fn authenticate( // The caller is authenticated from here on; a refusal names its key. let forbidden = || { tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %method, key = %key.key_prefix, "authenticated request refused" diff --git a/crates/temporal-server/src/gateway/deployment.rs b/crates/temporal-runtime/src/gateway/deployment.rs similarity index 99% rename from crates/temporal-server/src/gateway/deployment.rs rename to crates/temporal-runtime/src/gateway/deployment.rs index 698101186..4f904d7b3 100644 --- a/crates/temporal-server/src/gateway/deployment.rs +++ b/crates/temporal-runtime/src/gateway/deployment.rs @@ -32,7 +32,6 @@ use api::{ DeploymentUniverseReadParams, DeploymentUniverseReadResponse, DeploymentUniverseView, }; use async_trait::async_trait; -use engine::SessionId; use environment_protocol::shared::EnvironmentTransport; use environments::{ AdoptEnvironment, EnvironmentConnectionSpec, EnvironmentId, EnvironmentIncarnationId, @@ -41,6 +40,7 @@ use environments::{ EnvironmentProviderStore, EnvironmentProvisionRequestId, EnvironmentStore, ListEnvironmentProviders, PutEnvironmentProvider, PutEnvironmentProviderBinding, }; +use harness::SessionId; use object_store::ObjectStoreExt as _; use object_store::path::Path as ObjectPath; use temporal_workflow::{AgentSessionWorkflow, compose_workflow_id}; @@ -555,7 +555,7 @@ impl DeploymentApiService for GatewayDeploymentApi { match store_pg::delete_objects_under_prefix(object_store.as_ref(), &prefix).await { Ok(deleted) => blob_objects_deleted += deleted, Err(error) => tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", universe_id = %universe_id, prefix, %error, @@ -566,7 +566,7 @@ impl DeploymentApiService for GatewayDeploymentApi { self.runtime.evict(universe_id).await; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", universe_id = %universe_id, sessions = session_ids.len(), workflows_terminated, diff --git a/crates/temporal-server/src/gateway/enforcement.rs b/crates/temporal-runtime/src/gateway/enforcement.rs similarity index 100% rename from crates/temporal-server/src/gateway/enforcement.rs rename to crates/temporal-runtime/src/gateway/enforcement.rs diff --git a/crates/temporal-server/src/gateway/http.rs b/crates/temporal-runtime/src/gateway/http.rs similarity index 97% rename from crates/temporal-server/src/gateway/http.rs rename to crates/temporal-runtime/src/gateway/http.rs index 0397397d3..839cf94f0 100644 --- a/crates/temporal-server/src/gateway/http.rs +++ b/crates/temporal-runtime/src/gateway/http.rs @@ -362,7 +362,7 @@ pub async fn serve_gateway(config: GatewayServerConfig) -> anyhow::Result<()> { let state = Arc::new(GatewayState::multi(mode, runtime, public_base_url)); let app = gateway_router(state, config.max_request_body_bytes, GatewayRoutes::ALL); let listener = tokio::net::TcpListener::bind(config.bind).await?; - tracing::info!(target: "temporal_server", bind = %config.bind, "gateway listening"); + tracing::info!(target: "temporal_runtime", bind = %config.bind, "gateway listening"); axum::serve(listener, app).await?; reconciler.abort(); Ok(()) @@ -400,14 +400,14 @@ pub fn gateway_router( .route("/auth/callback", get(oauth_callback)) .route("/auth/client-metadata.json", get(cimd_document)) .route( - "/hooks/bots/:universe/:bot/:trigger/:token", + "/hooks/bots/{universe}/{bot}/{trigger}/{token}", post(bot_webhook_ingest), ); } if routes.environment { router = router .route( - &format!("{ROUTE_PATH_PREFIX}/:universe/:environment/:incarnation"), + &format!("{ROUTE_PATH_PREFIX}/{{universe}}/{{environment}}/{{incarnation}}"), get(environment_route_upgrade), ) .route(CONNECT_PATH, get(registration::connect_upgrade)) @@ -545,7 +545,7 @@ async fn environment_route_upgrade( let daemon_socket = match connect_async(&endpoint).await { Ok((socket, _)) => socket, Err(error) => { - tracing::warn!(target: "temporal_server", %error, %endpoint, "external environment connection failed"); + tracing::warn!(target: "temporal_runtime", %error, %endpoint, "external environment connection failed"); return StatusCode::SERVICE_UNAVAILABLE.into_response(); } }; @@ -591,7 +591,7 @@ async fn environment_route_upgrade( let provider_socket = match connect_async(&endpoint).await { Ok((socket, _)) => socket, Err(error) => { - tracing::warn!(target: "temporal_server", %error, %endpoint, "provider data connection failed"); + tracing::warn!(target: "temporal_runtime", %error, %endpoint, "provider data connection failed"); return StatusCode::SERVICE_UNAVAILABLE.into_response(); } }; @@ -627,7 +627,7 @@ async fn environment_route_upgrade( { Ok(paired) => paired, Err(status) => { - tracing::warn!(target: "temporal_server", environment = %key.environment_id, %status, "registered environment data route unavailable"); + tracing::warn!(target: "temporal_runtime", environment = %key.environment_id, %status, "registered environment data route unavailable"); return status.into_response(); } }; @@ -807,9 +807,9 @@ async fn proxy_provider_route( let close = matches!(message, Message::Close(_)); let message = match message { Message::Text(value) => ProviderMessage::Text(value.to_string().into()), - Message::Binary(value) => ProviderMessage::Binary(value.to_vec().into()), - Message::Ping(value) => ProviderMessage::Ping(value.to_vec().into()), - Message::Pong(value) => ProviderMessage::Pong(value.to_vec().into()), + Message::Binary(value) => ProviderMessage::Binary(value), + Message::Ping(value) => ProviderMessage::Ping(value), + Message::Pong(value) => ProviderMessage::Pong(value), Message::Close(_) => ProviderMessage::Close(None), }; if provider_writer.send(message).await.is_err() || close { break } @@ -818,10 +818,10 @@ async fn proxy_provider_route( let Some(Ok(message)) = message else { break }; let close = matches!(message, ProviderMessage::Close(_)); let message = match message { - ProviderMessage::Text(value) => Some(Message::Text(value.to_string())), - ProviderMessage::Binary(value) => Some(Message::Binary(value.to_vec())), - ProviderMessage::Ping(value) => Some(Message::Ping(value.to_vec())), - ProviderMessage::Pong(value) => Some(Message::Pong(value.to_vec())), + ProviderMessage::Text(value) => Some(Message::Text(value.to_string().into())), + ProviderMessage::Binary(value) => Some(Message::Binary(value)), + ProviderMessage::Ping(value) => Some(Message::Ping(value)), + ProviderMessage::Pong(value) => Some(Message::Pong(value)), ProviderMessage::Close(_) => Some(Message::Close(None)), ProviderMessage::Frame(_) => None, }; @@ -862,9 +862,9 @@ async fn proxy_external_route( let close = matches!(message, Message::Close(_)); let message = match message { Message::Text(value) => ProviderMessage::Text(value.to_string().into()), - Message::Binary(value) => ProviderMessage::Binary(value.to_vec().into()), - Message::Ping(value) => ProviderMessage::Ping(value.to_vec().into()), - Message::Pong(value) => ProviderMessage::Pong(value.to_vec().into()), + Message::Binary(value) => ProviderMessage::Binary(value), + Message::Ping(value) => ProviderMessage::Ping(value), + Message::Pong(value) => ProviderMessage::Pong(value), Message::Close(_) => ProviderMessage::Close(None), }; if daemon_writer.send(message).await.is_err() || close { break } @@ -873,10 +873,10 @@ async fn proxy_external_route( let Some(Ok(message)) = message else { break }; let close = matches!(message, ProviderMessage::Close(_)); let message = match message { - ProviderMessage::Text(value) => Some(Message::Text(value.to_string())), - ProviderMessage::Binary(value) => Some(Message::Binary(value.to_vec())), - ProviderMessage::Ping(value) => Some(Message::Ping(value.to_vec())), - ProviderMessage::Pong(value) => Some(Message::Pong(value.to_vec())), + ProviderMessage::Text(value) => Some(Message::Text(value.to_string().into())), + ProviderMessage::Binary(value) => Some(Message::Binary(value)), + ProviderMessage::Ping(value) => Some(Message::Ping(value)), + ProviderMessage::Pong(value) => Some(Message::Pong(value)), ProviderMessage::Close(_) => Some(Message::Close(None)), ProviderMessage::Frame(_) => None, }; @@ -916,7 +916,7 @@ async fn rpc( Err(error) => { if error.kind != api::AgentApiErrorKind::Forbidden { tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %method, kind = ?error.kind, "request refused before authentication" @@ -1021,7 +1021,7 @@ async fn oauth_callback( Ok(Some(universe_id)) => match runtime.state_for(universe_id, false).await { Ok(universe) => universe.api.clone(), Err(error) => { - tracing::error!(target: "temporal_server", %error, "oauth callback universe resolution failed"); + tracing::error!(target: "temporal_runtime", %error, "oauth callback universe resolution failed"); return callback_failure_page(); } }, @@ -1035,7 +1035,7 @@ async fn oauth_callback( ); } Err(error) => { - tracing::error!(target: "temporal_server", %error, "oauth callback flow lookup failed"); + tracing::error!(target: "temporal_runtime", %error, "oauth callback flow lookup failed"); return callback_failure_page(); } } diff --git a/crates/temporal-server/src/gateway/mod.rs b/crates/temporal-runtime/src/gateway/mod.rs similarity index 100% rename from crates/temporal-server/src/gateway/mod.rs rename to crates/temporal-runtime/src/gateway/mod.rs diff --git a/crates/temporal-server/src/gateway/registration.rs b/crates/temporal-runtime/src/gateway/registration.rs similarity index 97% rename from crates/temporal-server/src/gateway/registration.rs rename to crates/temporal-runtime/src/gateway/registration.rs index 91ece36f9..a1c24bdd9 100644 --- a/crates/temporal-server/src/gateway/registration.rs +++ b/crates/temporal-runtime/src/gateway/registration.rs @@ -358,7 +358,7 @@ fn map_registry_error(error: EnvironmentRegistryError) -> RegistrationRejection } fn unavailable(error: EnvironmentRegistryError) -> RegistrationRejection { - tracing::warn!(target: "temporal_server", %error, "registration store failure"); + tracing::warn!(target: "temporal_runtime", %error, "registration store failure"); RegistrationRejection::new( RegistrationRejectionCode::Unavailable, "registration is temporarily unavailable", @@ -378,7 +378,7 @@ pub(super) async fn connect_upgrade( .on_upgrade(move |socket| async move { let outcome = control_session(state, socket, permit).await; if let Err(error) = outcome { - tracing::debug!(target: "temporal_server", %error, "registration control session ended with error"); + tracing::debug!(target: "temporal_runtime", %error, "registration control session ended with error"); } }) .into_response() @@ -533,9 +533,11 @@ async fn control_session( _permit: tokio::sync::OwnedSemaphorePermit, ) -> anyhow::Result<()> { let nonce = { - use rand::RngCore as _; + use rand::TryRng as _; let mut bytes = [0u8; REGISTRATION_NONCE_BYTES]; - rand::rngs::OsRng.fill_bytes(&mut bytes); + rand::rngs::SysRng + .try_fill_bytes(&mut bytes) + .expect("OS random source unavailable"); bytes }; send_control( @@ -613,7 +615,7 @@ async fn control_session( return Ok(()); } Err(error) => { - tracing::warn!(target: "temporal_server", error = %error.message, "registration universe lookup failed"); + tracing::warn!(target: "temporal_runtime", error = %error.message, "registration universe lookup failed"); reject( &mut socket, RegistrationRejectionCode::Unavailable, @@ -626,7 +628,7 @@ async fn control_session( let api = match state.api_for_daemon(universe_id).await { Ok(api) => api, Err(error) => { - tracing::warn!(target: "temporal_server", error = %error.message, "registration universe unavailable"); + tracing::warn!(target: "temporal_runtime", error = %error.message, "registration universe unavailable"); reject( &mut socket, RegistrationRejectionCode::Unavailable, @@ -693,7 +695,7 @@ async fn control_session( ) .await; if let Err(error) = result { - tracing::warn!(target: "temporal_server", %error, "registered observation failed"); + tracing::warn!(target: "temporal_runtime", %error, "registered observation failed"); } } }; @@ -708,7 +710,7 @@ async fn control_session( _ => String::new(), }; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, environment = %environment_id, daemon = %daemon_id, @@ -754,7 +756,7 @@ async fn control_session( None => break "command channel closed", }, _ = heartbeat.tick() => { - if socket.send(Message::Ping(Vec::new())).await.is_err() { + if socket.send(Message::Ping(Default::default())).await.is_err() { break "ping failed"; } } @@ -766,7 +768,7 @@ async fn control_session( } Ok(_) => {} Err(error) => { - tracing::warn!(target: "temporal_server", %error, "registered control reauthorization failed"); + tracing::warn!(target: "temporal_runtime", %error, "registered control reauthorization failed"); } } } @@ -785,7 +787,7 @@ async fn control_session( }; let was_current = registrations.remove_if_current(universe_id, &environment_id, &connection_id); tracing::info!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, environment = %environment_id, connection = %connection_id, @@ -804,7 +806,7 @@ async fn send_control( message: &GatewayControlMessage, ) -> anyhow::Result<()> { socket - .send(Message::Text(serde_json::to_string(message)?)) + .send(Message::Text(serde_json::to_string(message)?.into())) .await .map_err(|error| anyhow::anyhow!("send control message: {error}")) } @@ -815,7 +817,7 @@ async fn reject( message: impl Into, ) { let message = message.into(); - tracing::info!(target: "temporal_server", ?code, %message, "registration rejected"); + tracing::info!(target: "temporal_runtime", ?code, %message, "registration rejected"); let _ = send_control(socket, &GatewayControlMessage::Rejected { code, message }).await; let _ = socket.send(Message::Close(None)).await; } @@ -847,9 +849,11 @@ async fn next_daemon_message( fn new_token() -> String { use base64::Engine as _; - use rand::RngCore as _; + use rand::TryRng as _; let mut bytes = [0u8; 32]; - rand::rngs::OsRng.fill_bytes(&mut bytes); + rand::rngs::SysRng + .try_fill_bytes(&mut bytes) + .expect("OS random source unavailable"); base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes) } diff --git a/crates/temporal-server/src/gateway/request_context.rs b/crates/temporal-runtime/src/gateway/request_context.rs similarity index 100% rename from crates/temporal-server/src/gateway/request_context.rs rename to crates/temporal-runtime/src/gateway/request_context.rs diff --git a/crates/temporal-server/src/gateway/service/api_config.rs b/crates/temporal-runtime/src/gateway/service/api_config.rs similarity index 85% rename from crates/temporal-server/src/gateway/service/api_config.rs rename to crates/temporal-runtime/src/gateway/service/api_config.rs index e146c4a5d..5a60d187b 100644 --- a/crates/temporal-server/src/gateway/service/api_config.rs +++ b/crates/temporal-runtime/src/gateway/service/api_config.rs @@ -13,7 +13,7 @@ impl GatewayAgentApi { .map_err(model_defaults::map_store_error) }) .await?; - let mut config = engine_session_config_from_api(api_config, model)?; + let mut config = harness_session_config_from_api(api_config, model)?; self.resolve_context_capacity(&mut config).await; config .validate() @@ -37,7 +37,7 @@ impl GatewayAgentApi { /// error, not a spawn-time surprise. pub(super) async fn validate_subagent_agents( &self, - features: &engine::FeaturesConfig, + features: &harness::FeaturesConfig, ) -> Result<(), AgentApiError> { let Some(subagents) = features.subagents.as_ref() else { return Ok(()); @@ -68,7 +68,7 @@ impl GatewayAgentApi { } /// Build only the per-run overrides supplied by `session/runs/start`. -/// Session defaults remain in `SessionConfig` and are resolved by the engine +/// Session defaults remain in `SessionConfig` and are resolved by the harness /// from its live state; they must not be copied into the override document. pub(super) fn run_config_for_start( session_config: &SessionConfig, @@ -79,10 +79,10 @@ pub(super) fn run_config_for_start( Ok(run_config) } -/// Translate the wire config document into the engine document. An absent +/// Translate the wire config document into the harness document. An absent /// `model` uses the caller's resolved creation model or current session model; /// everything else maps 1:1. -pub(super) fn engine_session_config_from_api( +pub(super) fn harness_session_config_from_api( api_config: api::SessionConfig, resolved_model: ModelSelection, ) -> Result { @@ -96,12 +96,12 @@ pub(super) fn engine_session_config_from_api( generation, limits: api_config .limits - .map(|limits| engine::LimitsConfig { + .map(|limits| harness::LimitsConfig { max_turns: limits.max_turns, max_tool_rounds: limits.max_tool_rounds, }) .unwrap_or_default(), - context: engine::ContextConfig { + context: harness::ContextConfig { reported_input_limit_tokens: None, input_limit_tokens: api_config .context @@ -119,9 +119,9 @@ pub(super) fn engine_session_config_from_api( fn generation_from_api( generation: Option, model: &ModelSelection, -) -> Result { +) -> Result { let Some(generation) = generation else { - return Ok(engine::GenerationConfig::default()); + return Ok(harness::GenerationConfig::default()); }; if let Some(effort) = generation.reasoning_effort.as_deref() { validate_reasoning_effort(&model.api_kind, effort)?; @@ -130,7 +130,7 @@ fn generation_from_api( .processing_tier .map(|tier| processing_tier_from_api(model, tier)) .transpose()?; - Ok(engine::GenerationConfig { + Ok(harness::GenerationConfig { max_output_tokens: generation.max_output_tokens, reasoning_effort: generation.reasoning_effort, tool_choice: generation @@ -145,7 +145,7 @@ fn generation_from_api( fn processing_tier_from_api( model: &ModelSelection, tier: api::ModelProcessingTier, -) -> Result { +) -> Result { if model.provider_id != "openai" || !matches!( model.api_kind, @@ -157,23 +157,23 @@ fn processing_tier_from_api( )); } Ok(match tier { - api::ModelProcessingTier::Standard => engine::ModelProcessingTier::Standard, - api::ModelProcessingTier::Fast => engine::ModelProcessingTier::Fast, - api::ModelProcessingTier::Flex => engine::ModelProcessingTier::Flex, + api::ModelProcessingTier::Standard => harness::ModelProcessingTier::Standard, + api::ModelProcessingTier::Fast => harness::ModelProcessingTier::Fast, + api::ModelProcessingTier::Flex => harness::ModelProcessingTier::Flex, }) } fn features_from_api( features: Option, -) -> Result { +) -> Result { let Some(features) = features else { - return Ok(engine::FeaturesConfig::default()); + return Ok(harness::FeaturesConfig::default()); }; - Ok(engine::FeaturesConfig { + Ok(harness::FeaturesConfig { vfs: features .vfs .map(|vfs| { - Ok::<_, AgentApiError>(engine::VfsFeature { + Ok::<_, AgentApiError>(harness::VfsFeature { version: vfs.version, working_directory: vfs.working_directory, workspaces: vfs @@ -181,58 +181,58 @@ fn features_from_api( .into_iter() .map(workspace_attachment_from_api) .collect::, _>>()?, - prompts: vfs.prompts.map(|prompts| engine::VfsPromptsConfig { + prompts: vfs.prompts.map(|prompts| harness::VfsPromptsConfig { roots: prompts.roots, }), - skills: vfs.skills.map(|skills| engine::VfsSkillsConfig { + skills: vfs.skills.map(|skills| harness::VfsSkillsConfig { roots: skills.roots, }), }) }) .transpose()?, - web: features.web.map(|web| engine::WebFeature { + web: features.web.map(|web| harness::WebFeature { version: web.version, - fetch: web.fetch.map(|_| engine::WebFetchFeature {}), - search: web.search.map(|search| engine::WebSearchFeature { + fetch: web.fetch.map(|_| harness::WebFetchFeature {}), + search: web.search.map(|search| harness::WebSearchFeature { allowed_domains: search.allowed_domains, blocked_domains: search.blocked_domains, }), }), subagents: features .subagents - .map(|subagents| engine::SubagentsFeature { + .map(|subagents| harness::SubagentsFeature { version: subagents.version, agents: subagents .agents .into_iter() - .map(|agent| engine::SubagentAgentConfig { + .map(|agent| harness::SubagentAgentConfig { profile_id: agent.profile_id.as_str().to_owned(), }) .collect(), - limits: engine::SubagentLimits { + limits: harness::SubagentLimits { max_depth: subagents.max_depth, max_descendants: subagents.max_descendants, max_concurrent: subagents.max_concurrent, deadline_ms: subagents.deadline_ms, }, }), - timers: features.timers.map(|timers| engine::TimersFeature { + timers: features.timers.map(|timers| harness::TimersFeature { version: timers.version, }), environments: features .environments .map(|environments| { - Ok::<_, AgentApiError>(engine::EnvironmentsFeature { + Ok::<_, AgentApiError>(harness::EnvironmentsFeature { version: environments.version, selection: environments.selection, prompts: environments .prompts - .map(|source| engine::EnvironmentPromptsConfig { + .map(|source| harness::EnvironmentPromptsConfig { roots: source.roots, }), skills: environments .skills - .map(|skills| engine::EnvironmentSkillsConfig { + .map(|skills| harness::EnvironmentSkillsConfig { roots: skills.roots, }), environments: environments @@ -243,12 +243,12 @@ fn features_from_api( }) }) .transpose()?, - mcp: features.mcp.map(|mcp| engine::McpFeature { + mcp: features.mcp.map(|mcp| harness::McpFeature { version: mcp.version, servers: mcp .servers .into_iter() - .map(|attachment| engine::McpServerAttachment { + .map(|attachment| harness::McpServerAttachment { server_id: attachment.server_id, tools: attachment.tools, }) @@ -259,10 +259,12 @@ fn features_from_api( fn workspace_attachment_from_api( attachment: api::WorkspaceAttachment, -) -> Result { +) -> Result { let target = match (attachment.workspace_id, attachment.snapshot_ref) { - (Some(workspace_id), None) => engine::WorkspaceAttachmentTarget::Workspace { workspace_id }, - (None, Some(snapshot_ref)) => engine::WorkspaceAttachmentTarget::Snapshot { snapshot_ref }, + (Some(workspace_id), None) => { + harness::WorkspaceAttachmentTarget::Workspace { workspace_id } + } + (None, Some(snapshot_ref)) => harness::WorkspaceAttachmentTarget::Snapshot { snapshot_ref }, _ => { return Err(AgentApiError::invalid_request(format!( "workspace attachment at {} must set exactly one of workspaceId and snapshotRef", @@ -270,12 +272,12 @@ fn workspace_attachment_from_api( ))); } }; - Ok(engine::WorkspaceAttachment { + Ok(harness::WorkspaceAttachment { path: attachment.path, target, access: match attachment.access { - api::WorkspaceAccess::Read => engine::WorkspaceAccess::Read, - api::WorkspaceAccess::Edit => engine::WorkspaceAccess::Edit, + api::WorkspaceAccess::Read => harness::WorkspaceAccess::Read, + api::WorkspaceAccess::Edit => harness::WorkspaceAccess::Edit, }, }) } @@ -285,7 +287,7 @@ fn workspace_attachment_from_api( /// here rather than silently dropped. fn environment_attachment_from_api( attachment: api::EnvironmentAttachment, -) -> Result { +) -> Result { let environment_id = match (attachment.environment_id, attachment.inherit) { (Some(environment_id), false) => environment_id, (None, true) => { @@ -299,7 +301,7 @@ fn environment_attachment_from_api( )); } }; - Ok(engine::EnvironmentAttachment { + Ok(harness::EnvironmentAttachment { environment_id, default: attachment.default, access: environment_access_from_api(attachment.access), @@ -309,12 +311,12 @@ fn environment_attachment_from_api( pub(super) fn environment_access_from_api( access: api::EnvironmentAccess, -) -> engine::EnvironmentAccess { +) -> harness::EnvironmentAccess { match access { - api::EnvironmentAccess::Read => engine::EnvironmentAccess::Read, - api::EnvironmentAccess::Edit => engine::EnvironmentAccess::Edit, - api::EnvironmentAccess::Exec => engine::EnvironmentAccess::Exec, - api::EnvironmentAccess::Jobs => engine::EnvironmentAccess::Jobs, + api::EnvironmentAccess::Read => harness::EnvironmentAccess::Read, + api::EnvironmentAccess::Edit => harness::EnvironmentAccess::Edit, + api::EnvironmentAccess::Exec => harness::EnvironmentAccess::Exec, + api::EnvironmentAccess::Jobs => harness::EnvironmentAccess::Jobs, } } @@ -451,7 +453,8 @@ mod tests { api_kind: ProviderApiKind::OpenAiCompletions, model: "deepseek-model".into(), }; - let session = engine_session_config_from_api(api::SessionConfig::default(), model).unwrap(); + let session = + harness_session_config_from_api(api::SessionConfig::default(), model).unwrap(); for (provider, kind, allowed) in [ ("deepseek", "openai:completions", true), ("glm", "openai:completions", false), diff --git a/crates/temporal-server/src/gateway/service/auth_api.rs b/crates/temporal-runtime/src/gateway/service/auth_api.rs similarity index 100% rename from crates/temporal-server/src/gateway/service/auth_api.rs rename to crates/temporal-runtime/src/gateway/service/auth_api.rs diff --git a/crates/temporal-server/src/gateway/service/authorization.rs b/crates/temporal-runtime/src/gateway/service/authorization.rs similarity index 96% rename from crates/temporal-server/src/gateway/service/authorization.rs rename to crates/temporal-runtime/src/gateway/service/authorization.rs index c9b4fb0bd..1b97b564a 100644 --- a/crates/temporal-server/src/gateway/service/authorization.rs +++ b/crates/temporal-runtime/src/gateway/service/authorization.rs @@ -42,7 +42,7 @@ impl GatewayAgentApi { let session = SessionId::try_new(params.session_id.clone()).map_err(|_| denied())?; let loaded = self.load_session_state(&session).await?; let bound = loaded.state.workflow_tools.bindings.values().any(|binding| matches!(&binding.target, - engine::WorkflowToolTarget::Bound { receiver, .. } + harness::WorkflowToolTarget::Bound { receiver, .. } if receiver.workflow_id == workflow_id && receiver.workflow_kind == temporal_workflow::channels::CHANNEL_CONVERSATION_WORKFLOW_KIND)); let bot = self .access_store() @@ -310,7 +310,7 @@ impl GatewayAgentApi { /// Removing a resource is never checked, only what remains. pub(super) async fn admit_attachments( &self, - features: &engine::FeaturesConfig, + features: &harness::FeaturesConfig, ) -> Result<(), AgentApiError> { require_resources( &self.access_store(), @@ -340,7 +340,7 @@ impl GatewayAgentApi { } // A refusal of internal work is a runtime fault worth a log line. tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %method, cause = %controller.cause, "internal controller was refused" @@ -397,14 +397,14 @@ impl GatewayAgentApi { }) } - /// The attribution as engine commands record it. - pub(super) fn requested_by(&self) -> Result, AgentApiError> { + /// The attribution as harness commands record it. + pub(super) fn requested_by(&self) -> Result, AgentApiError> { Ok(Some(match self.attribution()? { - Attribution::Actor { id } => engine::Attribution::Actor { id }, - Attribution::Key { prefix } => engine::Attribution::Key { prefix }, - Attribution::Local => engine::Attribution::Local, + Attribution::Actor { id } => harness::Attribution::Actor { id }, + Attribution::Key { prefix } => harness::Attribution::Key { prefix }, + Attribution::Local => harness::Attribution::Local, Attribution::Internal { component, cause } => { - engine::Attribution::Internal { component, cause } + harness::Attribution::Internal { component, cause } } })) } diff --git a/crates/temporal-server/src/gateway/service/blobs.rs b/crates/temporal-runtime/src/gateway/service/blobs.rs similarity index 100% rename from crates/temporal-server/src/gateway/service/blobs.rs rename to crates/temporal-runtime/src/gateway/service/blobs.rs diff --git a/crates/temporal-server/src/gateway/service/bots_api.rs b/crates/temporal-runtime/src/gateway/service/bots_api.rs similarity index 98% rename from crates/temporal-server/src/gateway/service/bots_api.rs rename to crates/temporal-runtime/src/gateway/service/bots_api.rs index 645eb366a..75ed9b7f7 100644 --- a/crates/temporal-server/src/gateway/service/bots_api.rs +++ b/crates/temporal-runtime/src/gateway/service/bots_api.rs @@ -17,7 +17,7 @@ use ::bots::{ validate::{validate_pairing_code, validate_trigger_document}, }; use ::channels::ChannelAccountStore; -use rand::RngCore as _; +use rand::TryRng as _; use serde_json::Value; use temporalio_client::{UntypedQuery, UntypedSignal, UntypedWorkflow, errors::WorkflowQueryError}; use temporalio_common::data_converters::{PayloadConverter, RawValue}; @@ -50,7 +50,9 @@ pub fn webhook_ingest_path( fn random_bytes(len: usize) -> Vec { let mut bytes = vec![0u8; len]; - rand::rngs::OsRng.fill_bytes(&mut bytes); + rand::rngs::SysRng + .try_fill_bytes(&mut bytes) + .expect("OS random source unavailable"); bytes } @@ -825,13 +827,13 @@ impl GatewayAgentApi { let bots = match self.store().list_bots_for_profile(profile_id).await { Ok(bots) => bots, Err(error) => { - tracing::warn!(target: "temporal_server", %profile_id, %error, "list bots for profile failed"); + tracing::warn!(target: "temporal_runtime", %profile_id, %error, "list bots for profile failed"); return; } }; for bot in bots { if let Err(error) = self.signal_bot_config(&bot).await { - tracing::warn!(target: "temporal_server", bot_id = %bot.bot_id, %error, "signal bot config after profile put failed"); + tracing::warn!(target: "temporal_runtime", bot_id = %bot.bot_id, %error, "signal bot config after profile put failed"); } } } diff --git a/crates/temporal-server/src/gateway/service/catalogs.rs b/crates/temporal-runtime/src/gateway/service/catalogs.rs similarity index 97% rename from crates/temporal-server/src/gateway/service/catalogs.rs rename to crates/temporal-runtime/src/gateway/service/catalogs.rs index eb62b7cd2..cd58cab42 100644 --- a/crates/temporal-server/src/gateway/service/catalogs.rs +++ b/crates/temporal-runtime/src/gateway/service/catalogs.rs @@ -9,7 +9,7 @@ pub(super) fn parse_client_context_key(value: String) -> Result Result<::environments::EnvironmentRecord, AgentApiError> { let feature = state .lifecycle @@ -30,7 +30,7 @@ impl GatewayAgentApi { pub(super) async fn wait_for_active_environment( &self, session_id: &SessionId, - expected: Option<&engine::EnvironmentId>, + expected: Option<&harness::EnvironmentId>, baseline_failures: usize, ) -> Result<(), AgentApiError> { let started = Instant::now(); @@ -81,7 +81,7 @@ pub(super) fn map_environment_resolve_error( } pub(super) fn activate_environment_command( - environment_id: engine::EnvironmentId, + environment_id: harness::EnvironmentId, ) -> CoreAgentCommand { CoreAgentCommand::SetActiveEnvironment { environment_id } } diff --git a/crates/temporal-server/src/gateway/service/errors.rs b/crates/temporal-runtime/src/gateway/service/errors.rs similarity index 95% rename from crates/temporal-server/src/gateway/service/errors.rs rename to crates/temporal-runtime/src/gateway/service/errors.rs index 5bd2800e6..245512ceb 100644 --- a/crates/temporal-server/src/gateway/service/errors.rs +++ b/crates/temporal-runtime/src/gateway/service/errors.rs @@ -11,7 +11,7 @@ pub(super) fn map_admission_failure_to_api_error(failure: &AgentAdmissionFailure match failure.kind { AgentAdmissionFailureKind::RejectedCommand if failure.rejection.as_ref().is_some_and(|rejection| { - rejection.kind == engine::CommandRejectionKind::RevisionConflict + rejection.kind == harness::CommandRejectionKind::RevisionConflict }) => { AgentApiError::conflict(failure.message.clone()) @@ -100,8 +100,8 @@ pub(super) fn map_workflow_start_error(error: WorkflowStartError) -> AgentApiErr pub(super) fn map_workflow_query_error(error: WorkflowQueryError) -> AgentApiError { match error { WorkflowQueryError::NotFound(_) => AgentApiError::not_found("agent workflow not found"), - WorkflowQueryError::Rejected(rejection) => { - AgentApiError::internal(format!("{rejection:?}")) + WorkflowQueryError::Rejected { status } => { + AgentApiError::internal(format!("query rejected for workflow status {status:?}")) } WorkflowQueryError::PayloadConversion(error) => AgentApiError::internal(error.to_string()), WorkflowQueryError::Rpc(status) => AgentApiError::internal(status.to_string()), diff --git a/crates/temporal-server/src/gateway/service/event_history.rs b/crates/temporal-runtime/src/gateway/service/event_history.rs similarity index 98% rename from crates/temporal-server/src/gateway/service/event_history.rs rename to crates/temporal-runtime/src/gateway/service/event_history.rs index 50d5c222e..e9e95fd34 100644 --- a/crates/temporal-server/src/gateway/service/event_history.rs +++ b/crates/temporal-runtime/src/gateway/service/event_history.rs @@ -4,7 +4,7 @@ use api::{AgentApiError, EventCursor, SessionEventsReadParams, SessionEventsRead use api_projection::{ CoreAgentProjector, decode_stored_entry, event_page_limit, map_session_store_error, }; -use engine::{ +use harness::{ CoreAgentCodec, EventSeq, SessionId, storage::{BlobStore, ReadSessionEventRange, SessionStore}, }; @@ -76,7 +76,7 @@ pub(super) async fn read( #[cfg(test)] mod tests { use super::*; - use engine::{ + use harness::{ CoreAgentEvent, CoreAgentJoins, CoreAgentLifecycleEvent, UncommittedCoreAgentEvent, storage::{AppendSessionEvents, CreateSession, InMemoryBlobStore, InMemorySessionStore}, }; @@ -161,7 +161,7 @@ mod tests { sequences.sort_unstable(); assert_eq!(sequences, (1..=12_005).collect::>()); let tail = store - .read_after(engine::storage::ReadSessionEvents { + .read_after(harness::storage::ReadSessionEvents { session_id: id, after: Some(EventSeq::new(12_005)), limit: 500, @@ -232,7 +232,7 @@ mod tests { let (store, blobs, parent) = setup(10).await; let child = SessionId::new("history-fork"); store - .create_forked_session(engine::storage::CreateForkedSession { + .create_forked_session(harness::storage::CreateForkedSession { source_session_id: parent, session_id: child.clone(), source_seq: EventSeq::new(7), diff --git a/crates/temporal-server/src/gateway/service/github_api.rs b/crates/temporal-runtime/src/gateway/service/github_api.rs similarity index 100% rename from crates/temporal-server/src/gateway/service/github_api.rs rename to crates/temporal-runtime/src/gateway/service/github_api.rs diff --git a/crates/temporal-server/src/gateway/service/input.rs b/crates/temporal-runtime/src/gateway/service/input.rs similarity index 97% rename from crates/temporal-server/src/gateway/service/input.rs rename to crates/temporal-runtime/src/gateway/service/input.rs index 5045abad5..e63c490e8 100644 --- a/crates/temporal-server/src/gateway/service/input.rs +++ b/crates/temporal-runtime/src/gateway/service/input.rs @@ -150,7 +150,7 @@ async fn media_message_input( kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: blob_ref, media_type: Some(mime), provider_kind: None, @@ -224,14 +224,14 @@ fn empty_context_append_item_error() -> AgentApiError { AgentApiError::invalid_request("session/context/append items must contain non-empty text") } -/// A client-owned catalog entry; the engine supersedes rather than replaces +/// A client-owned catalog entry; the harness supersedes rather than replaces /// it on change, so the previous version keeps the rendered prefix stable. pub(super) fn catalog_input(title: String, content_ref: BlobRef) -> ContextEntryInput { ContextEntryInput { kind: ContextEntryKind::Catalog { title: title.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/markdown".to_owned()), provider_kind: None, @@ -248,7 +248,7 @@ pub(super) fn user_message_input(content_ref: BlobRef) -> ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, diff --git a/crates/temporal-server/src/gateway/service/mcp_api.rs b/crates/temporal-runtime/src/gateway/service/mcp_api.rs similarity index 90% rename from crates/temporal-server/src/gateway/service/mcp_api.rs rename to crates/temporal-runtime/src/gateway/service/mcp_api.rs index e53f67b1c..1ab5561d4 100644 --- a/crates/temporal-server/src/gateway/service/mcp_api.rs +++ b/crates/temporal-runtime/src/gateway/service/mcp_api.rs @@ -138,10 +138,10 @@ pub(super) fn validate_mcp_server_credential( /// into the remote MCP tool spec. Shared by put-time validation and toolset /// reconciliation, so a config put fails fast when an attachment cannot resolve. pub(super) fn mcp_tool_from_config_attachment( - attachment: &engine::McpServerAttachment, + attachment: &harness::McpServerAttachment, record: &mcp::McpServerRecord, grant: Option<&auth::AuthGrantRecord>, -) -> Result { +) -> Result { match record.status { mcp::McpServerStatus::Disabled => { return Err(AgentApiError::rejected(format!( @@ -174,19 +174,19 @@ pub(super) fn mcp_tool_from_config_attachment( }; let tool_name = default_mcp_tool_name(&record.default_server_label)?; let auth_ref = auth_ref_for_server(record, grant)?; - Ok(engine::ToolSpec { + Ok(harness::ToolSpec { name: tool_name, - execution: engine::ToolExecutionSpec::default(), - kind: engine::ToolKind::RemoteMcp(engine::RemoteMcpToolSpec { + execution: harness::ToolExecutionSpec::default(), + kind: harness::ToolKind::RemoteMcp(harness::RemoteMcpToolSpec { server_id: record.server_id.as_str().to_owned(), record_revision: record.revision, server_label: record.default_server_label.clone(), server_url: record.server_url.clone(), description_ref: None, allowed_tools, - execution: engine_execution(record.execution), - exposure: engine_exposure(record.exposure), - approval: engine_approval(api_approval(record.approval)), + execution: harness_execution(record.execution), + exposure: harness_exposure(record.exposure), + approval: harness_approval(api_approval(record.approval)), defer_loading: record.defer_loading, auth_ref, auth_required: matches!( @@ -196,7 +196,7 @@ pub(super) fn mcp_tool_from_config_attachment( ), allow_private_network: record.allow_private_network, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, }) } @@ -206,8 +206,8 @@ impl super::session_preparation::SessionPreparationService { /// a config document at admission and to reconcile the session toolset. pub(crate) async fn desired_mcp_tools( &self, - features: &engine::FeaturesConfig, - ) -> Result, AgentApiError> { + features: &harness::FeaturesConfig, + ) -> Result, AgentApiError> { let Some(mcp) = features.mcp.as_ref() else { return Ok(BTreeMap::new()); }; @@ -256,15 +256,18 @@ impl super::session_preparation::SessionPreparationService { let find = tools::definitions::register( "mcp.find_tools", settings.clone(), - engine::ToolParallelism::ParallelSafe, - engine::ToolExecutionSpec::new(engine::ToolExecutionClass::RemoteInteractive, true), + harness::ToolParallelism::ParallelSafe, + harness::ToolExecutionSpec::new( + harness::ToolExecutionClass::RemoteInteractive, + true, + ), ); let call = tools::definitions::register( "mcp.call", settings, - engine::ToolParallelism::Exclusive, - engine::ToolExecutionSpec::new( - engine::ToolExecutionClass::RemoteInteractive, + harness::ToolParallelism::Exclusive, + harness::ToolExecutionSpec::new( + harness::ToolExecutionClass::RemoteInteractive, false, ), ); @@ -301,10 +304,10 @@ fn api_execution(value: mcp::McpExecution) -> api::RemoteMcpExecution { } } -fn engine_execution(value: mcp::McpExecution) -> engine::RemoteMcpExecution { +fn harness_execution(value: mcp::McpExecution) -> harness::RemoteMcpExecution { match value { - mcp::McpExecution::Provider => engine::RemoteMcpExecution::Provider, - mcp::McpExecution::Native => engine::RemoteMcpExecution::Native, + mcp::McpExecution::Provider => harness::RemoteMcpExecution::Provider, + mcp::McpExecution::Native => harness::RemoteMcpExecution::Native, } } @@ -322,10 +325,10 @@ fn api_exposure(value: mcp::McpExposure) -> api::RemoteMcpExposure { } } -fn engine_exposure(value: mcp::McpExposure) -> engine::RemoteMcpExposure { +fn harness_exposure(value: mcp::McpExposure) -> harness::RemoteMcpExposure { match value { - mcp::McpExposure::Inject => engine::RemoteMcpExposure::Inject, - mcp::McpExposure::Search => engine::RemoteMcpExposure::Search, + mcp::McpExposure::Inject => harness::RemoteMcpExposure::Inject, + mcp::McpExposure::Search => harness::RemoteMcpExposure::Search, } } @@ -336,10 +339,10 @@ fn api_approval(value: mcp::McpApprovalPolicy) -> api::RemoteMcpApprovalPolicy { } } -fn engine_approval(value: api::RemoteMcpApprovalPolicy) -> engine::RemoteMcpApprovalPolicy { +fn harness_approval(value: api::RemoteMcpApprovalPolicy) -> harness::RemoteMcpApprovalPolicy { match value { - api::RemoteMcpApprovalPolicy::Always => engine::RemoteMcpApprovalPolicy::Always, - api::RemoteMcpApprovalPolicy::Never => engine::RemoteMcpApprovalPolicy::Never, + api::RemoteMcpApprovalPolicy::Always => harness::RemoteMcpApprovalPolicy::Always, + api::RemoteMcpApprovalPolicy::Never => harness::RemoteMcpApprovalPolicy::Never, } } @@ -460,7 +463,7 @@ fn parse_mcp_tool_name(tool_id: String) -> Result { fn auth_ref_for_server( record: &mcp::McpServerRecord, grant: Option<&auth::AuthGrantRecord>, -) -> Result, AgentApiError> { +) -> Result, AgentApiError> { match (&record.auth_policy, grant) { (mcp::McpServerAuthPolicy::None, Some(_)) => Err(AgentApiError::invalid_request( "an MCP server credential is only valid with an auth policy", @@ -471,13 +474,13 @@ fn auth_ref_for_server( )), (_, Some(grant)) => { auth_api::validate_mcp_grant_for_server(record, grant)?; - Ok(Some(engine::SecretRef { + Ok(Some(harness::SecretRef { namespace: MCP_SERVER_SECRET_NAMESPACE.to_owned(), id: record.server_id.as_str().to_owned(), })) } (mcp::McpServerAuthPolicy::OptionalBearer, None) - | (mcp::McpServerAuthPolicy::OptionalOAuth { .. }, None) => Ok(Some(engine::SecretRef { + | (mcp::McpServerAuthPolicy::OptionalOAuth { .. }, None) => Ok(Some(harness::SecretRef { namespace: MCP_SERVER_SECRET_NAMESPACE.to_owned(), id: record.server_id.as_str().to_owned(), })), @@ -501,8 +504,8 @@ fn api_status(value: mcp::McpServerStatus) -> api::McpServerStatus { impl GatewayAgentApi { pub(super) async fn desired_mcp_tools( &self, - features: &engine::FeaturesConfig, - ) -> Result, AgentApiError> { + features: &harness::FeaturesConfig, + ) -> Result, AgentApiError> { self.preparation_service().desired_mcp_tools(features).await } } @@ -513,11 +516,12 @@ mod tests { #[test] fn search_meta_tools_are_not_strict_functions() { - let target = tools::runtime::ToolTarget::api_kind(engine::ProviderApiKind::OpenAiResponses); + let target = + tools::runtime::ToolTarget::api_kind(harness::ProviderApiKind::OpenAiResponses); for id in ["mcp.call", "mcp.find_tools"] { let resolved = tools::definitions::resolve( &ToolName::new(id), - &engine::BuiltinToolSpec::default(), + &harness::BuiltinToolSpec::default(), &target, ) .expect("resolve meta-tool"); diff --git a/crates/temporal-server/src/gateway/service/mcp_discovery.rs b/crates/temporal-runtime/src/gateway/service/mcp_discovery.rs similarity index 99% rename from crates/temporal-server/src/gateway/service/mcp_discovery.rs rename to crates/temporal-runtime/src/gateway/service/mcp_discovery.rs index f94322daf..32cdf29f4 100644 --- a/crates/temporal-server/src/gateway/service/mcp_discovery.rs +++ b/crates/temporal-runtime/src/gateway/service/mcp_discovery.rs @@ -13,7 +13,7 @@ use mcp::{ McpToolDiscoveryFailureKind as FailureKind, McpToolDiscoveryLimits, }; use rmcp::model::{ - CallToolRequestParams, CallToolResult, ClientInfo, ClientJsonRpcMessage, ClientRequest, + CallToolRequestParams, CallToolResult, ClientConfig, ClientJsonRpcMessage, ClientRequest, Implementation, PaginatedRequestParams, ProtocolVersion, ServerJsonRpcMessage, Tool, }; use rmcp::transport::{ @@ -215,7 +215,7 @@ impl ResponseBudget { fn reserve(&self, bytes: usize) -> Result<(), ResponseLimitError> { self.consumed - .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |consumed| { + .try_update(Ordering::Relaxed, Ordering::Relaxed, |consumed| { consumed .checked_add(bytes) .filter(|total| *total <= self.max) @@ -751,7 +751,7 @@ impl McpToolDiscoverer for HttpMcpToolDiscoverer { } } -type McpClientService = RunningService; +type McpClientService = RunningService; struct StartServiceFailure { failure: McpToolDiscoveryFailure, @@ -779,7 +779,7 @@ async fn start_service_once( let client = BoundedReqwestClient::new(client.clone(), max_response_bytes, operation); let diagnostics = client.diagnostics.clone(); let transport = StreamableHttpClientTransport::with_client(client, config); - let result = ClientInfo::new( + let result = ClientConfig::new( Default::default(), Implementation::new("lightspeed", env!("CARGO_PKG_VERSION")), ) @@ -829,7 +829,7 @@ fn client_lifecycle() -> ClientLifecycleMode { } async fn discover_pages( - service: &rmcp::service::RunningService, + service: &rmcp::service::RunningService, limits: McpToolDiscoveryLimits, diagnostics: &TransportDiagnostics, ) -> Result<(Vec, Option), McpToolDiscoveryFailure> { diff --git a/crates/temporal-server/src/gateway/service/mod.rs b/crates/temporal-runtime/src/gateway/service/mod.rs similarity index 97% rename from crates/temporal-server/src/gateway/service/mod.rs rename to crates/temporal-runtime/src/gateway/service/mod.rs index 49c25269c..994df3dfc 100644 --- a/crates/temporal-server/src/gateway/service/mod.rs +++ b/crates/temporal-runtime/src/gateway/service/mod.rs @@ -33,7 +33,7 @@ mod skills; mod vfs_api; mod workflow; -use api_config::engine_session_config_from_api; +use api_config::harness_session_config_from_api; #[cfg(test)] use api_config::*; use auth_api::{ @@ -95,7 +95,7 @@ use auth::{ TokenAudience, }; use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64}; -use engine::{ +use harness::{ ApprovalId, BlobRef, BoundWorkflowToolDispatch, CompactionPolicy, ContextEntry, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentStatus, FunctionToolSpec, ManagedSessionWorkflowTools, ModelSelection, @@ -108,12 +108,12 @@ use engine::{ use llm_clients::{anthropic::messages as anthropic, openai::responses as openai}; use mcp::McpRegistryStore; use store_pg::PgStore; +use temporalio_client::WorkflowExecutionStatus; use temporalio_client::{ Client, WorkflowDescribeOptions, WorkflowHandle, WorkflowQueryOptions, WorkflowSignalOptions, WorkflowStartOptions, WorkflowTerminateOptions, errors::WorkflowInteractionError, errors::WorkflowQueryError, errors::WorkflowStartError, }; -use temporalio_common::protos::temporal::api::enums::v1::WorkflowExecutionStatus; use tools::{ builtin::{BuiltinTool, BuiltinToolOperation}, catalog::SKILL_CATALOG_CONTEXT_KEY, @@ -198,8 +198,8 @@ fn validate_delete_after_close_ms(value: Option) -> Result<(), AgentApiErro } fn session_retention_view( - record: &engine::storage::SessionRecord, - root: &engine::storage::SessionRecord, + record: &harness::storage::SessionRecord, + root: &harness::storage::SessionRecord, ) -> SessionRetentionView { SessionRetentionView { root_session_id: record.retention_root_session_id.as_str().to_owned(), @@ -209,8 +209,8 @@ fn session_retention_view( } fn session_summary_view( - record: engine::storage::SessionRecord, - root: &engine::storage::SessionRecord, + record: harness::storage::SessionRecord, + root: &harness::storage::SessionRecord, access: ResourceAccessSummary, ) -> SessionSummaryView { let retention = session_retention_view(&record, root); @@ -221,9 +221,9 @@ fn session_summary_view( display_name: record.display_name, metadata: record.metadata, lifecycle_status: match record.lifecycle_status { - engine::storage::SessionLifecycleStatus::New => SessionLifecycleStatus::New, - engine::storage::SessionLifecycleStatus::Open => SessionLifecycleStatus::Open, - engine::storage::SessionLifecycleStatus::Closed => SessionLifecycleStatus::Closed, + harness::storage::SessionLifecycleStatus::New => SessionLifecycleStatus::New, + harness::storage::SessionLifecycleStatus::Open => SessionLifecycleStatus::Open, + harness::storage::SessionLifecycleStatus::Closed => SessionLifecycleStatus::Closed, }, activity, closed_at_ms: record.closed_at_ms, @@ -245,8 +245,8 @@ impl GatewayAgentApi { /// A summary for a single session, with its access looked up. async fn session_summary( &self, - record: engine::storage::SessionRecord, - root: &engine::storage::SessionRecord, + record: harness::storage::SessionRecord, + root: &harness::storage::SessionRecord, ) -> Result { let access = self .access_summary(&ResourceRef::Session(record.session_id.as_str().to_owned())) @@ -258,19 +258,19 @@ impl GatewayAgentApi { /// Opaque `session/list` cursor: `{updated_at_ms}:{session_id}`. Session ids /// cannot contain `:` at the first position of the numeric prefix, so /// `split_once` is unambiguous. -fn encode_session_list_cursor(cursor: &engine::storage::SessionListCursor) -> String { +fn encode_session_list_cursor(cursor: &harness::storage::SessionListCursor) -> String { format!("{}:{}", cursor.updated_at_ms, cursor.session_id) } fn decode_session_list_cursor( cursor: &str, -) -> Result { +) -> Result { let invalid = || AgentApiError::invalid_request(format!("invalid session list cursor: {cursor}")); let (updated_at_ms, session_id) = cursor.split_once(':').ok_or_else(invalid)?; let updated_at_ms = updated_at_ms.parse::().map_err(|_| invalid())?; let session_id = SessionId::try_new(session_id).map_err(|_| invalid())?; - Ok(engine::storage::SessionListCursor { + Ok(harness::storage::SessionListCursor { updated_at_ms, session_id, }) @@ -323,11 +323,11 @@ pub(super) enum ContextAppendWaitOutcome { } fn existing_run_submission( - state: &engine::CoreAgentState, + state: &harness::CoreAgentState, submission_id: &SubmissionId, - source: &engine::RunRequestSource, + source: &harness::RunRequestSource, run_config: &RunConfig, - notify_on_terminal: &[engine::RunTerminalNotifyIntent], + notify_on_terminal: &[harness::RunTerminalNotifyIntent], ) -> Option { if let Some(active) = state .runs @@ -368,7 +368,7 @@ fn existing_run_submission( .iter() .find(|run| run.submission_id.as_ref() == Some(submission_id)) { - let digest = engine::request_run_submission_digest(source, run_config, notify_on_terminal); + let digest = harness::request_run_submission_digest(source, run_config, notify_on_terminal); return Some(match completed.submission_digest { Some(existing) if existing != digest => ExistingRunSubmission::Reject, _ => ExistingRunSubmission::ReturnRun { @@ -500,10 +500,10 @@ fn input_admission_failure_from_api_error(error: AgentApiError) -> InputAdmissio /// so only tool results and user messages qualify and a tool result takes /// only text. fn replacement_input( - active: &engine::ContextEntry, - mut input: engine::ContextEntryInput, + active: &harness::ContextEntry, + mut input: harness::ContextEntryInput, item: &InputItem, -) -> Result { +) -> Result { let rejected = |message: &str| InputAdmissionFailureView { kind: InputAdmissionFailureKind::AdmissionRejected, message: message.to_owned(), @@ -526,9 +526,9 @@ fn replacement_input( input.origin = input.origin.or_else(|| active.origin.clone()); // Keep the context's combined estimate known when the entry carried one. input.token_estimate = active.token_estimate.as_ref().map(|estimate| match item { - InputItem::Text { text, .. } => engine::TokenEstimate { + InputItem::Text { text, .. } => harness::TokenEstimate { tokens: u32::try_from(text.trim().len().div_ceil(4)).unwrap_or(u32::MAX), - quality: engine::TokenEstimateQuality::Estimated, + quality: harness::TokenEstimateQuality::Estimated, }, _ => estimate.clone(), }); @@ -884,7 +884,7 @@ impl GatewayAgentApi { session_id: &SessionId, input: Vec, submission_id: SubmissionId, - notify_on_terminal: Vec, + notify_on_terminal: Vec, ) -> Result { let response = self .start_run_internal( @@ -904,7 +904,7 @@ impl GatewayAgentApi { async fn start_run_internal( &self, params: RunStartParams, - internal_notify_on_terminal: Vec, + internal_notify_on_terminal: Vec, ) -> Result, AgentApiError> { self.authorize_method( METHOD_SESSION_RUNS_START, @@ -946,7 +946,7 @@ impl GatewayAgentApi { } let RunStartSource::Input { items } = source; let input = run_input_from_api(self.store.as_ref(), &items).await?; - let source = engine::RunRequestSource::Input { input }; + let source = harness::RunRequestSource::Input { input }; if let Some(existing) = existing_run_submission( &loaded.state, &submission_id, @@ -976,7 +976,7 @@ impl GatewayAgentApi { || status_has_submission(status_before_signal.as_ref(), &submission_id); self.submit_core_command( &session_id, - CoreAgentCommand::RequestRun(engine::RunRequestCommand { + CoreAgentCommand::RequestRun(harness::RunRequestCommand { notify_on_terminal, requested_by: self.requested_by()?, submission_id: Some(submission_id.clone()), @@ -1034,8 +1034,8 @@ impl GatewayAgentApi { async fn load_retention_root( &self, - record: &engine::storage::SessionRecord, - ) -> Result { + record: &harness::storage::SessionRecord, + ) -> Result { if record.retention_root_session_id == record.session_id { return Ok(record.clone()); } @@ -1166,22 +1166,22 @@ impl GatewayAgentApi { async fn read_run_interval( &self, - record: &engine::storage::SessionRecord, + record: &harness::storage::SessionRecord, run_id: RunId, - first_seq: engine::EventSeq, - terminal_seq: Option, - ) -> Result, AgentApiError> { + first_seq: harness::EventSeq, + terminal_seq: Option, + ) -> Result, AgentApiError> { let through = terminal_seq .or_else(|| record.head.as_ref().map(|head| head.seq)) .unwrap_or(first_seq); - let mut after = engine::EventSeq::new(first_seq.as_u64().saturating_sub(1)); - let codec = engine::CoreAgentCodec; + let mut after = harness::EventSeq::new(first_seq.as_u64().saturating_sub(1)); + let codec = harness::CoreAgentCodec; let mut entries = Vec::new(); let mut scanned: usize = 0; loop { let page = self .store - .read_range(engine::storage::ReadSessionEventRange { + .read_range(harness::storage::ReadSessionEventRange { session_id: record.session_id.clone(), after, through, @@ -1217,23 +1217,23 @@ impl GatewayAgentApi { } pub(super) struct LoadedSession { - pub(super) record: engine::storage::SessionRecord, - pub(super) state: engine::CoreAgentState, + pub(super) record: harness::storage::SessionRecord, + pub(super) state: harness::CoreAgentState, } struct RunProjectionMetadata<'a> { - output: Option<&'a engine::ContentRef>, + output: Option<&'a harness::ContentRef>, status: api::RunStatus, - first_seq: engine::EventSeq, - terminal_seq: Option, - source: &'a engine::RunSource, + first_seq: harness::EventSeq, + terminal_seq: Option, + source: &'a harness::RunSource, started_at_ms: Option, completed_at_ms: Option, - usage: Option<&'a engine::LlmUsage>, + usage: Option<&'a harness::LlmUsage>, } fn run_projection_metadata( - state: &engine::CoreAgentState, + state: &harness::CoreAgentState, run_id: RunId, ) -> Option> { state @@ -1424,7 +1424,7 @@ fn managed_workflow_tools_from_api( name: tool_name, kind, parallelism, - execution: engine::ToolExecutionSpec::default(), + execution: harness::ToolExecutionSpec::default(), }, }, target, @@ -1469,8 +1469,8 @@ fn parse_workflow_tool_blob_ref( fn run_terminal_notify_intents( lifecycle_controller: Option<&WorkflowEndpointRef>, notification: Option, - internal: Vec, -) -> Result, AgentApiError> { + internal: Vec, +) -> Result, AgentApiError> { let Some(notification) = notification else { return Ok(internal); }; @@ -1496,7 +1496,7 @@ fn run_terminal_notify_intents( MAX_RUN_TERMINAL_NOTIFICATION_TOKEN_BYTES ))); } - Ok(vec![engine::RunTerminalNotifyIntent { + Ok(vec![harness::RunTerminalNotifyIntent { holder_workflow_id: controller.workflow_id.clone(), token: notification.token, }]) @@ -1509,17 +1509,17 @@ fn is_core_environment_job_tool_id(tool_id: &str) -> bool { ) } -fn is_core_environment_job_binding(binding: &engine::WorkflowToolBinding) -> bool { +fn is_core_environment_job_binding(binding: &harness::WorkflowToolBinding) -> bool { is_core_environment_job_tool_id(binding.definition.tool_id.as_str()) } -fn is_core_subagent_binding(binding: &engine::WorkflowToolBinding) -> bool { +fn is_core_subagent_binding(binding: &harness::WorkflowToolBinding) -> bool { tools::subagents::is_subagent_workflow_tool_id(binding.definition.tool_id.as_str()) } fn validate_subagent_deadline_for_existing_bindings( - state: &engine::CoreAgentState, - features: &engine::FeaturesConfig, + state: &harness::CoreAgentState, + features: &harness::FeaturesConfig, ) -> Result<(), AgentApiError> { let Some(requested_deadline_ms) = features .subagents @@ -2272,7 +2272,7 @@ impl AgentApiService for GatewayAgentApi { ))); } } - let mut config = engine_session_config_from_api( + let mut config = harness_session_config_from_api( params.config, model_defaults::current_session_model(&loaded.state)?, )?; @@ -2376,7 +2376,7 @@ impl AgentApiService for GatewayAgentApi { let page = self .store .list_sessions_for( - engine::storage::ListSessions { + harness::storage::ListSessions { cursor, limit, closed: params.closed, @@ -2511,7 +2511,9 @@ impl AgentApiService for GatewayAgentApi { .store .read_after(ReadSessionEvents { session_id: session_id.clone(), - after: params.after.map(|cursor| engine::EventSeq::new(cursor.seq)), + after: params + .after + .map(|cursor| harness::EventSeq::new(cursor.seq)), limit, }) .await @@ -2531,7 +2533,7 @@ impl AgentApiService for GatewayAgentApi { .await .map_err(map_session_store_error)? .map(|position| event_cursor(position.seq)); - let codec = engine::CoreAgentCodec; + let codec = harness::CoreAgentCodec; let mut events = Vec::with_capacity(page.entries.len()); for entry in &page.entries { let entry = decode_stored_entry(&codec, entry)?; @@ -2672,7 +2674,7 @@ impl AgentApiService for GatewayAgentApi { .await?; let deleted = crate::session_deletion::delete_session_subtree( self.store.as_ref(), - engine::storage::DeleteClosedSessions { + harness::storage::DeleteClosedSessions { session_id: session_id.clone(), cascade: params.cascade, due_at_or_before_ms: None, @@ -2799,7 +2801,7 @@ impl AgentApiService for GatewayAgentApi { match prepared { PreparedAppend::Failed(result) => ordered.push(PreparedAppend::Failed(result)), PreparedAppend::Ready { key, input, text } => { - if let Some(active) = engine::current_context_entry(&loaded.state, &key) + if let Some(active) = harness::current_context_entry(&loaded.state, &key) .filter(|active| active_context_entry_matches_input(active, &input)) { let effective = active_entry_input(active); @@ -3318,7 +3320,7 @@ impl AgentApiService for GatewayAgentApi { )); continue; } - if let Err(error) = engine::validate_note(input.note.as_deref()) { + if let Err(error) = harness::validate_note(input.note.as_deref()) { results.push(approval_decision_failure( input.approval_id, ApprovalDecisionFailureKind::InvalidNote, @@ -3342,8 +3344,8 @@ impl AgentApiService for GatewayAgentApi { )); continue; } - if record.status != engine::ApprovalStatus::Pending { - let kind = if record.status == engine::ApprovalStatus::Cancelled { + if record.status != harness::ApprovalStatus::Pending { + let kind = if record.status == harness::ApprovalStatus::Cancelled { ApprovalDecisionFailureKind::Cancelled } else { ApprovalDecisionFailureKind::AlreadyDecided @@ -3355,13 +3357,13 @@ impl AgentApiService for GatewayAgentApi { )); continue; } - let engine_decision = match input.decision { - ApprovalDecisionKind::Approve => engine::ApprovalDecision::Approved, - ApprovalDecisionKind::Reject => engine::ApprovalDecision::Rejected, + let harness_decision = match input.decision { + ApprovalDecisionKind::Approve => harness::ApprovalDecision::Approved, + ApprovalDecisionKind::Reject => harness::ApprovalDecision::Rejected, }; - let approve = engine_decision == engine::ApprovalDecision::Approved; + let approve = harness_decision == harness::ApprovalDecision::Approved; let response = match &record.request.continuation { - engine::ApprovalContinuation::OpenAiMcp { + harness::ApprovalContinuation::OpenAiMcp { provider_request_id, } => { let response_json = serde_json::json!({ @@ -3383,7 +3385,7 @@ impl AgentApiService for GatewayAgentApi { approval_request_id: provider_request_id.clone(), approve, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: response_ref, media_type: Some("application/json".to_owned()), provider_kind: Some( @@ -3403,16 +3405,16 @@ impl AgentApiService for GatewayAgentApi { token_estimate: None, }) } - engine::ApprovalContinuation::NativeMcp { .. } => None, + harness::ApprovalContinuation::NativeMcp { .. } => None, }; let correlation = format!("approval_{}", uuid::Uuid::new_v4().simple()); self.signal_submit_admissions( &session_id, vec![AgentAdmission { - command: CoreAgentCommand::DecideApproval(engine::ApprovalDecisionCommand { + command: CoreAgentCommand::DecideApproval(harness::ApprovalDecisionCommand { approval_id: approval_id.clone(), run_id, - decision: engine_decision, + decision: harness_decision, note: input.note, decided_by: decided_by.clone(), response, diff --git a/crates/temporal-server/src/gateway/service/model_defaults.rs b/crates/temporal-runtime/src/gateway/service/model_defaults.rs similarity index 90% rename from crates/temporal-server/src/gateway/service/model_defaults.rs rename to crates/temporal-runtime/src/gateway/service/model_defaults.rs index f7a7daf85..dcece8db5 100644 --- a/crates/temporal-server/src/gateway/service/model_defaults.rs +++ b/crates/temporal-runtime/src/gateway/service/model_defaults.rs @@ -27,7 +27,7 @@ pub(super) async fn creation_model( } pub(super) fn current_session_model( - state: &engine::CoreAgentState, + state: &harness::CoreAgentState, ) -> Result { state .lifecycle @@ -91,10 +91,10 @@ mod tests { api_config::model_selection_from_api(route("local", "openai:completions", "pinned")) .unwrap(); let mut previous = - engine_session_config_from_api(api::SessionConfig::default(), model.clone()).unwrap(); - previous.features.web = Some(engine::WebFeature { + harness_session_config_from_api(api::SessionConfig::default(), model.clone()).unwrap(); + previous.features.web = Some(harness::WebFeature { version: 1, - fetch: Some(engine::WebFetchFeature {}), + fetch: Some(harness::WebFetchFeature {}), search: None, }); let profile = api::ProfileDocument { @@ -107,7 +107,7 @@ mod tests { assert_eq!(config.model, model); assert_eq!(config.features.web, None); let replaced = - engine_session_config_from_api(api::SessionConfig::default(), previous.model).unwrap(); + harness_session_config_from_api(api::SessionConfig::default(), previous.model).unwrap(); assert_eq!(replaced, config); assert!( GatewayAgentApi::profile_intent(&profile, None) @@ -135,7 +135,7 @@ mod tests { .unwrap(); let second_model = creation_model(None, async { Ok(second) }).await.unwrap(); let existing = - engine_session_config_from_api(api::SessionConfig::default(), first_model).unwrap(); + harness_session_config_from_api(api::SessionConfig::default(), first_model).unwrap(); first.agent_run = None; let error = creation_model(None, async { Ok(first) }).await.unwrap_err(); assert_eq!(error.kind, AgentApiErrorKind::ModelDefaultUnset); @@ -146,7 +146,7 @@ mod tests { assert_eq!(existing.model.provider_id, "anthropic"); assert_eq!(second_model.provider_id, "private"); let replaced = - engine_session_config_from_api(api::SessionConfig::default(), existing.model.clone()) + harness_session_config_from_api(api::SessionConfig::default(), existing.model.clone()) .unwrap(); assert_eq!(replaced.model, existing.model); } diff --git a/crates/temporal-server/src/gateway/service/models_api.rs b/crates/temporal-runtime/src/gateway/service/models_api.rs similarity index 100% rename from crates/temporal-server/src/gateway/service/models_api.rs rename to crates/temporal-runtime/src/gateway/service/models_api.rs diff --git a/crates/temporal-server/src/gateway/service/oauth_api.rs b/crates/temporal-runtime/src/gateway/service/oauth_api.rs similarity index 100% rename from crates/temporal-server/src/gateway/service/oauth_api.rs rename to crates/temporal-runtime/src/gateway/service/oauth_api.rs diff --git a/crates/temporal-server/src/gateway/service/parse.rs b/crates/temporal-runtime/src/gateway/service/parse.rs similarity index 100% rename from crates/temporal-server/src/gateway/service/parse.rs rename to crates/temporal-runtime/src/gateway/service/parse.rs diff --git a/crates/temporal-server/src/gateway/service/profiles.rs b/crates/temporal-runtime/src/gateway/service/profiles.rs similarity index 94% rename from crates/temporal-server/src/gateway/service/profiles.rs rename to crates/temporal-runtime/src/gateway/service/profiles.rs index 43d92698d..ce14279ad 100644 --- a/crates/temporal-server/src/gateway/service/profiles.rs +++ b/crates/temporal-runtime/src/gateway/service/profiles.rs @@ -1,4 +1,4 @@ -use super::api_config::engine_session_config_from_api; +use super::api_config::harness_session_config_from_api; use super::*; use ::profiles::{ProfileError, ProfileSourceExt, ProfileStore}; @@ -166,7 +166,7 @@ impl GatewayAgentApi { profile .config .clone() - .map(|config| engine_session_config_from_api(config, current_model)) + .map(|config| harness_session_config_from_api(config, current_model)) .transpose()? } else { None @@ -187,14 +187,14 @@ impl GatewayAgentApi { /// The attachment a profile activates when the session has no active /// environment. pub(super) fn default_environment_id( - features: &engine::FeaturesConfig, -) -> Result, AgentApiError> { + features: &harness::FeaturesConfig, +) -> Result, AgentApiError> { features .environments .as_ref() .and_then(|environments| environments.default_attachment()) .map(|attachment| { - engine::EnvironmentId::try_new(attachment.environment_id.clone()) + harness::EnvironmentId::try_new(attachment.environment_id.clone()) .map_err(|error| AgentApiError::invalid_request(error.to_string())) }) .transpose() @@ -226,20 +226,20 @@ mod tests { #[test] fn default_environment_ids_are_fallible_even_before_config_validation() { - let mut features = engine::FeaturesConfig::default(); + let mut features = harness::FeaturesConfig::default(); assert_eq!(default_environment_id(&features).unwrap(), None); - features.environments = Some(engine::EnvironmentsFeature { - environments: vec![engine::EnvironmentAttachment { + features.environments = Some(harness::EnvironmentsFeature { + environments: vec![harness::EnvironmentAttachment { environment_id: "env_ok".into(), default: true, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }], ..Default::default() }); assert_eq!( default_environment_id(&features).unwrap(), - Some(engine::EnvironmentId::new("env_ok")) + Some(harness::EnvironmentId::new("env_ok")) ); features.environments.as_mut().unwrap().environments[0].default = false; assert_eq!(default_environment_id(&features).unwrap(), None); diff --git a/crates/temporal-server/src/gateway/service/session_jobs.rs b/crates/temporal-runtime/src/gateway/service/session_jobs.rs similarity index 99% rename from crates/temporal-server/src/gateway/service/session_jobs.rs rename to crates/temporal-runtime/src/gateway/service/session_jobs.rs index b6b69e903..06a74520d 100644 --- a/crates/temporal-server/src/gateway/service/session_jobs.rs +++ b/crates/temporal-runtime/src/gateway/service/session_jobs.rs @@ -2,7 +2,6 @@ use super::*; use ::environments::{EnvironmentId, EnvironmentJobGroupId, EnvironmentRecord}; use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64_STANDARD}; -use engine::validate_general_string_id; use environment_client::{EnvironmentClientError, EnvironmentDataClient, WebSocketConnectOptions}; use environment_protocol::{ data::{ @@ -25,6 +24,7 @@ use environment_protocol::{ EnvironmentPath, EnvironmentTransport, JobId, }, }; +use harness::validate_general_string_id; impl GatewayAgentApi { pub(super) async fn create_environment_job_records( @@ -83,7 +83,7 @@ impl GatewayAgentApi { let (_client, capabilities) = connect_initialized_environment_data_client( &connection, self.environment_gateway - .connect_options("lightspeed-temporal-server"), + .connect_options("lightspeed-temporal-runtime"), ) .await .map_err(|error| AgentApiError::rejected(error.to_string()))?; @@ -417,7 +417,7 @@ impl GatewayAgentApi { let (client, capabilities) = connect_initialized_environment_data_client( &connection, self.environment_gateway - .connect_options("lightspeed-temporal-server"), + .connect_options("lightspeed-temporal-runtime"), ) .await .map_err(|error| error.to_string())?; @@ -555,7 +555,7 @@ async fn connect_initialized_environment_data_client( let response = client .initialize(&DataInitializeParams { protocol_version: CURRENT_PROTOCOL_VERSION, - client_name: "lightspeed-temporal-server".to_owned(), + client_name: "lightspeed-temporal-runtime".to_owned(), scope: connection.scope.clone(), resume_connection_id: None, }) diff --git a/crates/temporal-server/src/gateway/service/session_lifecycle.rs b/crates/temporal-runtime/src/gateway/service/session_lifecycle.rs similarity index 98% rename from crates/temporal-server/src/gateway/service/session_lifecycle.rs rename to crates/temporal-runtime/src/gateway/service/session_lifecycle.rs index e7405e673..9378ebaf8 100644 --- a/crates/temporal-server/src/gateway/service/session_lifecycle.rs +++ b/crates/temporal-runtime/src/gateway/service/session_lifecycle.rs @@ -1,6 +1,6 @@ //! Session creation, recovery, and preparation at the gateway boundary. use super::*; -use engine::AdmittedManagedSessionWorkflowTools; +use harness::AdmittedManagedSessionWorkflowTools; // Only the effects needed to recover and await session creation. Keeping this // boundary small lets the same recovery logic run against scripted offline I/O. @@ -579,7 +579,7 @@ impl GatewayAgentApi { } fn validate_managed_session_retry( - state: &engine::CoreAgentState, + state: &harness::CoreAgentState, admitted: Option<&AdmittedManagedSessionWorkflowTools>, ) -> Result<(), AgentApiError> { let Some(admitted) = admitted else { @@ -683,7 +683,7 @@ mod tests { fn loaded(status: CoreAgentStatus, revision: u64, managed: bool) -> Box { let session_id = SessionId::new("session-lifecycle"); - let mut state = engine::CoreAgentState::new(); + let mut state = harness::CoreAgentState::new(); state.lifecycle.status = status; state.lifecycle.config_revision = revision; if managed { @@ -693,7 +693,7 @@ mod tests { } Box::new(LoadedSession { state, - record: engine::storage::SessionRecord { + record: harness::storage::SessionRecord { session_id: session_id.clone(), display_name: None, metadata: BTreeMap::new(), @@ -975,15 +975,15 @@ mod tests { #[test] fn managed_session_retry_requires_the_durable_creation_fingerprint() { let universe_id = uuid::Uuid::from_u128(1); - let declaration = engine::ManagedSessionWorkflowTools::v1( - Some(engine::WorkflowEndpointRef { + let declaration = harness::ManagedSessionWorkflowTools::v1( + Some(harness::WorkflowEndpointRef { workflow_id: "global controller/work-1".to_owned(), workflow_kind: "agent_work".to_owned(), }), Vec::new(), ); let admitted = declaration.admit(universe_id).expect("admit"); - let mut state = engine::CoreAgentState::new(); + let mut state = harness::CoreAgentState::new(); state.workflow_tools.session_universe_id = Some(universe_id); state.workflow_tools.managed_creation_fingerprint = Some( declaration @@ -992,8 +992,8 @@ mod tests { ); validate_managed_session_retry(&state, Some(&admitted)).expect("matching retry"); - let conflicting = engine::ManagedSessionWorkflowTools::v1( - Some(engine::WorkflowEndpointRef { + let conflicting = harness::ManagedSessionWorkflowTools::v1( + Some(harness::WorkflowEndpointRef { workflow_id: "another controller".to_owned(), workflow_kind: "agent_work".to_owned(), }), @@ -1006,7 +1006,7 @@ mod tests { AgentApiErrorKind::Conflict ); assert_eq!( - validate_managed_session_retry(&engine::CoreAgentState::new(), Some(&admitted)) + validate_managed_session_retry(&harness::CoreAgentState::new(), Some(&admitted)) .expect_err("standalone session cannot become managed") .kind, AgentApiErrorKind::Conflict diff --git a/crates/temporal-server/src/gateway/service/session_preparation.rs b/crates/temporal-runtime/src/gateway/service/session_preparation.rs similarity index 96% rename from crates/temporal-server/src/gateway/service/session_preparation.rs rename to crates/temporal-runtime/src/gateway/service/session_preparation.rs index af95d1ab2..68bdeed1f 100644 --- a/crates/temporal-server/src/gateway/service/session_preparation.rs +++ b/crates/temporal-runtime/src/gateway/service/session_preparation.rs @@ -26,11 +26,11 @@ impl SessionPreparationService { // installs the read tools, any editing attachment the write tools. config.builtin = match features.vfs.as_ref().and_then(|vfs| vfs.tool_access()) { None => tools::toolset::BuiltinToolsetConfig::disabled(), - Some(engine::WorkspaceAccess::Read) => tools::toolset::BuiltinToolsetConfig { + Some(harness::WorkspaceAccess::Read) => tools::toolset::BuiltinToolsetConfig { vfs: tools::toolset::FilesystemToolsetConfig::read_only(), ..tools::toolset::BuiltinToolsetConfig::disabled() }, - Some(engine::WorkspaceAccess::Edit) => { + Some(harness::WorkspaceAccess::Edit) => { tools::toolset::BuiltinToolsetConfig::workspace() } }; @@ -97,7 +97,7 @@ impl SessionPreparationService { WorkflowToolCompletion::Promises { reply_schema_ref: None, deadline_after_ms: None, - max_promises: engine::MAX_COMPLETION_PROMISES, + max_promises: harness::MAX_COMPLETION_PROMISES, key_source: WorkflowToolCompletionKeySource::ArrayItemField { pointer: "/jobs".to_owned(), field: "job_id".to_owned(), @@ -172,14 +172,14 @@ impl SessionPreparationService { tools::subagents::SubagentToolKind::Run, WorkflowToolCompletion::Joined { reply_schema_ref: None, - deadline_after_ms: engine::SUBAGENT_DEADLINE_CEILING_MS, + deadline_after_ms: harness::SUBAGENT_DEADLINE_CEILING_MS, }, ), ( tools::subagents::SubagentToolKind::Spawn, WorkflowToolCompletion::Promises { reply_schema_ref: None, - deadline_after_ms: Some(engine::SUBAGENT_DEADLINE_CEILING_MS), + deadline_after_ms: Some(harness::SUBAGENT_DEADLINE_CEILING_MS), max_promises: 1, key_source: WorkflowToolCompletionKeySource::Reply, }, @@ -193,7 +193,7 @@ impl SessionPreparationService { tools::subagents::SubagentToolKind::Spawn => "subagent.spawn", }, Default::default(), - engine::ToolParallelism::ParallelSafe, + harness::ToolParallelism::ParallelSafe, Default::default(), ); declarations.push(WorkflowToolDeclaration::new( @@ -252,7 +252,7 @@ impl SessionPreparationService { ))); } } - let mut validation_state = engine::CoreAgentState::new(); + let mut validation_state = harness::CoreAgentState::new(); validation_state.workflow_tools.bindings = source.bindings.clone(); validate_subagent_deadline_for_existing_bindings( &validation_state, @@ -265,7 +265,7 @@ impl SessionPreparationService { }); let mut bindings = source.bindings.clone(); for declaration in &declarations { - let binding = engine::WorkflowToolBinding::admit( + let binding = harness::WorkflowToolBinding::admit( self.store.config().universe_id, declaration.definition.clone(), declaration.target.clone(), @@ -315,7 +315,7 @@ impl SessionPreparationService { impl SessionPreparationService { pub(crate) async fn validate_workspace_attachment_targets( &self, - features: &engine::FeaturesConfig, + features: &harness::FeaturesConfig, ) -> Result<(), AgentApiError> { let Some(vfs) = features.vfs.as_ref() else { return Ok(()); @@ -399,7 +399,7 @@ impl SessionPreparationService { ContextEntryKey::new("instructions.050.profile"), ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(reference), + content: harness::ContentRef::text(reference), preview: Some("Profile instructions".to_owned()), origin: None, provenance_ref: None, diff --git a/crates/temporal-server/src/gateway/service/skills.rs b/crates/temporal-runtime/src/gateway/service/skills.rs similarity index 97% rename from crates/temporal-server/src/gateway/service/skills.rs rename to crates/temporal-runtime/src/gateway/service/skills.rs index 066d7fdee..980a5b98a 100644 --- a/crates/temporal-server/src/gateway/service/skills.rs +++ b/crates/temporal-runtime/src/gateway/service/skills.rs @@ -111,10 +111,10 @@ pub(super) fn skill_list_response( async fn vfs_skill_list_from_context( blobs: &dyn BlobStore, - state: &engine::CoreAgentState, + state: &harness::CoreAgentState, ) -> Result { let Some(entry) = - engine::current_context_entry(state, &ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY)) + harness::current_context_entry(state, &ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY)) else { return Ok(SkillListResponse { catalogs: Vec::new(), @@ -185,12 +185,12 @@ fn environment_skill_list_view( pub(super) async fn skill_list_from_context( blobs: &dyn BlobStore, - state: &engine::CoreAgentState, + state: &harness::CoreAgentState, ) -> Result { let mut response = vfs_skill_list_from_context(blobs, state).await?; let key = ContextEntryKey::new(tools::skills::environment::ENVIRONMENT_SKILL_CATALOG_CONTEXT_KEY); - if let Some(entry) = engine::current_context_entry(state, &key) + if let Some(entry) = harness::current_context_entry(state, &key) && let Some(reference) = &entry.provenance_ref { let bytes = blobs diff --git a/crates/temporal-server/src/gateway/service/tests.rs b/crates/temporal-runtime/src/gateway/service/tests.rs similarity index 91% rename from crates/temporal-server/src/gateway/service/tests.rs rename to crates/temporal-runtime/src/gateway/service/tests.rs index a9ffee91d..2b15e6318 100644 --- a/crates/temporal-server/src/gateway/service/tests.rs +++ b/crates/temporal-runtime/src/gateway/service/tests.rs @@ -5,22 +5,22 @@ use tools::prompts::active_prompt_instruction_entries as active_prompt_context_e use tools::skills::SkillLocation; use vfs::VfsPath; -fn active_entry(kind: ContextEntryKind) -> engine::ContextEntry { - engine::ContextEntry { +fn active_entry(kind: ContextEntryKind) -> harness::ContextEntry { + harness::ContextEntry { origin: Some("user:ada".to_owned()), - entry_id: engine::ContextEntryId::new(3), + entry_id: harness::ContextEntryId::new(3), key: None, kind, - source: engine::ContextEntrySource::RunInput { - run_id: engine::RunId::new(1), + source: harness::ContextEntrySource::RunInput { + run_id: harness::RunId::new(1), input_index: 0, }, - content: engine::ContentRef::text(BlobRef::from_bytes(b"original")), + content: harness::ContentRef::text(BlobRef::from_bytes(b"original")), preview: None, provenance_ref: None, - token_estimate: Some(engine::TokenEstimate { + token_estimate: Some(harness::TokenEstimate { tokens: 900, - quality: engine::TokenEstimateQuality::ProviderCounted, + quality: harness::TokenEstimateQuality::ProviderCounted, }), supersedes: None, } @@ -37,7 +37,7 @@ fn text_item(text: &str) -> InputItem { #[test] fn replacements_keep_the_entry_kind_and_origin() { let tool_result = ContextEntryKind::ToolResult { - call_id: engine::ToolCallId::try_new("call_1").expect("call id"), + call_id: harness::ToolCallId::try_new("call_1").expect("call id"), is_error: false, }; let active = active_entry(tool_result.clone()); @@ -52,9 +52,9 @@ fn replacements_keep_the_entry_kind_and_origin() { assert_eq!(input.origin.as_deref(), Some("user:ada")); assert_eq!( input.token_estimate, - Some(engine::TokenEstimate { + Some(harness::TokenEstimate { tokens: 9, - quality: engine::TokenEstimateQuality::Estimated, + quality: harness::TokenEstimateQuality::Estimated, }) ); @@ -93,7 +93,7 @@ fn admission_failure_mapping_uses_gateway_error_kinds() { AgentApiErrorKind::Rejected ); let mut revision_conflict = failure(AgentAdmissionFailureKind::RejectedCommand); - revision_conflict.rejection = Some(engine::CommandRejection::context_revision_conflict(1, 2)); + revision_conflict.rejection = Some(harness::CommandRejection::context_revision_conflict(1, 2)); assert_eq!( map_admission_failure_to_api_error(&revision_conflict).kind, AgentApiErrorKind::Conflict @@ -106,13 +106,13 @@ fn legacy_subagent_bindings_retain_their_immutable_deadline_ceiling() { let tool = tools::definitions::register( "subagent.run", Default::default(), - engine::ToolParallelism::ParallelSafe, + harness::ToolParallelism::ParallelSafe, Default::default(), ); let tool_id = WorkflowToolId::new(tools::subagents::AGENT_RUN_WORKFLOW_TOOL_ID); - let binding = engine::WorkflowToolBinding::admit( + let binding = harness::WorkflowToolBinding::admit( uuid::Uuid::from_u128(1), - engine::WorkflowToolDefinition { + harness::WorkflowToolDefinition { tool_id: tool_id.clone(), revision: 1, semantic_type: tools::subagents::AGENT_RUN_WORKFLOW_SEMANTIC_TYPE.to_owned(), @@ -131,20 +131,20 @@ fn legacy_subagent_bindings_retain_their_immutable_deadline_ceiling() { }, ) .expect("legacy subagent binding"); - let mut state = engine::CoreAgentState::new(); + let mut state = harness::CoreAgentState::new(); state.workflow_tools.bindings.insert(tool_id, binding); - let mut features = engine::FeaturesConfig { - subagents: Some(engine::SubagentsFeature { - agents: vec![engine::SubagentAgentConfig { + let mut features = harness::FeaturesConfig { + subagents: Some(harness::SubagentsFeature { + agents: vec![harness::SubagentAgentConfig { profile_id: "reviewer".to_owned(), }], - limits: engine::SubagentLimits { + limits: harness::SubagentLimits { deadline_ms: LEGACY_CEILING_MS, - ..engine::SubagentLimits::default() + ..harness::SubagentLimits::default() }, - ..engine::SubagentsFeature::default() + ..harness::SubagentsFeature::default() }), - ..engine::FeaturesConfig::default() + ..harness::FeaturesConfig::default() }; validate_subagent_deadline_for_existing_bindings(&state, &features) @@ -442,7 +442,7 @@ fn run_terminal_notification_derives_destination_from_controller() { Vec::new(), ) .expect("derive controller notification"), - vec![engine::RunTerminalNotifyIntent { + vec![harness::RunTerminalNotifyIntent { holder_workflow_id: "controller-workflow-1".to_owned(), token: "terminal-token-1".to_owned(), }] @@ -508,7 +508,7 @@ fn skill_list_response_exposes_readable_locations() { #[test] fn environment_activation_lowers_to_active_environment_command() { - let environment_id = engine::EnvironmentId::new("local"); + let environment_id = harness::EnvironmentId::new("local"); let command = super::environments::activate_environment_command(environment_id.clone()); assert!(matches!( @@ -534,7 +534,7 @@ fn declared_mcp_attachment_materializes_remote_tool() { record.allowed_tools = Some(vec!["lookup_customer".to_owned()]); record.approval = mcp::McpApprovalPolicy::Never; record.defer_loading = Some(true); - let attachment = engine::McpServerAttachment { + let attachment = harness::McpServerAttachment { server_id: "durable-crm-server".to_owned(), tools: None, }; @@ -546,13 +546,13 @@ fn declared_mcp_attachment_materializes_remote_tool() { let tools = patch.apply_to(&active).expect("apply MCP patch"); let tool = tools.get(&tool_name).expect("MCP tool"); - let engine::ToolKind::RemoteMcp(spec) = &tool.kind else { + let harness::ToolKind::RemoteMcp(spec) = &tool.kind else { panic!("expected remote MCP tool"); }; assert_eq!(spec.server_id, "durable-crm-server"); assert_eq!(spec.server_label, "crm"); assert_eq!(spec.allowed_tools, Some(vec!["lookup_customer".to_owned()])); - assert_eq!(spec.approval, engine::RemoteMcpApprovalPolicy::Never); + assert_eq!(spec.approval, harness::RemoteMcpApprovalPolicy::Never); assert_eq!(spec.defer_loading, Some(true)); } @@ -567,7 +567,7 @@ fn mcp_attachment_subsets_constrain_every_execution_and_exposure_mode() { record.execution = execution; record.exposure = exposure; record.allowed_tools = Some(vec!["search".into(), "delete_customer".into()]); - let attachment = engine::McpServerAttachment { + let attachment = harness::McpServerAttachment { server_id: "crm".into(), tools: Some(vec!["search".into()]), }; @@ -575,7 +575,7 @@ fn mcp_attachment_subsets_constrain_every_execution_and_exposure_mode() { record.allowed_tools = allowlist; let tool = mcp_api::mcp_tool_from_config_attachment(&attachment, &record, None).unwrap(); - let engine::ToolKind::RemoteMcp(spec) = tool.kind else { + let harness::ToolKind::RemoteMcp(spec) = tool.kind else { panic!("expected remote MCP tool"); }; assert_eq!(spec.allowed_tools, Some(vec!["search".into()])); @@ -586,14 +586,14 @@ fn mcp_attachment_subsets_constrain_every_execution_and_exposure_mode() { mcp_api::mcp_tool_from_config_attachment(&attachment, &record, None).unwrap_err(); assert_eq!(error.kind, AgentApiErrorKind::InvalidRequest); - let unrestricted_attachment = engine::McpServerAttachment { + let unrestricted_attachment = harness::McpServerAttachment { tools: None, ..attachment }; let tool = mcp_api::mcp_tool_from_config_attachment(&unrestricted_attachment, &record, None) .unwrap(); - let engine::ToolKind::RemoteMcp(spec) = tool.kind else { + let harness::ToolKind::RemoteMcp(spec) = tool.kind else { panic!("expected remote MCP tool"); }; assert_eq!(spec.allowed_tools, record.allowed_tools); @@ -643,8 +643,8 @@ fn grant_leases_require_creation_time_retrievable_exposure() { require_retrievable_grant(&retrievable).expect("retrievable grant accepted"); } -fn mcp_config_attachment() -> engine::McpServerAttachment { - engine::McpServerAttachment { +fn mcp_config_attachment() -> harness::McpServerAttachment { + harness::McpServerAttachment { server_id: "crm".to_owned(), tools: None, } @@ -684,12 +684,12 @@ fn mcp_attachment_with_grant_materializes_auth_ref_for_bearer_server() { mcp_api::mcp_tool_from_config_attachment(&mcp_config_attachment(), &record, Some(&grant)) .expect("materialize MCP tool with grant"); - let engine::ToolKind::RemoteMcp(spec) = &tool.kind else { + let harness::ToolKind::RemoteMcp(spec) = &tool.kind else { panic!("expected remote MCP tool"); }; assert_eq!( spec.auth_ref, - Some(engine::SecretRef { + Some(harness::SecretRef { namespace: "mcp_server".to_owned(), id: "crm".to_owned(), }) @@ -868,13 +868,13 @@ fn prompt_report_ref_reads_prompt_provider_metadata() { "prompt instructions: instructions.md", ); let entry = ContextEntry { - entry_id: engine::ContextEntryId::new(1), + entry_id: harness::ContextEntryId::new(1), key: Some(ContextEntryKey::new(format!( "{}.0000.project", tools::prompts::PROMPT_INSTRUCTIONS_CONTEXT_KEY_PREFIX ))), kind: input.kind, - source: engine::ContextEntrySource::ContextEdit, + source: harness::ContextEntrySource::ContextEdit, content: input.content, preview: input.preview, origin: input.origin, @@ -882,7 +882,7 @@ fn prompt_report_ref_reads_prompt_provider_metadata() { token_estimate: input.token_estimate, supersedes: None, }; - let mut state = engine::CoreAgentState::new(); + let mut state = harness::CoreAgentState::new(); state.context.entries = vec![entry]; let active_entries = active_prompt_context_entries(&state); @@ -893,7 +893,7 @@ fn prompt_report_ref_reads_prompt_provider_metadata() { #[test] fn session_start_config_maps_reasoning_and_max_output_tokens() { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { generation: Some(api::GenerationConfig { max_output_tokens: Some(2048), @@ -914,7 +914,7 @@ fn session_start_config_maps_reasoning_and_max_output_tokens() { #[test] fn session_start_config_rejects_unknown_reasoning_effort() { - let error = engine_session_config_from_api( + let error = harness_session_config_from_api( api::SessionConfig { generation: Some(api::GenerationConfig { max_output_tokens: None, @@ -934,7 +934,7 @@ fn session_start_config_rejects_unknown_reasoning_effort() { #[test] fn session_start_config_maps_tool_choice_and_parallel_tool_use() { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { generation: Some(api::GenerationConfig { max_output_tokens: None, @@ -953,7 +953,7 @@ fn session_start_config_maps_tool_choice_and_parallel_tool_use() { assert_eq!( config.generation.tool_choice, - Some(engine::ToolChoice::Specific { + Some(harness::ToolChoice::Specific { tool_name: ToolName::new("web_fetch") }) ); @@ -962,7 +962,7 @@ fn session_start_config_maps_tool_choice_and_parallel_tool_use() { #[test] fn session_start_config_maps_provider_triggered_compaction() { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { context: Some(api::ContextConfig { input_limit_tokens: None, @@ -986,7 +986,7 @@ fn session_start_config_maps_provider_triggered_compaction() { #[test] fn session_start_config_maps_provider_standalone_compaction() { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { context: Some(api::ContextConfig { input_limit_tokens: None, @@ -1013,7 +1013,7 @@ fn session_start_config_maps_provider_standalone_compaction() { #[test] fn run_start_config_maps_model_and_generation_overrides() { let session_config = - engine_session_config_from_api(api::SessionConfig::default(), openai_model()) + harness_session_config_from_api(api::SessionConfig::default(), openai_model()) .expect("session config"); let mut run_config = RunConfig::default(); @@ -1053,7 +1053,7 @@ fn run_start_config_maps_model_and_generation_overrides() { #[test] fn run_start_config_maps_tool_choice() { let session_config = - engine_session_config_from_api(api::SessionConfig::default(), openai_model()) + harness_session_config_from_api(api::SessionConfig::default(), openai_model()) .expect("session config"); let mut run_config = RunConfig::default(); @@ -1076,14 +1076,14 @@ fn run_start_config_maps_tool_choice() { assert_eq!( run_config.tool_choice.expect("tool choice"), - engine::ToolChoice::RequiredAny + harness::ToolChoice::RequiredAny ); } #[test] fn run_start_without_overrides_keeps_session_defaults_out_of_run_config() { let mut session_config = - engine_session_config_from_api(api::SessionConfig::default(), openai_model()) + harness_session_config_from_api(api::SessionConfig::default(), openai_model()) .expect("session config"); session_config.generation.max_output_tokens = Some(4096); session_config.generation.reasoning_effort = Some("high".to_owned()); @@ -1100,18 +1100,18 @@ fn session_processing_tier_maps_all_openai_tiers() { for (tier, expected) in [ ( api::ModelProcessingTier::Standard, - engine::ModelProcessingTier::Standard, + harness::ModelProcessingTier::Standard, ), ( api::ModelProcessingTier::Fast, - engine::ModelProcessingTier::Fast, + harness::ModelProcessingTier::Fast, ), ( api::ModelProcessingTier::Flex, - engine::ModelProcessingTier::Flex, + harness::ModelProcessingTier::Flex, ), ] { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { generation: Some(api::GenerationConfig { processing_tier: Some(tier), @@ -1128,7 +1128,7 @@ fn session_processing_tier_maps_all_openai_tiers() { #[test] fn run_processing_tier_overrides_the_session_default() { - let session_config = engine_session_config_from_api( + let session_config = harness_session_config_from_api( api::SessionConfig { generation: Some(api::GenerationConfig { processing_tier: Some(api::ModelProcessingTier::Standard), @@ -1154,7 +1154,7 @@ fn run_processing_tier_overrides_the_session_default() { assert_eq!( run_config.processing_tier, - Some(engine::ModelProcessingTier::Fast) + Some(harness::ModelProcessingTier::Fast) ); } @@ -1163,7 +1163,7 @@ fn session_processing_tier_rejects_compatible_custom_providers() { let mut model = openai_model(); model.provider_id = "deepseek".to_owned(); model.api_kind = ProviderApiKind::OpenAiCompletions; - let error = engine_session_config_from_api( + let error = harness_session_config_from_api( api::SessionConfig { generation: Some(api::GenerationConfig { processing_tier: Some(api::ModelProcessingTier::Fast), @@ -1181,7 +1181,7 @@ fn session_processing_tier_rejects_compatible_custom_providers() { #[test] fn run_start_records_only_explicit_limit_overrides() { let mut session_config = - engine_session_config_from_api(api::SessionConfig::default(), openai_model()) + harness_session_config_from_api(api::SessionConfig::default(), openai_model()) .expect("session config"); session_config.limits.max_turns = Some(12); session_config.limits.max_tool_rounds = Some(3); @@ -1209,28 +1209,28 @@ fn existing_run_submission_rejects_completed_duplicate_with_different_input() { let run_config = RunConfig::default(); let original_input = vec![test_user_message_input(BlobRef::from_bytes(b"original"))]; let changed_input = vec![test_user_message_input(BlobRef::from_bytes(b"changed"))]; - let original_source = engine::RunRequestSource::Input { + let original_source = harness::RunRequestSource::Input { input: original_input.clone(), }; - let changed_source = engine::RunRequestSource::Input { + let changed_source = harness::RunRequestSource::Input { input: changed_input, }; - let mut state = engine::CoreAgentState::new(); - state.runs.completed.push(engine::RunRecord { + let mut state = harness::CoreAgentState::new(); + state.runs.completed.push(harness::RunRecord { notify_on_terminal: Vec::new(), run_id: RunId::new(7), status: RunStatus::Completed, submission_id: Some(submission_id.clone()), - submission_digest: Some(engine::request_run_submission_digest( + submission_digest: Some(harness::request_run_submission_digest( &original_source, &run_config, &[], )), - source: engine::RunSource::Input { + source: harness::RunSource::Input { input: original_input, }, - first_seq: engine::EventSeq::new(1), - terminal_seq: engine::EventSeq::new(1), + first_seq: harness::EventSeq::new(1), + terminal_seq: harness::EventSeq::new(1), accepted_at_ms: 1, started_at_ms: Some(1), completed_at_ms: 1, @@ -1255,7 +1255,7 @@ fn existing_run_submission_rejects_completed_duplicate_with_different_input() { &submission_id, &original_source, &run_config, - &[engine::RunTerminalNotifyIntent { + &[harness::RunTerminalNotifyIntent { holder_workflow_id: "controller-1".to_owned(), token: "changed-token".to_owned(), }], @@ -1268,10 +1268,10 @@ fn existing_run_submission_rejects_completed_duplicate_with_different_input() { fn features_default_off_for_sessions() { // Secure by default: an empty config document grants nothing — no web // tools, no filesystem tools, no Fleet/timers. - let config = engine_session_config_from_api(api::SessionConfig::default(), openai_model()) + let config = harness_session_config_from_api(api::SessionConfig::default(), openai_model()) .expect("map config"); - assert_eq!(config.features, engine::FeaturesConfig::default()); + assert_eq!(config.features, harness::FeaturesConfig::default()); assert!(config.features.web.is_none()); assert!(config.features.vfs.is_none()); } @@ -1303,7 +1303,7 @@ fn environment_attachments_map_to_grants_and_reject_inherit_in_session_config() assert!(!default_feature.selection); assert!(default_feature.environments.is_empty()); - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { features: Some(api::FeaturesConfig { environments: Some(environments_feature(vec![environment_attachment( @@ -1321,7 +1321,7 @@ fn environment_attachments_map_to_grants_and_reject_inherit_in_session_config() assert!(environments.selection); assert_eq!( environments.tool_access(), - Some(engine::EnvironmentAccess::Jobs) + Some(harness::EnvironmentAccess::Jobs) ); assert_eq!( environments @@ -1337,7 +1337,7 @@ fn environment_attachments_map_to_grants_and_reject_inherit_in_session_config() environment_attachment(Some("env_a"), true), environment_attachment(None, false), ] { - let error = engine_session_config_from_api( + let error = harness_session_config_from_api( api::SessionConfig { features: Some(api::FeaturesConfig { environments: Some(environments_feature(vec![attachment])), @@ -1354,7 +1354,7 @@ fn environment_attachments_map_to_grants_and_reject_inherit_in_session_config() #[test] fn web_feature_grant_maps_search_and_fetch() { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { features: Some(api::FeaturesConfig { web: Some(api::WebFeature { @@ -1381,7 +1381,7 @@ fn web_feature_grant_maps_search_and_fetch() { #[test] fn web_search_rejects_explicit_enable_for_unsupported_api_kind() { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { features: Some(api::FeaturesConfig { web: Some(api::WebFeature { @@ -1409,13 +1409,13 @@ fn web_search_rejects_explicit_enable_for_unsupported_api_kind() { .expect_err("web search must reject OpenAI Completions"); assert!(matches!( error, - engine::DomainError::ProviderCompatibility(_) + harness::DomainError::ProviderCompatibility(_) )); } #[test] fn web_search_accepts_anthropic_messages() { - let config = engine_session_config_from_api( + let config = harness_session_config_from_api( api::SessionConfig { features: Some(api::FeaturesConfig { web: Some(api::WebFeature { @@ -1472,18 +1472,18 @@ fn vfs_attachments_derive_the_tool_surface() { (vec![], None), ( vec![attachment("/ref", api::WorkspaceAccess::Read)], - Some(engine::WorkspaceAccess::Read), + Some(harness::WorkspaceAccess::Read), ), ( vec![ attachment("/ref", api::WorkspaceAccess::Read), attachment("/workspace", api::WorkspaceAccess::Edit), ], - Some(engine::WorkspaceAccess::Edit), + Some(harness::WorkspaceAccess::Edit), ), ] { let config = - engine_session_config_from_api(vfs(workspaces), openai_model()).expect("map config"); + harness_session_config_from_api(vfs(workspaces), openai_model()).expect("map config"); assert_eq!( config.features.vfs.expect("vfs feature").tool_access(), expected @@ -1499,7 +1499,7 @@ fn vfs_attachments_derive_the_tool_surface() { ..attachment("/neither", api::WorkspaceAccess::Read) }; for invalid in [both, neither] { - let error = engine_session_config_from_api(vfs(vec![invalid]), openai_model()) + let error = harness_session_config_from_api(vfs(vec![invalid]), openai_model()) .expect_err("an attachment names exactly one resource"); assert_eq!(error.kind, AgentApiErrorKind::InvalidRequest); } @@ -1528,7 +1528,7 @@ fn profile_and_session_grants_derive_vfs_transfer_tools() { serde_json::from_value(serde_json::json!({"config": {"features": features}})) .unwrap(); let config = - engine_session_config_from_api(profile.config.unwrap(), openai_model()).unwrap(); + harness_session_config_from_api(profile.config.unwrap(), openai_model()).unwrap(); let toolset_config = GatewayAgentApi::session_toolset_config(&config, environments, false); let registered = tools::toolset::register_toolset(&toolset_config).unwrap(); @@ -1584,7 +1584,7 @@ fn profile_and_session_grants_derive_vfs_transfer_tools() { #[tokio::test(flavor = "current_thread")] async fn context_entry_input_from_api_stores_text_as_user_message() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let entry = context_entry_input_from_api( &store, @@ -1599,8 +1599,8 @@ async fn context_entry_input_from_api_stores_text_as_user_message() { assert_eq!( entry.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User, } ); assert_eq!(entry.content.media_type.as_deref(), Some("text/plain")); @@ -1615,7 +1615,7 @@ async fn context_entry_input_from_api_stores_text_as_user_message() { #[tokio::test(flavor = "current_thread")] async fn context_entry_input_from_api_rejects_empty_text() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let error = context_entry_input_from_api( &store, @@ -1633,7 +1633,7 @@ async fn context_entry_input_from_api_rejects_empty_text() { #[tokio::test(flavor = "current_thread")] async fn context_entry_input_from_api_stores_catalog_with_its_title() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let entry = context_entry_input_from_api( &store, @@ -1647,7 +1647,7 @@ async fn context_entry_input_from_api_stores_catalog_with_its_title() { assert_eq!( entry.kind, - engine::ContextEntryKind::Catalog { + harness::ContextEntryKind::Catalog { title: "Bot directory".to_owned(), } ); @@ -1674,7 +1674,7 @@ async fn context_entry_input_from_api_stores_catalog_with_its_title() { #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_rejects_catalog_items() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let error = run_input_from_api( &store, @@ -1691,7 +1691,7 @@ async fn run_input_from_api_rejects_catalog_items() { #[tokio::test(flavor = "current_thread")] async fn context_entry_input_from_api_preserves_text_ref() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store.insert_text("buffered room chatter").await; let entry = context_entry_input_from_api( @@ -1710,7 +1710,7 @@ async fn context_entry_input_from_api_preserves_text_ref() { #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_maps_image_media_to_user_message_entry() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store .put_bytes(vec![0x89, 0x50, 0x4e, 0x47]) .await @@ -1740,8 +1740,8 @@ async fn run_input_from_api_maps_image_media_to_user_message_entry() { let media = &input[1]; assert_eq!( media.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User, } ); assert_eq!(media.content.content_ref, blob_ref); @@ -1751,7 +1751,7 @@ async fn run_input_from_api_maps_image_media_to_user_message_entry() { #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_maps_document_media_to_user_message_entry() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let pdf_ref = store .put_bytes(b"%PDF-1.4 fake".to_vec()) .await @@ -1798,7 +1798,7 @@ async fn run_input_from_api_maps_document_media_to_user_message_entry() { #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_rejects_unsupported_document_media() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store.put_bytes(vec![1, 2, 3]).await.expect("store blob"); let docx = run_input_from_api( @@ -1838,7 +1838,7 @@ async fn run_input_from_api_rejects_unsupported_document_media() { #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_rejects_unprepared_audio() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store .put_bytes(b"OggS fake voice note".to_vec()) .await @@ -1863,7 +1863,7 @@ async fn run_input_from_api_rejects_unprepared_audio() { #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_rejects_unsupported_media() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store.put_bytes(vec![1, 2, 3]).await.expect("store blob"); let bad_mime = run_input_from_api( @@ -1883,7 +1883,7 @@ async fn run_input_from_api_rejects_unsupported_media() { #[tokio::test(flavor = "current_thread")] async fn context_entry_input_from_api_accepts_media() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store.put_bytes(vec![1, 2, 3]).await.expect("store blob"); let entry = context_entry_input_from_api( @@ -1901,8 +1901,8 @@ async fn context_entry_input_from_api_accepts_media() { assert_eq!( entry.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User, } ); assert_eq!(entry.content.content_ref, blob_ref); @@ -1912,7 +1912,7 @@ async fn context_entry_input_from_api_accepts_media() { #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_preserves_single_text_ref() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store.insert_text("hello from cas").await; let input = run_input_from_api( @@ -1930,15 +1930,15 @@ async fn run_input_from_api_preserves_single_text_ref() { assert_eq!(input[0].content.content_ref, blob_ref); assert_eq!( input[0].kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User, } ); } #[tokio::test(flavor = "current_thread")] async fn run_input_from_api_stores_text_and_preserves_refs() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let blob_ref = store.insert_text(" second ").await; let input = run_input_from_api( @@ -1973,7 +1973,7 @@ async fn run_input_from_api_stores_text_and_preserves_refs() { #[tokio::test(flavor = "current_thread")] async fn blob_api_helpers_put_get_and_check_many() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let put = put_blobs( &store, @@ -2022,7 +2022,7 @@ async fn blob_api_helpers_put_get_and_check_many() { #[tokio::test(flavor = "current_thread")] async fn vfs_snapshot_api_helpers_commit_and_read_manifest() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let snapshot = vfs::create_inline_snapshot( &store, None, @@ -2059,7 +2059,7 @@ async fn vfs_snapshot_api_helpers_commit_and_read_manifest() { #[tokio::test(flavor = "current_thread")] async fn vfs_snapshot_commit_rejects_missing_file_blob_refs() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let missing_ref = BlobRef::from_bytes(b"missing"); let manifest = vfs::VfsSnapshotManifest { schema_version: vfs::VFS_SNAPSHOT_SCHEMA_VERSION.to_owned(), @@ -2111,10 +2111,10 @@ fn openai_model() -> ModelSelection { fn test_user_message_input(content_ref: BlobRef) -> ContextEntryInput { ContextEntryInput { - kind: engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + kind: harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User, }, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, @@ -2350,7 +2350,7 @@ fn auth_flow_views_carry_derived_status() { #[tokio::test(flavor = "current_thread")] async fn input_origin_survives_admission_and_projection_without_changing_model_content() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let body = store.put_bytes(b"event body".to_vec()).await.unwrap(); let items = vec![ InputItem::Text { @@ -2404,14 +2404,14 @@ async fn input_origin_survives_admission_and_projection_without_changing_model_c .await .unwrap(); assert_eq!(appended, entries[i]); - let entry = engine::ContextEntry { - entry_id: engine::ContextEntryId::new(i as u64 + 1), + let entry = harness::ContextEntry { + entry_id: harness::ContextEntryId::new(i as u64 + 1), key: None, kind: entries[i].kind.clone(), content: entries[i].content.clone(), - source: engine::ContextEntrySource::Steering { - run_id: engine::RunId::new(1), - steering_id: engine::SteeringId::new(1), + source: harness::ContextEntrySource::Steering { + run_id: harness::RunId::new(1), + steering_id: harness::SteeringId::new(1), input_index: i as u32, }, origin: entries[i].origin.clone(), @@ -2437,7 +2437,7 @@ async fn input_origin_survives_admission_and_projection_without_changing_model_c #[tokio::test(flavor = "current_thread")] async fn input_origin_rejects_blank_and_oversized_values() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); for origin in ["".to_owned(), " ".to_owned(), "x".repeat(201)] { let item = InputItem::Text { provenance_ref: None, @@ -2463,8 +2463,8 @@ async fn input_origin_rejects_blank_and_oversized_values() { #[tokio::test(flavor = "current_thread")] async fn skill_list_reads_latest_structured_provenance() { - let blobs = engine::storage::InMemoryBlobStore::new(); - let mut state = engine::CoreAgentState::new(); + let blobs = harness::storage::InMemoryBlobStore::new(); + let mut state = harness::CoreAgentState::new(); assert!( super::skills::skill_list_from_context(&blobs, &state) .await @@ -2485,16 +2485,16 @@ async fn skill_list_reads_latest_structured_provenance() { .await .unwrap(); state.context.entries.push(ContextEntry { - entry_id: engine::ContextEntryId::new(id), + entry_id: harness::ContextEntryId::new(id), key: Some(ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY)), kind: input.kind, - source: engine::ContextEntrySource::ContextEdit, + source: harness::ContextEntrySource::ContextEdit, content: input.content, preview: input.preview, origin: input.origin, provenance_ref: input.provenance_ref, token_estimate: input.token_estimate, - supersedes: (id == 2).then(|| engine::ContextEntryId::new(1)), + supersedes: (id == 2).then(|| harness::ContextEntryId::new(1)), }); } assert!( @@ -2505,9 +2505,9 @@ async fn skill_list_reads_latest_structured_provenance() { .is_empty() ); let mut config = - engine_session_config_from_api(api::SessionConfig::default(), openai_model()).unwrap(); - config.features.vfs = Some(engine::VfsFeature { - skills: Some(engine::VfsSkillsConfig::default()), + harness_session_config_from_api(api::SessionConfig::default(), openai_model()).unwrap(); + config.features.vfs = Some(harness::VfsFeature { + skills: Some(harness::VfsSkillsConfig::default()), ..Default::default() }); state.lifecycle.config = Some(config); @@ -2543,12 +2543,12 @@ async fn skill_list_reads_latest_structured_provenance() { .await .unwrap(); let mut entry = state.context.entries[1].clone(); - entry.entry_id = engine::ContextEntryId::new(3); + entry.entry_id = harness::ContextEntryId::new(3); entry.key = Some(ContextEntryKey::new(ENVIRONMENT_SKILL_CATALOG_CONTEXT_KEY)); entry.supersedes = None; entry.provenance_ref = Some(reference.clone()); state.context.entries.push(entry); - state.environment.active_environment_id = Some(engine::EnvironmentId::new("machine")); + state.environment.active_environment_id = Some(harness::EnvironmentId::new("machine")); let response = super::skills::skill_list_from_context(&blobs, &state) .await .unwrap(); @@ -2573,7 +2573,7 @@ async fn skill_list_reads_latest_structured_provenance() { .get("environmentId") .is_none() ); - for selection in [Some(engine::EnvironmentId::new("other")), None] { + for selection in [Some(harness::EnvironmentId::new("other")), None] { state.environment.active_environment_id = selection; assert_eq!( super::skills::skill_list_from_context(&blobs, &state) @@ -2583,7 +2583,7 @@ async fn skill_list_reads_latest_structured_provenance() { vec![vfs.clone()] ); } - state.environment.active_environment_id = Some(engine::EnvironmentId::new("machine")); + state.environment.active_environment_id = Some(harness::EnvironmentId::new("machine")); state .lifecycle .config @@ -2628,18 +2628,18 @@ async fn skill_list_reads_latest_structured_provenance() { #[test] fn environment_access_ladder_derives_the_union_tool_surface() { - fn config_for(attachments: serde_json::Value) -> engine::SessionConfig { + fn config_for(attachments: serde_json::Value) -> harness::SessionConfig { let features = serde_json::json!({ "vfs":{"workspaces":[{"path":"/workspace","workspaceId":"ws_1","access":"edit"}]}, "environments":{"skills":{},"prompts":{},"environments":attachments} }); - engine_session_config_from_api( + harness_session_config_from_api( serde_json::from_value(serde_json::json!({"features":features})).unwrap(), openai_model(), ) .unwrap() } - fn assert_surface(config: &engine::SessionConfig, access: Option) { + fn assert_surface(config: &harness::SessionConfig, access: Option) { let registered = tools::toolset::register_toolset( &GatewayAgentApi::session_toolset_config(config, true, false), ) @@ -2676,10 +2676,10 @@ fn environment_access_ladder_derives_the_union_tool_surface() { // No attachment: the feature is granted but installs no machine tools. assert_surface(&config_for(serde_json::json!([])), None); for (access, level) in [ - ("read", engine::EnvironmentAccess::Read), - ("edit", engine::EnvironmentAccess::Edit), - ("exec", engine::EnvironmentAccess::Exec), - ("jobs", engine::EnvironmentAccess::Jobs), + ("read", harness::EnvironmentAccess::Read), + ("edit", harness::EnvironmentAccess::Edit), + ("exec", harness::EnvironmentAccess::Exec), + ("jobs", harness::EnvironmentAccess::Jobs), ] { assert_surface( &config_for(serde_json::json!([{"environmentId":"env_a","access":access}])), @@ -2693,7 +2693,7 @@ fn environment_access_ladder_derives_the_union_tool_surface() { {"environmentId":"env_a","access":"read"}, {"environmentId":"env_b","access":"exec"} ])), - Some(engine::EnvironmentAccess::Exec), + Some(harness::EnvironmentAccess::Exec), ); } @@ -2711,7 +2711,7 @@ fn a_missing_resource_names_only_its_kind_and_id() { #[tokio::test(flavor = "current_thread")] async fn text_inputs_preserve_generic_provenance_at_all_input_boundaries() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let source = store .put_bytes(b"source document or recording".to_vec()) .await @@ -2735,7 +2735,7 @@ async fn text_inputs_preserve_generic_provenance_at_all_input_boundaries() { .unwrap(); let append = context_entry_input_from_api(&store, &item).await.unwrap(); assert_eq!(run, vec![append.clone()]); - assert_eq!(append.content, engine::ContentRef::text(reference.clone())); + assert_eq!(append.content, harness::ContentRef::text(reference.clone())); assert_eq!(append.provenance_ref.as_ref(), Some(&source)); assert_eq!(append.origin.as_deref(), Some("user:test")); let projected = api_projection::CoreAgentProjector::new(&store) @@ -2780,7 +2780,7 @@ async fn text_inputs_preserve_generic_provenance_at_all_input_boundaries() { #[tokio::test(flavor = "current_thread")] async fn text_input_provenance_requires_an_existing_source_blob() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let text_ref = store.put_bytes(b"text".to_vec()).await.unwrap(); for reference in [ "not-a-blob".into(), diff --git a/crates/temporal-server/src/gateway/service/transcriptions.rs b/crates/temporal-runtime/src/gateway/service/transcriptions.rs similarity index 99% rename from crates/temporal-server/src/gateway/service/transcriptions.rs rename to crates/temporal-runtime/src/gateway/service/transcriptions.rs index 9ccfb3ed5..6b0e695a8 100644 --- a/crates/temporal-server/src/gateway/service/transcriptions.rs +++ b/crates/temporal-runtime/src/gateway/service/transcriptions.rs @@ -1,6 +1,6 @@ use super::*; use temporal_workflow::{TranscriptionSnapshot, TranscriptionWorkflow, TranscriptionWorkflowArgs}; -use temporalio_common::protos::temporal::api::enums::v1::WorkflowIdReusePolicy; +use temporalio_client::WorkflowIdReusePolicy; fn validate_id(id: &str) -> Result<(), AgentApiError> { if id diff --git a/crates/temporal-server/src/gateway/service/vfs_api.rs b/crates/temporal-runtime/src/gateway/service/vfs_api.rs similarity index 98% rename from crates/temporal-server/src/gateway/service/vfs_api.rs rename to crates/temporal-runtime/src/gateway/service/vfs_api.rs index fe18c6740..ec37b4e46 100644 --- a/crates/temporal-server/src/gateway/service/vfs_api.rs +++ b/crates/temporal-runtime/src/gateway/service/vfs_api.rs @@ -3,7 +3,7 @@ use super::*; impl GatewayAgentApi { pub(super) async fn validate_workspace_attachment_targets( &self, - features: &engine::FeaturesConfig, + features: &harness::FeaturesConfig, ) -> Result<(), AgentApiError> { self.preparation_service() .validate_workspace_attachment_targets(features) @@ -158,7 +158,7 @@ impl GatewayAgentApi { pub(super) async fn commit_vfs_snapshot( store: &dyn BlobStore, - blob_graph: Option<&dyn engine::storage::BlobGraphStore>, + blob_graph: Option<&dyn harness::storage::BlobGraphStore>, params: VfsSnapshotCommitParams, ) -> Result { let manifest: vfs::VfsSnapshotManifest = diff --git a/crates/temporal-server/src/gateway/service/workflow.rs b/crates/temporal-runtime/src/gateway/service/workflow.rs similarity index 96% rename from crates/temporal-server/src/gateway/service/workflow.rs rename to crates/temporal-runtime/src/gateway/service/workflow.rs index 946cdc08a..11de6a25a 100644 --- a/crates/temporal-server/src/gateway/service/workflow.rs +++ b/crates/temporal-runtime/src/gateway/service/workflow.rs @@ -121,7 +121,7 @@ impl GatewayAgentApi { ) -> Result<(), AgentApiError> { let value = serde_json::to_value(input) .map_err(|error| AgentApiError::internal(format!("encode admission: {error}")))?; - let refs = engine::storage::collect_blob_refs(&value); + let refs = harness::storage::collect_blob_refs(&value); self.store .touch_blob_refs(&refs.into_iter().collect::>()) .await @@ -255,7 +255,7 @@ impl GatewayAgentApi { pub(super) async fn wait_for_context_entries_replaced( &self, session_id: &SessionId, - expected: &[(engine::ContextEntryId, engine::ContentRef)], + expected: &[(harness::ContextEntryId, harness::ContentRef)], correlation_token: &str, ) -> Result<(u64, Option), AgentApiError> { let started = Instant::now(); @@ -420,7 +420,7 @@ impl GatewayAgentApi { run_id: RunId, baseline: usize, correlation_token: &str, - ) -> Result { + ) -> Result { let started = Instant::now(); loop { if started.elapsed() > self.operation_timeout { @@ -467,7 +467,7 @@ impl GatewayAgentApi { &self, session_id: &SessionId, run_id: RunId, - approval_id: &engine::ApprovalId, + approval_id: &harness::ApprovalId, correlation_token: &str, ) -> Result<(), AgentApiError> { let started = Instant::now(); @@ -691,7 +691,7 @@ impl GatewayAgentApi { if loaded.state.lifecycle.status == CoreAgentStatus::Closed { return Ok(()); } - let mut drive = engine::CoreAgentDrive::from_replayed( + let mut drive = harness::CoreAgentDrive::from_replayed( session_id.clone(), loaded.state, loaded.record.head, @@ -705,18 +705,18 @@ impl GatewayAgentApi { .map_err(|error| AgentApiError::internal(error.to_string()))?, ) .map_err(|error| match error { - engine::CoreAgentDriveError::Command(engine::CommandError::Rejected(rejection)) => { - AgentApiError::rejected(rejection.to_string()) - } + harness::CoreAgentDriveError::Command(harness::CommandError::Rejected( + rejection, + )) => AgentApiError::rejected(rejection.to_string()), other => AgentApiError::internal(format!("force close admission failed: {other}")), })?; match action { - engine::CoreAgentAction::AppendEvents { + harness::CoreAgentAction::AppendEvents { expected_head, events, } => { self.store - .append(engine::storage::AppendSessionEvents { + .append(harness::storage::AppendSessionEvents { session_id: session_id.clone(), expected_head, events, @@ -725,7 +725,7 @@ impl GatewayAgentApi { .map_err(map_session_store_error)?; Ok(()) } - engine::CoreAgentAction::Idle | engine::CoreAgentAction::Closed => Ok(()), + harness::CoreAgentAction::Idle | harness::CoreAgentAction::Closed => Ok(()), other => Err(AgentApiError::internal(format!( "force close produced unexpected action: {other:?}" ))), @@ -746,11 +746,11 @@ pub(super) fn session_bootstrap_failed_error( /// Catalog history retains older entries under the same key. Only the current /// entry can acknowledge an update; matching a historical version is insufficient. fn matching_current_context_entry<'a>( - state: &'a engine::CoreAgentState, + state: &'a harness::CoreAgentState, key: &ContextEntryKey, input: &ContextEntryInput, ) -> Option<&'a ContextEntry> { - engine::current_context_entry(state, key) + harness::current_context_entry(state, key) .filter(|entry| active_context_entry_matches_input(entry, input)) } @@ -797,16 +797,16 @@ mod tests { fn context_update_acknowledges_current_catalog_with_retained_history() { let key = ContextEntryKey::new(tools::skills::environment::ENVIRONMENT_SKILL_CATALOG_CONTEXT_KEY); - let mut state = engine::CoreAgentState::new(); + let mut state = harness::CoreAgentState::new(); for (id, text) in [(1, "old skills"), (2, "updated skills")] { state.context.entries.push(ContextEntry { - entry_id: engine::ContextEntryId::new(id), + entry_id: harness::ContextEntryId::new(id), key: Some(key.clone()), kind: ContextEntryKind::Catalog { title: "Environment skills".into(), }, - source: engine::ContextEntrySource::ContextEdit, - content: engine::ContentRef { + source: harness::ContextEntrySource::ContextEdit, + content: harness::ContentRef { content_ref: BlobRef::from_bytes(text.as_bytes()), media_type: Some("text/markdown".into()), provider_kind: None, @@ -815,7 +815,7 @@ mod tests { origin: Some("runtime.environment:test".into()), provenance_ref: None, token_estimate: None, - supersedes: (id == 2).then(|| engine::ContextEntryId::new(1)), + supersedes: (id == 2).then(|| harness::ContextEntryId::new(1)), }); } let old = active_entry_input(&state.context.entries[0]); @@ -825,7 +825,7 @@ mod tests { matching_current_context_entry(&state, &key, ¤t) .expect("the committed update must be acknowledged despite retained history") .entry_id, - engine::ContextEntryId::new(2), + harness::ContextEntryId::new(2), ); assert!( matching_current_context_entry(&state, &key, &old).is_none(), diff --git a/crates/temporal-server/src/lib.rs b/crates/temporal-runtime/src/lib.rs similarity index 100% rename from crates/temporal-server/src/lib.rs rename to crates/temporal-runtime/src/lib.rs diff --git a/crates/temporal-server/src/main.rs b/crates/temporal-runtime/src/main.rs similarity index 94% rename from crates/temporal-server/src/main.rs rename to crates/temporal-runtime/src/main.rs index 68a60e7ac..7d93c3b76 100644 --- a/crates/temporal-server/src/main.rs +++ b/crates/temporal-runtime/src/main.rs @@ -1,7 +1,7 @@ use std::{env, net::SocketAddr, sync::Arc, time::Duration}; use clap::{Args, Parser, Subcommand}; -use temporal_server::{ +use temporal_runtime::{ config::{ DeploymentStores, TaskQueues, cas_sweep_grace_from_env, environment_public_url_from_env, gateway_auth_mode_from_env, postgres_pool_from_env, task_queues_from_env, @@ -11,7 +11,7 @@ use temporal_server::{ DEFAULT_TEMPORAL_TARGET, GatewayRoutes, GatewayState, gateway_router, prewarm_single_universe, }, - roles::{Role, RoleSet, TaskTypes}, + roles::{Role, RoleSet}, universe::UniverseRuntime, worker::{self, BotWorkerActivities, ChannelWorkerActivities, WorkerActivities}, }; @@ -19,12 +19,12 @@ use tracing_subscriber::{EnvFilter, fmt}; #[derive(Debug, Parser)] #[command( - name = "lightspeed-server", + name = "lightspeed-runtime", version = release_info::LONG_VERSION, about = "Run the Lightspeed hosted runtime", after_help = "When no command is supplied, the server runs every role in this process: \ -gateway, sessions, bots, channels. Select a subset with --roles (or LIGHTSPEED_ROLES) and \ -split worker roles into workflow-only or activity-only pollers with --task-types." +gateway, environment-gateway, sessions, bots, channels. Select a subset with --roles \ +(or LIGHTSPEED_ROLES). Each worker role runs its workflows and activities together." )] struct Cli { #[command(subcommand)] @@ -137,10 +137,6 @@ struct RunArgs { #[arg(long, env = "LIGHTSPEED_ROLES")] roles: Option, - /// Task types the worker roles poll: all, workflows, or activities. - #[arg(long, env = "LIGHTSPEED_WORKER_TASK_TYPES")] - task_types: Option, - #[arg(long, env = "LIGHTSPEED_GATEWAY_BIND", default_value = DEFAULT_GATEWAY_BIND)] bind: SocketAddr, @@ -179,11 +175,6 @@ impl RunArgs { RoleSet::parse(self.roles.as_deref().unwrap_or("")).map_err(|error| anyhow::anyhow!(error)) } - fn task_types(&self) -> anyhow::Result { - TaskTypes::parse(self.task_types.as_deref().unwrap_or("")) - .map_err(|error| anyhow::anyhow!(error)) - } - fn task_queues(&self) -> anyhow::Result { let mut queues = task_queues_from_env()?; if let Some(queue) = self.task_queue.as_deref().filter(|value| !value.is_empty()) { @@ -530,17 +521,16 @@ async fn mint( /// Temporal worker on its own task queue; the gateway role adds the HTTP /// server and the deployment reconcilers. async fn run_roles(args: RunArgs) -> anyhow::Result<()> { - temporal_server::config::validate_model_environment()?; + temporal_runtime::config::validate_model_environment()?; let roles = args.roles()?; - let task_types = args.task_types()?; let task_queues = args.task_queues()?; let mode = gateway_auth_mode_from_env()?; - let runtime = worker::core_runtime()?; + let runtime = worker::worker_runtime()?; let client = - temporal_server::gateway::connect_temporal(&args.temporal_target, &args.namespace).await?; + temporal_runtime::gateway::connect_temporal(&args.temporal_target, &args.namespace).await?; let stores = DeploymentStores::from_env() .await? - .with_blob_cache(temporal_server::config::blob_cache_from_env()?); + .with_blob_cache(temporal_runtime::config::blob_cache_from_env()?); let reaper_stores = stores.clone(); let public_base_url = args .public_base_url @@ -559,15 +549,14 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { prewarm_single_universe(&mode, &universes).await?; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", roles = %roles, - task_types = %task_types, temporal_target = %args.temporal_target, namespace = %args.namespace, sessions_queue = %task_queues.sessions, bots_queue = %task_queues.bots, channels_queue = %task_queues.channels, - "lightspeed-server starting" + "lightspeed-runtime starting" ); let mut background: Vec> = Vec::new(); @@ -586,7 +575,6 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { client.clone(), task_queues.sessions.clone(), activities, - task_types.worker_task_types(), )?, )); background.push(tokio::spawn( @@ -600,7 +588,7 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { worker::CasBlobSweeper::new(reaper_stores, grace).run_forever(), )), None => tracing::info!( - target: "temporal_server", + target: "temporal_runtime", "cas blob sweeper disabled by LIGHTSPEED_CAS_SWEEP_GRACE_MS=0" ), } @@ -614,7 +602,6 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { client.clone(), task_queues.bots.clone(), activities, - task_types.worker_task_types(), )?, )); background.push(tokio::spawn( @@ -630,7 +617,6 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { client.clone(), task_queues.channels.clone(), activities, - task_types.worker_task_types(), )?, )); } @@ -658,7 +644,7 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { let app = gateway_router(gateway_state, args.max_request_body_bytes, routes); let listener = tokio::net::TcpListener::bind(args.bind).await?; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", bind = %args.bind, api_routes = routes.api, environment_routes = routes.environment, @@ -701,7 +687,7 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { let _ = tokio::time::timeout(Duration::from_secs(10), futures::future::join_all(remaining)).await; match worker_result { (role, Ok(())) => anyhow::bail!("{role} worker stopped while the process was still running"), - (role, Err(error)) => Err(error.context(format!("{role} worker failed"))), + (role, Err(error)) => Err(anyhow::Error::from(error).context(format!("{role} worker failed"))), } } gateway_result = gateway_future.as_mut() => { @@ -723,13 +709,13 @@ async fn run_roles(args: RunArgs) -> anyhow::Result<()> { async fn shutdown_signal() { if let Err(error) = tokio::signal::ctrl_c().await { - tracing::warn!(target: "temporal_server", %error, "failed to listen for shutdown signal"); + tracing::warn!(target: "temporal_runtime", %error, "failed to listen for shutdown signal"); } } fn init_logging() -> anyhow::Result<()> { let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| { - EnvFilter::new("warn,temporal_server=info,temporal_workflow=info,temporalio_sdk_core=info") + EnvFilter::new("warn,temporal_runtime=info,temporal_workflow=info,temporalio_sdk_core=info") }); match env::var("LIGHTSPEED_LOG_FORMAT") .unwrap_or_else(|_| "compact".to_owned()) @@ -761,6 +747,16 @@ fn init_logging() -> anyhow::Result<()> { mod tests { use super::*; + #[test] + fn worker_deployment_is_selected_by_role() { + let cli = Cli::try_parse_from(["lightspeed-runtime", "--roles", "sessions,bots"]) + .expect("select worker roles"); + assert_eq!(cli.run.roles().unwrap().to_string(), "sessions,bots"); + let error = Cli::try_parse_from(["lightspeed-runtime", "--task-types", "workflows"]) + .expect_err("removed polling override must be rejected"); + assert_eq!(error.kind(), clap::error::ErrorKind::UnknownArgument); + } + #[test] fn changed_migration_explains_safe_recovery_without_hashes() { let message = explain_migration_error(store_pg::PgStoreError::MigrationChecksumChanged { diff --git a/crates/temporal-server/src/roles.rs b/crates/temporal-runtime/src/roles.rs similarity index 68% rename from crates/temporal-server/src/roles.rs rename to crates/temporal-runtime/src/roles.rs index 3ef48b47d..6921b3cd0 100644 --- a/crates/temporal-server/src/roles.rs +++ b/crates/temporal-runtime/src/roles.rs @@ -1,13 +1,10 @@ //! Process roles. One binary runs any combination of roles in one process //! (all of them by default); each worker role is its own Temporal task queue //! with the workflow types, activities, and background loops of that -//! subsystem. `--task-types` further splits a process's worker roles into -//! workflow-only or activity-only pollers. +//! subsystem. Each worker role runs its workflows and activities together. use std::{collections::BTreeSet, fmt, str::FromStr}; -use temporalio_common::worker::WorkerTaskTypes; - #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Role { /// HTTP/JSON-RPC gateway, OAuth callbacks, and webhook hooks. @@ -124,62 +121,6 @@ impl fmt::Display for RoleSet { } } -/// Which task types a process's worker roles poll. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] -pub enum TaskTypes { - #[default] - All, - Workflows, - Activities, -} - -impl TaskTypes { - pub fn parse(value: &str) -> Result { - match value.trim() { - "" | "all" => Ok(Self::All), - "workflows" => Ok(Self::Workflows), - "activities" => Ok(Self::Activities), - other => Err(format!( - "unknown task types {other:?}; expected all, workflows, or activities" - )), - } - } - - pub fn as_str(self) -> &'static str { - match self { - Self::All => "all", - Self::Workflows => "workflows", - Self::Activities => "activities", - } - } - - /// Local activities run inside the workflow poller, so they follow the - /// workflow side of the split. - pub fn worker_task_types(self) -> WorkerTaskTypes { - match self { - Self::All => WorkerTaskTypes::all(), - Self::Workflows => WorkerTaskTypes { - enable_workflows: true, - enable_local_activities: true, - enable_remote_activities: false, - enable_nexus: false, - }, - Self::Activities => WorkerTaskTypes { - enable_workflows: false, - enable_local_activities: false, - enable_remote_activities: true, - enable_nexus: false, - }, - } - } -} - -impl fmt::Display for TaskTypes { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.as_str()) - } -} - #[cfg(test)] mod tests { use super::*; @@ -214,14 +155,4 @@ mod tests { .has(Role::EnvironmentGateway) ); } - - #[test] - fn task_types_split_the_poller() { - let workflows = TaskTypes::parse("workflows").unwrap().worker_task_types(); - assert!(workflows.enable_workflows && !workflows.enable_remote_activities); - let activities = TaskTypes::parse("activities").unwrap().worker_task_types(); - assert!(!activities.enable_workflows && activities.enable_remote_activities); - assert_eq!(TaskTypes::parse("").unwrap(), TaskTypes::All); - assert!(TaskTypes::parse("nexus").is_err()); - } } diff --git a/crates/temporal-server/src/session_deletion.rs b/crates/temporal-runtime/src/session_deletion.rs similarity index 95% rename from crates/temporal-server/src/session_deletion.rs rename to crates/temporal-runtime/src/session_deletion.rs index ca96853ee..9701d209c 100644 --- a/crates/temporal-server/src/session_deletion.rs +++ b/crates/temporal-runtime/src/session_deletion.rs @@ -1,4 +1,4 @@ -use engine::storage::{ +use harness::storage::{ DeleteClosedSessions, DeleteClosedSessionsResult, SessionStore, SessionStoreError, }; use store_pg::PgStore; @@ -28,7 +28,7 @@ pub(crate) async fn delete_session_subtree( let cascade = request.cascade; let deleted = SessionStore::delete_closed_sessions(store, request).await?; tracing::info!( - target: "temporal_server", + target: "temporal_runtime", requested_session_id = %requested_session_id, retention_root_session_id = %deleted.target.retention_root_session_id, deleted_session_count = deleted.deleted_session_ids.len(), diff --git a/crates/temporal-server/src/subagents.rs b/crates/temporal-runtime/src/subagents.rs similarity index 96% rename from crates/temporal-server/src/subagents.rs rename to crates/temporal-runtime/src/subagents.rs index 0f68a14ff..51e58791a 100644 --- a/crates/temporal-server/src/subagents.rs +++ b/crates/temporal-runtime/src/subagents.rs @@ -12,7 +12,7 @@ use api::{ ProfileSource, SessionCloseParams, SessionReadParams, }; use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, PromiseResolution, RunStatus, RunTerminalNotifyIntent, SessionId, SubmissionId, media::MediaDescriptor, storage::{ @@ -162,7 +162,7 @@ impl SubagentChildRuntime for AgentApiSubagentRuntime { MediaDescriptor::new( content_ref, entry.content.media_type.as_deref()?, - engine::media::media_preview_name(entry.preview.as_deref()).as_deref(), + harness::media::media_preview_name(entry.preview.as_deref()).as_deref(), ) }) .collect()) @@ -222,7 +222,7 @@ impl SubagentService { let Some(reply_promise_id) = invocation .completion_promises .as_ref() - .and_then(|promises| promises.get(engine::REPLY_COMPLETION_KEY)) + .and_then(|promises| promises.get(harness::REPLY_COMPLETION_KEY)) else { return Err(AgentApiError::invalid_request( "subagent invocation is missing its reply completion promise", @@ -450,7 +450,7 @@ impl SubagentService { loop { let page = self .sessions - .read_after(engine::storage::ReadSessionEvents { + .read_after(harness::storage::ReadSessionEvents { session_id: session_id.clone(), after, limit: 256, @@ -461,10 +461,10 @@ impl SubagentService { if entry.event.kind != "lightspeed.core.tool.call_completed" { continue; } - let event = engine::CoreAgentCodec + let event = harness::CoreAgentCodec .decode_event(&entry.event) .map_err(|error| AgentApiError::internal(error.to_string()))?; - if let engine::CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { + if let harness::CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { result, .. }) = event @@ -568,7 +568,7 @@ impl SubagentService { })?) .await .map_err(|error| AgentApiError::internal(error.to_string()))?; - engine::storage::record_contains_edges( + harness::storage::record_contains_edges( self.blob_graph.as_deref(), &payload_ref, envelope.attachments.iter().flat_map(Attachment::blob_refs), @@ -648,15 +648,15 @@ impl SubagentService { pub fn await_spec_from_args( args: AwaitArgs, now_ms: u64, -) -> Result { +) -> Result { let promise_ids = args .validated_promise_ids() .map_err(|error| AgentApiError::invalid_request(error.to_string()))?; - Ok(engine::AwaitSpec { + Ok(harness::AwaitSpec { promise_ids, mode: match args.mode { - AwaitModeArg::All => engine::AwaitMode::All, - AwaitModeArg::Any => engine::AwaitMode::Any, + AwaitModeArg::All => harness::AwaitMode::All, + AwaitModeArg::Any => harness::AwaitMode::Any, }, deadline_at_ms: args .timeout_ms @@ -775,7 +775,7 @@ mod tests { }; use api::{AgentApiErrorKind, ProfileDocument}; - use engine::{ + use harness::{ PromiseId, RunId, SessionId, SubagentLimits, ToolBatchId, ToolCallId, TurnId, WorkflowToolId, WorkflowToolInvocation, WorkflowToolInvocationId, storage::{ @@ -1001,7 +1001,7 @@ mod tests { arguments_ref, execution_context_ref: Some(context_ref), completion_promises: Some(BTreeMap::from([( - engine::REPLY_COMPLETION_KEY.to_owned(), + harness::REPLY_COMPLETION_KEY.to_owned(), reply_promise(), )])), }, @@ -1212,7 +1212,7 @@ mod tests { assert_eq!(first, second); let listed = h .sessions - .list_sessions(engine::storage::ListSessions { + .list_sessions(harness::storage::ListSessions { limit: 10, trees: vec![SessionId::new("parent")], subagent: Some(true), @@ -1488,7 +1488,7 @@ mod tests { child_ref(), SubagentTerminal::Run { status: RunStatus::Completed, - output: Some(engine::ContentRef::text(output)), + output: Some(harness::ContentRef::text(output)), failure_message_ref: None, }, ) @@ -1535,7 +1535,7 @@ mod tests { child_ref(), SubagentTerminal::Run { status: RunStatus::Completed, - output: Some(engine::ContentRef::text(output.clone())), + output: Some(harness::ContentRef::text(output.clone())), failure_message_ref: None, }, ) @@ -1557,7 +1557,7 @@ mod tests { child_ref(), SubagentTerminal::Run { status: RunStatus::Failed, - output: Some(engine::ContentRef::text(output)), + output: Some(harness::ContentRef::text(output)), failure_message_ref: None, }, ) @@ -1569,7 +1569,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn file_handoff_uses_recorded_versions_and_retains_them_for_nested_results() { - use engine::storage::{AppendSessionEvents, BlobEdge, UncommittedStoredEvent}; + use harness::storage::{AppendSessionEvents, BlobEdge, UncommittedStoredEvent}; let mut h = harness(Arc::new(FakeChildRuntime::default())).await; h.service = h.service.with_blob_graph(Some(h.blobs.clone())); let original = h @@ -1577,8 +1577,8 @@ mod tests { .put_bytes(b"original report".to_vec()) .await .unwrap(); - let reference = engine::FileAttachment::new(original.clone(), "report.txt".into(), None); - let unwanted = engine::FileAttachment::new( + let reference = harness::FileAttachment::new(original.clone(), "report.txt".into(), None); + let unwanted = harness::FileAttachment::new( h.blobs.put_bytes(b"intermediate".to_vec()).await.unwrap(), "intermediate.txt".into(), None, @@ -1596,14 +1596,14 @@ mod tests { .await .unwrap(); let completion = |attachments| { - engine::CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { - run_id: engine::RunId::new(5), - turn_id: engine::TurnId::new(1), - batch_id: engine::ToolBatchId::new(1), - result: engine::ToolCallResult { + harness::CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { + run_id: harness::RunId::new(5), + turn_id: harness::TurnId::new(1), + batch_id: harness::ToolBatchId::new(1), + result: harness::ToolCallResult { attachments, - call_id: engine::ToolCallId::new("call"), - status: engine::ToolCallStatus::Succeeded, + call_id: harness::ToolCallId::new("call"), + status: harness::ToolCallStatus::Succeeded, output_ref: None, model_visible_context_entries: vec![], error_ref: None, @@ -1621,7 +1621,7 @@ mod tests { events: vec![UncommittedStoredEvent { observed_at_ms: 1, joins: Default::default(), - event: engine::CoreAgentCodec + event: harness::CoreAgentCodec .encode_event(&completion(vec![ Attachment::File(reference.clone()), Attachment::File(unwanted.clone()), @@ -1642,7 +1642,7 @@ mod tests { child_ref(), SubagentTerminal::Run { status: RunStatus::Completed, - output: Some(engine::ContentRef::text(output.clone())), + output: Some(harness::ContentRef::text(output.clone())), failure_message_ref: None, }, ) @@ -1673,7 +1673,7 @@ mod tests { events: vec![UncommittedStoredEvent { observed_at_ms: 2, joins: Default::default(), - event: engine::CoreAgentCodec + event: harness::CoreAgentCodec .encode_event(&completion(vec![Attachment::File(reference.clone())])) .unwrap(), }], @@ -1698,7 +1698,7 @@ mod tests { child_ref(), SubagentTerminal::Run { status, - output: Some(engine::ContentRef::text(output.clone())), + output: Some(harness::ContentRef::text(output.clone())), failure_message_ref: None, }, ) @@ -1728,11 +1728,11 @@ mod tests { child_ref(), SubagentTerminal::Run { status: RunStatus::Completed, - output: Some(engine::ContentRef { + output: Some(harness::ContentRef { content_ref, media_type: Some("application/json".into()), provider_kind: Some( - engine::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND.into(), + harness::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND.into(), ), }), failure_message_ref: None, @@ -1872,11 +1872,11 @@ mod tests { assert!(message.contains("maxConcurrent"), "{message}"); // Close the first child in the store (the fake runtime does not). - let closed = engine::CoreAgentCodec - .encode_uncommitted(&engine::UncommittedCoreAgentEvent { + let closed = harness::CoreAgentCodec + .encode_uncommitted(&harness::UncommittedCoreAgentEvent { observed_at_ms: 150, - joins: engine::CoreAgentJoins::default(), - event: engine::CoreAgentEvent::Lifecycle(engine::CoreAgentLifecycleEvent::Closed), + joins: harness::CoreAgentJoins::default(), + event: harness::CoreAgentEvent::Lifecycle(harness::CoreAgentLifecycleEvent::Closed), }) .expect("encode close"); h.sessions diff --git a/crates/temporal-server/src/universe.rs b/crates/temporal-runtime/src/universe.rs similarity index 96% rename from crates/temporal-server/src/universe.rs rename to crates/temporal-runtime/src/universe.rs index fbd3cceb3..ed78de8b7 100644 --- a/crates/temporal-server/src/universe.rs +++ b/crates/temporal-runtime/src/universe.rs @@ -277,7 +277,7 @@ impl UniverseRuntime { { Ok(ids) => ids, Err(error) => { - tracing::warn!(target: "temporal_server", %error, "environment reconciler scan failed"); + tracing::warn!(target: "temporal_runtime", %error, "environment reconciler scan failed"); continue; } }; @@ -285,7 +285,7 @@ impl UniverseRuntime { let state = match self.state_for(universe_id, false).await { Ok(state) => state, Err(error) => { - tracing::warn!(target: "temporal_server", %universe_id, %error, "environment reconciler could not resolve universe"); + tracing::warn!(target: "temporal_runtime", %universe_id, %error, "environment reconciler could not resolve universe"); continue; } }; @@ -317,7 +317,7 @@ impl UniverseRuntime { { Ok(ids) => ids, Err(error) => { - tracing::warn!(target: "temporal_server", %error, "power reaper scan failed"); + tracing::warn!(target: "temporal_runtime", %error, "power reaper scan failed"); continue; } }; @@ -325,7 +325,7 @@ impl UniverseRuntime { let state = match self.state_for(universe_id, false).await { Ok(state) => state, Err(error) => { - tracing::warn!(target: "temporal_server", %universe_id, %error, "power reaper could not resolve universe"); + tracing::warn!(target: "temporal_runtime", %universe_id, %error, "power reaper could not resolve universe"); continue; } }; @@ -355,7 +355,7 @@ impl UniverseRuntime { let universes = match store_pg::list_universes(self.stores.pool()).await { Ok(universes) => universes, Err(error) => { - tracing::warn!(target: "temporal_server", %error, "bot schedule reconciler scan failed"); + tracing::warn!(target: "temporal_runtime", %error, "bot schedule reconciler scan failed"); continue; } }; @@ -363,7 +363,7 @@ impl UniverseRuntime { let state = match self.state_for(universe_id, false).await { Ok(state) => state, Err(error) => { - tracing::warn!(target: "temporal_server", %universe_id, %error, "bot schedule reconciler could not resolve universe"); + tracing::warn!(target: "temporal_runtime", %universe_id, %error, "bot schedule reconciler could not resolve universe"); continue; } }; @@ -435,7 +435,7 @@ fn evict_universe_states(states: &mut BTreeMap, now_ms: u64 ) { states.remove(&universe_id); tracing::debug!( - target: "temporal_server", + target: "temporal_runtime", universe_id = %universe_id, "evicted idle universe state" ); diff --git a/crates/temporal-server/src/worker/activities/audio.rs b/crates/temporal-runtime/src/worker/activities/audio.rs similarity index 100% rename from crates/temporal-server/src/worker/activities/audio.rs rename to crates/temporal-runtime/src/worker/activities/audio.rs diff --git a/crates/temporal-server/src/worker/activities/common.rs b/crates/temporal-runtime/src/worker/activities/common.rs similarity index 95% rename from crates/temporal-server/src/worker/activities/common.rs rename to crates/temporal-runtime/src/worker/activities/common.rs index 7e18e9124..ee67f2c7c 100644 --- a/crates/temporal-server/src/worker/activities/common.rs +++ b/crates/temporal-runtime/src/worker/activities/common.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ BlobRef, ContextCompactionRequest, ContextCompactionResult, ContextCompactionStatus, CoreAgentIoError, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, LlmGenerationStatus, ToolCallStatus, ToolInvocationBatchRequest, ToolInvocationBatchResult, @@ -12,8 +12,10 @@ use temporalio_sdk::{ activities::{ActivityContext, ActivityError}, }; -pub(super) fn activity_error(error: impl Into) -> ActivityError { - ActivityError::from(error.into()) +pub(super) fn activity_error( + error: impl Into>, +) -> ActivityError { + ActivityError::application(ApplicationFailure::new(error)) } /// Run `work` as a cancellable, heartbeating activity body. The @@ -33,7 +35,10 @@ pub(super) async fn cancellable( tokio::time::interval(temporal_workflow::ACTIVITY_CANCELLATION_HEARTBEAT_INTERVAL); loop { ticker.tick().await; - heartbeat_ctx.record_heartbeat(Vec::new()); + heartbeat_ctx + .record_heartbeat(()) + .await + .expect("unit heartbeat serializes"); } }; tokio::pin!(work); @@ -214,7 +219,7 @@ pub(super) async fn failed_tool_batch_result( pub(super) async fn failed_tool_call_result( blobs: &dyn BlobStore, - request: &engine::ToolInvocationCallRequest, + request: &harness::ToolInvocationCallRequest, error: impl AsRef, ) -> Result { let error_ref = write_error_blob( diff --git a/crates/temporal-server/src/worker/activities/compaction.rs b/crates/temporal-runtime/src/worker/activities/compaction.rs similarity index 95% rename from crates/temporal-server/src/worker/activities/compaction.rs rename to crates/temporal-runtime/src/worker/activities/compaction.rs index fcca7b3ae..d88abab55 100644 --- a/crates/temporal-server/src/worker/activities/compaction.rs +++ b/crates/temporal-runtime/src/worker/activities/compaction.rs @@ -1,4 +1,4 @@ -use engine::{ContextCompactionResult, CoreAgentIoError}; +use harness::{ContextCompactionResult, CoreAgentIoError}; use temporalio_sdk::activities::ActivityError; use crate::worker::ContextCompactActivityRequest; diff --git a/crates/temporal-server/src/worker/activities/context_refresh.rs b/crates/temporal-runtime/src/worker/activities/context_refresh.rs similarity index 95% rename from crates/temporal-server/src/worker/activities/context_refresh.rs rename to crates/temporal-runtime/src/worker/activities/context_refresh.rs index 909c520bb..f22796696 100644 --- a/crates/temporal-server/src/worker/activities/context_refresh.rs +++ b/crates/temporal-runtime/src/worker/activities/context_refresh.rs @@ -1,4 +1,4 @@ -use engine::{ContextEntryKey, ContextEntryKind, CoreAgentCommand}; +use harness::{ContextEntryKey, ContextEntryKind, CoreAgentCommand}; use temporal_workflow::{ RuntimeProjectionRefreshActivityRequest, RuntimeProjectionRefreshActivityResult, }; @@ -255,12 +255,12 @@ pub(super) async fn refresh_context( } async fn replace_prompt_instruction_source( - mut active: std::collections::BTreeMap, - prompts: std::collections::BTreeMap, - blobs: &dyn engine::storage::BlobStore, + mut active: std::collections::BTreeMap, + prompts: std::collections::BTreeMap, + blobs: &dyn harness::storage::BlobStore, ) -> Result< - std::collections::BTreeMap, - engine::storage::BlobStoreError, + std::collections::BTreeMap, + harness::storage::BlobStoreError, > { active.retain(|key, _| { !(key.as_str() == tools::prompts::PROMPT_INSTRUCTIONS_CONTEXT_KEY_PREFIX @@ -282,9 +282,9 @@ async fn replace_prompt_instruction_source( .await?; active.insert( default_key, - engine::ContextEntryInput { + harness::ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, @@ -308,7 +308,7 @@ fn append_optional( /// Join stable attachment details with registry display names, without live status. pub async fn environment_catalog_snapshot( resolver: Option<&crate::environments::resolver::EnvironmentResolver>, - environments: &engine::EnvironmentsFeature, + environments: &harness::EnvironmentsFeature, ) -> tools::environment::attachments::EnvironmentCatalogSnapshot { use tools::environment::attachments::{EnvironmentCatalogRecord, EnvironmentCatalogSnapshot}; let mut records: std::collections::BTreeMap = @@ -338,7 +338,7 @@ pub async fn environment_catalog_snapshot( /// A missing profile keeps its ID in the menu with no revision. pub async fn subagent_catalog_snapshot( profiles: Option<&dyn ::profiles::ProfileStore>, - subagents: &engine::SubagentsFeature, + subagents: &harness::SubagentsFeature, ) -> SubagentCatalogSnapshot { let mut agents = Vec::with_capacity(subagents.agents.len()); for agent in &subagents.agents { diff --git a/crates/temporal-server/src/worker/activities/environment_jobs.rs b/crates/temporal-runtime/src/worker/activities/environment_jobs.rs similarity index 98% rename from crates/temporal-server/src/worker/activities/environment_jobs.rs rename to crates/temporal-runtime/src/worker/activities/environment_jobs.rs index 59114af18..03272f9c8 100644 --- a/crates/temporal-server/src/worker/activities/environment_jobs.rs +++ b/crates/temporal-runtime/src/worker/activities/environment_jobs.rs @@ -1,6 +1,5 @@ use std::collections::{BTreeMap, BTreeSet}; -use engine::{BlobRef, PromiseSourceCheckResult, storage::BlobStore}; use environment_client::{EnvironmentClientError, EnvironmentDataClient}; use environment_protocol::{ data::{ @@ -11,6 +10,7 @@ use environment_protocol::{ shared::{CURRENT_PROTOCOL_VERSION, EnvironmentDataConnection, EnvironmentTransport}, }; use environments::{EnvironmentId, EnvironmentJobGroupId}; +use harness::{BlobRef, PromiseSourceCheckResult, storage::BlobStore}; use temporal_workflow::{ EnvironmentJobCancelActivityRequest, EnvironmentJobPollActivityRequest, EnvironmentJobPollActivityResult, EnvironmentJobPrepareWorkflowToolRequest, @@ -221,17 +221,17 @@ pub(super) async fn prepare_workflow_tool( ))); } let promise_id = completion_promises - .get(engine::REPLY_COMPLETION_KEY) + .get(harness::REPLY_COMPLETION_KEY) .ok_or_else(|| { activity_error(anyhow::anyhow!( "job_run is missing completion key {}", - engine::REPLY_COMPLETION_KEY + harness::REPLY_COMPLETION_KEY )) })?; vec![EnvironmentJobSubscription { holder_workflow_id: start.holder_workflow_id.clone(), promise_id: promise_id.as_str().to_owned(), - completion_key: engine::REPLY_COMPLETION_KEY.to_owned(), + completion_key: harness::REPLY_COMPLETION_KEY.to_owned(), job_id: params.jobs[0].job_id.clone(), notified: false, }] diff --git a/crates/temporal-server/src/worker/activities/llm.rs b/crates/temporal-runtime/src/worker/activities/llm.rs similarity index 98% rename from crates/temporal-server/src/worker/activities/llm.rs rename to crates/temporal-runtime/src/worker/activities/llm.rs index 572399b60..3dc29d6d8 100644 --- a/crates/temporal-server/src/worker/activities/llm.rs +++ b/crates/temporal-runtime/src/worker/activities/llm.rs @@ -3,7 +3,7 @@ use std::{ sync::{Mutex, OnceLock}, }; -use engine::{CoreAgentIoError, LlmGenerationResult, LlmUsage, SessionId}; +use harness::{CoreAgentIoError, LlmGenerationResult, LlmUsage, SessionId}; use temporalio_sdk::activities::ActivityError; use crate::worker::LlmGenerateActivityRequest; diff --git a/crates/temporal-server/src/worker/activities/mod.rs b/crates/temporal-runtime/src/worker/activities/mod.rs similarity index 96% rename from crates/temporal-server/src/worker/activities/mod.rs rename to crates/temporal-runtime/src/worker/activities/mod.rs index 9bc7a3827..176cf147e 100644 --- a/crates/temporal-server/src/worker/activities/mod.rs +++ b/crates/temporal-runtime/src/worker/activities/mod.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use engine::{ +use harness::{ BlobRef, ContextCompactionResult, LlmGenerationResult, PromiseSourceCheckResult, ToolBatchOutcome, }; @@ -117,16 +117,11 @@ impl WorkerActivities { /// Resolve the universe of the invoking workflow from the activity /// context's workflow id and return that universe's activity state. async fn state_for(&self, ctx: &ActivityContext) -> Result, ActivityError> { - let workflow_id = ctx - .info() - .workflow_execution - .as_ref() - .map(|execution| execution.workflow_id.as_str()) - .ok_or_else(|| { - ActivityError::application(ApplicationFailure::non_retryable(anyhow::anyhow!( - "activity task carries no workflow execution info" - ))) - })?; + let workflow_id = ctx.info().workflow_id.as_deref().ok_or_else(|| { + ActivityError::application(ApplicationFailure::non_retryable(anyhow::anyhow!( + "activity task carries no workflow execution info" + ))) + })?; let Some((universe_id, _session_id)) = temporal_workflow::split_workflow_id(workflow_id) else { return Err(ActivityError::application( @@ -176,7 +171,7 @@ impl WorkerActivities { mod tests { use std::sync::Arc; - use engine::{ + use harness::{ ContextSnapshot, CoreAgentLlm, CoreAgentTools, LlmGenerationRequest, LlmRequest, ModelSelection, ProviderApiKind, RunId, SessionId, ToolBatchId, ToolCallStatus, ToolInvocationBatchRequest, ToolInvocationRequest, TurnId, @@ -434,19 +429,19 @@ mod tests { entries: Vec::new(), token_estimate: None, }, - tools: vec![engine::ToolSpec { - name: engine::ToolName::new(FAKE_TOOL_NAME), + tools: vec![harness::ToolSpec { + name: harness::ToolName::new(FAKE_TOOL_NAME), execution: Default::default(), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: None, - input_schema_ref: engine::BlobRef::from_bytes( + input_schema_ref: harness::BlobRef::from_bytes( br#"{"type":"object","properties":{"text":{"type":"string"}}}"#, ), output_schema_ref: None, strict: Some(true), provider_options_ref: None, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, }], tool_choice: None, reasoning_effort: None, @@ -469,11 +464,7 @@ impl WorkerActivities { ctx: ActivityContext, args: temporal_workflow::TranscriptionWorkflowArgs, ) -> Result { - if ctx - .info() - .workflow_execution - .as_ref() - .map(|w| w.workflow_id.as_str()) + if ctx.info().workflow_id.as_deref() != Some(temporal_workflow::transcription_workflow_id(&args).as_str()) { return Err(common::activity_error(anyhow::anyhow!( @@ -528,7 +519,7 @@ impl WorkerActivities { self: Arc, ctx: ActivityContext, request: temporal_workflow::JoinedContextPreparationRequest, - ) -> Result, ActivityError> { + ) -> Result, ActivityError> { let state = self.state_for(&ctx).await?; storage::prepare_joined_context(state.storage(), request).await } @@ -538,7 +529,7 @@ impl WorkerActivities { self: Arc, ctx: ActivityContext, request: AppendEventsRequest, - ) -> Result { + ) -> Result { let state = self.state_for(&ctx).await?; storage::append_events(state.storage(), request).await } @@ -604,7 +595,7 @@ impl WorkerActivities { self: Arc, ctx: ActivityContext, request: ToolPreparePromiseControlsActivityRequest, - ) -> Result { + ) -> Result { let state = self.state_for(&ctx).await?; tools::prepare_promise_controls(state.tools().blobs.as_ref(), request.request).await } @@ -749,7 +740,7 @@ impl WorkerActivities { self: Arc, _ctx: ActivityContext, request: temporal_workflow::SubagentResolveActivityRequest, - ) -> Result { + ) -> Result { let state = self.state_for_universe(request.universe_id).await?; subagents::resolve(state.subagents(), request).await } diff --git a/crates/temporal-server/src/worker/activities/state.rs b/crates/temporal-runtime/src/worker/activities/state.rs similarity index 99% rename from crates/temporal-server/src/worker/activities/state.rs rename to crates/temporal-runtime/src/worker/activities/state.rs index ba3225eb2..f4361b161 100644 --- a/crates/temporal-server/src/worker/activities/state.rs +++ b/crates/temporal-runtime/src/worker/activities/state.rs @@ -5,11 +5,11 @@ use auth::{ GrantRefreshLock, HttpGitHubApiClient, HttpOAuthTokenClient, OAuthClientStore, OAuthRefreshRuntime, RegistryTokenBroker, SecretStore, }; -use engine::{ +use environments::EnvironmentStore; +use harness::{ CoreAgentLlm, CoreAgentTools, ProviderApiKind, storage::{BlobGraphStore, BlobStore, SessionStore}, }; -use environments::EnvironmentStore; use llm_clients::{ anthropic::messages as am, openai::{completions as oai_completions, responses as oai}, diff --git a/crates/temporal-server/src/worker/activities/storage.rs b/crates/temporal-runtime/src/worker/activities/storage.rs similarity index 94% rename from crates/temporal-server/src/worker/activities/storage.rs rename to crates/temporal-runtime/src/worker/activities/storage.rs index 74f7e6889..90f8384a8 100644 --- a/crates/temporal-server/src/worker/activities/storage.rs +++ b/crates/temporal-runtime/src/worker/activities/storage.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ BlobRef, RunId, SessionId, SessionPosition, WorkflowEndpointRef, WorkflowToolInvocation, storage::{ AppendSessionEvents, AppendSessionEventsResult, BlobEdge, CreateSession, ReadSessionEvents, @@ -19,7 +19,7 @@ pub(super) async fn create_or_load_session( deps: &StorageActivityDeps, request: CreateOrLoadSessionRequest, ) -> Result { - engine::storage::ensure_engine_blobs(deps.blobs.as_ref()) + harness::storage::ensure_harness_blobs(deps.blobs.as_ref()) .await .map_err(activity_error)?; let record = match deps @@ -153,7 +153,7 @@ pub(super) async fn materialize_await_result( let mut additional_context = Vec::new(); let mut attachments = Vec::new(); let mut file_budget = tools::attachments::MAX_FILE_ATTACHMENTS; - let mut budget = engine::media::MAX_TOOL_MEDIA_ITEMS; + let mut budget = harness::media::MAX_TOOL_MEDIA_ITEMS; let mut omitted = 0usize; for result in &request.results { if result.status != "resolved" { @@ -249,8 +249,8 @@ pub(super) async fn materialize_await_result( #[derive(Default)] struct PreparedAttachments { - entries: Vec, - attachments: Vec, + entries: Vec, + attachments: Vec, omitted: usize, } @@ -294,7 +294,7 @@ async fn prepare_payload_context( for attachment in attachments { match attachment { Attachment::Media(descriptor) => { - let Some(admitted) = engine::media::MediaDescriptor::new( + let Some(admitted) = harness::media::MediaDescriptor::new( descriptor.content_ref, &descriptor.media_type, descriptor.name.as_deref(), @@ -307,7 +307,7 @@ async fn prepare_payload_context( let Ok(info) = deps.blobs.stat_blob(&admitted.content_ref).await else { continue; }; - if engine::media::admit_tool_media(Some(&admitted.media_type), info.byte_len) + if harness::media::admit_tool_media(Some(&admitted.media_type), info.byte_len) .is_err() { continue; @@ -352,22 +352,22 @@ async fn omission_note( deps: &StorageActivityDeps, omitted: usize, what: &str, -) -> Result { +) -> Result { let text = format!( "[{omitted} media item{} omitted: at most {} per {what}]", if omitted == 1 { "" } else { "s" }, - engine::media::MAX_TOOL_MEDIA_ITEMS + harness::media::MAX_TOOL_MEDIA_ITEMS ); let content_ref = deps .blobs .put_bytes(text.clone().into_bytes()) .await .map_err(activity_error)?; - Ok(engine::ContextEntryInput { - kind: engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User, + Ok(harness::ContextEntryInput { + kind: harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User, }, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: Some(text), origin: None, provenance_ref: None, @@ -380,7 +380,7 @@ async fn omission_note( pub(super) async fn prepare_joined_context( deps: &StorageActivityDeps, request: temporal_workflow::JoinedContextPreparationRequest, -) -> Result, ActivityError> { +) -> Result, ActivityError> { let mut prepared = Vec::new(); for result in request.results { if result.status != "resolved" { @@ -389,10 +389,10 @@ pub(super) async fn prepare_joined_context( let Some(payload_ref) = result.payload_ref else { continue; }; - let Ok(promise_id) = engine::PromiseId::try_new(result.promise_id.clone()) else { + let Ok(promise_id) = harness::PromiseId::try_new(result.promise_id.clone()) else { continue; }; - let mut budget = engine::media::MAX_TOOL_MEDIA_ITEMS; + let mut budget = harness::media::MAX_TOOL_MEDIA_ITEMS; let mut file_budget = tools::attachments::MAX_FILE_ATTACHMENTS; let PreparedAttachments { mut entries, @@ -403,7 +403,7 @@ pub(super) async fn prepare_joined_context( entries.push(omission_note(deps, omitted, "result").await?); } if !entries.is_empty() || !attachments.is_empty() { - prepared.push(engine::PromiseContextEntries { + prepared.push(harness::PromiseContextEntries { promise_id, entries, attachments, @@ -482,7 +482,7 @@ pub(super) async fn read_blob( /// Read one run's workflow-tool emissions from this worker state's /// universe-scoped session store. Exact receiver authorization is evaluated -/// against the durable binding facts by the engine projection. +/// against the durable binding facts by the harness projection. // Work-cycle reconciliation is the first production caller. #[allow(dead_code)] pub(super) async fn read_tool_emissions( @@ -504,7 +504,7 @@ async fn read_tool_emissions_with_page_limit( let entries = read_all_session_events_with_page_limit(deps.sessions.as_ref(), session_id, page_limit) .await?; - engine::read_tool_emissions(&entries, receiver_endpoint, session_id, run_id) + harness::read_tool_emissions(&entries, receiver_endpoint, session_id, run_id) .map_err(activity_error) } @@ -546,7 +546,7 @@ async fn maybe_refresh_checkpoint_after_append( let terminal = result .entries .iter() - .any(engine::storage::is_terminal_run_entry); + .any(harness::storage::is_terminal_run_entry); let Some(record) = deps.sessions.load_session(session_id).await.ok().flatten() else { return; }; @@ -560,7 +560,7 @@ async fn maybe_refresh_checkpoint_after_append( let tail_event_count = record.head.as_ref().map_or(0, |head| { head.seq .as_u64() - .saturating_sub(checkpoint_seq.map_or(0, engine::EventSeq::as_u64)) + .saturating_sub(checkpoint_seq.map_or(0, harness::EventSeq::as_u64)) }); if !terminal && tail_event_count < crate::checkpoint::CHECKPOINT_TAIL_EVENT_THRESHOLD @@ -584,7 +584,7 @@ async fn maybe_refresh_checkpoint_after_append( let newly_terminal_seqs = result .entries .iter() - .filter(|entry| engine::storage::is_terminal_run_entry(entry)) + .filter(|entry| harness::storage::is_terminal_run_entry(entry)) .map(|entry| entry.position.seq) .collect::>(); let terminal_runs_due = terminal @@ -704,7 +704,7 @@ mod tests { }, }; - use engine::{ + use harness::{ CoreAgentIoError, CoreAgentLlm, CoreAgentTools, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, LlmGenerationStatus, ObservedToolCall, StoredEvent, ToolBatchOutcome, ToolCallStatus, ToolInvocationBatchRequest, @@ -763,11 +763,11 @@ mod tests { struct UnreachableLlm; #[async_trait::async_trait] - impl engine::CoreAgentLlm for UnreachableLlm { + impl harness::CoreAgentLlm for UnreachableLlm { async fn generate( &self, - _request: engine::LlmGenerationRequest, - ) -> Result { + _request: harness::LlmGenerationRequest, + ) -> Result { panic!("bootstrap-volume test must not generate") } } @@ -870,7 +870,7 @@ mod tests { ), ], error_ref: None, - effects: vec![engine::workflow_tool_emit_effect(&invocation)], + effects: vec![harness::workflow_tool_emit_effect(&invocation)], } }) .collect(); @@ -883,9 +883,9 @@ mod tests { } } - fn volume_session_config() -> engine::SessionConfig { - temporal_workflow::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + fn volume_session_config() -> harness::SessionConfig { + temporal_workflow::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".to_owned(), model: "gpt-test".to_owned(), }) @@ -899,7 +899,7 @@ mod tests { use test_support::{DriveCommand, RunnerStores, SessionRunner}; let store = Arc::new(InMemorySessionStore::new()); - let blobs: Arc = Arc::new(InMemoryBlobStore::new()); + let blobs: Arc = Arc::new(InMemoryBlobStore::new()); let session_id = SessionId::new("bridge_large_session"); store .create_session(CreateSession { @@ -921,7 +921,7 @@ mod tests { .drive_command(DriveCommand { session_id: session_id.clone(), observed_at_ms: 10, - command: engine::CoreAgentCommand::OpenSession { + command: harness::CoreAgentCommand::OpenSession { config: volume_session_config(), }, max_steps: None, @@ -941,13 +941,13 @@ mod tests { .drive_command(DriveCommand { session_id: session_id.clone(), observed_at_ms: 100 + index, - command: engine::CoreAgentCommand::UpsertContext { + command: harness::CoreAgentCommand::UpsertContext { expected_revision: None, - key: engine::ContextEntryKey::new("note.live"), - entry: engine::ContextEntryInput { - kind: engine::ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { - content_ref: engine::BlobRef::from_bytes( + key: harness::ContextEntryKey::new("note.live"), + entry: harness::ContextEntryInput { + kind: harness::ContextEntryKind::ProviderOpaque, + content: harness::ContentRef { + content_ref: harness::BlobRef::from_bytes( format!("note-content-{index}").as_bytes(), ), media_type: Some("application/json".to_owned()), @@ -1019,7 +1019,7 @@ mod tests { metadata: Default::default(), session_id: session_id.clone(), display_name: None, - lifecycle_status: engine::storage::SessionLifecycleStatus::New, + lifecycle_status: harness::storage::SessionLifecycleStatus::New, closed_at_seq: None, closed_at_ms: None, activity: Default::default(), @@ -1034,7 +1034,7 @@ mod tests { created_at_ms: 1, updated_at_ms: 1, }, - core_state: Some(engine::CoreAgentState::new()), + core_state: Some(harness::CoreAgentState::new()), run_submissions: Default::default(), head: None, fresh_session: true, @@ -1079,7 +1079,7 @@ mod tests { use tools::attachments::Attachment; let deps = storage_deps(Arc::new(InMemorySessionStore::new())); let blob = deps.blobs.put_bytes(b"report".to_vec()).await.unwrap(); - let reference = engine::FileAttachment::new( + let reference = harness::FileAttachment::new( blob.clone(), "report.txt".into(), Some("text/plain".into()), @@ -1130,7 +1130,7 @@ mod tests { assert!(awaited.additional_context.is_empty()); assert_eq!(awaited.attachments, joined[0].attachments); assert!( - engine::storage::collect_blob_refs( + harness::storage::collect_blob_refs( &serde_json::to_value(&awaited.attachments).unwrap() ) .contains(&blob) @@ -1142,7 +1142,7 @@ mod tests { use tools::attachments::Attachment; let deps = storage_deps(Arc::new(InMemorySessionStore::new())); let blob = deps.blobs.put_bytes(b"%PDF report".to_vec()).await.unwrap(); - let reference = engine::FileAttachment::new( + let reference = harness::FileAttachment::new( blob.clone(), "report.pdf".into(), Some("application/pdf".into()), @@ -1151,7 +1151,7 @@ mod tests { forged.content_ref = BlobRef::from_bytes(b"not recorded"); let payload = deps.blobs.put_bytes(serde_json::to_vec(&json!({"attachments": [ Attachment::File(forged), Attachment::File(reference.clone()), - Attachment::Media(engine::media::MediaDescriptor::new(blob, "application/pdf", None).unwrap()), + Attachment::Media(harness::media::MediaDescriptor::new(blob, "application/pdf", None).unwrap()), ]})).unwrap()).await.unwrap(); let prepared = prepare_payload_context(&deps, &payload, &mut 0, &mut 1) .await @@ -1187,10 +1187,10 @@ mod tests { .put_bytes(b"%PDF-1.7 report".to_vec()) .await .expect("pdf"); - let missing = engine::BlobRef::from_bytes(b"never stored"); - let describe = |blob_ref: &engine::BlobRef, media_type: &str, name: &str| { + let missing = harness::BlobRef::from_bytes(b"never stored"); + let describe = |blob_ref: &harness::BlobRef, media_type: &str, name: &str| { json!({ - "handle": engine::media::media_handle(blob_ref), + "handle": harness::media::media_handle(blob_ref), "content_ref": blob_ref, "media_type": media_type, "kind": if media_type == "application/pdf" { "document" } else { "image" }, @@ -1282,7 +1282,7 @@ mod tests { .await .expect("png"); media.push(json!({ - "handle": engine::media::media_handle(&blob), + "handle": harness::media::media_handle(&blob), "content_ref": blob, "media_type": "image/png", "kind": "image", @@ -1321,7 +1321,7 @@ mod tests { .iter() .map(|entry| entry.preview.clone().unwrap_or_default()) .collect::>(); - assert_eq!(previews.len(), engine::media::MAX_TOOL_MEDIA_ITEMS + 1); + assert_eq!(previews.len(), harness::media::MAX_TOOL_MEDIA_ITEMS + 1); assert_eq!(previews[0], "[image: p0-0.png]"); assert_eq!(previews[7], "[image: p1-2.png]"); assert_eq!( @@ -1435,15 +1435,15 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn preparation_batch_retry_after_lost_commit_response_preserves_all_changes_once() { - use engine::{ + use harness::{ ContextEntryInput, ContextEntryKey, ContextEntryKind, CoreAgentAction, CoreAgentCommand, CoreAgentDrive, CoreAgentState, EnvironmentsFeature, EventSeq, }; let store = Arc::new(InMemorySessionStore::new()); let deps = storage_deps(store.clone()); let session_id = create_test_session(store.as_ref()).await; - let mut config = temporal_workflow::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + let mut config = temporal_workflow::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".into(), model: "test-model".into(), }); @@ -1451,10 +1451,10 @@ mod tests { config: config.clone(), }; config.features.environments = Some(EnvironmentsFeature { - environments: vec![engine::EnvironmentAttachment { + environments: vec![harness::EnvironmentAttachment { environment_id: "existing".to_owned(), default: false, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }], ..EnvironmentsFeature::default() @@ -1469,7 +1469,7 @@ mod tests { config, }, CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("existing"), + environment_id: harness::EnvironmentId::new("existing"), }, CoreAgentCommand::ReplaceContextPrefix { expected_revision: None, @@ -1478,7 +1478,9 @@ mod tests { ContextEntryKey::new("instructions.050.profile"), ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(BlobRef::from_bytes(b"prepared profile")), + content: harness::ContentRef::text(BlobRef::from_bytes( + b"prepared profile", + )), preview: None, origin: None, provenance_ref: None, @@ -1535,7 +1537,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn tool_emission_retry_and_restarted_reads_are_complete_across_pages() { - use engine::{ + use harness::{ ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, FunctionToolSpec, ManagedSessionWorkflowTools, RunConfig, RunRequestCommand, RunRequestSource, ToolKind, ToolParallelism, ToolSpec, WorkflowEndpointRef, @@ -1611,7 +1613,7 @@ mod tests { generations: AtomicUsize::new(0), tool_calls: vec![ ObservedToolCall { - call_id: engine::ToolCallId::new("report-call"), + call_id: harness::ToolCallId::new("report-call"), tool_id: Some(ToolName::new("work_report")), tool_name: ToolName::new("work_report"), provider_kind: None, @@ -1619,7 +1621,7 @@ mod tests { native_call_ref: None, }, ObservedToolCall { - call_id: engine::ToolCallId::new("approval-call"), + call_id: harness::ToolCallId::new("approval-call"), tool_id: Some(ToolName::new("request_approval")), tool_name: ToolName::new("request_approval"), provider_kind: None, @@ -1685,7 +1687,7 @@ mod tests { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: BlobRef::from_bytes(b"complete the work"), media_type: None, provider_kind: None, diff --git a/crates/temporal-server/src/worker/activities/subagents.rs b/crates/temporal-runtime/src/worker/activities/subagents.rs similarity index 96% rename from crates/temporal-server/src/worker/activities/subagents.rs rename to crates/temporal-runtime/src/worker/activities/subagents.rs index c94c091b1..03db95ae1 100644 --- a/crates/temporal-server/src/worker/activities/subagents.rs +++ b/crates/temporal-runtime/src/worker/activities/subagents.rs @@ -25,7 +25,7 @@ pub(super) async fn prepare( pub(super) async fn resolve( deps: Option<&SubagentActivityDeps>, request: SubagentResolveActivityRequest, -) -> Result { +) -> Result { let deps = deps .ok_or_else(|| activity_error(anyhow::anyhow!("subagent activities are not configured")))?; deps.service diff --git a/crates/temporal-server/src/worker/activities/tools.rs b/crates/temporal-runtime/src/worker/activities/tools.rs similarity index 96% rename from crates/temporal-server/src/worker/activities/tools.rs rename to crates/temporal-runtime/src/worker/activities/tools.rs index 4080fc6d4..e7663e1b4 100644 --- a/crates/temporal-server/src/worker/activities/tools.rs +++ b/crates/temporal-runtime/src/worker/activities/tools.rs @@ -1,12 +1,12 @@ use std::collections::BTreeMap; -use engine::{ +use futures::{StreamExt, stream}; +use harness::{ NativeMcpApprovalRequest, PromiseControlArgumentCallFacts, PromiseControlArgumentFacts, PromiseControlArgumentRequest, PromiseControlKind, ToolBatchOutcome, ToolCallStatus, ToolExecutionClass, ToolExecutionSpec, ToolInvocationBatchRequest, ToolInvocationBatchResult, ToolInvocationResult, storage::BlobStore, }; -use futures::{StreamExt, stream}; use temporal_workflow::MAX_CONCURRENT_TOOL_CALLS_PER_BATCH; use temporalio_sdk::activities::ActivityError; use tools::concurrency::{CancelArgs, DetachArgs}; @@ -209,13 +209,13 @@ async fn invoke_runtime_batch( /// Order merged results by their call's position in the original batch. /// Results the runtime returned for calls this batch never scheduled keep -/// their relative order at the end; the engine rejects them on resume. +/// their relative order at the end; the harness rejects them on resume. fn merge_in_batch_order( request: &ToolInvocationBatchRequest, runtime_results: Vec, native_results: BTreeMap, ) -> Vec { - let position = |call_id: &engine::ToolCallId| { + let position = |call_id: &harness::ToolCallId| { request .calls .iter() @@ -254,7 +254,7 @@ enum NativeMcpCallOutcome { /// The call must receive a single-use run-owned decision before the /// worker performs any MCP wire I/O. NeedsApproval { - subject: engine::ApprovalSubject, + subject: harness::ApprovalSubject, }, } @@ -266,7 +266,7 @@ enum NativeMcpCallOutcome { /// activity. async fn invoke_native_mcp_call( deps: &ToolActivityDeps, - request: &engine::ToolInvocationCallRequest, + request: &harness::ToolInvocationCallRequest, ) -> Result { let deadline = temporal_workflow::tool_call_operation_timeout(ToolExecutionClass::RemoteInteractive); @@ -299,23 +299,23 @@ async fn invoke_native_mcp_call( async fn execute_native_mcp_call( deps: &ToolActivityDeps, - request: &engine::ToolInvocationCallRequest, -) -> Result { + request: &harness::ToolInvocationCallRequest, +) -> Result { let native = deps .native_mcp .as_ref() - .ok_or_else(|| engine::CoreAgentIoError::Failed { + .ok_or_else(|| harness::CoreAgentIoError::Failed { message: "native MCP execution is unavailable on this worker".to_owned(), })?; let argument_bytes = deps .blobs .read_bytes(&request.call.arguments_ref) .await - .map_err(|error| engine::CoreAgentIoError::Failed { + .map_err(|error| harness::CoreAgentIoError::Failed { message: format!("read native MCP arguments: {error}"), })?; let arguments = serde_json::from_slice(&argument_bytes).map_err(|error| { - engine::CoreAgentIoError::Failed { + harness::CoreAgentIoError::Failed { message: format!("native MCP arguments are invalid JSON: {error}"), } })?; @@ -333,7 +333,7 @@ async fn execute_native_mcp_call( let mut asset_refs = Vec::with_capacity(assets.len()); for asset in assets { let blob_ref = deps.blobs.put_bytes(asset.bytes).await.map_err(|error| { - engine::CoreAgentIoError::Failed { + harness::CoreAgentIoError::Failed { message: format!( "store native MCP {} asset ({}): {error}", asset.kind, @@ -347,29 +347,29 @@ async fn execute_native_mcp_call( let output_ref = deps .blobs .put_bytes(serde_json::to_vec(&output).map_err(|error| { - engine::CoreAgentIoError::Failed { + harness::CoreAgentIoError::Failed { message: format!("encode native MCP result: {error}"), } })?) .await - .map_err(|error| engine::CoreAgentIoError::Failed { + .map_err(|error| harness::CoreAgentIoError::Failed { message: format!("store native MCP result: {error}"), })?; // The output embeds the asset refs it was just given; the edges // keep the assets alive as long as the output. - engine::storage::record_contains_edges( + harness::storage::record_contains_edges( deps.blob_graph.as_deref(), &output_ref, asset_refs.iter().cloned(), ) .await - .map_err(|error| engine::CoreAgentIoError::Failed { + .map_err(|error| harness::CoreAgentIoError::Failed { message: format!("record native MCP asset edges: {error}"), })?; let visible = visible.into_bytes(); let output_bytes = visible.len() as u64; let visible_ref = deps.blobs.put_bytes(visible).await.map_err(|error| { - engine::CoreAgentIoError::Failed { + harness::CoreAgentIoError::Failed { message: format!("store native MCP visible result: {error}"), } })?; @@ -391,15 +391,15 @@ async fn execute_native_mcp_call( let Some(blob_ref) = asset_refs.get(item.asset_index) else { continue; }; - let descriptor = engine::media::MediaDescriptor { - handle: engine::media::media_handle(blob_ref), + let descriptor = harness::media::MediaDescriptor { + handle: harness::media::media_handle(blob_ref), content_ref: blob_ref.clone(), media_type: item.media_type, kind: item.kind, name: item.name, }; model_visible_context_entries.push(descriptor.context_entry()); - attachments.push(engine::Attachment::Media(descriptor)); + attachments.push(harness::Attachment::Media(descriptor)); } Ok(NativeMcpCallOutcome::Completed(ToolInvocationResult { attachments, @@ -414,7 +414,7 @@ async fn execute_native_mcp_call( effects: Vec::new(), })) } - Err(message) => Err(engine::CoreAgentIoError::Failed { message }), + Err(message) => Err(harness::CoreAgentIoError::Failed { message }), } } @@ -503,7 +503,11 @@ pub(super) async fn await_environment_ready( }; let deadline = tokio::time::Instant::now() + temporal_workflow::ENVIRONMENT_READY_WAIT; Ok(hosted - .await_environment_ready(&request, deadline, || ctx.record_heartbeat(Vec::new())) + .await_environment_ready(&request, deadline, || async { + ctx.record_heartbeat(()) + .await + .expect("unit heartbeat serializes") + }) .await) } @@ -512,7 +516,7 @@ mod tests { use std::sync::{Arc, Mutex}; use async_trait::async_trait; - use engine::{ + use harness::{ AwaitMode, AwaitSpec, BlobRef, CoreAgentIoError, CoreAgentTools, PromiseControlArgumentCall, RemoteMcpApprovalPolicy, RemoteMcpCallRuntime, RemoteMcpCallTarget, RunId, SessionId, ToolBatchId, ToolCallId, ToolInvocationRequest, @@ -569,8 +573,8 @@ mod tests { PromiseControlArgumentCallFacts::Parsed { call_id: ToolCallId::new("cancel"), promise_ids: vec![ - engine::PromiseId::new("promise_1"), - engine::PromiseId::new("promise_2") + harness::PromiseId::new("promise_1"), + harness::PromiseId::new("promise_2") ], }, PromiseControlArgumentCallFacts::Invalid { @@ -869,7 +873,7 @@ mod tests { vec!["call_m1", "call_m2"] ); for approval in &approvals { - let engine::ApprovalSubject::McpToolCall { + let harness::ApprovalSubject::McpToolCall { server_id, tool_name, .. diff --git a/crates/temporal-server/src/worker/activities/transcriptions.rs b/crates/temporal-runtime/src/worker/activities/transcriptions.rs similarity index 95% rename from crates/temporal-server/src/worker/activities/transcriptions.rs rename to crates/temporal-runtime/src/worker/activities/transcriptions.rs index 81b4baa86..bfebfd568 100644 --- a/crates/temporal-server/src/worker/activities/transcriptions.rs +++ b/crates/temporal-runtime/src/worker/activities/transcriptions.rs @@ -1,6 +1,6 @@ use super::{audio, state::ActivityState}; use api::{TranscriptionFailure, TranscriptionFailureKind as Kind}; -use engine::{BlobRef, storage::BlobStore}; +use harness::{BlobRef, storage::BlobStore}; use temporal_workflow::{TranscriptionActivityResult, TranscriptionWorkflowArgs}; use temporalio_sdk::activities::ActivityError; @@ -33,9 +33,9 @@ enum ExecutionError { Terminal(TranscriptionFailure), Retry(String), } -impl From for ExecutionError { - fn from(error: engine::storage::BlobStoreError) -> Self { - if matches!(error, engine::storage::BlobStoreError::NotFound { .. }) { +impl From for ExecutionError { + fn from(error: harness::storage::BlobStoreError) -> Self { + if matches!(error, harness::storage::BlobStoreError::NotFound { .. }) { Self::Terminal(failure( Kind::InvalidAudio, "Audio is unavailable; upload it again.", diff --git a/crates/temporal-server/src/worker/activities/workflow_tools.rs b/crates/temporal-runtime/src/worker/activities/workflow_tools.rs similarity index 96% rename from crates/temporal-server/src/worker/activities/workflow_tools.rs rename to crates/temporal-runtime/src/worker/activities/workflow_tools.rs index bd77a8b7f..79fc48e36 100644 --- a/crates/temporal-server/src/worker/activities/workflow_tools.rs +++ b/crates/temporal-runtime/src/worker/activities/workflow_tools.rs @@ -4,20 +4,20 @@ //! execution. No plugin workflow type or activity is compiled into this //! worker; the recipe is data. -use engine::PromiseSourceCheckResult; +use harness::PromiseSourceCheckResult; use temporal_workflow::{ WORKFLOW_TOOL_RECIPE_FORMAT_V1, WORKFLOW_TOOL_RECOVERY_QUERY, WorkflowToolExecutionCancelRequest, WorkflowToolExecutionCheckRequest, WorkflowToolRecipeV1, WorkflowToolRecoveryResult, WorkflowToolStartActivityRequest, WorkflowToolStartActivityResult, split_workflow_id, workflow_tool_recipe_fingerprint, }; +use temporalio_client::WorkflowExecutionStatus; use temporalio_client::{ UntypedWorkflow, WorkflowCancelOptions, WorkflowDescribeOptions, WorkflowQueryOptions, WorkflowStartOptions, }; use temporalio_common::data_converters::PayloadConverter; use temporalio_common::data_converters::RawValue; -use temporalio_common::protos::temporal::api::enums::v1::WorkflowExecutionStatus; use temporalio_sdk::activities::ActivityError; use super::{ @@ -155,17 +155,17 @@ pub(super) async fn check_execution( .and_then(|raw| decode_recovery_result(raw).map_err(|error| error.to_string())); match recovered { Ok(result) => match result.resolutions.get(&request.completion_key) { - Some(engine::PromiseResolution::Resolved { payload_ref }) => { + Some(harness::PromiseResolution::Resolved { payload_ref }) => { Ok(PromiseSourceCheckResult::Resolved { payload_ref: payload_ref.clone(), }) } - Some(engine::PromiseResolution::Failed { error_ref }) => { + Some(harness::PromiseResolution::Failed { error_ref }) => { Ok(PromiseSourceCheckResult::Failed { error_ref: error_ref.clone(), }) } - Some(engine::PromiseResolution::Cancelled) => { + Some(harness::PromiseResolution::Cancelled) => { failed(format!( "started execution {} reported completion key `{}` as cancelled", request.execution_id, request.completion_key diff --git a/crates/temporal-server/src/worker/bots.rs b/crates/temporal-runtime/src/worker/bots.rs similarity index 99% rename from crates/temporal-server/src/worker/bots.rs rename to crates/temporal-runtime/src/worker/bots.rs index ef6e7d52a..d4511b352 100644 --- a/crates/temporal-server/src/worker/bots.rs +++ b/crates/temporal-runtime/src/worker/bots.rs @@ -53,12 +53,11 @@ impl BotWorkerActivities { ActivityError, > { let api = self.universes.api_for(universe_id).await?; - let workflow_id = &ctx + let workflow_id = ctx .info() - .workflow_execution - .as_ref() - .ok_or_else(|| authority_error("missing controller workflow identity"))? - .workflow_id; + .workflow_id + .as_deref() + .ok_or_else(|| authority_error("missing controller workflow identity"))?; let authority = api .bot_activity_authority(workflow_id, bot) .await diff --git a/crates/temporal-server/src/worker/channels.rs b/crates/temporal-runtime/src/worker/channels.rs similarity index 93% rename from crates/temporal-server/src/worker/channels.rs rename to crates/temporal-runtime/src/worker/channels.rs index 7a843a519..96bc16d6e 100644 --- a/crates/temporal-server/src/worker/channels.rs +++ b/crates/temporal-runtime/src/worker/channels.rs @@ -113,18 +113,11 @@ impl ChannelWorkerActivities { request: ChatReconcileDeliveryRequest, ) -> Result { let api = self.universes.api_for(request.universe_id).await?; - let workflow_id = &_ctx - .info() - .workflow_execution - .as_ref() - .ok_or_else(|| { - ActivityError::application( - temporalio_common::error::ApplicationFailure::non_retryable(anyhow::anyhow!( - "missing conversation workflow identity" - )), - ) - })? - .workflow_id; + let workflow_id = _ctx.info().workflow_id.as_deref().ok_or_else(|| { + ActivityError::application(temporalio_common::error::ApplicationFailure::non_retryable( + anyhow::anyhow!("missing conversation workflow identity"), + )) + })?; crate::channels::activities::reconcile_delivery(&api, workflow_id, request).await } diff --git a/crates/temporal-server/src/worker/fake.rs b/crates/temporal-runtime/src/worker/fake.rs similarity index 98% rename from crates/temporal-server/src/worker/fake.rs rename to crates/temporal-runtime/src/worker/fake.rs index 9222d09da..013e25d97 100644 --- a/crates/temporal-server/src/worker/fake.rs +++ b/crates/temporal-runtime/src/worker/fake.rs @@ -7,7 +7,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentIoError, CoreAgentLlm, CoreAgentTools, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, LlmGenerationStatus, ObservedToolCall, ToolBatchOutcome, ToolCallId, ToolCallStatus, @@ -190,7 +190,7 @@ impl FakeLlm { fn take_scripted_transient_failure(&self) -> bool { self.transient_failures_remaining - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |remaining| { + .try_update(Ordering::SeqCst, Ordering::SeqCst, |remaining| { remaining.checked_sub(1) }) .is_ok() @@ -229,7 +229,7 @@ impl FakeLlm { call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: arguments_ref.clone(), media_type: Some("application/json".to_owned()), provider_kind: Some("fake".to_owned()), @@ -275,7 +275,7 @@ impl FakeLlm { ) -> Result { let mut text = format!("Fake agent completed run {}.", request.run_id); for entry in &request.request.context.entries { - if !matches!(entry.source, engine::ContextEntrySource::Steering { .. }) { + if !matches!(entry.source, harness::ContextEntrySource::Steering { .. }) { continue; } let steering = self @@ -299,7 +299,7 @@ impl FakeLlm { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: output_ref, media_type: Some("text/plain".to_owned()), provider_kind: Some("fake".to_owned()), diff --git a/crates/temporal-server/src/worker/mcp.rs b/crates/temporal-runtime/src/worker/mcp.rs similarity index 95% rename from crates/temporal-server/src/worker/mcp.rs rename to crates/temporal-runtime/src/worker/mcp.rs index 9f57d5c46..cbcad9d25 100644 --- a/crates/temporal-server/src/worker/mcp.rs +++ b/crates/temporal-runtime/src/worker/mcp.rs @@ -9,7 +9,7 @@ use std::{ use async_trait::async_trait; use auth::SecretValue; use base64::Engine; -use engine::RemoteMcpToolSpec; +use harness::RemoteMcpToolSpec; use ipnet::IpNet; use llm_runtime::{ McpInventoryError, McpInventoryResolver, NativeMcpTool, @@ -35,7 +35,7 @@ pub enum NativeMcpExecutionOutcome { media: Vec, }, NeedsApproval { - subject: engine::ApprovalSubject, + subject: harness::ApprovalSubject, }, } @@ -45,7 +45,7 @@ pub enum NativeMcpExecutionOutcome { pub struct NativeMcpAsset { pub bytes: Vec, /// Content identity of `bytes`; the store returns the same reference. - pub blob_ref: engine::BlobRef, + pub blob_ref: harness::BlobRef, pub media_type: Option, pub kind: String, /// Resource `uri`, when the asset came from an embedded resource. @@ -56,7 +56,7 @@ pub struct NativeMcpAsset { #[derive(Clone, Debug, PartialEq, Eq)] pub struct NativeMcpMedia { pub asset_index: usize, - pub kind: engine::media::MediaKind, + pub kind: harness::media::MediaKind, pub media_type: String, pub name: Option, } @@ -303,7 +303,7 @@ impl NativeMcpRuntime { pub async fn execute( &self, - request: &engine::ToolInvocationCallRequest, + request: &harness::ToolInvocationCallRequest, arguments: serde_json::Value, ) -> Result { let runtime = request @@ -312,7 +312,7 @@ impl NativeMcpRuntime { .as_ref() .ok_or_else(|| "native MCP runtime facts are missing".to_owned())?; match runtime { - engine::RemoteMcpCallRuntime::Injected { + harness::RemoteMcpCallRuntime::Injected { target, remote_tool_name, approval_decision, @@ -330,7 +330,7 @@ impl NativeMcpRuntime { ) .await } - engine::RemoteMcpCallRuntime::Search { + harness::RemoteMcpCallRuntime::Search { targets, approval_decision, } if request @@ -341,7 +341,7 @@ impl NativeMcpRuntime { { self.find_tools(targets, arguments).await } - engine::RemoteMcpCallRuntime::Search { + harness::RemoteMcpCallRuntime::Search { targets, approval_decision, } if request @@ -374,7 +374,7 @@ impl NativeMcpRuntime { self.call(request, target, tool, inner, *approval_decision) .await } - engine::RemoteMcpCallRuntime::Search { .. } => { + harness::RemoteMcpCallRuntime::Search { .. } => { Err("unknown native MCP search meta-tool".to_owned()) } } @@ -382,7 +382,7 @@ impl NativeMcpRuntime { async fn find_tools( &self, - targets: &[engine::RemoteMcpCallTarget], + targets: &[harness::RemoteMcpCallTarget], arguments: serde_json::Value, ) -> Result { let object = arguments @@ -436,7 +436,7 @@ impl NativeMcpRuntime { .iter() .find(|target| target.server_id == server) .expect("selected server was validated"); - let spec = spec_from_target(target, engine::RemoteMcpExposure::Search); + let spec = spec_from_target(target, harness::RemoteMcpExposure::Search); let inventory = self .inventory .list_tools(&spec) @@ -468,7 +468,7 @@ impl NativeMcpRuntime { .iter() .filter(|target| selected_server.is_none_or(|server| server == target.server_id)) { - let spec = spec_from_target(target, engine::RemoteMcpExposure::Search); + let spec = spec_from_target(target, harness::RemoteMcpExposure::Search); for tool in self .inventory .list_tools(&spec) @@ -510,7 +510,7 @@ impl NativeMcpRuntime { async fn validate_search_call( &self, - target: &engine::RemoteMcpCallTarget, + target: &harness::RemoteMcpCallTarget, tool_name: &str, arguments: &serde_json::Map, ) -> Result<(), String> { @@ -524,7 +524,7 @@ impl NativeMcpRuntime { target.server_id )); } - let spec = spec_from_target(target, engine::RemoteMcpExposure::Search); + let spec = spec_from_target(target, harness::RemoteMcpExposure::Search); let tools = self .inventory .list_tools(&spec) @@ -544,17 +544,17 @@ impl NativeMcpRuntime { async fn call( &self, - request: &engine::ToolInvocationCallRequest, - target: &engine::RemoteMcpCallTarget, + request: &harness::ToolInvocationCallRequest, + target: &harness::RemoteMcpCallTarget, tool_name: &str, arguments: serde_json::Map, approval_decision: Option, ) -> Result { - if target.approval == engine::RemoteMcpApprovalPolicy::Always { + if target.approval == harness::RemoteMcpApprovalPolicy::Always { match approval_decision { None => { return Ok(NativeMcpExecutionOutcome::NeedsApproval { - subject: engine::ApprovalSubject::McpToolCall { + subject: harness::ApprovalSubject::McpToolCall { server_id: target.server_id.clone(), server_label: target.server_label.clone(), tool_name: tool_name.to_owned(), @@ -639,7 +639,7 @@ impl NativeMcpRuntime { async fn validate_current_record( &self, - target: &engine::RemoteMcpCallTarget, + target: &harness::RemoteMcpCallTarget, ) -> Result<(), String> { let id = mcp::McpServerId::try_new(target.server_id.clone()) .map_err(|error| format!("invalid MCP server id: {error}"))?; @@ -670,7 +670,7 @@ impl NativeMcpRuntime { async fn bearer_for_target( &self, - target: &engine::RemoteMcpCallTarget, + target: &harness::RemoteMcpCallTarget, ) -> Result, String> { let Some(secret_ref) = target.auth_ref.as_ref() else { return Ok(None); @@ -860,7 +860,7 @@ fn extract_mcp_assets( .map_err(|error| format!("MCP {kind:?} content is invalid base64: {error}"))?; let index = assets.len(); assets.push(NativeMcpAsset { - blob_ref: engine::BlobRef::from_bytes(&bytes), + blob_ref: harness::BlobRef::from_bytes(&bytes), bytes, media_type: object .get("mimeType") @@ -884,7 +884,7 @@ fn extract_mcp_assets( .map_err(|error| format!("MCP resource content is invalid base64: {error}"))?; let index = assets.len(); assets.push(NativeMcpAsset { - blob_ref: engine::BlobRef::from_bytes(&bytes), + blob_ref: harness::BlobRef::from_bytes(&bytes), bytes, media_type: resource .get("mimeType") @@ -907,7 +907,7 @@ fn extract_mcp_assets( Ok(()) } -pub fn attach_mcp_asset_refs(value: &mut serde_json::Value, refs: &[engine::BlobRef]) { +pub fn attach_mcp_asset_refs(value: &mut serde_json::Value, refs: &[harness::BlobRef]) { match value { serde_json::Value::Array(values) => { for value in values { @@ -932,8 +932,8 @@ pub fn attach_mcp_asset_refs(value: &mut serde_json::Value, refs: &[engine::Blob } fn spec_from_target( - target: &engine::RemoteMcpCallTarget, - exposure: engine::RemoteMcpExposure, + target: &harness::RemoteMcpCallTarget, + exposure: harness::RemoteMcpExposure, ) -> RemoteMcpToolSpec { RemoteMcpToolSpec { server_id: target.server_id.clone(), @@ -942,7 +942,7 @@ fn spec_from_target( server_url: target.server_url.clone(), description_ref: None, allowed_tools: target.allowed_tools.clone(), - execution: engine::RemoteMcpExecution::Native, + execution: harness::RemoteMcpExecution::Native, exposure, approval: target.approval.clone(), defer_loading: None, @@ -1074,7 +1074,7 @@ fn render_mcp_asset( name: Option, media: &mut Vec, ) -> String { - use engine::media::{ + use harness::media::{ MediaRejection, admit_tool_media, tool_media_line, tool_media_omitted_line, }; @@ -1089,9 +1089,9 @@ fn render_mcp_asset( admit_tool_media(asset.media_type.as_deref(), asset.bytes.len() as u64) }; let admission = admission.and_then(|kind| { - if media.len() >= engine::media::MAX_TOOL_MEDIA_ITEMS { + if media.len() >= harness::media::MAX_TOOL_MEDIA_ITEMS { Err(MediaRejection::TooMany { - limit: engine::media::MAX_TOOL_MEDIA_ITEMS, + limit: harness::media::MAX_TOOL_MEDIA_ITEMS, }) } else { Ok(kind) @@ -1099,7 +1099,7 @@ fn render_mcp_asset( }); match admission { Ok(kind) => { - let media_type = engine::media::normalized_media_type( + let media_type = harness::media::normalized_media_type( asset.media_type.as_deref().unwrap_or_default(), ); let line = tool_media_line( @@ -1239,9 +1239,9 @@ mod tests { server_url: "http://127.0.0.1/mcp".to_owned(), description_ref: None, allowed_tools: None, - execution: engine::RemoteMcpExecution::Native, - exposure: engine::RemoteMcpExposure::Inject, - approval: engine::RemoteMcpApprovalPolicy::Never, + execution: harness::RemoteMcpExecution::Native, + exposure: harness::RemoteMcpExposure::Inject, + approval: harness::RemoteMcpApprovalPolicy::Never, defer_loading: None, auth_ref: None, auth_required: false, @@ -1361,7 +1361,7 @@ mod tests { assert_eq!(assets.len(), 1); assert_eq!(assets[0].bytes, b"hello"); assert!(!value.to_string().contains("aGVsbG8=")); - attach_mcp_asset_refs(&mut value, &[engine::BlobRef::from_bytes(b"hello")]); + attach_mcp_asset_refs(&mut value, &[harness::BlobRef::from_bytes(b"hello")]); assert!(value.to_string().contains("sha256:")); } @@ -1380,12 +1380,12 @@ mod tests { extract_mcp_assets(&mut value, &mut assets).expect("extract"); let refs = assets .iter() - .map(|asset| engine::BlobRef::from_bytes(&asset.bytes)) + .map(|asset| harness::BlobRef::from_bytes(&asset.bytes)) .collect::>(); assert_eq!(refs.len(), 2); attach_mcp_asset_refs(&mut value, &refs); assert_eq!( - engine::storage::collect_blob_refs(&value), + harness::storage::collect_blob_refs(&value), refs.iter().cloned().collect() ); } @@ -1541,7 +1541,7 @@ mod tests { lines[1], format!( "[image 1 · {} · image/png · 2 KiB]", - engine::media::media_handle(&engine::BlobRef::from_bytes(&png)) + harness::media::media_handle(&harness::BlobRef::from_bytes(&png)) ) ); assert!( @@ -1566,19 +1566,19 @@ mod tests { vec![ NativeMcpMedia { asset_index: 0, - kind: engine::media::MediaKind::Image, + kind: harness::media::MediaKind::Image, media_type: "image/png".into(), name: None }, NativeMcpMedia { asset_index: 1, - kind: engine::media::MediaKind::Image, + kind: harness::media::MediaKind::Image, media_type: "image/jpeg".into(), name: None }, NativeMcpMedia { asset_index: 2, - kind: engine::media::MediaKind::Document, + kind: harness::media::MediaKind::Document, media_type: "application/pdf".into(), name: Some("report.pdf".into()) }, @@ -1596,7 +1596,7 @@ mod tests { let mut content = vec![ serde_json::json!({"type": "image", "mimeType": "image/svg+xml", "data": b64(b"")}), serde_json::json!({"type": "audio", "mimeType": "audio/wav", "data": b64(b"RIFF")}), - serde_json::json!({"type": "image", "mimeType": "image/png", "data": b64(&vec![0u8; (engine::media::MAX_TOOL_MEDIA_BYTES + 1) as usize])}), + serde_json::json!({"type": "image", "mimeType": "image/png", "data": b64(&vec![0u8; (harness::media::MAX_TOOL_MEDIA_BYTES + 1) as usize])}), ]; for index in 0..9u8 { content.push(serde_json::json!({"type": "image", "mimeType": "image/png", "data": b64(&[index; 16])})); @@ -1612,11 +1612,11 @@ mod tests { lines[2], format!( "[image 2 omitted: {} bytes exceeds the {} byte limit]", - engine::media::MAX_TOOL_MEDIA_BYTES + 1, - engine::media::MAX_TOOL_MEDIA_BYTES + harness::media::MAX_TOOL_MEDIA_BYTES + 1, + harness::media::MAX_TOOL_MEDIA_BYTES ) ); - assert_eq!(media.len(), engine::media::MAX_TOOL_MEDIA_ITEMS); + assert_eq!(media.len(), harness::media::MAX_TOOL_MEDIA_ITEMS); assert!(lines[3].starts_with("[image 3 · media:")); assert_eq!( lines[11], @@ -1633,12 +1633,12 @@ mod tests { serde_json::json!({"type": "audio", "mimeType": "image/png", "data": b64(b"audio")}), ]; let mut expected_media = Vec::new(); - for index in 0..engine::media::MAX_TOOL_MEDIA_ITEMS { + for index in 0..harness::media::MAX_TOOL_MEDIA_ITEMS { let (kind, media_type, name) = if index % 2 == 0 { content.push(serde_json::json!({ "type": "image", "mimeType": "Image/PNG; charset=binary", "data": b64(b"png") })); - (engine::media::MediaKind::Image, "image/png", None) + (harness::media::MediaKind::Image, "image/png", None) } else { let name = format!("report-{index}.pdf"); content.push(serde_json::json!({"type": "resource", "resource": { @@ -1646,7 +1646,7 @@ mod tests { "mimeType": "Application/PDF", "blob": b64(b"pdf") }})); ( - engine::media::MediaKind::Document, + harness::media::MediaKind::Document, "application/pdf", Some(name), ) @@ -1670,7 +1670,7 @@ mod tests { ]); let (visible, media, assets) = native_result(serde_json::Value::Array(content)); assert_eq!(media, expected_media); - assert_eq!(assets.len(), engine::media::MAX_TOOL_MEDIA_ITEMS + 5); + assert_eq!(assets.len(), harness::media::MAX_TOOL_MEDIA_ITEMS + 5); let lines: Vec<_> = visible.lines().collect(); assert_eq!( lines[0], @@ -1684,7 +1684,7 @@ mod tests { index / 2 + 1 }; let label = if index % 2 == 0 { "image" } else { "document" }; - let handle = engine::media::media_handle(&assets[item.asset_index].blob_ref); + let handle = harness::media::media_handle(&assets[item.asset_index].blob_ref); let name = item .name .as_ref() @@ -1699,7 +1699,7 @@ mod tests { ); } assert_eq!( - &lines[engine::media::MAX_TOOL_MEDIA_ITEMS + 2..], + &lines[harness::media::MAX_TOOL_MEDIA_ITEMS + 2..], &[ "between blocks", "[image 6 omitted: at most 8 media items per result]", @@ -1715,7 +1715,7 @@ mod tests { {"type": "image", "mimeType": "image/png", "data": b64(&png_bytes())} ])); let item = &media[0]; - let entry = engine::media::media_context_entry( + let entry = harness::media::media_context_entry( assets[item.asset_index].blob_ref.clone(), &item.media_type, item.kind, @@ -1725,8 +1725,8 @@ mod tests { assert_eq!(entry.preview.as_deref(), Some("[image]")); assert!(matches!( entry.kind, - engine::ContextEntryKind::Message { - role: engine::ContextMessageRole::User + harness::ContextEntryKind::Message { + role: harness::ContextMessageRole::User } )); } diff --git a/crates/temporal-server/src/worker/mod.rs b/crates/temporal-runtime/src/worker/mod.rs similarity index 69% rename from crates/temporal-server/src/worker/mod.rs rename to crates/temporal-runtime/src/worker/mod.rs index 2775130b4..476091e51 100644 --- a/crates/temporal-server/src/worker/mod.rs +++ b/crates/temporal-runtime/src/worker/mod.rs @@ -11,9 +11,7 @@ mod session_tools; mod universes; use temporalio_client::Client; -use temporalio_common::{telemetry::TelemetryOptions, worker::WorkerTaskTypes}; -use temporalio_sdk::{Worker, WorkerOptions}; -use temporalio_sdk_core::{CoreRuntime, RuntimeOptions}; +use temporalio_sdk::{Runtime, Worker, WorkerOptions, runtime::RuntimeOptions}; use temporal_workflow::{ BotControllerWorkflow, BotTriggerFireWorkflow, ChannelConversationWorkflow, @@ -62,81 +60,55 @@ pub use temporal_workflow::{ AwaitEnvironmentReadyActivityResult, ToolInvokeCallActivityResult, }; -pub fn core_runtime() -> anyhow::Result { - CoreRuntime::new_assume_tokio( - RuntimeOptions::builder() - .telemetry_options(TelemetryOptions::builder().build()) - .build() - .map_err(|error| anyhow::anyhow!("{error}"))?, - ) -} - -/// The `sessions` worker: session, environment-job, and sub-agent -/// workflows with their activities, polling every task type. -pub fn worker_with_activities( - runtime: &CoreRuntime, - client: Client, - task_queue: String, - activities: WorkerActivities, -) -> anyhow::Result { - sessions_worker( - runtime, - client, - task_queue, - activities, - WorkerTaskTypes::all(), - ) +pub fn worker_runtime() -> anyhow::Result { + Ok(Runtime::from_current_tokio(RuntimeOptions::default())?) } +/// The `sessions` worker runs session, environment-job, and sub-agent +/// workflows together with their activities. pub fn sessions_worker( - runtime: &CoreRuntime, + runtime: &Runtime, client: Client, task_queue: String, activities: WorkerActivities, - task_types: WorkerTaskTypes, ) -> anyhow::Result { let worker_options = WorkerOptions::new(task_queue) - .register_workflow::() - .register_workflow::() - .register_workflow::() - .register_workflow::() + .register_workflow::()? + .register_workflow::()? + .register_workflow::()? + .register_workflow::()? .register_activities(activities) - .task_types(task_types) .build(); - Worker::new(runtime, client, worker_options).map_err(|error| anyhow::anyhow!("{error}")) + Ok(Worker::new(runtime, client, worker_options)?) } /// The `bots` worker: bot controllers and trigger fires with their /// activities. pub fn bots_worker( - runtime: &CoreRuntime, + runtime: &Runtime, client: Client, task_queue: String, activities: BotWorkerActivities, - task_types: WorkerTaskTypes, ) -> anyhow::Result { let worker_options = WorkerOptions::new(task_queue) - .register_workflow::() - .register_workflow::() + .register_workflow::()? + .register_workflow::()? .register_activities(activities) - .task_types(task_types) .build(); - Worker::new(runtime, client, worker_options).map_err(|error| anyhow::anyhow!("{error}")) + Ok(Worker::new(runtime, client, worker_options)?) } /// The `channels` worker: conversation workflows with their core-side /// activities. pub fn channels_worker( - runtime: &CoreRuntime, + runtime: &Runtime, client: Client, task_queue: String, activities: ChannelWorkerActivities, - task_types: WorkerTaskTypes, ) -> anyhow::Result { let worker_options = WorkerOptions::new(task_queue) - .register_workflow::() + .register_workflow::()? .register_activities(activities) - .task_types(task_types) .build(); - Worker::new(runtime, client, worker_options).map_err(|error| anyhow::anyhow!("{error}")) + Ok(Worker::new(runtime, client, worker_options)?) } diff --git a/crates/temporal-server/src/worker/reaper.rs b/crates/temporal-runtime/src/worker/reaper.rs similarity index 96% rename from crates/temporal-server/src/worker/reaper.rs rename to crates/temporal-runtime/src/worker/reaper.rs index 85a6f004a..208f09a23 100644 --- a/crates/temporal-server/src/worker/reaper.rs +++ b/crates/temporal-runtime/src/worker/reaper.rs @@ -15,13 +15,13 @@ use std::{collections::BTreeMap, sync::Arc, time::Duration}; use anyhow::Context as _; use api_projection::MAX_EVENT_PAGE_LIMIT; use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, CodecError, CoreAgentAction, CoreAgentCodec, CoreAgentCommand, CoreAgentDrive, CoreAgentState, CoreAgentStatus, DomainError, EventSeq, Promise, PromiseId, PromiseResolution, PromiseScope, PromiseSource, SessionId, storage::{ AppendSessionEvents, DeleteClosedSessions, ListSessions, ReadSessionEvents, - SessionListCursor, SessionRecord, SessionStore, SessionStoreError, engine_blob_refs, + SessionListCursor, SessionRecord, SessionStore, SessionStoreError, harness_blob_refs, }, }; use store_pg::{ @@ -29,10 +29,10 @@ use store_pg::{ CasSweepPage, PgStore, }; use temporal_workflow::{AgentAdmission, AgentSessionWorkflow, compose_workflow_id}; +use temporalio_client::WorkflowExecutionStatus; use temporalio_client::{ Client, WorkflowDescribeOptions, WorkflowSignalOptions, errors::WorkflowInteractionError, }; -use temporalio_common::protos::temporal::api::enums::v1::WorkflowExecutionStatus; use thiserror::Error; use uuid::Uuid; @@ -109,7 +109,7 @@ impl CasBlobSweeper { Ok(Some(mut leader)) => loop { match self.run_pass(false, Some(&mut leader)).await { Ok(stats) if stats.reportable() => tracing::info!( - target: "temporal_server", + target: "temporal_runtime", universes_scanned = stats.universes_scanned, rows_scanned = stats.rows_scanned, candidates = stats.candidates, @@ -123,7 +123,7 @@ impl CasBlobSweeper { ), Ok(_) => {} Err(error) => { - tracing::warn!(target: "temporal_server", %error, "cas blob sweep leader failed"); + tracing::warn!(target: "temporal_runtime", %error, "cas blob sweep leader failed"); break; } } @@ -131,7 +131,7 @@ impl CasBlobSweeper { }, Ok(None) => {} Err(error) => { - tracing::warn!(target: "temporal_server", %error, "could not acquire cas sweep leadership") + tracing::warn!(target: "temporal_runtime", %error, "could not acquire cas sweep leadership") } } tokio::time::sleep(self.interval).await; @@ -170,7 +170,7 @@ impl CasBlobSweeper { } let deadline = std::time::Instant::now() + CAS_SWEEP_PASS_BUDGET; let cutoff_ms = now_ms().saturating_sub(duration_ms(self.grace)); - let pinned = engine_blob_refs(); + let pinned = harness_blob_refs(); let mut stats = CasSweepStats::default(); for (universe_id, _) in universes { if std::time::Instant::now() >= deadline { @@ -314,7 +314,7 @@ async fn sweep_universe_page( Err(error) => { stats.errors += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, %error, "could not list cas sweep candidates" @@ -353,7 +353,7 @@ async fn sweep_universe_page( // this page alone and revisit it after the cursor wraps. stats.holder_conflicts += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, constraint, message, @@ -364,7 +364,7 @@ async fn sweep_universe_page( Err(error) => { stats.errors += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, %error, "could not delete dead cas blobs" @@ -390,7 +390,7 @@ async fn sweep_universe_page( let objects_succeeded = objects.failures.is_empty(); for (key, error) in objects.failures { tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, key, error, @@ -459,7 +459,7 @@ impl SessionRetentionReaper { loop { match self.run_once().await { Ok(stats) if stats.reportable() => tracing::info!( - target: "temporal_server", + target: "temporal_runtime", universes_scanned = stats.universes_scanned, due_roots_scanned = stats.due_roots_scanned, roots_deleted = stats.roots_deleted, @@ -471,7 +471,7 @@ impl SessionRetentionReaper { ), Ok(_) => {} Err(error) => tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %error, "session retention reaper pass failed" ), @@ -495,7 +495,7 @@ impl SessionRetentionReaper { Err(error) => { stats.errors += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, %error, "could not list due session-retention roots" @@ -531,7 +531,7 @@ impl SessionRetentionReaper { Err(error) => { stats.errors += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, session_id = %root.session_id, %error, @@ -603,7 +603,7 @@ impl PromiseReaper { || stats.conflicts > 0 => { tracing::info!( - target: "temporal_server", + target: "temporal_runtime", universes_scanned = stats.universes_scanned, sessions_scanned = stats.sessions_scanned, promises_examined = stats.promises_examined, @@ -619,7 +619,7 @@ impl PromiseReaper { Ok(_) => {} Err(error) => { tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", error = %format_args!("{error:#}"), "promise reaper pass failed" ); @@ -826,21 +826,21 @@ async fn observe_active_projection_statuses( SessionWorkflowStatus::Terminal(status) => { stats.stale_active_projections += 1; tracing::error!( - target: "temporal_server", + target: "temporal_runtime", event = "stale_active_projection", %universe_id, %session_id, %workflow_id, lightspeed_run_id = active_run_id.as_u64(), session_head_seq, - temporal_status = status.as_str_name(), + temporal_status = ?status, "session projection is active but its workflow is terminal" ); } SessionWorkflowStatus::NotFound => { stats.stale_active_projections += 1; tracing::error!( - target: "temporal_server", + target: "temporal_runtime", event = "stale_active_projection", %universe_id, %session_id, @@ -854,7 +854,7 @@ async fn observe_active_projection_statuses( SessionWorkflowStatus::Unavailable(error) => { stats.workflow_status_errors += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", event = "session_workflow_status_unavailable", %universe_id, %session_id, @@ -891,7 +891,7 @@ async fn apply_holder_repairs( Err(WorkflowSignalFailure::Other(error)) => { stats.errors += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, %session_id, %error, @@ -910,7 +910,7 @@ async fn apply_holder_repairs( Err(DirectAppendError::Other(error)) => { stats.errors += 1; tracing::warn!( - target: "temporal_server", + target: "temporal_runtime", %universe_id, %session_id, %error, @@ -1011,7 +1011,7 @@ async fn load_session_snapshots( Ok(page) => page, Err(error) => { stats.errors += 1; - tracing::warn!(target: "temporal_server", %universe_id, operation = "list_sessions", + tracing::warn!(target: "temporal_runtime", %universe_id, operation = "list_sessions", %error, "promise reaper could not list sessions"); return snapshots; } @@ -1022,7 +1022,7 @@ async fn load_session_snapshots( Ok(state) => state, Err(error) => { stats.errors += 1; - tracing::warn!(target: "temporal_server", %universe_id, + tracing::warn!(target: "temporal_runtime", %universe_id, session_id = %record.session_id, operation = error.operation(), event_seq = error.event_seq().map(EventSeq::as_u64), %error, "promise reaper skipped unreadable session"); @@ -1091,7 +1091,7 @@ async fn load_session_state( let entry = CoreAgentCodec .decode_entry(stored) .map_err(|source| SessionLoadError::Decode { seq, source })?; - engine::apply_event(&mut state, &entry) + harness::apply_event(&mut state, &entry) .map_err(|source| SessionLoadError::Replay { seq, source })?; } if page.complete { @@ -1188,7 +1188,7 @@ mod tests { use std::collections::BTreeSet; use std::sync::Mutex; - use engine::{ + use harness::{ ActiveRun, ModelSelection, ProviderApiKind, RunId, RunSource, RunStatus, storage::{BlobGraphStore as _, BlobStore as _}, }; @@ -1197,13 +1197,13 @@ mod tests { use super::*; async fn stored_session( - store: &engine::storage::InMemorySessionStore, + store: &harness::storage::InMemorySessionStore, id: &str, - events: Vec, + events: Vec, ) -> SessionId { let session_id = SessionId::new(id); store - .create_session(engine::storage::CreateSession { + .create_session(harness::storage::CreateSession { session_id: session_id.clone(), display_name: None, metadata: Default::default(), @@ -1219,7 +1219,7 @@ mod tests { expected_head: None, events: events .into_iter() - .map(|event| engine::session::UncommittedStoredEvent { + .map(|event| harness::session::UncommittedStoredEvent { observed_at_ms: 1, joins: Default::default(), event, @@ -1246,11 +1246,11 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn unreadable_sessions_are_identified_without_blocking_healthy_repairs() { - use engine::{ + use harness::{ CoreAgentEvent, CoreAgentLifecycleEvent, PromiseEvent, PromiseOwnership, PromiseStatus, StoredEvent, }; - let store = Arc::new(engine::storage::InMemorySessionStore::new()); + let store = Arc::new(harness::storage::InMemorySessionStore::new()); let opened = CoreAgentCodec .encode_event(&CoreAgentEvent::Lifecycle( CoreAgentLifecycleEvent::Opened { @@ -1446,7 +1446,7 @@ mod tests { input_consumed_by_turn_id: None, run_config: default_run_config(), config_revision: 0, - first_seq: engine::EventSeq::new(1), + first_seq: harness::EventSeq::new(1), accepted_at_ms: 1, started_at_ms: Some(1), usage: None, @@ -1470,7 +1470,7 @@ mod tests { /// list drive the object phase. #[derive(Default)] struct FakeSweepStore { - blobs: engine::storage::InMemoryBlobStore, + blobs: harness::storage::InMemoryBlobStore, live: Mutex>, object_backed: BTreeSet, failing_objects: BTreeSet, @@ -1604,7 +1604,7 @@ mod tests { let now = Arc::new(std::sync::atomic::AtomicU64::new(1_000)); let clock_now = now.clone(); let mut store = FakeSweepStore { - blobs: engine::storage::InMemoryBlobStore::with_clock(Arc::new(move || { + blobs: harness::storage::InMemoryBlobStore::with_clock(Arc::new(move || { clock_now.load(std::sync::atomic::Ordering::SeqCst) })), ..FakeSweepStore::default() @@ -1614,13 +1614,13 @@ mod tests { let live = aged_blob(&store, b"held by a session").await; let parent = aged_blob(&store, b"manifest").await; let child = aged_blob(&store, b"file inside the manifest").await; - let pinned = engine_blob_refs(); - for content in engine::storage::ENGINE_BLOB_CONTENTS { + let pinned = harness_blob_refs(); + for content in harness::storage::ENGINE_BLOB_CONTENTS { aged_blob(&store, content.as_bytes()).await; } store .blobs - .record_blob_edges(vec![engine::storage::BlobEdge::contains( + .record_blob_edges(vec![harness::storage::BlobEdge::contains( parent.clone(), child.clone(), )]) @@ -1746,7 +1746,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn cas_sweep_counts_holder_conflicts_and_object_failures_without_failing_the_pass() { let store = FakeSweepStore { - blobs: engine::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), + blobs: harness::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), holder_conflict: true, ..FakeSweepStore::default() }; @@ -1759,7 +1759,7 @@ mod tests { assert!(stats.reportable()); let mut store = FakeSweepStore { - blobs: engine::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), + blobs: harness::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), ..FakeSweepStore::default() }; let failing = aged_blob(&store, b"object whose delete fails").await; @@ -1778,7 +1778,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn cas_sweep_respects_the_batch_limit() { let store = FakeSweepStore { - blobs: engine::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), + blobs: harness::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), ..FakeSweepStore::default() }; for index in 0..5u8 { @@ -1793,7 +1793,7 @@ mod tests { async fn paged_sweep_store(count: usize) -> FakeSweepStore { let store = FakeSweepStore { - blobs: engine::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), + blobs: harness::storage::InMemoryBlobStore::with_clock(Arc::new(|| 10)), ..FakeSweepStore::default() }; for index in 0..count { @@ -1943,7 +1943,7 @@ mod tests { metadata: Default::default(), session_id: session_id.clone(), display_name: None, - lifecycle_status: engine::storage::SessionLifecycleStatus::New, + lifecycle_status: harness::storage::SessionLifecycleStatus::New, closed_at_seq: None, closed_at_ms: None, activity: Default::default(), diff --git a/crates/temporal-server/src/worker/secrets.rs b/crates/temporal-runtime/src/worker/secrets.rs similarity index 99% rename from crates/temporal-server/src/worker/secrets.rs rename to crates/temporal-runtime/src/worker/secrets.rs index eb5d3fdd9..69addeb9d 100644 --- a/crates/temporal-server/src/worker/secrets.rs +++ b/crates/temporal-runtime/src/worker/secrets.rs @@ -2,7 +2,7 @@ //! //! Adapts the auth token broker to `llm-runtime`'s [`SecretResolver`] boundary. //! Resolution runs only inside activity execution; resolved values never enter -//! Temporal history, engine events, or persisted provider request blobs. +//! Temporal history, harness events, or persisted provider request blobs. use std::sync::Arc; @@ -11,7 +11,7 @@ use auth::{ AuthBrokerError, AuthProviderConfig, AuthProviderId, AuthProviderStatus, AuthProviderStore, AuthRegistryError, AuthTokenBroker, SecretStore, TokenAudience, model_auth_provider_id, }; -use engine::SecretRef; +use harness::SecretRef; use llm_runtime::provider_keys::{ ModelProviderResolver, ProviderKeyError, ResolvedEndpoint, ResolvedModelProvider, ResolvedProviderAuth, diff --git a/crates/temporal-server/src/worker/session_tools.rs b/crates/temporal-runtime/src/worker/session_tools.rs similarity index 93% rename from crates/temporal-server/src/worker/session_tools.rs rename to crates/temporal-runtime/src/worker/session_tools.rs index 8417cdf4d..dc9796ac1 100644 --- a/crates/temporal-server/src/worker/session_tools.rs +++ b/crates/temporal-runtime/src/worker/session_tools.rs @@ -1,13 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; use async_trait::async_trait; -use engine::PromiseIdAllocator; -use engine::{ - CoreAgentIoError, CoreAgentTools, PromiseSource, SessionId, ToolBatchOutcome, ToolCallStatus, - ToolInvocationBatchRequest, ToolInvocationBatchResult, ToolInvocationResult, - promise_create_effect, - storage::{BlobEdge, BlobGraphStore, BlobStore, BlobStoreError}, -}; use environment_client::{EnvironmentClientError, EnvironmentDataClient, WebSocketConnectOptions}; use environment_protocol::{ data::{ @@ -17,6 +10,13 @@ use environment_protocol::{ shared::{CURRENT_PROTOCOL_VERSION, EnvironmentDataConnection, EnvironmentTransport}, }; use environments::{EnvironmentId, EnvironmentRecord, EnvironmentRegistryError, EnvironmentStore}; +use harness::PromiseIdAllocator; +use harness::{ + CoreAgentIoError, CoreAgentTools, PromiseSource, SessionId, ToolBatchOutcome, ToolCallStatus, + ToolInvocationBatchRequest, ToolInvocationBatchResult, ToolInvocationResult, + promise_create_effect, + storage::{BlobEdge, BlobGraphStore, BlobStore, BlobStoreError}, +}; use store_pg::PgStore; use tools::{ builtin::BuiltinToolRequirements, @@ -141,7 +141,7 @@ impl SessionTools { async fn invoke_concurrency_call( &self, request: &ToolInvocationBatchRequest, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, promise_ids: &PromiseIdAllocator, ) -> Result { match call.tool_id.as_ref().map(|id| id.as_str()) { @@ -169,7 +169,7 @@ impl SessionTools { async fn invoke_cancel_call( &self, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, ) -> Result { let result = match async { let args: CancelArgs = self.read_tool_args(call).await?; @@ -192,8 +192,8 @@ impl SessionTools { async fn invoke_detach_call( &self, - run_id: engine::RunId, - call: &engine::ToolInvocationRequest, + run_id: harness::RunId, + call: &harness::ToolInvocationRequest, ) -> Result { let result = match async { let args: DetachArgs = self.read_tool_args(call).await?; @@ -217,7 +217,7 @@ impl SessionTools { async fn invoke_sleep_call( &self, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, promise_ids: &PromiseIdAllocator, ) -> Result { let args: SleepArgs = self.read_tool_args(call).await?; @@ -252,7 +252,7 @@ impl SessionTools { async fn invoke_store_backed_await_batch( &self, request: ToolInvocationBatchRequest, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, ) -> Result { let args: AwaitArgs = self.read_tool_args(call).await?; match await_spec_from_args(args, now_unix_ms()?).map_err(io_error) { @@ -392,7 +392,7 @@ impl SessionTools { async fn invoke_environment_job_call( &self, request: &ToolInvocationBatchRequest, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, environments: &SessionEnvironmentManager, ) -> Result { match call.tool_id.as_ref().map(|id| id.as_str()) { @@ -428,7 +428,7 @@ impl SessionTools { &self, session_id: &SessionId, active_environment_id: Option<&EnvironmentId>, - policy: Option<&engine::EnvironmentsFeature>, + policy: Option<&harness::EnvironmentsFeature>, environments: &SessionEnvironmentManager, handles: Vec, output_bytes: Option, @@ -541,7 +541,7 @@ impl SessionTools { async fn read_tool_args( &self, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, ) -> Result where T: serde::de::DeserializeOwned, @@ -558,19 +558,19 @@ impl SessionTools { async fn invoke_workflow_tool_call( &self, request: &ToolInvocationBatchRequest, - call: &engine::ToolInvocationRequest, - binding: &engine::WorkflowToolBinding, + call: &harness::ToolInvocationRequest, + binding: &harness::WorkflowToolBinding, emitted_count: u32, promise_ids: &PromiseIdAllocator, ) -> Result { - if emitted_count >= engine::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN { + if emitted_count >= harness::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN { return failed_result( self.blobs.as_ref(), call.call_id.clone(), format!( "workflow tool {} reached its per-run emission cap of {}", binding.definition.tool_id, - engine::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN + harness::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN ), ) .await; @@ -733,15 +733,15 @@ impl SessionTools { async fn invoke_supplied_workflow_tool_call( &self, request: &ToolInvocationBatchRequest, - call: &engine::ToolInvocationRequest, - successful_siblings: &mut BTreeMap, + call: &harness::ToolInvocationRequest, + successful_siblings: &mut BTreeMap, promise_ids: &PromiseIdAllocator, ) -> Result { let runtime = call .workflow_tool .as_ref() .expect("supplied workflow-tool dispatch requires runtime facts"); - if runtime.version != engine::WorkflowToolCallRuntime::VERSION { + if runtime.version != harness::WorkflowToolCallRuntime::VERSION { return failed_result( self.blobs.as_ref(), call.call_id.clone(), @@ -766,7 +766,7 @@ impl SessionTools { async fn succeeded_tool_result( &self, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, output: &T, visible: impl Into, ) -> Result { @@ -802,7 +802,7 @@ impl SessionTools { async fn succeeded_job_read_result( &self, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, jobs: Vec, ) -> Result { let output = ModelJobResultSet { jobs }; @@ -853,7 +853,7 @@ impl SessionTools { async fn invoke_environment_control_call( &self, request: &ToolInvocationBatchRequest, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, ) -> Result { let Some(resolver) = self.environment_resolver.as_ref() else { return failed_result( @@ -1027,7 +1027,7 @@ impl SessionTools { ) }; let mut result = self.succeeded_tool_result(call, &output, summary).await?; - result.effects.push(engine::environment_activate_effect( + result.effects.push(harness::environment_activate_effect( &environment.environment_id, )); Ok(result) @@ -1038,7 +1038,9 @@ impl SessionTools { let mut result = self .succeeded_tool_result(call, &output, "Active environment cleared.") .await?; - result.effects.push(engine::environment_deactivate_effect()); + result + .effects + .push(harness::environment_deactivate_effect()); Ok(result) } other => { @@ -1162,13 +1164,13 @@ impl SessionTools { ); let mut client = connect_environment_data_client( &connection, - gateway.connect_options("lightspeed-temporal-server"), + gateway.connect_options("lightspeed-temporal-runtime"), ) .await?; let response = client .initialize(&InitializeParams { protocol_version: CURRENT_PROTOCOL_VERSION, - client_name: "lightspeed-temporal-server".to_owned(), + client_name: "lightspeed-temporal-runtime".to_owned(), scope: connection.scope.clone(), resume_connection_id: None, }) @@ -1275,10 +1277,10 @@ struct EnvironmentJobRead { /// One attached environment as the model sees it: the attachment's grant /// joined with the registry record, which may be missing. fn environment_model_view( - attachment: &engine::EnvironmentAttachment, + attachment: &harness::EnvironmentAttachment, environment: Option<&EnvironmentRecord>, active: Option<&EnvironmentId>, - policy: &engine::EnvironmentsFeature, + policy: &harness::EnvironmentsFeature, ) -> serde_json::Value { serde_json::json!({ "environment_id": tools::environment::handles::environment_reference(&attachment.environment_id, policy.environments.iter().map(|attachment| attachment.environment_id.as_str())), @@ -1295,7 +1297,7 @@ fn environment_model_view( fn unattached_message( environment_id: &EnvironmentId, - policy: &engine::EnvironmentsFeature, + policy: &harness::EnvironmentsFeature, ) -> String { let attached = policy .environments @@ -1322,7 +1324,7 @@ enum EnvironmentReadTargetError { fn resolve_attached_environment( reference: &str, - policy: Option<&engine::EnvironmentsFeature>, + policy: Option<&harness::EnvironmentsFeature>, ) -> Result { tools::environment::handles::resolve_environment_reference( reference, @@ -1337,7 +1339,7 @@ fn resolve_attached_environment( fn environment_read_target( args: EnvironmentReadArgs, active: Option<&EnvironmentId>, - policy: Option<&engine::EnvironmentsFeature>, + policy: Option<&harness::EnvironmentsFeature>, ) -> Result { match args.environment_id { Some(environment_id) => resolve_attached_environment(&environment_id, policy) @@ -1354,19 +1356,19 @@ fn environment_read_target( /// applies. Without an active environment the environment-required path /// reports that instead. fn environment_tool_denial( - policy: Option<&engine::EnvironmentsFeature>, + policy: Option<&harness::EnvironmentsFeature>, active: Option<&EnvironmentId>, - call: &engine::ToolInvocationRequest, + call: &harness::ToolInvocationRequest, ) -> Option { let id = call.tool_id.as_ref()?.as_str(); let required = match id { "env.read_file" | "env.grep" | "env.glob" | "env.list_dir" | "vfs.capture" => { - engine::EnvironmentAccess::Read + harness::EnvironmentAccess::Read } "env.write_file" | "env.edit_file" | "env.apply_patch" | "vfs.materialize" => { - engine::EnvironmentAccess::Edit + harness::EnvironmentAccess::Edit } - "env.run_process" | "env.continue_process" => engine::EnvironmentAccess::Exec, + "env.run_process" | "env.continue_process" => harness::EnvironmentAccess::Exec, _ => return None, }; let active = active?; @@ -1379,10 +1381,10 @@ fn environment_tool_denial( "{} requires {} access on the active environment {active}, which grants {}", call.tool_name, match required { - engine::EnvironmentAccess::Read => "read", - engine::EnvironmentAccess::Edit => "edit", - engine::EnvironmentAccess::Exec => "exec", - engine::EnvironmentAccess::Jobs => "jobs", + harness::EnvironmentAccess::Read => "read", + harness::EnvironmentAccess::Edit => "edit", + harness::EnvironmentAccess::Exec => "exec", + harness::EnvironmentAccess::Jobs => "jobs", }, attachment.access.describe() )), @@ -1391,7 +1393,7 @@ fn environment_tool_denial( fn supplied_environment_policy( request: &ToolInvocationBatchRequest, -) -> Result<&engine::EnvironmentsFeature, CoreAgentIoError> { +) -> Result<&harness::EnvironmentsFeature, CoreAgentIoError> { request .environment_policy .as_ref() @@ -1483,7 +1485,7 @@ impl BatchCallRoute { } struct BatchCall<'a> { - call: &'a engine::ToolInvocationRequest, + call: &'a harness::ToolInvocationRequest, route: BatchCallRoute, denial: Option, needs_vfs: bool, @@ -1491,7 +1493,7 @@ struct BatchCall<'a> { } impl<'a> BatchCall<'a> { - fn new(request: &ToolInvocationBatchRequest, call: &'a engine::ToolInvocationRequest) -> Self { + fn new(request: &ToolInvocationBatchRequest, call: &'a harness::ToolInvocationRequest) -> Self { let id = call.tool_id.as_ref(); let requirements = id.map(BuiltinToolRequirements::for_id).unwrap_or_default(); let is_job_read = id.is_some_and(|id| id.as_str() == "env.job_read"); @@ -1527,7 +1529,7 @@ impl CoreAgentTools for SessionTools { request: ToolInvocationBatchRequest, ) -> Result { // One allocator per dispatch: every promise this batch's calls mint - // is numbered from the engine's base, whichever call draws first. + // is numbered from the harness's base, whichever call draws first. let promise_ids = PromiseIdAllocator::new(request.promise_id_base); let selection_calls = request .calls @@ -1691,7 +1693,7 @@ impl CoreAgentTools for SessionTools { async fn invoke_call( &self, - request: engine::ToolInvocationCallRequest, + request: harness::ToolInvocationCallRequest, ) -> Result { match self.invoke_call_execution(request).await? { ToolCallExecution::Completed(result) => Ok(result), @@ -1722,7 +1724,7 @@ pub enum ToolCallExecution { /// still provisioning or booting. The workflow waits for readiness and /// re-dispatches the same call. EnvironmentNotReady { - call_id: engine::ToolCallId, + call_id: harness::ToolCallId, environment_id: String, status: environments::EnvironmentStatus, }, @@ -1734,7 +1736,7 @@ impl SessionTools { /// can wait outside the tool activity's tight class deadline. pub async fn invoke_call_execution( &self, - request: engine::ToolInvocationCallRequest, + request: harness::ToolInvocationCallRequest, ) -> Result { let call = request.call.clone(); if let Some(message) = environment_tool_denial( @@ -1869,11 +1871,11 @@ impl SessionTools { /// Poll the registry (and probe the route) until the environment is /// ready for use, terminally unusable, or `deadline` passes. `heartbeat` is /// invoked on every poll so the hosting activity stays alive. - pub async fn await_environment_ready( + pub async fn await_environment_ready>( &self, request: &temporal_workflow::AwaitEnvironmentReadyActivityRequest, deadline: tokio::time::Instant, - heartbeat: impl Fn(), + heartbeat: impl Fn() -> F, ) -> temporal_workflow::AwaitEnvironmentReadyActivityResult { use temporal_workflow::AwaitEnvironmentReadyActivityResult as Outcome; let Some(resolver) = self.environment_resolver.as_ref() else { @@ -1891,7 +1893,7 @@ impl SessionTools { }; let mut last_status; loop { - heartbeat(); + heartbeat().await; let now = i64::try_from(now_unix_ms().unwrap_or_default()).unwrap_or(i64::MAX); match resolver.ready_for_use(&environment_id, now).await { Ok(_) => return Outcome::Ready, @@ -1940,7 +1942,7 @@ impl SessionTools { /// so the common read needs just the job id. fn resolve_job_handle_arg( active_environment_id: Option<&EnvironmentId>, - policy: Option<&engine::EnvironmentsFeature>, + policy: Option<&harness::EnvironmentsFeature>, handle: JobHandleArg, ) -> Result { let environment_id = match handle.environment_id { @@ -1974,10 +1976,10 @@ fn active_environment_blocker_message(blocker: &ActiveEnvironmentBlocker) -> Str /// calls participating in a violation fail; unrelated siblings execute /// normally. fn per_call_batch_rule_violation( - request: &engine::ToolInvocationCallRequest, + request: &harness::ToolInvocationCallRequest, ) -> Option<&'static str> { let call = &request.call; - let is_env_dependent = |tool_id: Option<&engine::ToolName>| { + let is_env_dependent = |tool_id: Option<&harness::ToolName>| { tool_id.is_some_and(|id| BuiltinToolRequirements::for_id(id).active_environment) }; let sibling_selection = request.sibling_calls.iter().any(|sibling| { @@ -2010,7 +2012,7 @@ fn per_call_batch_rule_violation( async fn failed_result( blobs: &dyn BlobStore, - call_id: engine::ToolCallId, + call_id: harness::ToolCallId, message: impl Into, ) -> Result { failed_result_bytes(blobs, call_id, message.into().into_bytes()).await @@ -2018,7 +2020,7 @@ async fn failed_result( async fn failed_structured_result( blobs: &dyn BlobStore, - call_id: engine::ToolCallId, + call_id: harness::ToolCallId, code: &str, message: &str, ) -> Result { @@ -2032,7 +2034,7 @@ async fn failed_structured_result( async fn failed_result_bytes( blobs: &dyn BlobStore, - call_id: engine::ToolCallId, + call_id: harness::ToolCallId, bytes: Vec, ) -> Result { let error_ref = blobs.put_bytes(bytes).await.map_err(map_blob_error)?; @@ -2086,7 +2088,7 @@ fn io_error(error: impl std::fmt::Display) -> CoreAgentIoError { #[cfg(test)] mod tests { - use engine::ProviderApiKind; + use harness::ProviderApiKind; use std::{ collections::BTreeMap, sync::{Arc, Mutex}, @@ -2095,16 +2097,6 @@ mod tests { use tools::environment::control::ENVIRONMENT_LIST_TOOL_NAME; use crate::environments::runtime::RuntimeEnvironment; - use engine::{ - BlobRef, ContextEntryKind, FunctionToolSpec, RunId, SessionId, ToolBatchId, ToolCallId, - ToolKind, ToolName, ToolParallelism, ToolSpec, TurnId, WorkflowEndpointRef, - WorkflowToolDefinition, WorkflowToolId, WorkspaceAccess, WorkspaceAttachment, - WorkspaceAttachmentTarget, - storage::{ - AppendSessionEvents, CreateSession, InMemoryBlobStore, InMemorySessionStore, - SessionStore, - }, - }; use environment_protocol::shared::{EnvironmentTransport, ProviderTargetId}; use environments::{ CreateEnvironment, EnvironmentConnectionSpec, EnvironmentIncarnationId, @@ -2115,6 +2107,16 @@ mod tests { InMemoryEnvironmentRegistryStore, ObserveProvisionedEnvironment, PutEnvironmentProvider, PutEnvironmentProviderBinding, }; + use harness::{ + BlobRef, ContextEntryKind, FunctionToolSpec, RunId, SessionId, ToolBatchId, ToolCallId, + ToolKind, ToolName, ToolParallelism, ToolSpec, TurnId, WorkflowEndpointRef, + WorkflowToolDefinition, WorkflowToolId, WorkspaceAccess, WorkspaceAttachment, + WorkspaceAttachmentTarget, + storage::{ + AppendSessionEvents, CreateSession, InMemoryBlobStore, InMemorySessionStore, + SessionStore, + }, + }; use tools::environment::{ EnvironmentToolContext, process::{ @@ -2161,12 +2163,12 @@ mod tests { }) } - fn test_builtin_runtime() -> engine::BuiltinToolCallRuntime { - engine::BuiltinToolCallRuntime { - spec: engine::BuiltinToolSpec { + fn test_builtin_runtime() -> harness::BuiltinToolCallRuntime { + harness::BuiltinToolCallRuntime { + spec: harness::BuiltinToolSpec { settings: serde_json::json!({"presentation":"canonical"}), }, - model: engine::ModelSelection { + model: harness::ModelSelection { api_kind: ProviderApiKind::OpenAiResponses, provider_id: "test".into(), model: "test".into(), @@ -2177,32 +2179,32 @@ mod tests { /// An environments grant attaching `attached` with jobs access and /// selection tools: the widest grant, so tests exercise policy through /// the active attachment rather than the tool surface. - fn test_environment_policy(attached: &[&str]) -> engine::EnvironmentsFeature { - test_environment_policy_with_access(attached, engine::EnvironmentAccess::Jobs) + fn test_environment_policy(attached: &[&str]) -> harness::EnvironmentsFeature { + test_environment_policy_with_access(attached, harness::EnvironmentAccess::Jobs) } fn test_environment_policy_with_access( attached: &[&str], - access: engine::EnvironmentAccess, - ) -> engine::EnvironmentsFeature { - engine::EnvironmentsFeature { + access: harness::EnvironmentAccess, + ) -> harness::EnvironmentsFeature { + harness::EnvironmentsFeature { selection: true, environments: attached .iter() - .map(|id| engine::EnvironmentAttachment { + .map(|id| harness::EnvironmentAttachment { environment_id: (*id).to_owned(), default: false, access, working_directory: None, }) .collect(), - ..engine::EnvironmentsFeature::default() + ..harness::EnvironmentsFeature::default() } } #[tokio::test(flavor = "current_thread")] async fn ungranted_environment_operations_fail_before_resolving_domains() { - use engine::EnvironmentAccess; + use harness::EnvironmentAccess; let active = EnvironmentId::new("environment-active"); for access in [ EnvironmentAccess::Read, @@ -2284,7 +2286,7 @@ mod tests { batch.active_environment_id = Some(EnvironmentId::new("environment-active")); batch.environment_policy = Some(test_environment_policy_with_access( &["environment-active"], - engine::EnvironmentAccess::Read, + harness::EnvironmentAccess::Read, )); batch.calls.push(denied); let results = tools @@ -2309,8 +2311,8 @@ mod tests { tool_name: &str, arguments: &[u8], siblings: &[(&str, &[u8])], - ) -> engine::ToolInvocationCallRequest { - engine::ToolInvocationCallRequest { + ) -> harness::ToolInvocationCallRequest { + harness::ToolInvocationCallRequest { vfs_working_directory: None, session_id: SessionId::new("session-a"), run_id: RunId::new(1), @@ -2321,7 +2323,7 @@ mod tests { active_environment_id: None, environment_policy: None, subagents_policy: None, - call: engine::ToolInvocationRequest { + call: harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_self"), tool_id: Some(test_tool_id(tool_name)), @@ -2334,14 +2336,14 @@ mod tests { sibling_calls: siblings .iter() .enumerate() - .map(|(index, (name, arguments))| engine::ToolCallSummary { + .map(|(index, (name, arguments))| harness::ToolCallSummary { call_id: ToolCallId::new(format!("call_sibling_{index}")), tool_id: Some(test_tool_id(name)), tool_name: ToolName::new(*name), arguments_ref: BlobRef::from_bytes(arguments), }) .collect(), - execution: engine::ToolExecutionSpec::default(), + execution: harness::ToolExecutionSpec::default(), } } @@ -2468,7 +2470,7 @@ mod tests { async fn workflow_tool_session( blobs: &dyn BlobStore, sessions: &InMemorySessionStore, - ) -> (SessionId, engine::WorkflowToolBinding) { + ) -> (SessionId, harness::WorkflowToolBinding) { let session_id = SessionId::new("workflow-tool-session"); let schema_ref = blobs .put_bytes( @@ -2498,9 +2500,9 @@ mod tests { workflow_id: "opaque work workflow id".to_owned(), workflow_kind: "agent_work".to_owned(), }; - let workflow_tools = engine::ManagedSessionWorkflowTools::v1( + let workflow_tools = harness::ManagedSessionWorkflowTools::v1( Some(receiver.clone()), - vec![engine::WorkflowToolDeclaration::bound_notify( + vec![harness::WorkflowToolDeclaration::bound_notify( definition.clone(), receiver, )], @@ -2524,14 +2526,14 @@ mod tests { }) .await .expect("create session"); - let config = crate::worker::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + let config = crate::worker::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "test".to_owned(), model: "test-model".to_owned(), }); - let proposals = engine::admit_command( - &engine::CoreAgentState::new(), - engine::CoreAgentCommand::OpenManagedSession { + let proposals = harness::admit_command( + &harness::CoreAgentState::new(), + harness::CoreAgentCommand::OpenManagedSession { config, session_universe_id: universe_id, workflow_tools, @@ -2542,7 +2544,7 @@ mod tests { let events = proposals .into_iter() .map(|proposal| { - engine::CoreAgentCodec + harness::CoreAgentCodec .encode_uncommitted(&proposal.into_uncommitted(2)) .expect("encode opening event") }) @@ -2587,9 +2589,9 @@ mod tests { }; let mut workflow = call("work_report", "workflow", workflow_args); workflow.builtin = None; - workflow.workflow_tool = Some(engine::WorkflowToolCallRuntime::v1( + workflow.workflow_tool = Some(harness::WorkflowToolCallRuntime::v1( binding, - engine::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN - 1, + harness::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN - 1, )); let mut bad_route = workflow.clone(); bad_route.call_id = ToolCallId::new("bad-route"); @@ -2677,7 +2679,7 @@ mod tests { ); assert_eq!( results[2].effects[0].kind, - engine::WORKFLOW_TOOL_EMIT_EFFECT_KIND + harness::WORKFLOW_TOOL_EMIT_EFFECT_KIND ); assert!(results[1].effects.is_empty()); assert!(results[5].effects.is_empty()); @@ -2709,46 +2711,46 @@ mod tests { let tools = SessionTools::new(blobs.clone(), catalog); let mut corrupt_binding = binding.clone(); corrupt_binding.binding_fingerprint.push_str("-corrupt"); - let mut calls = vec![engine::ToolInvocationRequest { + let mut calls = vec![harness::ToolInvocationRequest { builtin: None, call_id: ToolCallId::new("call-invalid-schema"), tool_id: Some(binding.definition.tool.name.clone()), tool_name: binding.definition.tool.name.clone(), arguments_ref: invalid_arguments, - workflow_tool: Some(engine::WorkflowToolCallRuntime::v1( + workflow_tool: Some(harness::WorkflowToolCallRuntime::v1( binding.clone(), prior_emission_count, )), promise_control: None, remote_mcp: None, }]; - calls.push(engine::ToolInvocationRequest { + calls.push(harness::ToolInvocationRequest { builtin: None, call_id: ToolCallId::new("call-name-mismatch"), tool_id: Some(ToolName::new("other_tool")), tool_name: ToolName::new("other_tool"), arguments_ref: valid_arguments.clone(), - workflow_tool: Some(engine::WorkflowToolCallRuntime::v1( + workflow_tool: Some(harness::WorkflowToolCallRuntime::v1( binding.clone(), prior_emission_count, )), promise_control: None, remote_mcp: None, }); - calls.push(engine::ToolInvocationRequest { + calls.push(harness::ToolInvocationRequest { builtin: None, call_id: ToolCallId::new("call-fingerprint-mismatch"), tool_id: Some(binding.definition.tool.name.clone()), tool_name: binding.definition.tool.name.clone(), arguments_ref: valid_arguments.clone(), - workflow_tool: Some(engine::WorkflowToolCallRuntime::v1( + workflow_tool: Some(harness::WorkflowToolCallRuntime::v1( corrupt_binding, prior_emission_count, )), promise_control: None, remote_mcp: None, }); - calls.push(engine::ToolInvocationRequest { + calls.push(harness::ToolInvocationRequest { builtin: None, call_id: ToolCallId::new("call-missing-runtime"), tool_id: Some(binding.definition.tool.name.clone()), @@ -2759,14 +2761,14 @@ mod tests { remote_mcp: None, }); calls.extend( - (0..engine::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN - prior_emission_count).map(|index| { - engine::ToolInvocationRequest { + (0..harness::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN - prior_emission_count).map(|index| { + harness::ToolInvocationRequest { builtin: None, call_id: ToolCallId::new(format!("call-{index}")), tool_id: Some(binding.definition.tool.name.clone()), tool_name: binding.definition.tool.name.clone(), arguments_ref: valid_arguments.clone(), - workflow_tool: Some(engine::WorkflowToolCallRuntime::v1( + workflow_tool: Some(harness::WorkflowToolCallRuntime::v1( binding.clone(), prior_emission_count, )), @@ -2775,13 +2777,13 @@ mod tests { } }), ); - calls.push(engine::ToolInvocationRequest { + calls.push(harness::ToolInvocationRequest { builtin: None, call_id: ToolCallId::new("call-over-cap"), tool_id: Some(binding.definition.tool.name.clone()), tool_name: binding.definition.tool.name.clone(), arguments_ref: valid_arguments, - workflow_tool: Some(engine::WorkflowToolCallRuntime::v1( + workflow_tool: Some(harness::WorkflowToolCallRuntime::v1( binding.clone(), prior_emission_count, )), @@ -2816,11 +2818,11 @@ mod tests { .collect::>(); assert_eq!( successful.len(), - (engine::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN - prior_emission_count) as usize + (harness::MAX_WORKFLOW_TOOL_EMISSIONS_PER_RUN - prior_emission_count) as usize ); assert!(successful.iter().all(|result| { result.effects.len() == 1 - && result.effects[0].kind == engine::WORKFLOW_TOOL_EMIT_EFFECT_KIND + && result.effects[0].kind == harness::WORKFLOW_TOOL_EMIT_EFFECT_KIND })); let acknowledgement = blobs .read_text( @@ -2920,22 +2922,22 @@ mod tests { parallelism: ToolParallelism::ParallelSafe, }, }; - let binding = engine::WorkflowToolBinding::admit( + let binding = harness::WorkflowToolBinding::admit( uuid::Uuid::from_u128(1), definition, - engine::WorkflowToolTarget::Start { - start: engine::WorkflowStartRef { + harness::WorkflowToolTarget::Start { + start: harness::WorkflowStartRef { recipe_format: temporal_workflow::WORKFLOW_TOOL_RECIPE_FORMAT_V1, revision: 1, recipe_ref, recipe_fingerprint, }, }, - engine::WorkflowToolCompletion::Promises { + harness::WorkflowToolCompletion::Promises { reply_schema_ref: None, deadline_after_ms: None, - max_promises: engine::MAX_COMPLETION_PROMISES, - key_source: engine::WorkflowToolCompletionKeySource::ArrayItemField { + max_promises: harness::MAX_COMPLETION_PROMISES, + key_source: harness::WorkflowToolCompletionKeySource::ArrayItemField { pointer: "/jobs".to_owned(), field: "job_id".to_owned(), }, @@ -2946,13 +2948,13 @@ mod tests { .put_bytes(br#"{"jobs":[{"job_id":"build","argv":["make"]}]}"#.to_vec()) .await .expect("put job arguments"); - let call = engine::ToolInvocationRequest { + let call = harness::ToolInvocationRequest { builtin: None, call_id: ToolCallId::new("call-job-start"), tool_id: Some(binding.definition.tool.name.clone()), tool_name: binding.definition.tool.name.clone(), arguments_ref: arguments_ref.clone(), - workflow_tool: Some(engine::WorkflowToolCallRuntime::v1(binding.clone(), 0)), + workflow_tool: Some(harness::WorkflowToolCallRuntime::v1(binding.clone(), 0)), promise_control: None, remote_mcp: None, }; @@ -3044,18 +3046,18 @@ mod tests { /// The `agent_run` system binding as the gateway admits it: a /// start-on-call recipe with joined completion. - async fn agent_run_binding(blobs: &InMemoryBlobStore) -> engine::WorkflowToolBinding { + async fn agent_run_binding(blobs: &InMemoryBlobStore) -> harness::WorkflowToolBinding { let kind = tools::subagents::SubagentToolKind::Run; let tool = tools::definitions::register( "subagent.run", Default::default(), - engine::ToolParallelism::ParallelSafe, + harness::ToolParallelism::ParallelSafe, Default::default(), ); let recipe = b"test subagent recipe".to_vec(); let recipe_fingerprint = temporal_workflow::workflow_tool_recipe_fingerprint(&recipe); let recipe_ref = blobs.put_bytes(recipe).await.expect("put subagent recipe"); - engine::WorkflowToolBinding::admit( + harness::WorkflowToolBinding::admit( uuid::Uuid::from_u128(1), WorkflowToolDefinition { tool_id: WorkflowToolId::new(kind.workflow_tool_id()), @@ -3063,17 +3065,17 @@ mod tests { semantic_type: kind.semantic_type().to_owned(), tool, }, - engine::WorkflowToolTarget::Start { - start: engine::WorkflowStartRef { + harness::WorkflowToolTarget::Start { + start: harness::WorkflowStartRef { recipe_format: temporal_workflow::WORKFLOW_TOOL_RECIPE_FORMAT_V1, revision: 1, recipe_ref, recipe_fingerprint, }, }, - engine::WorkflowToolCompletion::Joined { + harness::WorkflowToolCompletion::Joined { reply_schema_ref: None, - deadline_after_ms: engine::SUBAGENT_DEADLINE_CEILING_MS, + deadline_after_ms: harness::SUBAGENT_DEADLINE_CEILING_MS, }, ) .expect("admit agent_run binding") @@ -3081,25 +3083,25 @@ mod tests { fn subagents_policy( agents: &[&str], - limits: engine::SubagentLimits, - ) -> engine::SubagentsFeature { - engine::SubagentsFeature { + limits: harness::SubagentLimits, + ) -> harness::SubagentsFeature { + harness::SubagentsFeature { agents: agents .iter() - .map(|profile_id| engine::SubagentAgentConfig { + .map(|profile_id| harness::SubagentAgentConfig { profile_id: (*profile_id).to_owned(), }) .collect(), limits, - ..engine::SubagentsFeature::default() + ..harness::SubagentsFeature::default() } } async fn agent_run_batch( blobs: &InMemoryBlobStore, - binding: &engine::WorkflowToolBinding, + binding: &harness::WorkflowToolBinding, arguments: &[u8], - policy: Option, + policy: Option, ) -> ToolInvocationBatchRequest { let arguments_ref = blobs .put_bytes(arguments.to_vec()) @@ -3116,13 +3118,13 @@ mod tests { environment_policy: None, subagents_policy: policy, workspace_attachments: Vec::new(), - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call-agent-run"), tool_id: Some(binding.definition.tool.name.clone()), tool_name: ToolName::new("agent_run"), arguments_ref, - workflow_tool: Some(engine::WorkflowToolCallRuntime::v1(binding.clone(), 0)), + workflow_tool: Some(harness::WorkflowToolCallRuntime::v1(binding.clone(), 0)), promise_control: None, remote_mcp: None, }], @@ -3166,7 +3168,7 @@ mod tests { let blobs = Arc::new(InMemoryBlobStore::new()); let binding = agent_run_binding(&blobs).await; let tools = SessionTools::new(blobs.clone(), Arc::new(TestCatalog::default())); - let policy = subagents_policy(&["reviewer", "planner"], engine::SubagentLimits::default()); + let policy = subagents_policy(&["reviewer", "planner"], harness::SubagentLimits::default()); let unlisted = tools .invoke_batch( @@ -3212,7 +3214,7 @@ mod tests { let blobs = Arc::new(InMemoryBlobStore::new()); let binding = agent_run_binding(&blobs).await; let tools = SessionTools::new(blobs.clone(), Arc::new(TestCatalog::default())); - let limits = engine::SubagentLimits { + let limits = harness::SubagentLimits { max_depth: 1, max_descendants: 3, max_concurrent: 2, @@ -3463,7 +3465,7 @@ mod tests { ) -> RuntimeEnvironment { let target_id = ProviderTargetId::new("test"); let resource = environments::EnvironmentRecord { - environment_id: engine::EnvironmentId::new("test"), + environment_id: harness::EnvironmentId::new("test"), request_id: EnvironmentProvisionRequestId::new("request-test"), source: EnvironmentSource::Provisioned { provider_id: EnvironmentProviderId::new("test-provider"), @@ -3524,7 +3526,7 @@ mod tests { async fn dispatch( tools: &SessionTools, - request: engine::ToolInvocationCallRequest, + request: harness::ToolInvocationCallRequest, batch: bool, ) -> ToolInvocationResult { if batch { @@ -3906,7 +3908,9 @@ mod tests { if tool_name == "environment_activate" { assert_eq!( result.effects, - vec![engine::environment_activate_effect(&EnvironmentId::new(id))] + vec![harness::environment_activate_effect(&EnvironmentId::new( + id + ))] ); } } @@ -3960,7 +3964,7 @@ mod tests { .put_bytes(br#"{}"#.to_vec()) .await .expect("list arguments"); - let request = engine::ToolInvocationCallRequest { + let request = harness::ToolInvocationCallRequest { vfs_working_directory: None, session_id: SessionId::new("session-per-call-list"), run_id: RunId::new(1), @@ -3974,7 +3978,7 @@ mod tests { "environment-allowed-2", ])), subagents_policy: None, - call: engine::ToolInvocationRequest { + call: harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call-environment-list"), tool_id: Some(test_tool_id(ENVIRONMENT_LIST_TOOL_NAME)), @@ -3985,7 +3989,7 @@ mod tests { remote_mcp: None, }, sibling_calls: Vec::new(), - execution: engine::ToolExecutionSpec::default(), + execution: harness::ToolExecutionSpec::default(), }; let result = tools.invoke_call(request).await.expect("invoke call"); @@ -4035,7 +4039,7 @@ mod tests { .put_bytes(br#"{"path":"README.md"}"#.to_vec()) .await .expect("read_file arguments"); - let request = engine::ToolInvocationCallRequest { + let request = harness::ToolInvocationCallRequest { vfs_working_directory: None, session_id: SessionId::new("session-per-call-not-ready"), run_id: RunId::new(1), @@ -4046,7 +4050,7 @@ mod tests { active_environment_id: Some(EnvironmentId::new("environment-pending")), environment_policy: Some(test_environment_policy(&["environment-pending"])), subagents_policy: None, - call: engine::ToolInvocationRequest { + call: harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call-read-file"), tool_id: Some(test_tool_id("read_file")), @@ -4057,7 +4061,7 @@ mod tests { remote_mcp: None, }, sibling_calls: Vec::new(), - execution: engine::ToolExecutionSpec::default(), + execution: harness::ToolExecutionSpec::default(), }; // Hosted per-call path: the call does not run and reports not-ready. @@ -4085,7 +4089,7 @@ mod tests { // The generic trait path degrades to an ordinary failed result. let result = tools.invoke_call(request).await.expect("invoke call"); - assert_eq!(result.status, engine::ToolCallStatus::Failed); + assert_eq!(result.status, harness::ToolCallStatus::Failed); // Once observed ready, resolution no longer blocks (the route probe // itself is exercised by live tests). @@ -4107,7 +4111,7 @@ mod tests { environment_policy: None, }, tokio::time::Instant::now() + std::time::Duration::from_millis(50), - || {}, + || async {}, ) .await; // No gateway on this runtime, so the probe fails and the bounded wait @@ -4146,7 +4150,7 @@ mod tests { environment_policy: None, }, tokio::time::Instant::now() + std::time::Duration::from_secs(30), - || {}, + || async {}, ) .await; assert!(matches!( @@ -4164,7 +4168,7 @@ mod tests { .put_bytes(br#"{}"#.to_vec()) .await .expect("await arguments"); - let request = engine::ToolInvocationCallRequest { + let request = harness::ToolInvocationCallRequest { vfs_working_directory: None, session_id: SessionId::new("session-per-call-await"), run_id: RunId::new(1), @@ -4175,7 +4179,7 @@ mod tests { active_environment_id: None, environment_policy: None, subagents_policy: None, - call: engine::ToolInvocationRequest { + call: harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call-await"), tool_id: Some(test_tool_id(AWAIT_TOOL_NAME)), @@ -4186,7 +4190,7 @@ mod tests { remote_mcp: None, }, sibling_calls: Vec::new(), - execution: engine::ToolExecutionSpec::default(), + execution: harness::ToolExecutionSpec::default(), }; let result = tools.invoke_call(request).await.expect("invoke call"); @@ -4231,7 +4235,7 @@ mod tests { ])), subagents_policy: None, workspace_attachments: Vec::new(), - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call-environment-list"), tool_id: Some(test_tool_id(ENVIRONMENT_LIST_TOOL_NAME)), @@ -4354,7 +4358,7 @@ mod tests { environment_policy: None, subagents_policy: None, workspace_attachments, - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_1"), tool_id: Some(test_tool_id("vfs_read_file")), @@ -4399,10 +4403,10 @@ mod tests { environment_policy: None, subagents_policy: None, workspace_attachments, - calls: vec![engine::ToolInvocationRequest { - builtin: Some(engine::BuiltinToolCallRuntime { - spec: engine::BuiltinToolSpec::default(), - model: engine::ModelSelection { + calls: vec![harness::ToolInvocationRequest { + builtin: Some(harness::BuiltinToolCallRuntime { + spec: harness::BuiltinToolSpec::default(), + model: harness::ModelSelection { api_kind: ProviderApiKind::AnthropicMessages, provider_id: "anthropic".into(), model: "claude-test".into(), @@ -4458,7 +4462,7 @@ mod tests { subagents_policy: None, workspace_attachments, calls: vec![ - engine::ToolInvocationRequest { + harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_read"), tool_id: Some(test_tool_id("vfs_read_file")), @@ -4468,7 +4472,7 @@ mod tests { promise_control: None, remote_mcp: None, }, - engine::ToolInvocationRequest { + harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_process"), // The canonical surface takes argv; `exec_command` is @@ -4533,28 +4537,28 @@ mod tests { }) .await .expect("create parent"); - let mut state = engine::CoreAgentState::new(); + let mut state = harness::CoreAgentState::new(); state.lifecycle.config = Some(crate::worker::default_session_config( - engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "test".to_owned(), model: "test-model".to_owned(), }, )); let mut opening_events = - engine::core_agent_clone_opening_events(&state, 2).expect("opening events"); + harness::core_agent_clone_opening_events(&state, 2).expect("opening events"); opening_events.push( - engine::CoreAgentCodec - .encode_uncommitted(&engine::UncommittedCoreAgentEvent { + harness::CoreAgentCodec + .encode_uncommitted(&harness::UncommittedCoreAgentEvent { observed_at_ms: 3, joins: Default::default(), - event: engine::CoreAgentEvent::Promise(engine::PromiseEvent::Created { - promise: engine::Promise { - promise_id: engine::PromiseId::new("promise_1"), - source: engine::PromiseSource::Timer { fire_at_ms: 60_000 }, - scope: engine::PromiseScope::Session, - ownership: engine::PromiseOwnership::Model, - status: engine::PromiseStatus::Pending, + event: harness::CoreAgentEvent::Promise(harness::PromiseEvent::Created { + promise: harness::Promise { + promise_id: harness::PromiseId::new("promise_1"), + source: harness::PromiseSource::Timer { fire_at_ms: 60_000 }, + scope: harness::PromiseScope::Session, + ownership: harness::PromiseOwnership::Model, + status: harness::PromiseStatus::Pending, payload_ref: None, error_ref: None, deadline_ms: None, @@ -4564,7 +4568,7 @@ mod tests { .expect("encode promise"), ); sessions - .append(engine::storage::AppendSessionEvents { + .append(harness::storage::AppendSessionEvents { session_id: parent.clone(), expected_head: None, events: opening_events, @@ -4594,7 +4598,7 @@ mod tests { subagents_policy: None, workspace_attachments: Vec::new(), calls: vec![ - engine::ToolInvocationRequest { + harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_wait"), tool_id: Some(test_tool_id(::tools::concurrency::AWAIT_TOOL_NAME)), @@ -4604,7 +4608,7 @@ mod tests { promise_control: None, remote_mcp: None, }, - engine::ToolInvocationRequest { + harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_read"), tool_id: Some(test_tool_id("read_file")), @@ -4630,7 +4634,7 @@ mod tests { }; assert_eq!(batch_id, ToolBatchId::new(1)); assert_eq!(call_id, ToolCallId::new("call_wait")); - assert_eq!(spec.promise_ids, vec![engine::PromiseId::new("promise_1")]); + assert_eq!(spec.promise_ids, vec![harness::PromiseId::new("promise_1")]); assert_eq!(completed_results.len(), 1); assert_eq!(completed_results[0].call_id, ToolCallId::new("call_read")); assert_eq!(completed_results[0].status, ToolCallStatus::Failed); @@ -4654,26 +4658,30 @@ mod tests { .await .expect("create parent"); sessions - .append(engine::storage::AppendSessionEvents { + .append(harness::storage::AppendSessionEvents { session_id: parent.clone(), expected_head: None, events: vec![ - engine::CoreAgentCodec - .encode_uncommitted(&engine::UncommittedCoreAgentEvent { + harness::CoreAgentCodec + .encode_uncommitted(&harness::UncommittedCoreAgentEvent { observed_at_ms: 3, joins: Default::default(), - event: engine::CoreAgentEvent::Promise(engine::PromiseEvent::Created { - promise: engine::Promise { - promise_id: engine::PromiseId::new("promise_1"), - source: engine::PromiseSource::Timer { fire_at_ms: 60_000 }, - scope: engine::PromiseScope::Session, - ownership: engine::PromiseOwnership::Model, - status: engine::PromiseStatus::Pending, - payload_ref: None, - error_ref: None, - deadline_ms: None, + event: harness::CoreAgentEvent::Promise( + harness::PromiseEvent::Created { + promise: harness::Promise { + promise_id: harness::PromiseId::new("promise_1"), + source: harness::PromiseSource::Timer { + fire_at_ms: 60_000, + }, + scope: harness::PromiseScope::Session, + ownership: harness::PromiseOwnership::Model, + status: harness::PromiseStatus::Pending, + payload_ref: None, + error_ref: None, + deadline_ms: None, + }, }, - }), + ), }) .expect("encode promise"), ], @@ -4698,7 +4706,7 @@ mod tests { environment_policy: None, subagents_policy: None, workspace_attachments: Vec::new(), - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_wait"), tool_id: Some(test_tool_id(::tools::concurrency::AWAIT_TOOL_NAME)), @@ -4723,7 +4731,7 @@ mod tests { }; assert_eq!(call_id, ToolCallId::new("call_wait")); assert!(completed_results.is_empty()); - assert_eq!(spec.promise_ids, vec![engine::PromiseId::new("promise_1")]); + assert_eq!(spec.promise_ids, vec![harness::PromiseId::new("promise_1")]); } #[tokio::test(flavor = "current_thread")] @@ -4749,20 +4757,20 @@ mod tests { environment_policy: None, subagents_policy: None, workspace_attachments: Vec::new(), - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_cancel"), tool_id: Some(test_tool_id(::tools::concurrency::CANCEL_TOOL_NAME)), tool_name: ToolName::new(::tools::concurrency::CANCEL_TOOL_NAME), arguments_ref: cancel_args, workflow_tool: None, - promise_control: Some(engine::PromiseControlCallRuntime::v1(vec![ - engine::PromiseControlRuntime { - promise_id: engine::PromiseId::new("promise_1"), - state: engine::PromiseControlStateRuntime::Known { - ownership: engine::PromiseOwnership::Model, - scope: engine::PromiseScope::Session, - promise_status: engine::PromiseStatus::Pending, + promise_control: Some(harness::PromiseControlCallRuntime::v1(vec![ + harness::PromiseControlRuntime { + promise_id: harness::PromiseId::new("promise_1"), + state: harness::PromiseControlStateRuntime::Known { + ownership: harness::PromiseOwnership::Model, + scope: harness::PromiseScope::Session, + promise_status: harness::PromiseStatus::Pending, }, }, ])), @@ -4778,7 +4786,7 @@ mod tests { assert_eq!(result.results[0].effects.len(), 1); assert_eq!( result.results[0].effects[0].kind, - engine::PROMISE_CANCEL_EFFECT_KIND + harness::PROMISE_CANCEL_EFFECT_KIND ); } @@ -4805,22 +4813,22 @@ mod tests { environment_policy: None, subagents_policy: None, workspace_attachments: Vec::new(), - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_detach"), tool_id: Some(test_tool_id(::tools::concurrency::DETACH_TOOL_NAME)), tool_name: ToolName::new(::tools::concurrency::DETACH_TOOL_NAME), arguments_ref: detach_args, workflow_tool: None, - promise_control: Some(engine::PromiseControlCallRuntime::v1(vec![ - engine::PromiseControlRuntime { - promise_id: engine::PromiseId::new("promise_1"), - state: engine::PromiseControlStateRuntime::Known { - ownership: engine::PromiseOwnership::Model, - scope: engine::PromiseScope::Run { + promise_control: Some(harness::PromiseControlCallRuntime::v1(vec![ + harness::PromiseControlRuntime { + promise_id: harness::PromiseId::new("promise_1"), + state: harness::PromiseControlStateRuntime::Known { + ownership: harness::PromiseOwnership::Model, + scope: harness::PromiseScope::Run { run_id: RunId::new(1), }, - promise_status: engine::PromiseStatus::Pending, + promise_status: harness::PromiseStatus::Pending, }, }, ])), @@ -4843,7 +4851,7 @@ mod tests { assert_eq!(result.results[0].effects.len(), 1); assert_eq!( result.results[0].effects[0].kind, - engine::PROMISE_DETACH_EFFECT_KIND + harness::PROMISE_DETACH_EFFECT_KIND ); } @@ -4856,7 +4864,7 @@ mod tests { .put_bytes(br#"{"ms":50}"#.to_vec()) .await .expect("sleep args"); - let sleep_call = |id: &str| engine::ToolInvocationRequest { + let sleep_call = |id: &str| harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new(id), tool_id: Some(test_tool_id(::tools::concurrency::SLEEP_TOOL_NAME)), @@ -4887,13 +4895,13 @@ mod tests { .expect("completed"); // Two promise-creating calls in one batch draw disjoint ids from the - // engine's base, and the model-visible text names the same handle. + // harness's base, and the model-visible text names the same handle. let mut minted = Vec::new(); for (index, call_result) in result.results.iter().enumerate() { assert_eq!(call_result.status, ToolCallStatus::Succeeded); assert_eq!(call_result.effects.len(), 1); let effect = &call_result.effects[0]; - assert_eq!(effect.kind, engine::PROMISE_CREATE_EFFECT_KIND); + assert_eq!(effect.kind, harness::PROMISE_CREATE_EFFECT_KIND); assert_eq!(effect.data.get("source"), Some(&"timer".to_owned())); assert!(effect.data.contains_key("fire_at_ms")); let promise_id = effect.data.get("promise_id").expect("promise id"); @@ -4973,7 +4981,7 @@ mod tests { environment_policy: None, subagents_policy: None, workspace_attachments: Vec::new(), - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_1"), tool_id: Some(test_tool_id("vfs_read_file")), @@ -5019,7 +5027,7 @@ mod tests { environment_policy: None, subagents_policy: None, workspace_attachments: Vec::new(), - calls: vec![engine::ToolInvocationRequest { + calls: vec![harness::ToolInvocationRequest { builtin: Some(test_builtin_runtime()), call_id: ToolCallId::new("call_1"), tool_id: Some(test_tool_id("web_fetch")), diff --git a/crates/temporal-server/src/worker/universes.rs b/crates/temporal-runtime/src/worker/universes.rs similarity index 100% rename from crates/temporal-server/src/worker/universes.rs rename to crates/temporal-runtime/src/worker/universes.rs diff --git a/crates/temporal-server/tests/authentication_live.rs b/crates/temporal-runtime/tests/authentication_live.rs similarity index 96% rename from crates/temporal-server/tests/authentication_live.rs rename to crates/temporal-runtime/tests/authentication_live.rs index a28cc3c04..c53c23df9 100644 --- a/crates/temporal-server/tests/authentication_live.rs +++ b/crates/temporal-runtime/tests/authentication_live.rs @@ -14,7 +14,7 @@ use sqlx::{ postgres::{PgConnectOptions, PgPoolOptions}, }; use store_pg::{PgApiKeyStore, PgStore}; -use temporal_server::gateway::authentication::{ACTOR_HEADER, UNIVERSE_HEADER, authenticate}; +use temporal_runtime::gateway::authentication::{ACTOR_HEADER, UNIVERSE_HEADER, authenticate}; use uuid::Uuid; #[tokio::test(flavor = "current_thread")] @@ -29,7 +29,9 @@ async fn keys_scope_groups_actors_and_revocation() { .unwrap(); let schema = format!("lightspeed_auth_test_{}", Uuid::new_v4().simple()); admin - .execute(format!("CREATE SCHEMA \"{schema}\"").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "CREATE SCHEMA \"{schema}\"" + )))) .await .unwrap(); let pool = PgPoolOptions::new() @@ -44,7 +46,9 @@ async fn keys_scope_groups_actors_and_revocation() { let outcome = AssertUnwindSafe(exercise(&pool)).catch_unwind().await; pool.close().await; admin - .execute(format!("DROP SCHEMA \"{schema}\" CASCADE").as_str()) + .execute(sqlx::raw_sql(sqlx::AssertSqlSafe(format!( + "DROP SCHEMA \"{schema}\" CASCADE" + )))) .await .unwrap(); admin.close().await; diff --git a/crates/temporal-server/tests/authorization_live.rs b/crates/temporal-runtime/tests/authorization_live.rs similarity index 99% rename from crates/temporal-server/tests/authorization_live.rs rename to crates/temporal-runtime/tests/authorization_live.rs index 49c3c7cab..b6d38df9f 100644 --- a/crates/temporal-server/tests/authorization_live.rs +++ b/crates/temporal-runtime/tests/authorization_live.rs @@ -8,7 +8,7 @@ use base64::Engine as _; use serde_json::{Value, json}; use std::{collections::BTreeSet, sync::Arc}; use store_pg::{PgApiKeyStore, PgStore}; -use temporal_server::{ +use temporal_runtime::{ DeploymentStores, UniverseRuntime, config::GatewayAuthMode, gateway::{GatewayRoutes, GatewayState, gateway_router}, diff --git a/crates/temporal-server/tests/bots_live.rs b/crates/temporal-runtime/tests/bots_live.rs similarity index 95% rename from crates/temporal-server/tests/bots_live.rs rename to crates/temporal-runtime/tests/bots_live.rs index 5469acac0..f827a4e26 100644 --- a/crates/temporal-server/tests/bots_live.rs +++ b/crates/temporal-runtime/tests/bots_live.rs @@ -7,7 +7,7 @@ //! //! ```bash //! source scripts/dev/env.sh -//! cargo test -p temporal-server --test bots_live -- --ignored --test-threads=1 +//! cargo test -p temporal-runtime --test bots_live -- --ignored --test-threads=1 //! ``` mod support; @@ -17,6 +17,7 @@ use std::{ sync::Arc, time::{Duration, Instant}, }; +use temporalio_client::WorkflowExecutionStatus; use api::{ AgentApiService, AgentProfileInput, BotBreaker, BotCloseParams, BotCoalescePolicy, @@ -28,24 +29,21 @@ use api::{ SessionReadParams, SessionStatus, WebhookVerification, }; use bots::ids::{bot_controller_workflow_id, bot_main_session_id, bot_schedule_id}; -use engine::{CoreAgentLlm, CoreAgentTools, storage::BlobStore}; +use harness::{CoreAgentLlm, CoreAgentTools, storage::BlobStore}; use support::live::{ LIVE_TEST_LOCK, live_universe_id, require_openai_live_env, require_storage_live_env, }; -use temporal_server::{ +use temporal_runtime::{ config::TaskQueues, gateway::GatewayAgentApi, pg_store_from_env, worker::{ ActivityState, BotWorkerActivities, FakeLlm, FakeTools, WorkerActivities, bots_worker, - core_runtime, worker_with_activities, + sessions_worker, worker_runtime, }, }; use temporal_workflow::{DEFAULT_TEMPORAL_NAMESPACE, DEFAULT_TEMPORAL_TARGET, connect_temporal}; use temporalio_client::{Client, WorkflowDescribeOptions}; -use temporalio_common::{ - protos::temporal::api::enums::v1::WorkflowExecutionStatus, worker::WorkerTaskTypes, -}; const WAIT: Duration = Duration::from_secs(90); @@ -74,7 +72,7 @@ where std::env::var("TEMPORAL_ADDRESS").unwrap_or_else(|_| DEFAULT_TEMPORAL_TARGET.to_owned()); let namespace = std::env::var("TEMPORAL_NAMESPACE") .unwrap_or_else(|_| DEFAULT_TEMPORAL_NAMESPACE.to_owned()); - let runtime = core_runtime()?; + let runtime = worker_runtime()?; let client = connect_temporal(&temporal_target, &namespace).await?; let builder = GatewayAgentApi::builder(client.clone(), store.clone()) @@ -93,7 +91,7 @@ where }; let api = Arc::new(builder.build()); - let mut sessions_worker = worker_with_activities( + let mut sessions_worker = sessions_worker( &runtime, client.clone(), queues.sessions.clone(), @@ -104,13 +102,16 @@ where client.clone(), queues.bots.clone(), BotWorkerActivities::for_universe(universe, api.clone()), - WorkerTaskTypes::all(), )?; let shutdown_sessions = sessions_worker.shutdown_handle(); let shutdown_bots = bots.shutdown_handle(); - let workers = async { tokio::try_join!(sessions_worker.run(), bots.run()).map(|_| ()) }; + let workers = async { + tokio::try_join!(sessions_worker.run(), bots.run()) + .map(|_| ()) + .map_err(anyhow::Error::from) + }; tokio::pin!(workers); - let body = temporal_server::gateway::request_context::with_request_context( + let body = temporal_runtime::gateway::request_context::with_request_context( support::live::local_request_context().await?, body(api.clone(), client.clone()), ); @@ -435,7 +436,7 @@ async fn bots_live_reset_main_recovers_a_missing_session_row() -> anyhow::Result let first_workflow = client.get_workflow_handle::( temporal_workflow::compose_workflow_id( live_universe_id()?, - &engine::session::SessionId::new(first), + &harness::session::SessionId::new(first), ), ); assert_ne!( @@ -544,7 +545,7 @@ async fn bots_live_hmac_webhook_verifies_without_a_caller() -> anyhow::Result<() assert!( matches!( admitted, - temporal_server::bots::hooks::WebhookIngestOutcome::Admitted { .. } + temporal_runtime::bots::hooks::WebhookIngestOutcome::Admitted { .. } ), "{admitted:?}" ); @@ -556,8 +557,8 @@ async fn bots_live_hmac_webhook_verifies_without_a_caller() -> anyhow::Result<() assert!( !matches!( forged, - temporal_server::bots::hooks::WebhookIngestOutcome::Admitted { .. } - | temporal_server::bots::hooks::WebhookIngestOutcome::SecretUnavailable { .. } + temporal_runtime::bots::hooks::WebhookIngestOutcome::Admitted { .. } + | temporal_runtime::bots::hooks::WebhookIngestOutcome::SecretUnavailable { .. } ), "{forged:?}" ); @@ -624,7 +625,7 @@ async fn bots_live_webhook_trigger_coalesces_events() -> anyhow::Result<()> { assert!( matches!( outcome, - temporal_server::bots::hooks::WebhookIngestOutcome::Admitted { .. } + temporal_runtime::bots::hooks::WebhookIngestOutcome::Admitted { .. } ), "{outcome:?}" ); @@ -642,7 +643,7 @@ async fn bots_live_webhook_trigger_coalesces_events() -> anyhow::Result<()> { assert!( matches!( filtered, - temporal_server::bots::hooks::WebhookIngestOutcome::Filtered { .. } + temporal_runtime::bots::hooks::WebhookIngestOutcome::Filtered { .. } ), "{filtered:?}" ); @@ -658,7 +659,7 @@ async fn bots_live_webhook_trigger_coalesces_events() -> anyhow::Result<()> { .await; assert_eq!( probe, - temporal_server::bots::hooks::WebhookIngestOutcome::UnknownEndpoint + temporal_runtime::bots::hooks::WebhookIngestOutcome::UnknownEndpoint ); let events = wait_for_outcomes(&api, &bot_id, 3).await?; @@ -763,7 +764,7 @@ async fn bots_live_schedule_trigger_reconciles_temporal_schedule() -> anyhow::Re let schedule_id = bot_schedule_id(live_universe_id()?, &bot_id, &trigger_id); let handle = client.get_schedule_handle(schedule_id.clone()); - let described = handle.describe().await?; + let described = handle.describe(Default::default()).await?; assert!(!described.paused()); assert!( !described.future_action_times().is_empty(), @@ -772,7 +773,10 @@ async fn bots_live_schedule_trigger_reconciles_temporal_schedule() -> anyhow::Re // A manual trigger of the Schedule admits one schedule event. handle - .trigger(temporalio_client::schedules::ScheduleOverlapPolicy::AllowAll) + .trigger( + temporalio_client::schedules::ScheduleOverlapPolicy::AllowAll, + Default::default(), + ) .await?; let events = wait_for_outcomes(&api, &bot_id, 1).await?; assert_eq!(events[0].kind, "schedule"); @@ -796,7 +800,7 @@ async fn bots_live_schedule_trigger_reconciles_temporal_schedule() -> anyhow::Re expected_revision: Some(bot.revision), }) .await?; - assert!(handle.describe().await?.paused()); + assert!(handle.describe(Default::default()).await?.paused()); api.delete_bot_trigger(BotTriggerDeleteParams { bot_id: bot_id.clone(), @@ -804,7 +808,7 @@ async fn bots_live_schedule_trigger_reconciles_temporal_schedule() -> anyhow::Re }) .await?; assert!( - handle.describe().await.is_err(), + handle.describe(Default::default()).await.is_err(), "schedule deleted with the trigger" ); // Disabling reconciles the main session; let it finish before the diff --git a/crates/temporal-server/tests/channels_live.rs b/crates/temporal-runtime/tests/channels_live.rs similarity index 94% rename from crates/temporal-server/tests/channels_live.rs rename to crates/temporal-runtime/tests/channels_live.rs index cfbfd1c82..878a306ce 100644 --- a/crates/temporal-server/tests/channels_live.rs +++ b/crates/temporal-runtime/tests/channels_live.rs @@ -8,7 +8,7 @@ //! //! ```bash //! source scripts/dev/env.sh -//! cargo test -p temporal-server --test channels_live -- --ignored --test-threads=1 +//! cargo test -p temporal-runtime --test channels_live -- --ignored --test-threads=1 //! ``` mod support; @@ -32,15 +32,15 @@ use channels::{ delivery::{ChannelDeliveryCommand, ChannelDeliveryOperation, ChannelDeliveryResult}, media::{MaintainChannelTypingInput, PrepareChannelMediaInput, PrepareChannelMediaResult}, }; -use engine::{CoreAgentLlm, CoreAgentTools, storage::BlobStore}; +use harness::{CoreAgentLlm, CoreAgentTools, storage::BlobStore}; use support::live::{LIVE_TEST_LOCK, live_universe_id, require_storage_live_env}; -use temporal_server::{ +use temporal_runtime::{ config::TaskQueues, gateway::GatewayAgentApi, pg_store_from_env, worker::{ ActivityState, BotWorkerActivities, ChannelWorkerActivities, FakeLlm, FakeTools, - WorkerActivities, bots_worker, channels_worker, core_runtime, worker_with_activities, + WorkerActivities, bots_worker, channels_worker, sessions_worker, worker_runtime, }, }; use temporal_workflow::{ @@ -52,10 +52,9 @@ use temporal_workflow::{ connect_temporal, }; use temporalio_client::Client; -use temporalio_common::worker::WorkerTaskTypes; use temporalio_macros::activities; use temporalio_sdk::{ - Worker, WorkerOptions, + WorkerOptions, activities::{ActivityContext, ActivityError}, }; @@ -123,7 +122,9 @@ impl FakeConnector { ) -> Result<(), ActivityError> { *self.typing_started.lock().expect("typing lock") += 1; loop { - ctx.record_heartbeat(Vec::new()); + ctx.record_heartbeat(()) + .await + .expect("unit heartbeat serializes"); tokio::select! { _ = ctx.cancelled() => return Ok(()), _ = tokio::time::sleep(Duration::from_secs(2)) => {} @@ -157,7 +158,7 @@ where std::env::var("TEMPORAL_ADDRESS").unwrap_or_else(|_| DEFAULT_TEMPORAL_TARGET.to_owned()); let namespace = std::env::var("TEMPORAL_NAMESPACE") .unwrap_or_else(|_| DEFAULT_TEMPORAL_NAMESPACE.to_owned()); - let runtime = core_runtime()?; + let runtime = worker_runtime()?; let client = connect_temporal(&temporal_target, &namespace).await?; let api = Arc::new( GatewayAgentApi::builder(client.clone(), store.clone()) @@ -173,7 +174,7 @@ where let blobs: Arc = store.clone(); let llm = Arc::new(FakeLlm::new(blobs.clone()).with_tool_rounds(0)) as Arc; let tools = Arc::new(FakeTools::new(blobs)) as Arc; - let mut sessions_worker = worker_with_activities( + let mut sessions_worker = sessions_worker( &runtime, client.clone(), queues.sessions.clone(), @@ -189,20 +190,18 @@ where client.clone(), queues.bots.clone(), BotWorkerActivities::for_universe(universe, api.clone()), - WorkerTaskTypes::all(), )?; let mut channels = channels_worker( &runtime, client.clone(), queues.channels.clone(), ChannelWorkerActivities::for_universe(universe, api.clone()), - WorkerTaskTypes::all(), )?; // The account is created before the connector worker so the queue name // is known; every test uses one fresh account. let account_id = ChannelAccountId::new(unique("tg")); let context = support::live::local_request_context().await?; - temporal_server::gateway::request_context::with_request_context( + temporal_runtime::gateway::request_context::with_request_context( context.clone(), api.create_channel_account(ChannelAccountCreateParams { account: ChannelAccountInput { @@ -221,7 +220,7 @@ where .await?; let connector_queue = connector_task_queue(universe, &ChannelProvider::new("telegram"), &account_id); - let mut connector_worker = Worker::new( + let mut connector_worker = temporalio_sdk::Worker::new( &runtime, client.clone(), WorkerOptions::new(connector_queue) @@ -229,12 +228,6 @@ where // SDK to cancel them on shutdown instead of draining forever. .graceful_shutdown_period(Duration::from_millis(100)) .register_activities(connector.clone()) - .task_types(WorkerTaskTypes { - enable_workflows: false, - enable_local_activities: false, - enable_remote_activities: true, - enable_nexus: false, - }) .build(), ) .map_err(|error| anyhow::anyhow!("{error}"))?; @@ -253,9 +246,10 @@ where connector_worker.run() ) .map(|_| ()) + .map_err(anyhow::Error::from) }; tokio::pin!(workers); - let body = temporal_server::gateway::request_context::with_request_context( + let body = temporal_runtime::gateway::request_context::with_request_context( context, body(Live { api: api.clone(), @@ -578,8 +572,8 @@ async fn channels_live_pairing_gates_a_conversation() -> anyhow::Result<()> { async fn temporal_live_chat_rebuilds_collected_declarations_and_retains_assets() -> anyhow::Result<()> { use bots::BotEventStore; - use engine::{BlobRef, WorkflowEndpointRef, storage::collect_blob_refs}; - use temporal_server::channels::activities::{chat_tool_declarations, emit_chat_event}; + use harness::{BlobRef, WorkflowEndpointRef, storage::collect_blob_refs}; + use temporal_runtime::channels::activities::{chat_tool_declarations, emit_chat_event}; use temporal_workflow::channels::{ CHANNEL_CONVERSATION_WORKFLOW_KIND, ChatEmitEventRequest, ChatEmitEventResult, ChatMessage, ChatToolDeclarationsRequest, @@ -653,17 +647,17 @@ async fn temporal_live_chat_rebuilds_collected_declarations_and_retains_assets() struct FakeVoiceTranscriber(Arc); #[async_trait::async_trait] -impl temporal_server::worker::AudioTranscriber for FakeVoiceTranscriber { +impl temporal_runtime::worker::AudioTranscriber for FakeVoiceTranscriber { async fn transcribe( &self, - request: temporal_server::worker::AudioTranscriptionRequest, + request: temporal_runtime::worker::AudioTranscriptionRequest, ) -> Result< - temporal_server::worker::AudioTranscription, - temporal_server::worker::AudioTranscriptionError, + temporal_runtime::worker::AudioTranscription, + temporal_runtime::worker::AudioTranscriptionError, > { assert_eq!(request.model.model, "channel-speech"); self.0.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - Ok(temporal_server::worker::AudioTranscription { + Ok(temporal_runtime::worker::AudioTranscription { text: "/reset spoken words".into(), }) } @@ -739,7 +733,7 @@ async fn channels_live_voice_preparation_preserves_provenance_and_redelivery_ide let store = pg_store_from_env().await?; let doc: serde_json::Value = serde_json::from_slice( &store - .read_bytes(&engine::BlobRef::parse(&voice.document_ref)?) + .read_bytes(&harness::BlobRef::parse(&voice.document_ref)?) .await?, )?; assert_eq!(doc["data"]["message"]["text"], "/reset spoken words"); diff --git a/crates/temporal-server/tests/environment_provider_live.rs b/crates/temporal-runtime/tests/environment_provider_live.rs similarity index 99% rename from crates/temporal-server/tests/environment_provider_live.rs rename to crates/temporal-runtime/tests/environment_provider_live.rs index 5b1bb6e3e..6f2c35b1b 100644 --- a/crates/temporal-server/tests/environment_provider_live.rs +++ b/crates/temporal-runtime/tests/environment_provider_live.rs @@ -19,12 +19,12 @@ use api::{ SessionConfig, SessionStartParams, }; use api_projection::model_to_api; -use engine::SessionId; +use harness::SessionId; use support::live::{ LIVE_TEST_LOCK, fake_worker_activities, read_session_view, require_storage_live_env, run_with_live_worker, wait_for_environment_status, }; -use temporal_server::{ +use temporal_runtime::{ DeploymentStores, UniverseRuntime, gateway::{GatewayAgentApi, GatewayDeploymentApi}, pg_store_from_env, @@ -59,7 +59,7 @@ async fn environment_provider_lifecycle_and_adoption_round_trip() -> anyhow::Res let operator = GatewayDeploymentApi::new(runtime.clone()); let reconciler = tokio::spawn(runtime.clone().run_environment_reconciler()); // Direct service calls carry an explicit local request context. - use temporal_server::gateway::request_context::{ + use temporal_runtime::gateway::request_context::{ RequestContext, with_request_context as calling, }; let deployment_caller = RequestContext::local(api::AccessScope::Deployment); @@ -293,7 +293,7 @@ async fn environment_provider_lifecycle_and_adoption_round_trip() -> anyhow::Res } async fn wait_for_status( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, environment_id: &str, expected: EnvironmentLifecycleStatusView, ) -> anyhow::Result { diff --git a/crates/temporal-server/tests/environment_registration_live.rs b/crates/temporal-runtime/tests/environment_registration_live.rs similarity index 99% rename from crates/temporal-server/tests/environment_registration_live.rs rename to crates/temporal-runtime/tests/environment_registration_live.rs index 848bf27f7..8a45ff53c 100644 --- a/crates/temporal-server/tests/environment_registration_live.rs +++ b/crates/temporal-runtime/tests/environment_registration_live.rs @@ -36,7 +36,7 @@ use environment_protocol::{ }; use environments::EnvironmentStore as _; use support::live::{LIVE_TEST_LOCK, require_storage_live_env}; -use temporal_server::{ +use temporal_runtime::{ DeploymentStores, GatewayAuthMode, UniverseRuntime, gateway::{ DEFAULT_MAX_REQUEST_BODY_BYTES, GatewayAgentApi, GatewayDeploymentApi, GatewayRoutes, @@ -289,7 +289,7 @@ async fn scenario( // Workers reach this test's gateway, not whatever the sourced dev // environment points LIGHTSPEED_ENVIRONMENT_GATEWAY_URL at; the route // bearer is the deployment token the gateway state checks. - let gateway = temporal_server::environments::gateway::EnvironmentGatewayClientConfig::new( + let gateway = temporal_runtime::environments::gateway::EnvironmentGatewayClientConfig::new( base_url, runtime.environment_gateway().deployment_token(), ); diff --git a/crates/temporal-server/tests/fake_loop.rs b/crates/temporal-runtime/tests/fake_loop.rs similarity index 95% rename from crates/temporal-server/tests/fake_loop.rs rename to crates/temporal-runtime/tests/fake_loop.rs index cf298882f..26bfcbc94 100644 --- a/crates/temporal-server/tests/fake_loop.rs +++ b/crates/temporal-runtime/tests/fake_loop.rs @@ -1,12 +1,12 @@ use std::{collections::BTreeMap, sync::Arc}; -use engine::{ +use harness::{ BlobRef, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentCommand, FunctionToolSpec, ModelSelection, ProviderApiKind, SessionId, SubmissionId, ToolChoice, ToolKind, ToolName, ToolParallelism, ToolSpec, storage::{BlobStore, CreateSession, InMemoryBlobStore, InMemorySessionStore, SessionStore}, }; -use temporal_server::worker::{ +use temporal_runtime::worker::{ FAKE_TOOL_NAME, FakeLlm, FakeTools, default_run_config, default_session_config, }; use test_support::{DriveCommand, RunnerQuiescence, RunnerStores, SessionRunner}; @@ -107,11 +107,11 @@ async fn assert_tool_loop(builtin: bool) { .drive_command(DriveCommand { session_id: session_id.clone(), observed_at_ms: 13, - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: Some(SubmissionId::new("submit_test")), - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: user_input(input_ref), }, run_config: default_run_config(), @@ -127,7 +127,7 @@ async fn assert_tool_loop(builtin: bool) { .emitted_entries .iter() .flat_map(|entry| match &entry.event { - engine::CoreAgentEvent::Tool(engine::ToolEvent::BatchStarted { calls, .. }) => { + harness::CoreAgentEvent::Tool(harness::ToolEvent::BatchStarted { calls, .. }) => { calls.as_slice() } _ => &[], @@ -181,7 +181,7 @@ fn user_input(content_ref: BlobRef) -> Vec { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, diff --git a/crates/temporal-server/tests/mcp_live.rs b/crates/temporal-runtime/tests/mcp_live.rs similarity index 98% rename from crates/temporal-server/tests/mcp_live.rs rename to crates/temporal-runtime/tests/mcp_live.rs index 503ff18c6..47b6718a8 100644 --- a/crates/temporal-server/tests/mcp_live.rs +++ b/crates/temporal-runtime/tests/mcp_live.rs @@ -25,7 +25,7 @@ use axum::{ response::{IntoResponse, Response}, routing::post, }; -use engine::{ +use harness::{ ApprovalContinuation, ApprovalSubject, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentIoError, CoreAgentLlm, CoreAgentTools, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, LlmGenerationStatus, ObservedApprovalRequest, @@ -37,7 +37,7 @@ use support::live::{ live_workflow_handle, read_run, read_session_view, require_storage_live_env, run_with_live_worker, wait_for_terminal_run, }; -use temporal_server::{ +use temporal_runtime::{ gateway::{DEFAULT_MAX_REQUEST_BODY_BYTES, GatewayAgentApi, GatewayState, gateway_router}, pg_store_from_env, worker::{ActivityState, FakeTools, SessionTools, WorkerActivities}, @@ -156,9 +156,9 @@ impl CoreAgentLlm for MatrixScriptedLlm { // entries the model can see; the audio clip is dropped with // a note. let png_handle = - engine::media::media_handle(&engine::BlobRef::from_bytes(RICH_PNG_BYTES)); + harness::media::media_handle(&harness::BlobRef::from_bytes(RICH_PNG_BYTES)); let pdf_handle = - engine::media::media_handle(&engine::BlobRef::from_bytes(RICH_PDF_BYTES)); + harness::media::media_handle(&harness::BlobRef::from_bytes(RICH_PDF_BYTES)); require_contains( &result, &format!("[image 1 · {png_handle} · image/png"), @@ -180,12 +180,12 @@ impl CoreAgentLlm for MatrixScriptedLlm { .entries .iter() .filter(|entry| { - matches!(entry.source, engine::ContextEntrySource::Tool { .. }) - && engine::media::is_media_content(&entry.content) + matches!(entry.source, harness::ContextEntrySource::Tool { .. }) + && harness::media::is_media_content(&entry.content) }) .map(|entry| { ( - engine::media::media_handle(&entry.content.content_ref), + harness::media::media_handle(&entry.content.content_ref), entry.content.media_type.clone().unwrap_or_default(), entry.preview.clone().unwrap_or_default(), ) @@ -350,7 +350,7 @@ impl MatrixScriptedLlm { call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: arguments_ref.clone(), media_type: Some("application/json".to_owned()), provider_kind: Some("mcp-live-matrix".to_owned()), @@ -398,7 +398,7 @@ impl MatrixScriptedLlm { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/plain".to_owned()), provider_kind: Some("mcp-live-matrix".to_owned()), @@ -568,8 +568,8 @@ async fn run_matrix_client( .flat_map(|batch| batch.calls.iter()) .find(|call| call.call_id == "matrix_inject_rich") .expect("rich call in run view"); - let png_handle = engine::media::media_handle(&engine::BlobRef::from_bytes(RICH_PNG_BYTES)); - let pdf_handle = engine::media::media_handle(&engine::BlobRef::from_bytes(RICH_PDF_BYTES)); + let png_handle = harness::media::media_handle(&harness::BlobRef::from_bytes(RICH_PNG_BYTES)); + let pdf_handle = harness::media::media_handle(&harness::BlobRef::from_bytes(RICH_PDF_BYTES)); assert_eq!( rich_call .media @@ -785,7 +785,7 @@ impl LiveMcpFixture { calls: Vec::new(), })); let app = Router::new() - .route("/:kind", post(fixture_handler).delete(fixture_delete)) + .route("/{kind}", post(fixture_handler).delete(fixture_delete)) .with_state(state.clone()); let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await?; let address = listener.local_addr()?; @@ -1168,7 +1168,7 @@ impl NativeMcpScriptedLlm { call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: arguments_ref.clone(), media_type: Some("application/json".to_owned()), provider_kind: Some("native-mcp-script".to_owned()), @@ -1216,7 +1216,7 @@ impl NativeMcpScriptedLlm { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/plain".to_owned()), provider_kind: Some("native-mcp-script".to_owned()), @@ -1259,7 +1259,7 @@ impl CoreAgentLlm for ApprovalScriptedLlm { return None; }; match &entry.source { - engine::ContextEntrySource::ApprovalDecision { run_id, .. } + harness::ContextEntrySource::ApprovalDecision { run_id, .. } if *run_id == request.run_id => { Some(approve) @@ -1284,7 +1284,7 @@ impl CoreAgentLlm for ApprovalScriptedLlm { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: output_ref, media_type: Some("text/plain".to_owned()), provider_kind: Some("approval-script".to_owned()), @@ -1338,11 +1338,11 @@ impl CoreAgentLlm for ApprovalScriptedLlm { failure_ref: None, context_entries: vec![ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: opaque_ref, media_type: Some("application/json".to_owned()), provider_kind: Some( - engine::OPENAI_RESPONSES_MCP_APPROVAL_REQUEST_PROVIDER_KIND.to_owned(), + harness::OPENAI_RESPONSES_MCP_APPROVAL_REQUEST_PROVIDER_KIND.to_owned(), ), }, preview: None, @@ -1843,7 +1843,7 @@ impl LiveConfigurator { let repo_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")) .parent() .and_then(std::path::Path::parent) - .expect("temporal-server crate must be inside the workspace") + .expect("temporal-runtime crate must be inside the workspace") .to_owned(); let tsx = repo_root.join("node_modules/.bin/tsx"); if !tsx.is_file() { @@ -1858,7 +1858,7 @@ impl LiveConfigurator { let gateway = gateway_router( Arc::new(GatewayState::for_api(api)), DEFAULT_MAX_REQUEST_BODY_BYTES, - temporal_server::gateway::GatewayRoutes::ALL, + temporal_runtime::gateway::GatewayRoutes::ALL, ); let gateway_task = tokio::spawn(async move { let _ = axum::serve(gateway_listener, gateway).await; @@ -1930,7 +1930,7 @@ fn expected_configurator_tool_names() -> anyhow::Result> { let repo_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")) .parent() .and_then(std::path::Path::parent) - .expect("temporal-server crate must be inside the workspace") + .expect("temporal-runtime crate must be inside the workspace") .to_owned(); let manifest: serde_json::Value = serde_json::from_slice(&std::fs::read( repo_root.join("crates/api/contract/methods.json"), @@ -2099,7 +2099,7 @@ impl MixedBatchScriptedLlm { call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: arguments_ref.clone(), media_type: Some("application/json".to_owned()), provider_kind: Some("mixed-batch-script".to_owned()), @@ -2155,7 +2155,7 @@ impl MixedBatchScriptedLlm { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/plain".to_owned()), provider_kind: Some("mixed-batch-script".to_owned()), diff --git a/crates/temporal-server/tests/mcp_oauth_live.rs b/crates/temporal-runtime/tests/mcp_oauth_live.rs similarity index 99% rename from crates/temporal-server/tests/mcp_oauth_live.rs rename to crates/temporal-runtime/tests/mcp_oauth_live.rs index 72779e4e8..477922aee 100644 --- a/crates/temporal-server/tests/mcp_oauth_live.rs +++ b/crates/temporal-runtime/tests/mcp_oauth_live.rs @@ -345,7 +345,8 @@ async fn live_store() -> anyhow::Result> { fn random_master_key() -> SecretsMasterKey { let mut bytes = [0u8; 32]; - rand::RngCore::fill_bytes(&mut rand::rngs::OsRng, &mut bytes); + rand::TryRng::try_fill_bytes(&mut rand::rngs::SysRng, &mut bytes) + .expect("OS random source unavailable"); SecretsMasterKey::from_bytes(bytes) } diff --git a/crates/temporal-server/tests/profiles_live.rs b/crates/temporal-runtime/tests/profiles_live.rs similarity index 99% rename from crates/temporal-server/tests/profiles_live.rs rename to crates/temporal-runtime/tests/profiles_live.rs index 7edbffe9b..a52610405 100644 --- a/crates/temporal-server/tests/profiles_live.rs +++ b/crates/temporal-runtime/tests/profiles_live.rs @@ -10,13 +10,13 @@ use api::{ RunStartParams, RunStartSource, SessionConfig, SessionStartParams, }; use api_projection::model_to_api; -use engine::SessionId; +use harness::SessionId; use support::live::{ LIVE_TEST_LOCK, fake_worker_activities, final_assistant_text, live_workflow_handle, read_session_view, require_storage_live_env, run_with_live_worker, wait_for_environment_status, wait_for_terminal_run, }; -use temporal_server::{gateway::GatewayAgentApi, pg_store_from_env}; +use temporal_runtime::{gateway::GatewayAgentApi, pg_store_from_env}; use temporalio_client::{Client, WorkflowTerminateOptions}; #[tokio::test(flavor = "current_thread")] diff --git a/crates/temporal-server/tests/runs_live.rs b/crates/temporal-runtime/tests/runs_live.rs similarity index 98% rename from crates/temporal-server/tests/runs_live.rs rename to crates/temporal-runtime/tests/runs_live.rs index 7ba0f0dab..b82013fef 100644 --- a/crates/temporal-server/tests/runs_live.rs +++ b/crates/temporal-runtime/tests/runs_live.rs @@ -11,7 +11,7 @@ use api::{ SessionEventsReadParams, SessionStartParams, }; use api_projection::model_to_api; -use engine::{ModelSelection, SessionId}; +use harness::{ModelSelection, SessionId}; use support::live::{ LIVE_TEST_LOCK, fake_worker_activities_for_run_control, fake_worker_activities_with_parallel_tool_calls, fake_worker_activities_with_tool_rounds, @@ -19,7 +19,7 @@ use support::live::{ read_run, require_storage_live_env, run_with_live_worker, start_text_run, terminate_live_session, wait_for_terminal_run, wait_until, }; -use temporal_server::{gateway::GatewayAgentApi, pg_store_from_env}; +use temporal_runtime::{gateway::GatewayAgentApi, pg_store_from_env}; use temporal_workflow::LLM_RETRY_MAX_ATTEMPTS; use temporalio_client::{Client, WorkflowDescribeOptions, WorkflowTerminateOptions}; @@ -45,7 +45,7 @@ async fn temporal_live_parallel_tool_batch_completes_per_call() -> anyhow::Resul // Three parallel-safe calls in one batch exercise the per-call activity // path: concurrent scheduling, completion-order resumes, and progressive - // engine appends. One call fails terminally while its siblings succeed, + // harness appends. One call fails terminally while its siblings succeed, // proving per-call independence. The terminal-run polling issues status // queries while the batch is in flight, which regresses the // workflow-waker class of bug (TMPRL1100) that batch-level activities @@ -95,7 +95,7 @@ async fn temporal_live_cancel_mid_generation_aborts_the_provider_call() -> anyho require_storage_live_env()?; // Cancel mid-generation: the fake provider sleeps inside generate. Cancelling the run - // while that call is in flight must cancel the turn in the engine at + // while that call is in flight must cancel the turn in the harness at // once (run reaches `cancelled`, no grace turn, no `failed`), abandon // the worker-side provider call through activity cancellation, and // leave the session serving a later run. @@ -255,7 +255,7 @@ async fn run_cancel_mid_generation_live_client( client: Client, task_queue: String, session_id: SessionId, - counters: temporal_server::worker::FakeRuntimeCounters, + counters: temporal_runtime::worker::FakeRuntimeCounters, ) -> anyhow::Result<()> { let api = run_control_api(&client, task_queue, &session_id, false).await?; @@ -354,7 +354,7 @@ async fn run_cancel_during_tool_batch_live_client( client: Client, task_queue: String, session_id: SessionId, - counters: temporal_server::worker::FakeRuntimeCounters, + counters: temporal_runtime::worker::FakeRuntimeCounters, ) -> anyhow::Result<()> { let api = run_control_api(&client, task_queue, &session_id, true).await?; @@ -439,7 +439,7 @@ async fn run_steering_live_client( client: Client, task_queue: String, session_id: SessionId, - counters: temporal_server::worker::FakeRuntimeCounters, + counters: temporal_runtime::worker::FakeRuntimeCounters, ) -> anyhow::Result<()> { let api = run_control_api(&client, task_queue, &session_id, true).await?; @@ -507,7 +507,7 @@ async fn run_steering_final_turn_live_client( client: Client, task_queue: String, session_id: SessionId, - counters: temporal_server::worker::FakeRuntimeCounters, + counters: temporal_runtime::worker::FakeRuntimeCounters, ) -> anyhow::Result<()> { // No tools: the fake model answers in one turn. let api = run_control_api(&client, task_queue, &session_id, false).await?; @@ -590,7 +590,7 @@ async fn run_queue_live_client( client: Client, task_queue: String, session_id: SessionId, - counters: temporal_server::worker::FakeRuntimeCounters, + counters: temporal_runtime::worker::FakeRuntimeCounters, ) -> anyhow::Result<()> { let api = run_control_api(&client, task_queue, &session_id, false).await?; @@ -978,7 +978,7 @@ async fn run_llm_retry_exhaustion_live_client( api::RunStatus::Failed, "exhausted provider retries must fail the run with a terminal generation result" ); - // The failure event carries the engine's classification, not only text. + // The failure event carries the harness's classification, not only text. let events = api .read_session_events(SessionEventsReadParams { direction: Default::default(), diff --git a/crates/temporal-server/tests/runs_live_slow.rs b/crates/temporal-runtime/tests/runs_live_slow.rs similarity index 96% rename from crates/temporal-server/tests/runs_live_slow.rs rename to crates/temporal-runtime/tests/runs_live_slow.rs index c646fa3be..e1364c011 100644 --- a/crates/temporal-server/tests/runs_live_slow.rs +++ b/crates/temporal-runtime/tests/runs_live_slow.rs @@ -4,7 +4,7 @@ //! //! ```bash //! source scripts/dev/env.sh -//! cargo test -p temporal-server --test runs_live_slow -- --ignored --test-threads=1 +//! cargo test -p temporal-runtime --test runs_live_slow -- --ignored --test-threads=1 //! ``` mod support; @@ -21,13 +21,13 @@ use api::{ AgentApiService, InputItem, RunStartParams, RunStartSource, RunStatus, SessionReadParams, SessionStartParams, }; -use engine::SessionId; +use harness::SessionId; use support::live::{ LIVE_TEST_LOCK, fake_worker_activities_with_stall_switch, final_assistant_text, live_workflow_handle, require_storage_live_env, run_with_live_worker_timeout, wait_for_terminal_run, }; -use temporal_server::{gateway::GatewayAgentApi, pg_store_from_env, worker::FakeRuntimeCounters}; +use temporal_runtime::{gateway::GatewayAgentApi, pg_store_from_env, worker::FakeRuntimeCounters}; use temporal_workflow::{LLM_SCHEDULE_TO_CLOSE, LLM_START_TO_CLOSE}; use temporalio_client::{Client, WorkflowDescribeOptions, WorkflowTerminateOptions}; diff --git a/crates/temporal-server/tests/sessions_live.rs b/crates/temporal-runtime/tests/sessions_live.rs similarity index 98% rename from crates/temporal-server/tests/sessions_live.rs rename to crates/temporal-runtime/tests/sessions_live.rs index 1610f0e27..dae364774 100644 --- a/crates/temporal-server/tests/sessions_live.rs +++ b/crates/temporal-runtime/tests/sessions_live.rs @@ -13,7 +13,7 @@ use api::{ }; use api_projection::model_to_api; use base64::Engine as _; -use engine::{ +use harness::{ CoreAgentCommand, SessionId, storage::{BlobStore, SessionStore}, }; @@ -23,7 +23,7 @@ use support::live::{ require_storage_live_env, run_with_live_worker, start_text_run, wait_for_admission_failure, wait_for_session_status, wait_for_terminal_run, }; -use temporal_server::{gateway::GatewayAgentApi, pg_store_from_env, worker::WorkerActivities}; +use temporal_runtime::{gateway::GatewayAgentApi, pg_store_from_env, worker::WorkerActivities}; use temporal_workflow::{AgentAdmission, AgentAdmissionFailureKind, AgentSessionWorkflow}; use temporalio_client::{ Client, WorkflowDescribeOptions, WorkflowSignalOptions, WorkflowTerminateOptions, @@ -54,9 +54,9 @@ async fn temporal_live_anthropic_standalone_compaction_and_continuation() -> any std::env::var("ANTHROPIC_API_KEY").is_ok_and(|key| !key.trim().is_empty()), "ANTHROPIC_API_KEY must be set" ); - let model = engine::ModelSelection { + let model = harness::ModelSelection { provider_id: "anthropic".into(), - api_kind: engine::ProviderApiKind::AnthropicMessages, + api_kind: harness::ProviderApiKind::AnthropicMessages, model: "claude-opus-5-5".into(), }; let activities = WorkerActivities::from_env().await?; @@ -70,7 +70,7 @@ async fn run_compaction_live_client( client: Client, queue: String, session_id: SessionId, - model: engine::ModelSelection, + model: harness::ModelSelection, ) -> anyhow::Result<()> { let store = pg_store_from_env().await?; support::live::seed_agent_default(&store, &model).await?; @@ -121,10 +121,10 @@ async fn run_compaction_live_client( .compaction, Some(api::CompactionPolicy::Disabled) ); - let provider_kind = if model.api_kind == engine::ProviderApiKind::AnthropicMessages { - engine::ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND + let provider_kind = if model.api_kind == harness::ProviderApiKind::AnthropicMessages { + harness::ANTHROPIC_MESSAGES_COMPACTION_PROVIDER_KIND } else { - engine::OPENAI_RESPONSES_COMPACTION_PROVIDER_KIND + harness::OPENAI_RESPONSES_COMPACTION_PROVIDER_KIND }; assert!( view.active_context @@ -412,8 +412,8 @@ async fn temporal_live_anthropic_messages_tool_call_round_trip() -> anyhow::Resu std::env::var("ANTHROPIC_API_KEY").is_ok_and(|key| !key.trim().is_empty()), "ANTHROPIC_API_KEY must be set to run the Anthropic live test" ); - let model = engine::ModelSelection { - api_kind: engine::ProviderApiKind::AnthropicMessages, + let model = harness::ModelSelection { + api_kind: harness::ProviderApiKind::AnthropicMessages, provider_id: "anthropic".to_owned(), model: std::env::var("ANTHROPIC_MESSAGES_MODEL") .or_else(|_| std::env::var("ANTHROPIC_LIVE_MODEL")) @@ -1171,7 +1171,7 @@ async fn run_context_append_live_client( }], }) .await?; - let borrowed = engine::BlobRef::parse(&uploaded.result.blobs[0].blob_ref)?; + let borrowed = harness::BlobRef::parse(&uploaded.result.blobs[0].blob_ref)?; sqlx::query("UPDATE cas_blobs SET created_at_ms = 1, touched_at_ms = 1 WHERE universe_id = $1 AND digest = $2") .bind(store.config().universe_id) .bind(borrowed.as_str().trim_start_matches("sha256:")) @@ -1397,7 +1397,7 @@ async fn run_admission_failure_live_client( // session must keep serving later admissions regardless. command: CoreAgentCommand::RequestRunSteering { requested_by: None, - run_id: engine::RunId::new(1), + run_id: harness::RunId::new(1), input: Vec::new(), }, correlation_token: None, @@ -1614,11 +1614,11 @@ async fn run_builtin_tool_live_client( client: Client, task_queue: String, session_id: SessionId, - model: engine::ModelSelection, + model: harness::ModelSelection, ) -> anyhow::Result<()> { // gpt-6-sol requires reasoning to be disabled when combining function // tools with Chat Completions. This fixture tests tool execution. - let generation = (model.api_kind == engine::ProviderApiKind::OpenAiCompletions).then(|| { + let generation = (model.api_kind == harness::ProviderApiKind::OpenAiCompletions).then(|| { api::GenerationConfig { reasoning_effort: Some("none".to_owned()), ..Default::default() @@ -1712,7 +1712,7 @@ async fn run_builtin_tool_live_client( _ => None, }) .expect("completed run output descriptor"); - if model.api_kind == engine::ProviderApiKind::OpenAiCompletions { + if model.api_kind == harness::ProviderApiKind::OpenAiCompletions { assert_eq!(content.media_type.as_deref(), Some("application/json")); assert_eq!( content.provider_kind.as_deref(), diff --git a/crates/temporal-server/tests/subagents_live.rs b/crates/temporal-runtime/tests/subagents_live.rs similarity index 97% rename from crates/temporal-server/tests/subagents_live.rs rename to crates/temporal-runtime/tests/subagents_live.rs index c9db710b3..bd5f7f0ef 100644 --- a/crates/temporal-server/tests/subagents_live.rs +++ b/crates/temporal-runtime/tests/subagents_live.rs @@ -12,7 +12,7 @@ use api::{ }; use api_projection::model_to_api; use async_trait::async_trait; -use engine::{ +use harness::{ ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentIoError, CoreAgentLlm, CoreAgentTools, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, LlmGenerationStatus, ModelSelection, ObservedToolCall, SessionId, ToolCallId, ToolName, @@ -22,11 +22,11 @@ use support::live::{ LIVE_TEST_LOCK, final_assistant_text, live_workflow_handle, require_storage_live_env, terminate_live_session, wait_for_terminal_run, wait_until, }; -use temporal_server::{ +use temporal_runtime::{ gateway::GatewayAgentApi, pg_store_from_env, subagents::AgentApiSubagentRuntime, - worker::{ActivityState, SessionTools, WorkerActivities, core_runtime, worker_with_activities}, + worker::{ActivityState, SessionTools, WorkerActivities, sessions_worker, worker_runtime}, }; use temporal_workflow::{ AgentSessionWorkflow, DEFAULT_TEMPORAL_NAMESPACE, DEFAULT_TEMPORAL_TARGET, connect_temporal, @@ -169,7 +169,7 @@ impl SubagentScriptedLlm { for entry in request.request.context.entries.iter().rev() { // Media entries carry bytes, not text; a real adapter lowers // them to provider blocks, the script looks past them. - if matches_kind(&entry.kind) && !engine::media::is_media_content(&entry.content) { + if matches_kind(&entry.kind) && !harness::media::is_media_content(&entry.content) { return self .blobs .read_text(&entry.content.content_ref) @@ -209,7 +209,7 @@ impl SubagentScriptedLlm { call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: arguments_ref.clone(), media_type: Some("application/json".to_owned()), provider_kind: Some("subagent-script".to_owned()), @@ -268,11 +268,11 @@ impl SubagentScriptedLlm { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: output_ref, media_type: Some("application/json".to_owned()), provider_kind: Some( - engine::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND.to_owned(), + harness::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND.to_owned(), ), }, preview: Some("subagent scripted final".to_owned()), @@ -376,7 +376,7 @@ impl CoreAgentLlm for SubagentScriptedLlm { if user_text.starts_with("CHILD_MEDIA") { // The child links the image it read by the handle the tool // result announced, plus one handle it never saw. - let handles = engine::media::find_media_handles(&tool_result); + let handles = harness::media::find_media_handles(&tool_result); let Some(handle) = handles.first() else { return Err(CoreAgentIoError::Failed { message: format!( @@ -412,10 +412,10 @@ impl CoreAgentLlm for SubagentScriptedLlm { .entries .iter() .filter(|entry| { - matches!(entry.source, engine::ContextEntrySource::Tool { .. }) - && engine::media::is_media_content(&entry.content) + matches!(entry.source, harness::ContextEntrySource::Tool { .. }) + && harness::media::is_media_content(&entry.content) }) - .map(|entry| engine::media::media_handle(&entry.content.content_ref)) + .map(|entry| harness::media::media_handle(&entry.content.content_ref)) .collect::>(); let media_report = if media.is_empty() { String::new() @@ -564,7 +564,7 @@ where let namespace = env::var("TEMPORAL_NAMESPACE").unwrap_or_else(|_| DEFAULT_TEMPORAL_NAMESPACE.to_owned()); - let runtime = core_runtime()?; + let runtime = worker_runtime()?; let client = connect_temporal(&temporal_target, &namespace).await?; let store = pg_store_from_env().await?; let model = support::live::openai_live_model(); @@ -586,15 +586,14 @@ where .with_workflow_tool_executions(client.clone()) .with_subagent_runtime(Arc::new(AgentApiSubagentRuntime::new(api.clone()))), ); - let mut worker = - worker_with_activities(&runtime, client.clone(), task_queue.clone(), activities)?; + let mut worker = sessions_worker(&runtime, client.clone(), task_queue.clone(), activities)?; let shutdown_worker = worker.shutdown_handle(); - let worker_future = worker.run(); + let worker_future = async { worker.run().await.map_err(anyhow::Error::from) }; tokio::pin!(worker_future); let blobs_for_client: Arc = store.clone(); let sessions_for_client: Arc = store; - let client_future = temporal_server::gateway::request_context::with_request_context( + let client_future = temporal_runtime::gateway::request_context::with_request_context( support::live::local_request_context().await?, run_client( client.clone(), @@ -752,9 +751,9 @@ async fn start_subagent_parent_with_features( async fn list_children( sessions: &Arc, parent: &SessionId, -) -> anyhow::Result> { +) -> anyhow::Result> { Ok(sessions - .list_sessions(engine::storage::ListSessions { + .list_sessions(harness::storage::ListSessions { limit: 50, parent: Some(parent.clone()), ..Default::default() @@ -767,7 +766,7 @@ async fn wait_for_children_closed( sessions: &Arc, parent: &SessionId, expected: usize, -) -> anyhow::Result> { +) -> anyhow::Result> { let mut children = Vec::new(); wait_until( "sub-agent children to close", @@ -776,7 +775,7 @@ async fn wait_for_children_closed( children = list_children(sessions, parent).await?; Ok(children.len() == expected && children.iter().all(|child| { - child.lifecycle_status == engine::storage::SessionLifecycleStatus::Closed + child.lifecycle_status == harness::storage::SessionLifecycleStatus::Closed })) }, ) @@ -807,7 +806,7 @@ async fn run_agent_run_media_live_client( // A workspace holding one PNG, linked read-only into the child's profile. let mut png = b"\x89PNG\r\n\x1a\n".to_vec(); png.extend_from_slice(b"live-subagent-render"); - let handle = engine::media::media_handle(&engine::BlobRef::from_bytes(&png)); + let handle = harness::media::media_handle(&harness::BlobRef::from_bytes(&png)); let snapshot = support::live::upload_snapshot( api.as_ref(), vec![vfs::InlineFile::new("/render.png", png)?], @@ -911,8 +910,11 @@ async fn run_file_attachment_live_client( spawned: bool, ) -> anyhow::Result<()> { let bytes = b"# Final report\n"; - let reference = - engine::FileAttachment::new(engine::BlobRef::from_bytes(bytes), "report.md".into(), None); + let reference = harness::FileAttachment::new( + harness::BlobRef::from_bytes(bytes), + "report.md".into(), + None, + ); let snapshot = support::live::upload_snapshot( api.as_ref(), vec![ @@ -1062,7 +1064,7 @@ async fn run_agent_run_inline_live_client( assert_eq!(output.media_type.as_deref(), Some("application/json")); assert_eq!( output.provider_kind.as_deref(), - Some(engine::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND) + Some(harness::ANTHROPIC_MESSAGES_TEXT_BLOCKS_PROVIDER_KIND) ); assert_eq!(parent_run.output.as_ref(), Some(&output)); assert_eq!(parent_run.output_text.as_deref(), Some(parent_output)); @@ -1557,7 +1559,7 @@ async fn run_agent_spawn_cancel_live_client( .await?; Ok(status .active_run - .is_some_and(|run| run.status == engine::RunStatus::Parked)) + .is_some_and(|run| run.status == harness::RunStatus::Parked)) }, ) .await; @@ -1642,7 +1644,7 @@ async fn run_agent_spawn_cancel_live_client( "cancelled child supervisor to finish", Duration::from_secs(30), async || { - use temporalio_common::protos::temporal::api::enums::v1::WorkflowExecutionStatus; + use temporalio_client::WorkflowExecutionStatus; let status = execution .describe(temporalio_client::WorkflowDescribeOptions::default()) .await? diff --git a/crates/temporal-server/tests/support/live.rs b/crates/temporal-runtime/tests/support/live.rs similarity index 94% rename from crates/temporal-server/tests/support/live.rs rename to crates/temporal-runtime/tests/support/live.rs index a10e25929..5b190bfc4 100644 --- a/crates/temporal-server/tests/support/live.rs +++ b/crates/temporal-runtime/tests/support/live.rs @@ -11,14 +11,14 @@ use api::{ AgentApiService, ContextEntryKindView, ContextMessageRoleView, InputItem, RunStartParams, RunStartSource, RunStatus, SessionReadParams, SessionStatus, }; -use engine::{ +use harness::{ CoreAgentLlm, CoreAgentTools, ModelSelection, ProviderApiKind, SessionId, storage::BlobStore, }; -use temporal_server::{ +use temporal_runtime::{ pg_store_from_env, worker::{ ActivityState, AudioTranscoder, AudioTranscriber, FakeLlm, FakeRuntimeCounters, FakeTools, - WorkerActivities, core_runtime, worker_with_activities, + WorkerActivities, sessions_worker, worker_runtime, }, }; use temporal_workflow::{ @@ -45,7 +45,7 @@ pub const LIVE_TEST_BUDGET: Duration = Duration::from_secs(180); /// Explicit test identity for direct in-process clients; never inherited by workers. pub async fn local_request_context() --> anyhow::Result { +-> anyhow::Result { local_request_context_for(api::AccessScope::Universe { universe_id: live_universe_id()?, }) @@ -54,8 +54,8 @@ pub async fn local_request_context() pub async fn local_request_context_for( scope: api::AccessScope, -) -> anyhow::Result { - Ok(temporal_server::gateway::request_context::RequestContext::local(scope)) +) -> anyhow::Result { + Ok(temporal_runtime::gateway::request_context::RequestContext::local(scope)) } pub async fn run_with_live_worker( @@ -117,23 +117,22 @@ where let namespace = env::var("TEMPORAL_NAMESPACE").unwrap_or_else(|_| DEFAULT_TEMPORAL_NAMESPACE.to_owned()); - let runtime = core_runtime()?; + let runtime = worker_runtime()?; let client = connect_temporal(&temporal_target, &namespace).await?; let activities = build_activities(client.clone(), task_queue.clone()).await?; - let mut worker = - worker_with_activities(&runtime, client.clone(), task_queue.clone(), activities)?; + let mut worker = sessions_worker(&runtime, client.clone(), task_queue.clone(), activities)?; let shutdown_worker = worker.shutdown_handle(); - let worker_future = worker.run(); + let worker_future = async { worker.run().await.map_err(anyhow::Error::from) }; tokio::pin!(worker_future); // A fixture may explicitly target a fresh universe. Preserve its request // authority on the client only; workers must install controller contexts. - let context = match temporal_server::gateway::request_context::request_context() { + let context = match temporal_runtime::gateway::request_context::request_context() { Ok(context) => context, Err(_) => local_request_context().await?, }; // Large client futures must not inflate the stack used to poll the worker. - let client_future = temporal_server::gateway::request_context::with_request_context( + let client_future = temporal_runtime::gateway::request_context::with_request_context( context, Box::pin(run_client(client, task_queue, session_id)), ); @@ -192,7 +191,7 @@ pub async fn upload_snapshot( vfs::write_manifest_file_ref( &mut manifest, &file.path, - engine::BlobRef::parse(&uploaded.blob_ref)?, + harness::BlobRef::parse(&uploaded.blob_ref)?, uploaded.bytes, file.media_type, file.executable, @@ -208,7 +207,7 @@ pub async fn upload_snapshot( /// Universe used by live tests: the one bound by `LIGHTSPEED_PG_UNIVERSE_ID`. pub fn live_universe_id() -> anyhow::Result { - temporal_server::universe_id_from_env() + temporal_runtime::universe_id_from_env() } /// Temporal workflow handle for a session, addressed by the composed @@ -370,7 +369,7 @@ pub fn final_assistant_text(run: &api::RunView) -> Option<&str> { } pub async fn wait_for_terminal_run( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, session_id: &SessionId, run_id: &str, ) -> anyhow::Result { @@ -378,7 +377,7 @@ pub async fn wait_for_terminal_run( } pub async fn wait_for_terminal_run_with_timeout( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, session_id: &SessionId, run_id: &str, budget: Duration, @@ -422,7 +421,7 @@ pub async fn wait_for_terminal_run_with_timeout( } pub async fn start_text_run( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, session_id: &SessionId, text: &str, ) -> anyhow::Result { @@ -446,7 +445,7 @@ pub async fn start_text_run( } pub async fn read_run( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, session_id: &SessionId, run_id: &str, ) -> anyhow::Result> { @@ -460,7 +459,7 @@ pub async fn read_run( } pub async fn read_session_view( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, session_id: &SessionId, ) -> anyhow::Result { Ok(api @@ -474,7 +473,7 @@ pub async fn read_session_view( } pub async fn wait_for_environment_status( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, environment_id: &str, expected: api::EnvironmentLifecycleStatusView, ) -> anyhow::Result { @@ -557,7 +556,7 @@ pub async fn wait_for_admission_failure( } pub async fn wait_for_session_status( - api: &temporal_server::gateway::GatewayAgentApi, + api: &temporal_runtime::gateway::GatewayAgentApi, session_id: &SessionId, expected: SessionStatus, ) -> anyhow::Result<()> { diff --git a/crates/temporal-server/tests/support/mod.rs b/crates/temporal-runtime/tests/support/mod.rs similarity index 100% rename from crates/temporal-server/tests/support/mod.rs rename to crates/temporal-runtime/tests/support/mod.rs diff --git a/crates/temporal-server/tests/tenancy_live.rs b/crates/temporal-runtime/tests/tenancy_live.rs similarity index 92% rename from crates/temporal-server/tests/tenancy_live.rs rename to crates/temporal-runtime/tests/tenancy_live.rs index 9b48e068c..8a1786af1 100644 --- a/crates/temporal-server/tests/tenancy_live.rs +++ b/crates/temporal-runtime/tests/tenancy_live.rs @@ -9,11 +9,11 @@ use api::{ ProfileId, ProfileListParams, ProfileReadParams, SessionReadParams, SessionStartParams, SessionStatus, }; -use engine::SessionId; +use harness::SessionId; use support::live::{LIVE_TEST_LOCK, require_storage_live_env}; -use temporal_server::{ +use temporal_runtime::{ DeploymentStores, UniverseRuntime, - worker::{WorkerActivities, core_runtime, worker_with_activities}, + worker::{WorkerActivities, sessions_worker, worker_runtime}, }; use temporal_workflow::{ AgentSessionWorkflow, DEFAULT_TEMPORAL_NAMESPACE, DEFAULT_TEMPORAL_TARGET, connect_temporal, @@ -37,7 +37,7 @@ async fn temporal_live_two_universes_share_one_worker_with_isolation() -> anyhow env::var("TEMPORAL_ADDRESS").unwrap_or_else(|_| DEFAULT_TEMPORAL_TARGET.to_owned()); let namespace = env::var("TEMPORAL_NAMESPACE").unwrap_or_else(|_| DEFAULT_TEMPORAL_NAMESPACE.to_owned()); - let runtime = core_runtime()?; + let runtime = worker_runtime()?; let client = connect_temporal(&temporal_target, &namespace).await?; let stores = DeploymentStores::from_env().await?; let universes = Arc::new(UniverseRuntime::new( @@ -48,10 +48,9 @@ async fn temporal_live_two_universes_share_one_worker_with_isolation() -> anyhow )?); let activities = WorkerActivities::with_runtime(universes.clone()); - let mut worker = - worker_with_activities(&runtime, client.clone(), task_queue.clone(), activities)?; + let mut worker = sessions_worker(&runtime, client.clone(), task_queue.clone(), activities)?; let shutdown_worker = worker.shutdown_handle(); - let worker_future = worker.run(); + let worker_future = async { worker.run().await.map_err(anyhow::Error::from) }; tokio::pin!(worker_future); let universe_a = uuid::Uuid::new_v4(); @@ -64,17 +63,17 @@ async fn temporal_live_two_universes_share_one_worker_with_isolation() -> anyhow let api_a = state_a.api.clone(); let api_b = state_b.api.clone(); // Direct service calls carry an explicit caller, one per universe. - let caller_a = temporal_server::gateway::request_context::RequestContext::local( + let caller_a = temporal_runtime::gateway::request_context::RequestContext::local( api::AccessScope::Universe { universe_id: universe_a, }, ); - let caller_b = temporal_server::gateway::request_context::RequestContext::local( + let caller_b = temporal_runtime::gateway::request_context::RequestContext::local( api::AccessScope::Universe { universe_id: universe_b, }, ); - use temporal_server::gateway::request_context::with_request_context as calling; + use temporal_runtime::gateway::request_context::with_request_context as calling; // The same client-chosen session id starts independently in both // universes on the same queue, served by the same worker. diff --git a/crates/temporal-server/tests/transcriptions_live.rs b/crates/temporal-runtime/tests/transcriptions_live.rs similarity index 98% rename from crates/temporal-server/tests/transcriptions_live.rs rename to crates/temporal-runtime/tests/transcriptions_live.rs index 15491c3ad..cad99e5f3 100644 --- a/crates/temporal-server/tests/transcriptions_live.rs +++ b/crates/temporal-runtime/tests/transcriptions_live.rs @@ -9,13 +9,13 @@ use api::{ use api_projection::model_to_api; use async_trait::async_trait; use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64}; -use engine::SessionId; +use harness::SessionId; use support::live::{ LIVE_TEST_LOCK, fake_worker_activities_with_audio_processing, fake_worker_activities_with_audio_transcriber, final_assistant_text, live_workflow_handle, require_storage_live_env, run_with_live_worker, wait_for_terminal_run, }; -use temporal_server::{ +use temporal_runtime::{ gateway::GatewayAgentApi, pg_store_from_env, worker::{ @@ -498,7 +498,7 @@ async fn transcribe( assert_eq!(terminal.text.as_deref(), Some(TRANSCRIPT_TEXT)); let mut other = support::live::local_request_context().await?; other.actor = Some("another-person".into()); - let denied = temporal_server::gateway::request_context::with_request_context( + let denied = temporal_runtime::gateway::request_context::with_request_context( other, api.read_transcription(api::TranscriptionReadParams { transcription_id: initial.transcription_id.clone(), @@ -605,7 +605,7 @@ async fn transcription_live_retries_transient_failure_and_cancels_running_activi assert_eq!(transcriber.attempts.load(std::sync::atomic::Ordering::SeqCst), if block { 1 } else { 2 }); if !block { let store = pg_store_from_env().await?; - let reference = engine::BlobRef::parse(terminal.transcript_ref.as_ref().unwrap())?; + let reference = harness::BlobRef::parse(terminal.transcript_ref.as_ref().unwrap())?; sqlx::query("UPDATE cas_blobs SET created_at_ms = 1, touched_at_ms = 1 WHERE universe_id = $1 AND digest = $2") .bind(store.config().universe_id).bind(reference.as_str().trim_start_matches("sha256:")).execute(store.pool()).await?; assert_eq!(store.delete_dead_blobs(&[reference], 2, &[]).await?.len(), 1, "unsubmitted workflows do not create retention roots"); diff --git a/crates/temporal-server/tests/vfs_transfer_live.rs b/crates/temporal-runtime/tests/vfs_transfer_live.rs similarity index 98% rename from crates/temporal-server/tests/vfs_transfer_live.rs rename to crates/temporal-runtime/tests/vfs_transfer_live.rs index 3a6fea1da..4db5f7e70 100644 --- a/crates/temporal-server/tests/vfs_transfer_live.rs +++ b/crates/temporal-runtime/tests/vfs_transfer_live.rs @@ -8,12 +8,6 @@ use std::{path::Path, sync::Arc, time::Duration}; use api::{AgentApiService, DeploymentApiService}; use async_trait::async_trait; -use engine::{ - BlobRef, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentIoError, - CoreAgentLlm, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, - LlmGenerationStatus, ObservedToolCall, ProviderApiKind, SessionId, ToolCallId, ToolName, - storage::BlobStore, -}; use environment_daemon::{ DaemonRuntime, config::{DaemonConfig, RegistrationConfig}, @@ -26,11 +20,17 @@ use environment_protocol::{ shared::{CURRENT_PROTOCOL_VERSION, EnvironmentPath, SecretString}, }; use environments::EnvironmentStore; +use harness::{ + BlobRef, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentIoError, + CoreAgentLlm, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, + LlmGenerationStatus, ObservedToolCall, ProviderApiKind, SessionId, ToolCallId, ToolName, + storage::BlobStore, +}; use serde_json::json; use support::live::{ LIVE_TEST_LOCK, require_storage_live_env, run_with_live_worker, wait_for_terminal_run, }; -use temporal_server::{ +use temporal_runtime::{ DeploymentStores, GatewayAuthMode, UniverseRuntime, gateway::{ DEFAULT_MAX_REQUEST_BODY_BYTES, GatewayAgentApi, GatewayDeploymentApi, GatewayRoutes, @@ -80,7 +80,7 @@ async fn temporal_live_vfs_transfers_follow_profile_grants_and_publish_large_fil Some(base_url.clone()), stores, )?); - temporal_server::gateway::request_context::with_request_context( + temporal_runtime::gateway::request_context::with_request_context( support::live::local_request_context_for(api::AccessScope::Deployment).await?, GatewayDeploymentApi::new(runtime.clone()).create_universe( api::DeploymentUniverseCreateParams { @@ -93,7 +93,7 @@ async fn temporal_live_vfs_transfers_follow_profile_grants_and_publish_large_fil // The sourced development URL names the normal gateway. This fixture // binds an ephemeral port, while retaining the deployment's route token. let gateway_config = - temporal_server::environments::gateway::EnvironmentGatewayClientConfig::new( + temporal_runtime::environments::gateway::EnvironmentGatewayClientConfig::new( &base_url, runtime.environment_gateway().deployment_token(), ); @@ -116,7 +116,7 @@ async fn temporal_live_vfs_transfers_follow_profile_grants_and_publish_large_fil support::live::local_request_context_for(api::AccessScope::Universe { universe_id }) .await?; // Keep the large transfer scenario off the current-thread test stack. - let result = temporal_server::gateway::request_context::with_request_context(context, Box::pin(async { + let result = temporal_runtime::gateway::request_context::with_request_context(context, Box::pin(async { let state = runtime.state_for(universe_id, false).await?; let key = state.api.create_environment_registration_key(api::EnvironmentRegistrationKeyCreateParams { display_name: "VFS transfer live".into(), @@ -172,7 +172,7 @@ async fn temporal_live_vfs_transfers_follow_profile_grants_and_publish_large_fil case?; } // Scan negotiation and conditional observations use the same reverse route. - let record = store.read_environment(&engine::EnvironmentId::new(&environment.environment_id)).await?; + let record = store.read_environment(&harness::EnvironmentId::new(&environment.environment_id)).await?; let connection = gateway_config.connection_for(universe_id, &record); let mut remote = environment_client::EnvironmentDataClient::connect(&connection.endpoint, gateway_config.connect_options("transfer-live-scan")).await?; let initialized = remote.initialize(&InitializeParams { @@ -609,7 +609,7 @@ impl CoreAgentLlm for TransferLlm { failure_ref: None, context_entries: vec![ContextEntryInput { kind, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some(media_type.into()), provider_kind: None, diff --git a/crates/temporal-server/tests/workflow_tool_plugins_live.rs b/crates/temporal-runtime/tests/workflow_tool_plugins_live.rs similarity index 94% rename from crates/temporal-server/tests/workflow_tool_plugins_live.rs rename to crates/temporal-runtime/tests/workflow_tool_plugins_live.rs index 2bd2b1ea2..712450d55 100644 --- a/crates/temporal-server/tests/workflow_tool_plugins_live.rs +++ b/crates/temporal-runtime/tests/workflow_tool_plugins_live.rs @@ -1,14 +1,14 @@ //! Live proof: workflow plugins run in their own Temporal worker //! and are reached only through data — an opaque bound endpoint or a //! CAS-backed start recipe. The session worker registers no plugin workflow -//! type (`worker_with_activities` is used unchanged); the plugin workflows +//! type (`sessions_worker` is used unchanged); the plugin workflows //! below are registered on a second worker with its own task queue. //! //! Run serially against the local stack: //! //! ```bash //! source scripts/dev/env.sh -//! cargo test -p temporal-server --test workflow_tool_plugins_live -- --ignored --test-threads=1 +//! cargo test -p temporal-runtime --test workflow_tool_plugins_live -- --ignored --test-threads=1 //! ``` mod support; @@ -20,7 +20,7 @@ use api::{ RunStartSource, RunTerminalNotificationInput, SessionReadParams, }; use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentIoError, CoreAgentLlm, CoreAgentTools, EmissionBody, EmissionEnvelope, EmissionProducer, FunctionToolSpec, LlmFinish, LlmGenerationFacts, LlmGenerationRequest, LlmGenerationResult, @@ -33,10 +33,10 @@ use support::live::{ LIVE_TEST_LOCK, final_assistant_text, live_universe_id, live_workflow_handle, require_storage_live_env, }; -use temporal_server::{ +use temporal_runtime::{ gateway::GatewayAgentApi, pg_store_from_env, - worker::{ActivityState, SessionTools, WorkerActivities, core_runtime, worker_with_activities}, + worker::{ActivityState, SessionTools, WorkerActivities, sessions_worker, worker_runtime}, }; use temporal_workflow::{ AgentSessionWorkflow, DEFAULT_TEMPORAL_NAMESPACE, DEFAULT_TEMPORAL_TARGET, @@ -44,11 +44,10 @@ use temporal_workflow::{ WorkflowToolStartArgs, compose_workflow_id, connect_temporal, workflow_tool_recipe_fingerprint, }; use temporalio_client::{Client, WorkflowStartOptions, WorkflowTerminateOptions}; -use temporalio_common::worker::WorkerTaskTypes; use temporalio_macros::{workflow, workflow_methods}; use temporalio_sdk::{ - ContinueAsNewOptions, SyncWorkflowContext, Worker, WorkerOptions, WorkflowContext, - WorkflowContextView, WorkflowResult, + ContinueAsNewOptions, SyncWorkflowContext, WorkerOptions, WorkflowContext, WorkflowContextView, + WorkflowResult, }; use tools::concurrency::AWAIT_TOOL_NAME; @@ -81,7 +80,7 @@ pub struct BoundPluginSnapshot { /// through the fixed `deliver_emission` signal and resolves each keyed /// completion promise with a `SourceResolution` emission back to the /// producing session — sent twice to prove duplicate delivery is a no-op. -#[workflow(name = "TestBoundPluginWorkflow")] +#[workflow] #[derive(Default)] pub struct TestBoundPluginWorkflow { inbox: Vec, @@ -91,10 +90,12 @@ pub struct TestBoundPluginWorkflow { #[workflow_methods] impl TestBoundPluginWorkflow { - #[run] + #[run(name = "TestBoundPluginWorkflow")] pub async fn run(ctx: &mut WorkflowContext, args: BoundPluginArgs) -> WorkflowResult<()> { loop { - ctx.wait_condition(|state| !state.inbox.is_empty()).await; + ctx.wait_condition(|state| !state.inbox.is_empty()) + .await + .map_err(|_| temporalio_sdk::WorkflowTermination::cancelled())?; let envelopes = ctx.state_mut(|state| std::mem::take(&mut state.inbox)); for envelope in envelopes { match envelope.body { @@ -134,7 +135,11 @@ impl TestBoundPluginWorkflow { for _ in 0..2 { let _ = ctx .external_workflow(holder.clone(), None) - .signal(AgentSessionWorkflow::deliver_emission, reply.clone()) + .signal( + AgentSessionWorkflow::deliver_emission, + reply.clone(), + Default::default(), + ) .await; ctx.state_mut(|state| state.snapshot.replies_sent += 1); } @@ -176,7 +181,7 @@ impl TestBoundPluginWorkflow { #[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct SelfReceiverControllerSnapshot { /// Channels-shaped durable outbox: invocation id is the idempotency key. - outbox: std::collections::BTreeMap, + outbox: std::collections::BTreeMap, duplicate_invocations: u32, replies_sent: u32, terminal_tokens: Vec, @@ -197,7 +202,7 @@ pub struct SelfReceiverControllerArgs { /// Pushed invocations are processed directly from the workflow inbox while /// the managed run is active; run-terminal handling is a separate branch and /// is never a prerequisite for enqueue or reply. -#[workflow(name = "TestSelfReceiverControllerWorkflow")] +#[workflow] #[derive(Default)] pub struct TestSelfReceiverControllerWorkflow { inbox: Vec, @@ -206,14 +211,16 @@ pub struct TestSelfReceiverControllerWorkflow { #[workflow_methods] impl TestSelfReceiverControllerWorkflow { - #[run] + #[run(name = "TestSelfReceiverControllerWorkflow")] pub async fn run( ctx: &mut WorkflowContext, args: SelfReceiverControllerArgs, ) -> WorkflowResult<()> { ctx.state_mut(|state| state.snapshot = args.snapshot.clone()); loop { - ctx.wait_condition(|state| !state.inbox.is_empty()).await; + ctx.wait_condition(|state| !state.inbox.is_empty()) + .await + .map_err(|_| temporalio_sdk::WorkflowTermination::cancelled())?; let envelopes = ctx.state_mut(|state| std::mem::take(&mut state.inbox)); for envelope in envelopes { match envelope.body { @@ -254,7 +261,11 @@ impl TestSelfReceiverControllerWorkflow { for _ in 0..2 { let _ = ctx .external_workflow(holder.clone(), None) - .signal(AgentSessionWorkflow::deliver_emission, reply.clone()) + .signal( + AgentSessionWorkflow::deliver_emission, + reply.clone(), + Default::default(), + ) .await; ctx.state_mut(|state| state.snapshot.replies_sent += 1); } @@ -280,7 +291,7 @@ impl TestSelfReceiverControllerWorkflow { let mut next = args.clone(); ctx.state_mut(|state| state.snapshot.continue_as_new_count += 1); next.snapshot = ctx.state(|state| state.snapshot.clone()); - ctx.continue_as_new(&next, ContinueAsNewOptions::default())?; + ctx.continue_as_new(next, ContinueAsNewOptions::default())?; } } } @@ -303,7 +314,7 @@ impl TestSelfReceiverControllerWorkflow { /// Start-on-call plugin: started by the generic adapter from a CAS recipe, /// resolves every keyed completion promise back to the holder, exposes the /// fixed recovery query, then completes. -#[workflow(name = "TestStartPluginWorkflow")] +#[workflow] #[derive(Default)] pub struct TestStartPluginWorkflow { recovery: WorkflowToolRecoveryResult, @@ -311,17 +322,17 @@ pub struct TestStartPluginWorkflow { #[workflow_methods] impl TestStartPluginWorkflow { - #[run] + #[run(name = "TestStartPluginWorkflow")] pub async fn run( ctx: &mut WorkflowContext, args: WorkflowToolStartArgs, ) -> WorkflowResult<()> { if ctx.workflow_id() != args.execution_id { - return Err(anyhow::anyhow!( + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( "started execution id mismatch: workflow_id={} execution_id={}", ctx.workflow_id(), args.execution_id - ) + )) .into()); } for (key, promise_id) in args.invocation.completion_promises.iter().flatten() { @@ -341,7 +352,11 @@ impl TestStartPluginWorkflow { ); let _ = ctx .external_workflow(args.holder_workflow_id.clone(), None) - .signal(AgentSessionWorkflow::deliver_emission, envelope) + .signal( + AgentSessionWorkflow::deliver_emission, + envelope, + Default::default(), + ) .await; } // Keep the started execution alive after its semantic reply. Joined @@ -359,7 +374,7 @@ impl TestStartPluginWorkflow { /// Start-on-call plugin that never signals its result: the holder's slow /// recovery poll must recover the keyed resolutions through the fixed query /// after the execution completes. -#[workflow(name = "TestSilentStartPluginWorkflow")] +#[workflow] #[derive(Default)] pub struct TestSilentStartPluginWorkflow { recovery: WorkflowToolRecoveryResult, @@ -367,7 +382,7 @@ pub struct TestSilentStartPluginWorkflow { #[workflow_methods] impl TestSilentStartPluginWorkflow { - #[run] + #[run(name = "TestSilentStartPluginWorkflow")] pub async fn run( ctx: &mut WorkflowContext, args: WorkflowToolStartArgs, @@ -391,13 +406,13 @@ impl TestSilentStartPluginWorkflow { /// A bound receiver that has already completed by the time the session /// binds to it: push delivery must exhaust and fail terminally. -#[workflow(name = "TestClosedPluginWorkflow")] +#[workflow] #[derive(Default)] pub struct TestClosedPluginWorkflow {} #[workflow_methods] impl TestClosedPluginWorkflow { - #[run] + #[run(name = "TestClosedPluginWorkflow")] pub async fn run( _ctx: &mut WorkflowContext, _args: BoundPluginArgs, @@ -410,7 +425,7 @@ impl TestClosedPluginWorkflow { /// exercise holder continue-as-new during a parked completion (the rebuilt /// start work re-issues the deterministic start and `AlreadyStarted` is /// success). -#[workflow(name = "TestSlowStartPluginWorkflow")] +#[workflow] #[derive(Default)] pub struct TestSlowStartPluginWorkflow { recovery: WorkflowToolRecoveryResult, @@ -418,7 +433,7 @@ pub struct TestSlowStartPluginWorkflow { #[workflow_methods] impl TestSlowStartPluginWorkflow { - #[run] + #[run(name = "TestSlowStartPluginWorkflow")] pub async fn run( ctx: &mut WorkflowContext, args: WorkflowToolStartArgs, @@ -427,13 +442,19 @@ impl TestSlowStartPluginWorkflow { // against the cancellation request and end as cancelled. { use futures_util::FutureExt; - let work = ctx.timer(Duration::from_secs(20)).fuse(); + let work = ctx + .timer( + temporalio_sdk::TimerOptions::builder(Duration::from_secs(20)) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) + .build(), + ) + .fuse(); let cancelled = ctx.cancelled(); futures_util::pin_mut!(work, cancelled); futures_util::select! { _ = work => {} _ = cancelled => { - return Err(temporalio_sdk::WorkflowTermination::Cancelled); + return Err(temporalio_sdk::WorkflowTermination::cancelled()); } } } @@ -454,7 +475,11 @@ impl TestSlowStartPluginWorkflow { ); let _ = ctx .external_workflow(args.holder_workflow_id.clone(), None) - .signal(AgentSessionWorkflow::deliver_emission, envelope) + .signal( + AgentSessionWorkflow::deliver_emission, + envelope, + Default::default(), + ) .await; } Ok(()) @@ -477,19 +502,19 @@ impl TestSlowStartPluginWorkflow { /// A started execution that can only finish by cancellation. A timed fake /// could complete on a busy machine before the holder's cancellation arrives. -#[workflow(name = "TestCancellationPluginWorkflow")] +#[workflow] #[derive(Default)] pub struct TestCancellationPluginWorkflow; #[workflow_methods] impl TestCancellationPluginWorkflow { - #[run] + #[run(name = "TestCancellationPluginWorkflow")] pub async fn run( ctx: &mut WorkflowContext, _args: WorkflowToolStartArgs, ) -> WorkflowResult<()> { ctx.cancelled().await; - Err(temporalio_sdk::WorkflowTermination::Cancelled) + Err(temporalio_sdk::WorkflowTermination::cancelled()) } #[signal(name = "deliver_emission")] @@ -563,7 +588,7 @@ impl WorkflowToolScriptedLlm { call_id: call_id.clone(), name: tool_name.clone(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: arguments_ref.clone(), media_type: Some("application/json".to_owned()), provider_kind: Some("workflow-tool-script".to_owned()), @@ -615,7 +640,7 @@ impl WorkflowToolScriptedLlm { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: output_ref, media_type: Some("text/plain".to_owned()), provider_kind: Some("workflow-tool-script".to_owned()), @@ -758,7 +783,7 @@ async fn tool_definition( )?) .await?; Ok(WorkflowToolDefinition { - tool_id: engine::WorkflowToolId::new(tool_id), + tool_id: harness::WorkflowToolId::new(tool_id), revision: 1, semantic_type: semantic_type.to_owned(), tool: ToolSpec { @@ -782,19 +807,19 @@ fn reply_completion() -> WorkflowToolCompletion { fn promises_completion( deadline_after_ms: Option, - reply_schema_ref: Option, + reply_schema_ref: Option, ) -> WorkflowToolCompletion { WorkflowToolCompletion::Promises { reply_schema_ref, deadline_after_ms, max_promises: 1, - key_source: engine::WorkflowToolCompletionKeySource::Reply, + key_source: harness::WorkflowToolCompletionKeySource::Reply, } } fn joined_completion( deadline_after_ms: u64, - reply_schema_ref: Option, + reply_schema_ref: Option, ) -> WorkflowToolCompletion { WorkflowToolCompletion::Joined { reply_schema_ref, @@ -830,7 +855,7 @@ where let namespace = std::env::var("TEMPORAL_NAMESPACE") .unwrap_or_else(|_| DEFAULT_TEMPORAL_NAMESPACE.to_owned()); - let runtime = core_runtime()?; + let runtime = worker_runtime()?; let client = connect_temporal(&temporal_target, &namespace).await?; let store = pg_store_from_env().await?; let blobs: Arc = store.clone(); @@ -851,28 +876,28 @@ where .with_workflow_tool_executions(client.clone()), ); let mut session_worker = - worker_with_activities(&runtime, client.clone(), session_queue.clone(), activities)?; + sessions_worker(&runtime, client.clone(), session_queue.clone(), activities)?; let shutdown_session_worker = session_worker.shutdown_handle(); - let session_worker_future = session_worker.run(); + let session_worker_future = async { session_worker.run().await.map_err(anyhow::Error::from) }; tokio::pin!(session_worker_future); let plugin_worker_options = WorkerOptions::new(plugin_queue.clone()) - .register_workflow::() - .register_workflow::() - .register_workflow::() - .register_workflow::() - .register_workflow::() - .register_workflow::() - .register_workflow::() - .task_types(WorkerTaskTypes::workflow_only()) + .register_workflow::()? + .register_workflow::()? + .register_workflow::()? + .register_workflow::()? + .register_workflow::()? + .register_workflow::()? + .register_workflow::()? .build(); - let mut plugin_worker = Worker::new(&runtime, client.clone(), plugin_worker_options) - .map_err(|error| anyhow::anyhow!("{error}"))?; + let mut plugin_worker = + temporalio_sdk::Worker::new(&runtime, client.clone(), plugin_worker_options) + .map_err(|error| anyhow::anyhow!("{error}"))?; let shutdown_plugin_worker = plugin_worker.shutdown_handle(); - let plugin_worker_future = plugin_worker.run(); + let plugin_worker_future = async { plugin_worker.run().await.map_err(anyhow::Error::from) }; tokio::pin!(plugin_worker_future); - let client_future = temporal_server::gateway::request_context::with_request_context( + let client_future = temporal_runtime::gateway::request_context::with_request_context( support::live::local_request_context().await?, run_client(client.clone(), api, blobs, session_id, plugin_queue), ); @@ -923,7 +948,7 @@ async fn start_managed_session_and_run( session_id, false, None, - engine::ManagedSessionWorkflowTools::v1(None, declarations), + harness::ManagedSessionWorkflowTools::v1(None, declarations), ) .await .map_err(|error| anyhow::anyhow!("start managed session: {error:?}"))?; @@ -1009,7 +1034,7 @@ async fn workflow_tool_bound_request_reply_resolves_via_plugin_worker() -> anyho workflow_id: receiver_id.clone(), workflow_kind: "test_approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, reply_completion(), )], @@ -1133,13 +1158,13 @@ async fn workflow_tool_controller_self_receiver_resolves_before_run_terminal() - &session_id, false, None, - engine::ManagedSessionWorkflowTools::v1( + harness::ManagedSessionWorkflowTools::v1( Some(controller.clone()), vec![WorkflowToolDeclaration::new( definition, WorkflowToolTarget::Bound { receiver: controller, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, joined_completion(30_000, None), )], @@ -1247,7 +1272,7 @@ async fn workflow_tool_controller_self_receiver_resolves_before_run_terminal() - EmissionEnvelope::tool_invocation( universe_id, session_id.clone(), - engine::EventSeq::new(999), + harness::EventSeq::new(999), invocation, compose_workflow_id(universe_id, &session_id), ), @@ -1312,7 +1337,7 @@ async fn workflow_tool_pushed_accepted_delivers_after_run_terminal() -> anyhow:: workflow_id: receiver_id.clone(), workflow_kind: "test_accepted_receiver".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, WorkflowToolCompletion::Accepted, )], @@ -1409,13 +1434,13 @@ async fn workflow_tool_controller_self_receiver_deadline_breaks_stalled_reply() &session_id, false, None, - engine::ManagedSessionWorkflowTools::v1( + harness::ManagedSessionWorkflowTools::v1( Some(controller.clone()), vec![WorkflowToolDeclaration::new( definition, WorkflowToolTarget::Bound { receiver: controller, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, joined_completion(5_000, None), )], @@ -1531,7 +1556,7 @@ async fn workflow_tool_reply_requires_exact_stored_producer() -> anyhow::Result< &session_id, false, None, - engine::ManagedSessionWorkflowTools::v1( + harness::ManagedSessionWorkflowTools::v1( None, vec![WorkflowToolDeclaration::new( definition, @@ -1540,7 +1565,7 @@ async fn workflow_tool_reply_requires_exact_stored_producer() -> anyhow::Result< workflow_id: receiver_id.clone(), workflow_kind: "test_approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, reply_completion(), )], @@ -1640,7 +1665,7 @@ async fn workflow_tool_reply_requires_exact_stored_producer() -> anyhow::Result< .await?; Ok(status .active_run - .is_some_and(|run| run.status == engine::RunStatus::Parked)) + .is_some_and(|run| run.status == harness::RunStatus::Parked)) }, ) .await?; @@ -1650,7 +1675,7 @@ async fn workflow_tool_reply_requires_exact_stored_producer() -> anyhow::Result< universe_id, "plugin/imposter".to_owned(), &temporal_workflow::compose_workflow_id(universe_id, &session_id), - engine::PromiseId::new(promise_id.clone()), + harness::PromiseId::new(promise_id.clone()), PromiseResolution::Resolved { payload_ref: None }, ); session_handle @@ -1689,7 +1714,7 @@ async fn workflow_tool_reply_requires_exact_stored_producer() -> anyhow::Result< universe_id, receiver_id.clone(), &temporal_workflow::compose_workflow_id(universe_id, &session_id), - engine::PromiseId::new(promise_id), + harness::PromiseId::new(promise_id), PromiseResolution::Resolved { payload_ref: None }, ); session_handle @@ -1746,29 +1771,29 @@ async fn workflow_tool_reply_requires_exact_stored_producer() -> anyhow::Result< // Duplicate push: the receiver keys its state by invocation id, so a // re-delivered invocation envelope is a plugin-side no-op. - let synthetic_invocation = engine::WorkflowToolInvocation { - invocation_id: engine::WorkflowToolInvocationId::new(format!( + let synthetic_invocation = harness::WorkflowToolInvocation { + invocation_id: harness::WorkflowToolInvocationId::new(format!( "wti:sha256:{}", "b".repeat(64) )), - tool_id: engine::WorkflowToolId::new("approve"), + tool_id: harness::WorkflowToolId::new("approve"), semantic_type: "lightspeed.test.approval.v1".to_owned(), schema_revision: 1, binding_fingerprint: format!("wtb:sha256:{}", "c".repeat(64)), session_universe_id: universe_id, session_id: session_id.clone(), - run_id: engine::RunId::new(1), - turn_id: engine::TurnId::new(1), - tool_batch_id: engine::ToolBatchId::new(1), - tool_call_id: engine::ToolCallId::new("synthetic-call"), - arguments_ref: engine::BlobRef::from_bytes(b"{}"), + run_id: harness::RunId::new(1), + turn_id: harness::TurnId::new(1), + tool_batch_id: harness::ToolBatchId::new(1), + tool_call_id: harness::ToolCallId::new("synthetic-call"), + arguments_ref: harness::BlobRef::from_bytes(b"{}"), execution_context_ref: None, completion_promises: None, }; let duplicate_push = EmissionEnvelope::tool_invocation( universe_id, session_id.clone(), - engine::EventSeq::new(999), + harness::EventSeq::new(999), synthetic_invocation, compose_workflow_id(universe_id, &session_id), ); @@ -1890,7 +1915,7 @@ async fn workflow_tool_start_on_call_resolves_via_plugin_worker() -> anyhow::Res }) .ok_or_else(|| anyhow::anyhow!("Start + Joined execution event was not projected"))?; let handle = client.get_workflow_handle::(execution_id); - use temporalio_common::protos::temporal::api::enums::v1::WorkflowExecutionStatus; + use temporalio_client::WorkflowExecutionStatus; let description = handle .describe(temporalio_client::WorkflowDescribeOptions::default()) .await @@ -1988,13 +2013,13 @@ async fn workflow_tool_dead_receiver_fails_promise_terminally() -> anyhow::Resul &session_id, false, None, - engine::ManagedSessionWorkflowTools::v1( + harness::ManagedSessionWorkflowTools::v1( Some(absent_controller.clone()), vec![WorkflowToolDeclaration::new( definition, WorkflowToolTarget::Bound { receiver: absent_controller, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, promises_completion(Some(30_000), None), )], @@ -2155,7 +2180,7 @@ async fn workflow_tool_reply_schema_gates_resolutions() -> anyhow::Result<()> { &session_id, false, None, - engine::ManagedSessionWorkflowTools::v1( + harness::ManagedSessionWorkflowTools::v1( None, vec![WorkflowToolDeclaration::new( definition, @@ -2164,7 +2189,7 @@ async fn workflow_tool_reply_schema_gates_resolutions() -> anyhow::Result<()> { workflow_id: receiver_id.clone(), workflow_kind: "test_approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, promises_completion(None, Some(reply_schema_ref)), )], @@ -2219,7 +2244,7 @@ async fn workflow_tool_reply_schema_gates_resolutions() -> anyhow::Result<()> { live_universe_id()?, receiver_id, &temporal_workflow::compose_workflow_id(live_universe_id()?, &session_id), - engine::PromiseId::new(promise_id), + harness::PromiseId::new(promise_id), PromiseResolution::Resolved { payload_ref: Some(payload_ref), }, @@ -2293,7 +2318,7 @@ async fn workflow_tool_closed_receiver_fails_delivery_terminally() -> anyhow::Re .describe(temporalio_client::WorkflowDescribeOptions::default()) .await .map_err(|error| anyhow::anyhow!("describe closed plugin: {error}"))?; - use temporalio_common::protos::temporal::api::enums::v1::WorkflowExecutionStatus; + use temporalio_client::WorkflowExecutionStatus; if description.status() == WorkflowExecutionStatus::Completed { break; } @@ -2317,7 +2342,7 @@ async fn workflow_tool_closed_receiver_fails_delivery_terminally() -> anyhow::Re workflow_id: receiver_id, workflow_kind: "test_approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, reply_completion(), )], @@ -2439,7 +2464,7 @@ async fn workflow_tool_start_survives_continue_as_new() -> anyhow::Result<()> { completion_promises, .. } => completion_promises - .get(engine::REPLY_COMPLETION_KEY) + .get(harness::REPLY_COMPLETION_KEY) .map(|promise_id| (call_id.clone(), promise_id.clone())), _ => None, }) @@ -2493,7 +2518,7 @@ async fn workflow_tool_run_terminal_auto_cancel_notifies_bound_receiver() -> any &session_id, false, None, - engine::ManagedSessionWorkflowTools::v1( + harness::ManagedSessionWorkflowTools::v1( None, vec![WorkflowToolDeclaration::new( definition, @@ -2502,7 +2527,7 @@ async fn workflow_tool_run_terminal_auto_cancel_notifies_bound_receiver() -> any workflow_id: receiver_id.clone(), workflow_kind: "test_approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, reply_completion(), )], @@ -2585,7 +2610,7 @@ async fn workflow_tool_auto_cancel_cancels_started_execution() -> anyhow::Result &session_id, false, None, - engine::ManagedSessionWorkflowTools::v1( + harness::ManagedSessionWorkflowTools::v1( None, vec![WorkflowToolDeclaration::new( definition, @@ -2640,7 +2665,7 @@ async fn workflow_tool_auto_cancel_cancels_started_execution() -> anyhow::Result if started.elapsed() > Duration::from_secs(60) { anyhow::bail!("started execution was never cancelled"); } - use temporalio_common::protos::temporal::api::enums::v1::WorkflowExecutionStatus; + use temporalio_client::WorkflowExecutionStatus; let status = match handle .describe(temporalio_client::WorkflowDescribeOptions::default()) .await diff --git a/crates/temporal-workflow/Cargo.toml b/crates/temporal-workflow/Cargo.toml index 265f3b445..b6d5bfce0 100644 --- a/crates/temporal-workflow/Cargo.toml +++ b/crates/temporal-workflow/Cargo.toml @@ -7,9 +7,9 @@ edition = "2024" api = { path = "../api" } bots = { path = "../bots" } channels = { path = "../channels" } -engine = { path = "../engine", features = ["contract"] } +harness = { path = "../harness", features = ["contract"] } schemars = { version = "1", features = ["uuid1"] } -sha2 = "0.10" +sha2 = "0.11" hex = "0.4" environment-protocol = { path = "../environment-protocol" } anyhow = "1" @@ -18,13 +18,14 @@ futures = "0.3" futures-util = "0.3" serde = { version = "1", features = ["derive"] } serde_json = "1" -temporalio-client = "0.4.0" -temporalio-common = "0.4.0" -temporalio-macros = "0.4.0" -temporalio-sdk = "0.4.0" -temporalio-sdk-core = "0.4.0" +temporalio-client = "1" +temporalio-common = "1" +temporalio-macros = "1" +temporalio-sdk = "1" +temporalio-workflow = "1" +url = "2" tracing = "0.1" uuid = { version = "1", features = ["serde"] } [dev-dependencies] -jsonschema = { version = "0.33", default-features = false } +jsonschema = { version = "0.58", default-features = false } diff --git a/crates/temporal-workflow/contract/workflow-contract.md b/crates/temporal-workflow/contract/workflow-contract.md index 902358c7f..d3911d6d2 100644 --- a/crates/temporal-workflow/contract/workflow-contract.md +++ b/crates/temporal-workflow/contract/workflow-contract.md @@ -1,6 +1,6 @@ # Lightspeed Workflow Contract -Generated from the Rust contract types in `engine` and `temporal-workflow`. +Generated from the Rust contract types in `harness` and `temporal-workflow`. Type shapes live in `workflow.schema.json`; constants and known-answer vectors live in `workflow.json`. Regenerate both artifacts and this reference with: diff --git a/crates/temporal-workflow/contract/workflow.schema.json b/crates/temporal-workflow/contract/workflow.schema.json index 214d658c8..e21a7d918 100644 --- a/crates/temporal-workflow/contract/workflow.schema.json +++ b/crates/temporal-workflow/contract/workflow.schema.json @@ -384,7 +384,7 @@ ] }, "ContentRef": { - "description": "Durable content identity and encoding. The payload stays in CAS; consumers\nproject it outside the engine rather than assuming every output is text.", + "description": "Durable content identity and encoding. The payload stays in CAS; consumers\nproject it outside the harness rather than assuming every output is text.", "properties": { "content_ref": { "type": "string" @@ -551,7 +551,7 @@ { "properties": { "holder_workflow_id": { - "description": "Workflow id of the session that emitted the invocation — the\nendpoint a receiver signals its reply to. Supplied by the\nsubstrate adapter; the engine treats it as opaque.", + "description": "Workflow id of the session that emitted the invocation — the\nendpoint a receiver signals its reply to. Supplied by the\nsubstrate adapter; the harness treats it as opaque.", "type": "string" }, "invocation": { @@ -764,7 +764,7 @@ "type": "object" }, "PromiseId": { - "description": "Stable identifier for a promise: a session-scoped counter rendered as\n`promise_`, the same convention as `run_`, so the model copies a\nshort handle rather than a digest. The engine hands every tool batch a\nbase one past the session cursor (`ToolInvocationBatchRequest::\npromise_id_base`); the executor numbers the promises it creates from\nthat base, and the reducer accepts a creation only at or above the\nbatch's base and never twice. Producer correlation lives on\n`PromiseSource`, not in the id.", + "description": "Stable identifier for a promise: a session-scoped counter rendered as\n`promise_`, the same convention as `run_`, so the model copies a\nshort handle rather than a digest. The harness hands every tool batch a\nbase one past the session cursor (`ToolInvocationBatchRequest::\npromise_id_base`); the executor numbers the promises it creates from\nthat base, and the reducer accepts a creation only at or above the\nbatch's base and never twice. Producer correlation lives on\n`PromiseSource`, not in the id.", "type": "string" }, "PromiseResolution": { diff --git a/crates/temporal-workflow/src/activities.rs b/crates/temporal-workflow/src/activities.rs index f8b84639b..71eb35d79 100644 --- a/crates/temporal-workflow/src/activities.rs +++ b/crates/temporal-workflow/src/activities.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ BlobRef, ContextCompactionResult, LlmGenerationResult, PromiseSourceCheckResult, ToolBatchOutcome, }; @@ -107,7 +107,7 @@ impl WorkflowActivities { pub async fn prepare_joined_context( _ctx: ActivityContext, _request: JoinedContextPreparationRequest, - ) -> Result, ActivityError> { + ) -> Result, ActivityError> { unimplemented!("workflow activity definition only") } @@ -115,7 +115,7 @@ impl WorkflowActivities { pub async fn append_events( _ctx: ActivityContext, _request: AppendEventsRequest, - ) -> Result { + ) -> Result { unimplemented!("workflow activity definition only") } @@ -169,7 +169,7 @@ impl WorkflowActivities { pub async fn tool_prepare_promise_controls( _ctx: ActivityContext, _request: ToolPreparePromiseControlsActivityRequest, - ) -> Result { + ) -> Result { unimplemented!("workflow activity definition only") } @@ -231,7 +231,7 @@ impl WorkflowActivities { /// Bounded CAS load + JSON Schema check of one keyed reply payload /// against the binding's immutable reply schema. The deterministic - /// engine never performs CAS I/O; a receiver cannot bypass reply + /// harness never performs CAS I/O; a receiver cannot bypass reply /// validation by returning an arbitrary blob reference. #[activity(name = ACTIVITY_VALIDATE_WORKFLOW_TOOL_REPLY)] pub async fn validate_workflow_tool_reply( @@ -289,7 +289,7 @@ impl WorkflowActivities { pub async fn subagent_resolve( _ctx: ActivityContext, _request: SubagentResolveActivityRequest, - ) -> Result { + ) -> Result { unimplemented!("workflow activity definition only") } diff --git a/crates/temporal-workflow/src/config.rs b/crates/temporal-workflow/src/config.rs index 4a0e667eb..229e49129 100644 --- a/crates/temporal-workflow/src/config.rs +++ b/crates/temporal-workflow/src/config.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use engine::{ModelSelection, RunConfig, SessionConfig, ToolExecutionClass, ToolExecutionSpec}; +use harness::{ModelSelection, RunConfig, SessionConfig, ToolExecutionClass, ToolExecutionSpec}; use temporalio_common::protos::temporal::api::common::v1::RetryPolicy; use temporalio_sdk::{ActivityCloseTimeouts, ActivityOptions}; @@ -43,7 +43,9 @@ pub fn default_instructions() -> &'static str { } pub fn activity_options() -> ActivityOptions { - ActivityOptions::start_to_close_timeout(DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT) + ActivityOptions::with_start_to_close_timeout(DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) + .build() } // Tool execution classes. Every tool activity carries a bounded @@ -71,7 +73,7 @@ pub const TOOL_REMOTE_SCHEDULE_TO_CLOSE: Duration = Duration::from_secs(600); /// Deployment-owned ceiling on a validated `run_process` timeout. The worker /// clamps requested process timeouts to the same ceiling /// (`tools::ToolLimits::max_process_timeout_ms`, asserted equal by a -/// temporal-server test); the process activity deadline derives from it. +/// temporal-runtime test); the process activity deadline derives from it. pub const PROCESS_TIMEOUT_CEILING: Duration = Duration::from_secs(30 * 60); /// Transport/completion grace added on top of the process timeout ceiling. pub const TOOL_PROCESS_GRACE: Duration = Duration::from_secs(60); @@ -102,12 +104,13 @@ pub const MAX_CONCURRENT_TOOL_CALLS_PER_BATCH: usize = 8; /// Bounded options for materializing a boundary-failure error blob. The /// failure-conversion path must never reintroduce Temporal's default /// unlimited retries; when these attempts are exhausted the workflow falls -/// back to the engine's well-known boundary-failure blob. +/// back to the harness's well-known boundary-failure blob. pub fn boundary_error_blob_activity_options() -> ActivityOptions { - ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close: Duration::from_secs(30), schedule_to_close: Duration::from_secs(120), }) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(tool_retry_policy(TOOL_RETRY_SAFE_MAX_ATTEMPTS)) .build() } @@ -146,11 +149,12 @@ pub const ACTIVITY_CANCELLATION_HEARTBEAT_INTERVAL: Duration = Duration::from_se /// default unlimited retries. Heartbeated so the session workflow can cancel /// an in-flight generation. pub fn llm_activity_options() -> ActivityOptions { - ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close: LLM_START_TO_CLOSE, schedule_to_close: LLM_SCHEDULE_TO_CLOSE, }) .heartbeat_timeout(ACTIVITY_CANCELLATION_HEARTBEAT_TIMEOUT) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(RetryPolicy { initial_interval: Some( LLM_RETRY_INITIAL_INTERVAL @@ -226,11 +230,12 @@ pub fn tool_call_activity_options(execution: ToolExecutionSpec) -> ActivityOptio } else { 1 }; - ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close, schedule_to_close, }) .heartbeat_timeout(ACTIVITY_CANCELLATION_HEARTBEAT_TIMEOUT) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(tool_retry_policy(max_attempts)) .build() } @@ -240,11 +245,12 @@ pub fn tool_call_activity_options(execution: ToolExecutionSpec) -> ActivityOptio /// failures. Never Temporal's default unlimited retries. pub fn environment_ready_activity_options() -> ActivityOptions { let start_to_close = ENVIRONMENT_READY_WAIT + ENVIRONMENT_READY_GRACE; - ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close, schedule_to_close: start_to_close * 2, }) .heartbeat_timeout(ENVIRONMENT_READY_HEARTBEAT_TIMEOUT) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(tool_retry_policy(TOOL_RETRY_SAFE_MAX_ATTEMPTS)) .build() } @@ -253,11 +259,12 @@ pub fn environment_ready_activity_options() -> ActivityOptions { /// workflow-tool batches execute as one unit). Bounded: one attempt and an /// explicit total deadline, never Temporal's default unlimited retries. pub fn tool_batch_activity_options() -> ActivityOptions { - ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close: DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT, schedule_to_close: DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT + Duration::from_secs(60), }) .heartbeat_timeout(ACTIVITY_CANCELLATION_HEARTBEAT_TIMEOUT) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(tool_retry_policy(1)) .build() } @@ -295,7 +302,7 @@ mod tests { fn tool_call_options_keep_the_deadline_invariant_for_every_class() { for execution in all_execution_specs() { let options = tool_call_activity_options(execution); - let ActivityCloseTimeouts::Both { + let ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close, schedule_to_close, } = options.close_timeouts @@ -317,7 +324,7 @@ mod tests { #[test] fn environment_ready_options_are_heartbeated_bounded_and_leave_tool_classes_alone() { let options = environment_ready_activity_options(); - let ActivityCloseTimeouts::Both { + let ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close, schedule_to_close, } = options.close_timeouts @@ -332,7 +339,7 @@ mod tests { ); assert!(ENVIRONMENT_READY_POLL_INTERVAL < ENVIRONMENT_READY_HEARTBEAT_TIMEOUT); let retry = options.retry_policy.expect("bounded retry policy"); - assert!(retry.maximum_attempts > 0); + assert!(retry.raw().maximum_attempts > 0); // The readiness wait must not have loosened the per-class tool // deadlines: interactive calls stay well below the wait window. assert!(TOOL_INTERACTIVE_START_TO_CLOSE < ENVIRONMENT_READY_WAIT); @@ -354,26 +361,29 @@ mod tests { } else { 1 }; - assert_eq!(retry.maximum_attempts, expected, "{execution:?}"); + assert_eq!(retry.raw().maximum_attempts, expected, "{execution:?}"); } let batch_retry = tool_batch_activity_options() .retry_policy .expect("batch options declare a retry policy"); - assert_eq!(batch_retry.maximum_attempts, 1); + assert_eq!(batch_retry.raw().maximum_attempts, 1); let blob_retry = boundary_error_blob_activity_options() .retry_policy .expect("boundary blob options declare a retry policy"); - assert_eq!(blob_retry.maximum_attempts, TOOL_RETRY_SAFE_MAX_ATTEMPTS); + assert_eq!( + blob_retry.raw().maximum_attempts, + TOOL_RETRY_SAFE_MAX_ATTEMPTS + ); assert!(matches!( boundary_error_blob_activity_options().close_timeouts, - ActivityCloseTimeouts::Both { .. } + ActivityCloseTimeouts::ScheduleAndStartToClose { .. } )); } #[test] fn llm_options_keep_the_deadline_invariant_and_a_bounded_retry_policy() { let options = llm_activity_options(); - let ActivityCloseTimeouts::Both { + let ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close, schedule_to_close, } = options.close_timeouts @@ -390,10 +400,10 @@ mod tests { let retry = options .retry_policy .expect("llm options declare a retry policy"); - assert_eq!(retry.maximum_attempts, LLM_RETRY_MAX_ATTEMPTS); - assert!(retry.maximum_attempts > 1); + assert_eq!(retry.raw().maximum_attempts, LLM_RETRY_MAX_ATTEMPTS); + assert!(retry.raw().maximum_attempts > 1); assert_eq!( - retry.maximum_interval, + retry.raw().maximum_interval, Some( LLM_RETRY_MAX_INTERVAL .try_into() @@ -405,7 +415,7 @@ mod tests { #[test] fn retry_safe_calls_get_headroom_for_their_attempts() { let execution = ToolExecutionSpec::new(ToolExecutionClass::Interactive, true); - let ActivityCloseTimeouts::Both { + let ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close, schedule_to_close, } = tool_call_activity_options(execution).close_timeouts diff --git a/crates/temporal-workflow/src/rehydrate.rs b/crates/temporal-workflow/src/rehydrate.rs index 1846c00b9..046d86266 100644 --- a/crates/temporal-workflow/src/rehydrate.rs +++ b/crates/temporal-workflow/src/rehydrate.rs @@ -10,7 +10,7 @@ use std::collections::BTreeMap; -use engine::{ +use harness::{ CoreAgentCodec, CoreAgentEntry, CoreAgentEvent, CoreAgentState, RunEvent, SubmissionId, storage::StoredSessionEntry, }; @@ -86,14 +86,14 @@ pub fn accumulate_session_entry( .run_submissions .insert(accepted.run_id.as_u64(), accepted.submission_id.clone()); } - engine::apply_event(&mut reduced.core_state, entry) + harness::apply_event(&mut reduced.core_state, entry) .map_err(|error| RehydrateError::Apply(error.to_string())) } #[cfg(test)] mod tests { use super::*; - use engine::{ + use harness::{ CoreAgentEntry, CoreAgentJoins, CoreAgentLifecycleEvent, EventSeq, ModelSelection, ProviderApiKind, SessionPosition, }; diff --git a/crates/temporal-workflow/src/session_preparation.rs b/crates/temporal-workflow/src/session_preparation.rs index d2bd1dba2..07aa96567 100644 --- a/crates/temporal-workflow/src/session_preparation.rs +++ b/crates/temporal-workflow/src/session_preparation.rs @@ -1,6 +1,6 @@ //! Durable session preparation requests. These carry intent and references, //! never credentials or provider transport payloads. -use engine::{ +use harness::{ CoreAgentState, SessionConfig, SessionId, ToolName, ToolSpec, WorkflowToolBinding, WorkflowToolDeclaration, WorkflowToolId, }; @@ -33,16 +33,16 @@ impl SessionToolsetSource { /// attaches, in document order and without repeats: what must exist in the /// universe when the configuration is admitted. A snapshot attachment names /// immutable content, not a resource, and is admitted as content instead. -pub fn attached_resources(features: &engine::FeaturesConfig) -> Vec { +pub fn attached_resources(features: &harness::FeaturesConfig) -> Vec { let workspaces = features .vfs .iter() .flat_map(|vfs| &vfs.workspaces) .filter_map(|attachment| match &attachment.target { - engine::WorkspaceAttachmentTarget::Workspace { workspace_id } => { + harness::WorkspaceAttachmentTarget::Workspace { workspace_id } => { Some(api::ResourceRef::Workspace(workspace_id.clone())) } - engine::WorkspaceAttachmentTarget::Snapshot { .. } => None, + harness::WorkspaceAttachmentTarget::Snapshot { .. } => None, }); let environments = features .environments @@ -72,7 +72,7 @@ pub struct SessionToolsetPreparation { /// The resolved profile is captured at submission so workflow retries do not /// reread a mutable named profile. Configuration has already been translated -/// into the engine's provider-neutral document. +/// into the harness's provider-neutral document. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct SessionProfileIntent { pub config: Option, @@ -80,7 +80,7 @@ pub struct SessionProfileIntent { /// The environment to activate when the session has none after the /// configuration is applied: the config's default attachment, or a /// creation-time override. Never overrides a live selection. - pub environment: Option, + pub environment: Option, } impl SessionProfileIntent { @@ -90,7 +90,7 @@ impl SessionProfileIntent { pub(crate) fn environment_to_prepare( &self, state: &CoreAgentState, - ) -> Option { + ) -> Option { let config = self.config.as_ref().or(state.lifecycle.config.as_ref()); let retains_active = state .environment @@ -217,16 +217,16 @@ pub struct SessionProfilePreparationRequest { pub instructions: Option, /// Candidate to fill an empty active pointer; must be attached in the /// source configuration and selectable in the registry. - pub environment: Option, + pub environment: Option, pub source: SessionToolsetSource, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct SessionProfilePreparation { pub toolset: SessionToolsetPreparation, - pub instructions: BTreeMap, + pub instructions: BTreeMap, /// The validated fill candidate; applied only while nothing is active. - pub environment_id: Option, + pub environment_id: Option, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -237,10 +237,10 @@ pub struct SessionToolsetRequest { /// Compute a minimal patch from the currently published tools to an observed desired set. pub fn session_toolset_patch( - active: &BTreeMap, - desired: &BTreeMap, -) -> engine::ToolPatch { - engine::ToolPatch { + active: &BTreeMap, + desired: &BTreeMap, +) -> harness::ToolPatch { + harness::ToolPatch { remove: active .keys() .filter(|name| !desired.contains_key(*name)) @@ -257,22 +257,22 @@ pub fn session_toolset_patch( #[cfg(test)] mod tests { use super::*; - use engine::BlobRef; + use harness::BlobRef; #[test] fn profile_preparation_omits_unused_defaults_and_prepares_replacements() { - let mut config = crate::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + let mut config = crate::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".into(), model: "test".into(), }); - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { environments: ["active", "default"] .into_iter() - .map(|id| engine::EnvironmentAttachment { + .map(|id| harness::EnvironmentAttachment { environment_id: id.into(), default: id == "default", - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }) .collect(), @@ -280,13 +280,13 @@ mod tests { }); let mut state = CoreAgentState::new(); state.lifecycle.config = Some(config.clone()); - state.environment.active_environment_id = Some(engine::EnvironmentId::new("active")); + state.environment.active_environment_id = Some(harness::EnvironmentId::new("active")); let mut profile = SessionProfileIntent { config: Some(config), instructions: Some(api::ProfileInstructions::Text { text: "updated instructions".into(), }), - environment: Some(engine::EnvironmentId::new("default")), + environment: Some(harness::EnvironmentId::new("default")), }; // The preparation activity receives no candidate, so it cannot try // to select a closed or missing default when the active item survives. @@ -314,44 +314,44 @@ mod tests { #[test] fn attached_resources_name_each_workspace_environment_and_server_once() { - let features = engine::FeaturesConfig { - vfs: Some(engine::VfsFeature { + let features = harness::FeaturesConfig { + vfs: Some(harness::VfsFeature { workspaces: vec![ - engine::WorkspaceAttachment { + harness::WorkspaceAttachment { path: "/repo".into(), - target: engine::WorkspaceAttachmentTarget::Workspace { + target: harness::WorkspaceAttachmentTarget::Workspace { workspace_id: "repo".into(), }, - access: engine::WorkspaceAccess::Edit, + access: harness::WorkspaceAccess::Edit, }, - engine::WorkspaceAttachment { + harness::WorkspaceAttachment { path: "/pinned".into(), - target: engine::WorkspaceAttachmentTarget::Snapshot { + target: harness::WorkspaceAttachmentTarget::Snapshot { snapshot_ref: format!("sha256:{}", "a".repeat(64)), }, - access: engine::WorkspaceAccess::Read, + access: harness::WorkspaceAccess::Read, }, - engine::WorkspaceAttachment { + harness::WorkspaceAttachment { path: "/repo-again".into(), - target: engine::WorkspaceAttachmentTarget::Workspace { + target: harness::WorkspaceAttachmentTarget::Workspace { workspace_id: "repo".into(), }, - access: engine::WorkspaceAccess::Read, + access: harness::WorkspaceAccess::Read, }, ], ..Default::default() }), - environments: Some(engine::EnvironmentsFeature { - environments: vec![engine::EnvironmentAttachment { + environments: Some(harness::EnvironmentsFeature { + environments: vec![harness::EnvironmentAttachment { environment_id: "prod-1".into(), default: true, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }], ..Default::default() }), - mcp: Some(engine::McpFeature { - servers: vec![engine::McpServerAttachment { + mcp: Some(harness::McpFeature { + servers: vec![harness::McpServerAttachment { server_id: "crm".into(), tools: None, }], @@ -369,7 +369,7 @@ mod tests { api::ResourceRef::McpServer("crm".into()), ] ); - assert!(attached_resources(&engine::FeaturesConfig::default()).is_empty()); + assert!(attached_resources(&harness::FeaturesConfig::default()).is_empty()); } fn operation(id: usize, submitted_at_ms: u64) -> SessionOperationRequest { @@ -555,19 +555,19 @@ mod tests { let call_tool_name = ToolName::new("mcp_call"); let mut inject_all = test_remote_mcp_tool(remote_tool_name.clone()); - let engine::ToolKind::RemoteMcp(spec) = &mut inject_all.kind else { + let harness::ToolKind::RemoteMcp(spec) = &mut inject_all.kind else { unreachable!("test helper must produce a remote MCP tool"); }; - spec.execution = engine::RemoteMcpExecution::Native; + spec.execution = harness::RemoteMcpExecution::Native; let mut active = BTreeMap::from([(remote_tool_name.clone(), inject_all)]); let mut search_selected = test_remote_mcp_tool(remote_tool_name.clone()); - let engine::ToolKind::RemoteMcp(spec) = &mut search_selected.kind else { + let harness::ToolKind::RemoteMcp(spec) = &mut search_selected.kind else { unreachable!("test helper must produce a remote MCP tool"); }; spec.record_revision = 2; - spec.execution = engine::RemoteMcpExecution::Native; - spec.exposure = engine::RemoteMcpExposure::Search; + spec.execution = harness::RemoteMcpExecution::Native; + spec.exposure = harness::RemoteMcpExposure::Search; spec.allowed_tools = Some(vec!["lookup_customer".to_owned()]); let desired = BTreeMap::from([ (remote_tool_name.clone(), search_selected), @@ -585,14 +585,14 @@ mod tests { .expect("switch inject-all to search-selected"); assert!(active.contains_key(&find_tool_name)); assert!(active.contains_key(&call_tool_name)); - let engine::ToolKind::RemoteMcp(spec) = &active[&remote_tool_name].kind else { + let harness::ToolKind::RemoteMcp(spec) = &active[&remote_tool_name].kind else { panic!("expected remote MCP tool"); }; - assert_eq!(spec.exposure, engine::RemoteMcpExposure::Search); + assert_eq!(spec.exposure, harness::RemoteMcpExposure::Search); assert_eq!(spec.allowed_tools, Some(vec!["lookup_customer".to_owned()])); let mut search_other_selection = active[&remote_tool_name].clone(); - let engine::ToolKind::RemoteMcp(spec) = &mut search_other_selection.kind else { + let harness::ToolKind::RemoteMcp(spec) = &mut search_other_selection.kind else { unreachable!("expected remote MCP tool"); }; spec.record_revision = 3; @@ -605,17 +605,17 @@ mod tests { active = session_toolset_patch(&active, &desired) .apply_to(&active) .expect("change selected search tools"); - let engine::ToolKind::RemoteMcp(spec) = &active[&remote_tool_name].kind else { + let harness::ToolKind::RemoteMcp(spec) = &active[&remote_tool_name].kind else { panic!("expected remote MCP tool"); }; assert_eq!(spec.allowed_tools, Some(vec!["create_customer".to_owned()])); let mut inject_selected = active[&remote_tool_name].clone(); - let engine::ToolKind::RemoteMcp(spec) = &mut inject_selected.kind else { + let harness::ToolKind::RemoteMcp(spec) = &mut inject_selected.kind else { unreachable!("expected remote MCP tool"); }; spec.record_revision = 4; - spec.exposure = engine::RemoteMcpExposure::Inject; + spec.exposure = harness::RemoteMcpExposure::Inject; let desired = BTreeMap::from([(remote_tool_name.clone(), inject_selected)]); active = session_toolset_patch(&active, &desired) .apply_to(&active) @@ -624,7 +624,7 @@ mod tests { assert!(!active.contains_key(&call_tool_name)); let mut inject_all = active[&remote_tool_name].clone(); - let engine::ToolKind::RemoteMcp(spec) = &mut inject_all.kind else { + let harness::ToolKind::RemoteMcp(spec) = &mut inject_all.kind else { unreachable!("expected remote MCP tool"); }; spec.record_revision = 5; @@ -633,48 +633,48 @@ mod tests { active = session_toolset_patch(&active, &desired) .apply_to(&active) .expect("switch inject-selected to inject-all"); - let engine::ToolKind::RemoteMcp(spec) = &active[&remote_tool_name].kind else { + let harness::ToolKind::RemoteMcp(spec) = &active[&remote_tool_name].kind else { panic!("expected remote MCP tool"); }; - assert_eq!(spec.exposure, engine::RemoteMcpExposure::Inject); + assert_eq!(spec.exposure, harness::RemoteMcpExposure::Inject); assert_eq!(spec.allowed_tools, None); } - fn test_remote_mcp_tool(tool_name: ToolName) -> engine::ToolSpec { - engine::ToolSpec { + fn test_remote_mcp_tool(tool_name: ToolName) -> harness::ToolSpec { + harness::ToolSpec { name: tool_name, execution: Default::default(), - kind: engine::ToolKind::RemoteMcp(engine::RemoteMcpToolSpec { + kind: harness::ToolKind::RemoteMcp(harness::RemoteMcpToolSpec { server_id: "crm".to_owned(), record_revision: 1, server_label: "crm".to_owned(), server_url: "https://crm.example.com/mcp".to_owned(), description_ref: None, allowed_tools: None, - execution: engine::RemoteMcpExecution::Provider, - exposure: engine::RemoteMcpExposure::Inject, - approval: engine::RemoteMcpApprovalPolicy::Never, + execution: harness::RemoteMcpExecution::Provider, + exposure: harness::RemoteMcpExposure::Inject, + approval: harness::RemoteMcpApprovalPolicy::Never, defer_loading: None, auth_ref: None, auth_required: false, allow_private_network: false, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, } } - fn test_function_tool(tool_name: ToolName) -> engine::ToolSpec { - engine::ToolSpec { + fn test_function_tool(tool_name: ToolName) -> harness::ToolSpec { + harness::ToolSpec { name: tool_name, execution: Default::default(), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: None, input_schema_ref: BlobRef::from_bytes(b"schema"), output_schema_ref: None, strict: Some(true), provider_options_ref: None, }), - parallelism: engine::ToolParallelism::Exclusive, + parallelism: harness::ToolParallelism::Exclusive, } } } diff --git a/crates/temporal-workflow/src/temporal_helpers.rs b/crates/temporal-workflow/src/temporal_helpers.rs index 2cbb2bd18..b4c443e22 100644 --- a/crates/temporal-workflow/src/temporal_helpers.rs +++ b/crates/temporal-workflow/src/temporal_helpers.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use temporalio_client::{Client, ClientOptions, Connection, ConnectionOptions}; -use temporalio_sdk_core::Url; +use url::Url; pub async fn connect_temporal(target_url: &str, namespace: &str) -> anyhow::Result { let connection_options = ConnectionOptions::new(temporal_target_url(target_url)?).build(); diff --git a/crates/temporal-workflow/src/types.rs b/crates/temporal-workflow/src/types.rs index 1d2f15567..48f61686f 100644 --- a/crates/temporal-workflow/src/types.rs +++ b/crates/temporal-workflow/src/types.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use engine::{ +use harness::{ BlobRef, CommandRejection, ContextEntryInput, CoreAgentCommand, CoreAgentState, EmissionEnvelope, ManagedSessionWorkflowTools, RunStatus, SessionConfig, SessionId, SessionPosition, SubmissionId, ToolBatchId, @@ -164,7 +164,7 @@ pub struct AgentActiveRunSummary { pub run_id: u64, pub status: RunStatus, pub submission_id: Option, - pub output: Option, + pub output: Option, pub active_turn_id: Option, pub active_tool_batch_id: Option, } @@ -181,7 +181,7 @@ pub struct AgentCompletedRunSummary { pub run_id: u64, pub status: RunStatus, pub submission_id: Option, - pub output: Option, + pub output: Option, pub failure_message_ref: Option, } @@ -217,7 +217,7 @@ impl PendingEmission { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PendingPromiseCancellation { pub promise_id: String, - pub source: engine::PromiseSource, + pub source: harness::PromiseSource, /// Log sequence of the cancellation event, used as the emission /// producer sequence for per-key workflow-tool cancellation facts. #[serde(default)] @@ -229,9 +229,9 @@ pub struct PendingPromiseCancellation { /// admission. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PendingSourceResolution { - pub promise_id: engine::PromiseId, - pub resolution: engine::PromiseResolution, - pub producer: engine::EmissionProducer, + pub promise_id: harness::PromiseId, + pub resolution: harness::PromiseResolution, + pub producer: harness::EmissionProducer, } /// Fixed, versioned recovery query every start-on-call plugin workflow must @@ -245,7 +245,7 @@ pub const WORKFLOW_TOOL_RECOVERY_QUERY: &str = "workflow_tool_recovery"; #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, schemars::JsonSchema)] pub struct WorkflowToolRecoveryResult { #[serde(default)] - pub resolutions: BTreeMap, + pub resolutions: BTreeMap, } /// Start arguments every start-on-call plugin workflow receives. The plugin @@ -257,7 +257,7 @@ pub struct WorkflowToolStartArgs { pub universe_id: uuid::Uuid, pub holder_workflow_id: String, pub execution_id: String, - pub invocation: engine::WorkflowToolInvocation, + pub invocation: harness::WorkflowToolInvocation, } /// Prefix of every start-on-call recipe fingerprint. @@ -292,10 +292,10 @@ pub struct WorkflowToolStartActivityRequest { pub execution_id: String, pub recipe_format: u32, pub recipe_revision: u32, - pub recipe_ref: engine::BlobRef, + pub recipe_ref: harness::BlobRef, pub recipe_fingerprint: String, pub holder_workflow_id: String, - pub invocation: engine::WorkflowToolInvocation, + pub invocation: harness::WorkflowToolInvocation, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -324,21 +324,21 @@ pub struct WorkflowToolExecutionCancelRequest { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct WorkflowToolReplyValidationRequest { - pub reply_schema_ref: engine::BlobRef, - pub payload_ref: Option, + pub reply_schema_ref: harness::BlobRef, + pub payload_ref: Option, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case", tag = "kind")] pub enum WorkflowToolReplyValidationResult { Valid, - Invalid { error_ref: engine::BlobRef }, + Invalid { error_ref: harness::BlobRef }, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PromiseSourcePoll { pub promise_id: String, - pub source: engine::PromiseSource, + pub source: harness::PromiseSource, pub next_check_at_ms: u64, pub poll_attempt: u32, } @@ -358,9 +358,9 @@ pub struct JoinedContextPreparationRequest { pub struct AwaitMaterializationResult { pub result_ref: BlobRef, #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub additional_context: Vec, + pub additional_context: Vec, #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub attachments: Vec, + pub attachments: Vec, } /// Bounded, ref-only snapshot passed to the storage-backed await materializer. @@ -413,7 +413,7 @@ pub struct AwaitPromiseResult { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PendingToolBatchResume { pub batch_id: ToolBatchId, - pub command: engine::ResumeToolBatchCommand, + pub command: harness::ResumeToolBatchCommand, } /// Armed while the active run sits in `cancelling`; the workflow forces the @@ -464,7 +464,7 @@ pub struct EnvironmentJobWorkflowArgs { #[serde(default, skip_serializing_if = "Vec::is_empty")] pub jobs: Vec, #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub resolutions: BTreeMap, + pub resolutions: BTreeMap, #[serde(default = "default_environment_job_poll_ms")] pub poll_ms: u64, #[serde(default)] @@ -476,7 +476,7 @@ pub struct EnvironmentJobWorkflowArgs { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct EnvironmentJobWorkflowToolContext { pub execution_id: String, - pub invocation_id: engine::WorkflowToolInvocationId, + pub invocation_id: harness::WorkflowToolInvocationId, } /// Accepted inputs for the core job workflow. Bare public starts arrive as @@ -531,8 +531,8 @@ pub struct SubagentChildRef { #[serde(rename_all = "snake_case", tag = "kind")] pub enum SubagentTerminal { Run { - status: engine::RunStatus, - output: Option, + status: harness::RunStatus, + output: Option, failure_message_ref: Option, }, Deadline, @@ -568,7 +568,7 @@ pub struct SubagentExecutionSnapshot { #[serde(default, skip_serializing_if = "Option::is_none")] pub child: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub resolution: Option, + pub resolution: Option, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -589,7 +589,7 @@ pub struct EnvironmentJobWorkflowSnapshot { #[serde(default)] pub jobs: Vec, #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub resolutions: BTreeMap, + pub resolutions: BTreeMap, pub terminal: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub last_error: Option, @@ -607,7 +607,7 @@ pub struct EnvironmentJobPollActivityRequest { pub struct EnvironmentJobPollActivityResult { pub jobs: Vec, #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub resolutions: BTreeMap, + pub resolutions: BTreeMap, pub terminal: bool, } @@ -738,22 +738,22 @@ pub struct AppendEventsRequest { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct LlmGenerateActivityRequest { - pub request: engine::LlmGenerationRequest, + pub request: harness::LlmGenerationRequest, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ContextCompactActivityRequest { - pub request: engine::ContextCompactionRequest, + pub request: harness::ContextCompactionRequest, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ToolInvokeBatchActivityRequest { - pub request: engine::ToolInvocationBatchRequest, + pub request: harness::ToolInvocationBatchRequest, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ToolInvokeCallActivityRequest { - pub request: engine::ToolInvocationCallRequest, + pub request: harness::ToolInvocationCallRequest, } /// Outcome of one per-call tool activity. @@ -762,7 +762,7 @@ pub struct ToolInvokeCallActivityRequest { pub enum ToolInvokeCallActivityResult { /// The call ran (or failed at tool level) and produced a terminal result. Completed { - result: engine::ToolInvocationResult, + result: harness::ToolInvocationResult, }, /// The call did not execute: the session's active environment is still /// provisioning or booting. The workflow waits for readiness with @@ -770,7 +770,7 @@ pub enum ToolInvokeCallActivityResult { EnvironmentNotReady { environment_id: String }, /// The native MCP call must receive a single-use run-owned decision /// before the worker performs any MCP wire I/O. - NeedsApproval { subject: engine::ApprovalSubject }, + NeedsApproval { subject: harness::ApprovalSubject }, } /// Wait for the session's active environment to become reachable. @@ -779,7 +779,7 @@ pub struct AwaitEnvironmentReadyActivityRequest { pub session_id: SessionId, pub environment_id: String, #[serde(default, skip_serializing_if = "Option::is_none")] - pub environment_policy: Option, + pub environment_policy: Option, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -800,32 +800,32 @@ pub enum AwaitEnvironmentReadyActivityResult { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ToolPreparePromiseControlsActivityRequest { - pub request: engine::PromiseControlArgumentRequest, + pub request: harness::PromiseControlArgumentRequest, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct RuntimeProjectionRefreshActivityRequest { #[serde(default, skip_serializing_if = "Option::is_none")] - pub environments: Option, + pub environments: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub active_environment_id: Option, + pub active_environment_id: Option, pub session_id: SessionId, #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub workspace_attachments: Vec, + pub workspace_attachments: Vec, pub vfs_catalog_enabled: bool, pub vfs_prompts_enabled: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub vfs_prompt_roots: Option>, #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub active_instruction_inputs: BTreeMap, + pub active_instruction_inputs: BTreeMap, #[serde(default, skip_serializing_if = "Option::is_none")] - pub vfs_skills: Option, + pub vfs_skills: Option, /// Current keyed catalogs, including source provenance, for publication comparison. #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub active_catalogs: BTreeMap, + pub active_catalogs: BTreeMap, /// The admitted sub-agent grant; the catalog entry follows it. #[serde(default, skip_serializing_if = "Option::is_none")] - pub subagents: Option, + pub subagents: Option, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] diff --git a/crates/temporal-workflow/src/workflow_contract.rs b/crates/temporal-workflow/src/workflow_contract.rs index 1861c69cf..8a5ca4491 100644 --- a/crates/temporal-workflow/src/workflow_contract.rs +++ b/crates/temporal-workflow/src/workflow_contract.rs @@ -16,7 +16,7 @@ use std::collections::BTreeMap; -use engine::{ +use harness::{ BlobRef, EMISSION_HASH_DOMAIN, EMISSION_ID_PREFIX, EmissionEnvelope, EmissionId, EventSeq, PromiseId, PromiseResolution, REPLY_COMPLETION_KEY, RunId, RunStatus, SessionId, ToolBatchId, ToolCallId, TurnId, WORKFLOW_TOOL_EXECUTION_KIND, WorkflowToolId, WorkflowToolInvocation, @@ -220,7 +220,7 @@ fn vectors() -> Value { VECTOR_TOKEN.to_owned(), run_id, RunStatus::Completed, - Some(engine::ContentRef::text(BlobRef::from_bytes(b"output"))), + Some(harness::ContentRef::text(BlobRef::from_bytes(b"output"))), None, ), EmissionEnvelope::source_resolution( @@ -310,7 +310,7 @@ fn reference(definitions: &BTreeMap) -> String { format!( r#"# Lightspeed Workflow Contract -Generated from the Rust contract types in `engine` and `temporal-workflow`. +Generated from the Rust contract types in `harness` and `temporal-workflow`. Type shapes live in `workflow.schema.json`; constants and known-answer vectors live in `workflow.json`. Regenerate both artifacts and this reference with: diff --git a/crates/temporal-workflow/src/workflows/bots/activities.rs b/crates/temporal-workflow/src/workflows/bots/activities.rs index a4e846dda..c11817b23 100644 --- a/crates/temporal-workflow/src/workflows/bots/activities.rs +++ b/crates/temporal-workflow/src/workflows/bots/activities.rs @@ -1,5 +1,5 @@ //! Activity definitions of the `bots` worker role. Definition only: the -//! implementations live in `temporal-server::worker::bots` and must keep +//! implementations live in `temporal-runtime::worker::bots` and must keep //! these names (a test there asserts they match). use temporalio_macros::activities; @@ -169,7 +169,7 @@ impl BotActivities { } /// Put the `bot:directory` catalog into the session before a delivery - /// (same content is an engine no-op, so the prefix cache holds). + /// (same content is an harness no-op, so the prefix cache holds). #[activity(name = ACTIVITY_BOT_PUBLISH_DIRECTORY)] pub async fn publish_directory( _ctx: ActivityContext, diff --git a/crates/temporal-workflow/src/workflows/bots/controller.rs b/crates/temporal-workflow/src/workflows/bots/controller.rs index b0693fe81..bf379b116 100644 --- a/crates/temporal-workflow/src/workflows/bots/controller.rs +++ b/crates/temporal-workflow/src/workflows/bots/controller.rs @@ -15,6 +15,7 @@ mod lanes; mod state; +use crate::workflows::WorkflowContextExt as _; use std::collections::BTreeMap; use std::future::Future; use std::pin::Pin; @@ -27,9 +28,9 @@ use bots::{ BOT_CONFIG_SIGNAL, BOT_EVENT_SIGNAL, BOT_SESSION_ROTATE_SIGNAL, BOT_STATE_QUERY, BotControllerConfig, BotEvent, BotSessionRotate, }; -use engine::{EmissionEnvelope, WorkflowEndpointRef}; use futures::future::poll_fn; use futures::{FutureExt, pin_mut, select}; +use harness::{EmissionEnvelope, WorkflowEndpointRef}; use serde::{Deserialize, Serialize}; use temporalio_macros::{workflow, workflow_methods}; use temporalio_sdk::{ @@ -101,7 +102,7 @@ pub struct BotControllerCarry { pub tools_revision: Option, } -#[workflow(name = "BotControllerWorkflow")] +#[workflow] pub struct BotControllerWorkflow { state: ControllerState, } @@ -139,7 +140,7 @@ impl BotControllerWorkflow { #[init] pub fn new(ctx: &WorkflowContextView, args: BotControllerArgs) -> Self { let now = ctx - .start_time + .start_time() .and_then(|time| time.duration_since(UNIX_EPOCH).ok()) .map(|elapsed| elapsed.as_millis() as i64) .unwrap_or(0); @@ -148,7 +149,7 @@ impl BotControllerWorkflow { } } - #[run] + #[run(name = "BotControllerWorkflow")] pub async fn run(ctx: &mut WorkflowContext) -> WorkflowResult<()> { run_controller(ctx).await } @@ -274,12 +275,14 @@ async fn park(ctx: &Ctx, lanes: &mut Vec) { let now = now_ms(ctx); let (lane_tick, event_tick, deadline) = ctx.state(|state| (state.lane_tick, state.event_tick, state.wake_deadline(now))); - let wait = ctx.wait_condition(move |state| state.wake_ready(lane_tick, event_tick)); + let wait = ctx.wait_for_state(move |state| state.wake_ready(lane_tick, event_tick)); match deadline { None => with_lanes(lanes, wait).await, Some(deadline) => { let timer = ctx - .timer(Duration::from_millis((deadline - now).max(1) as u64)) + .timer_with_manual_cancellation(Duration::from_millis( + (deadline - now).max(1) as u64 + )) .fuse(); with_lanes(lanes, async move { pin_mut!(wait, timer); @@ -330,7 +333,7 @@ fn request_continue_as_new(ctx: &Ctx) -> WorkflowResult<()> { config: state.config.clone(), carry: Some(state.carry()), }); - match ctx.continue_as_new(&args, ContinueAsNewOptions::default()) { + match ctx.continue_as_new(args, ContinueAsNewOptions::default()) { Ok(never) => match never {}, Err(termination) => Err(termination), } @@ -368,7 +371,7 @@ pub(super) async fn activity( definition: AD, input: AD::Input, ) -> Result { - ctx.start_activity(definition, input, bot_activity_options()) + ctx.execute_activity(definition, input, bot_activity_options()) .await .map_err(|error| error.to_string()) } @@ -614,7 +617,8 @@ pub(super) async fn wait_until_session_idle(ctx: &Ctx, target: &str) -> Result<( BotSessionStatus::Closed => return Err(format!("session {target} is closed")), BotSessionStatus::Missing => return Err(format!("session {target} is missing")), } - ctx.timer(BOT_BUSY_RETRY_DELAY).await; + ctx.timer_with_manual_cancellation(BOT_BUSY_RETRY_DELAY) + .await; } } diff --git a/crates/temporal-workflow/src/workflows/bots/controller/lanes.rs b/crates/temporal-workflow/src/workflows/bots/controller/lanes.rs index 927c564fc..38059172b 100644 --- a/crates/temporal-workflow/src/workflows/bots/controller/lanes.rs +++ b/crates/temporal-workflow/src/workflows/bots/controller/lanes.rs @@ -3,10 +3,11 @@ //! Each lane owns a context clone, finishes its own bookkeeping, and //! records failures on the controller instead of failing the workflow. +use crate::workflows::WorkflowContextExt as _; use api::{BotEventOutcome, BotRecentDeliverySnapshot, LlmUsageView}; use bots::{BotDeliveryPhase, RoutedSession, ids}; -use engine::{BlobRef, EmissionEnvelope, PromiseResolution, REPLY_COMPLETION_KEY}; use futures::{FutureExt, pin_mut, select}; +use harness::{BlobRef, EmissionEnvelope, PromiseResolution, REPLY_COMPLETION_KEY}; use super::super::{ BOT_BUSY_RETRY_DELAY, BOT_EVENT_TERMINAL_TIMEOUT, BOT_EXTRA_SESSION_CAP, BotActivities, @@ -180,7 +181,8 @@ async fn run_delivery_inner( // A direct run can win the narrow read/start race. Hold the // lane through a short delay, then requeue at the front. ctx.state_mut(|state| state.record_error(message)); - ctx.timer(BOT_BUSY_RETRY_DELAY).await; + ctx.timer_with_manual_cancellation(BOT_BUSY_RETRY_DELAY) + .await; ctx.state_mut(|state| { state.active_by_session.remove(target.as_str()); state.requeue_front(delivery.clone()); @@ -204,8 +206,10 @@ async fn run_delivery_inner( { let session_id = target.clone(); - let wait = ctx.wait_condition(move |state| state.lane_has_terminal(&session_id)); - let timeout = ctx.timer(BOT_EVENT_TERMINAL_TIMEOUT).fuse(); + let wait = ctx.wait_for_state(move |state| state.lane_has_terminal(&session_id)); + let timeout = ctx + .timer_with_manual_cancellation(BOT_EVENT_TERMINAL_TIMEOUT) + .fuse(); pin_mut!(wait, timeout); select! { _ = wait => {} @@ -655,13 +659,17 @@ pub(super) async fn handle_invocation(ctx: Ctx, pending: PendingInvocation) { ); let signalled = ctx .external_workflow(holder_workflow_id.clone(), None) - .signal(AgentSessionWorkflow::deliver_emission, envelope) + .signal( + AgentSessionWorkflow::deliver_emission, + envelope, + crate::workflows::signal_options(), + ) .await; if let Err(failure) = signalled { ctx.state_mut(|state| { state.record_error(format!( "resolve pushed invocation at {holder_workflow_id}: {}", - failure.message + failure )) }); } diff --git a/crates/temporal-workflow/src/workflows/bots/controller/state.rs b/crates/temporal-workflow/src/workflows/bots/controller/state.rs index 28f238ba6..60f28dd15 100644 --- a/crates/temporal-workflow/src/workflows/bots/controller/state.rs +++ b/crates/temporal-workflow/src/workflows/bots/controller/state.rs @@ -16,7 +16,7 @@ use bots::tools::{BOT_EVENT_RESOLVE_TOOL_ID, BOT_TOOLS_REVISION, is_pushed_tool} use bots::{ BotCoalesceParams, BotControllerConfig, BotEvent, RoutedSession, RoutedSessionClosePolicy, ids, }; -use engine::{ +use harness::{ BlobRef, EmissionBody, EmissionEnvelope, EmissionProducer, RunStatus, WorkflowToolInvocation, }; use serde::{Deserialize, Serialize}; @@ -1397,7 +1397,7 @@ pub fn ms_until_next_utc_day(now_ms: i64) -> i64 { #[cfg(test)] mod tests { use api::{BotId, ProfileId}; - use engine::{EventSeq, PromiseId, PromiseResolution, RunId, SessionId}; + use harness::{EventSeq, PromiseId, PromiseResolution, RunId, SessionId}; use uuid::Uuid; use super::*; @@ -1509,24 +1509,24 @@ mod tests { fn invocation(session: &str, tool_id: &str, suffix: char) -> WorkflowToolInvocation { let mut promises = BTreeMap::new(); promises.insert( - engine::REPLY_COMPLETION_KEY.to_owned(), + harness::REPLY_COMPLETION_KEY.to_owned(), PromiseId::new("promise_3"), ); WorkflowToolInvocation { - invocation_id: engine::WorkflowToolInvocationId::new(format!( + invocation_id: harness::WorkflowToolInvocationId::new(format!( "wti:sha256:{}", suffix.to_string().repeat(64) )), - tool_id: engine::WorkflowToolId::new(tool_id), + tool_id: harness::WorkflowToolId::new(tool_id), semantic_type: "lightspeed.bots.tool".to_owned(), schema_revision: 1, binding_fingerprint: "fp".to_owned(), session_universe_id: UNIVERSE, session_id: SessionId::new(session), run_id: RunId::new(7), - turn_id: engine::TurnId::new(1), - tool_batch_id: engine::ToolBatchId::new(1), - tool_call_id: engine::ToolCallId::new("call_1"), + turn_id: harness::TurnId::new(1), + tool_batch_id: harness::ToolBatchId::new(1), + tool_call_id: harness::ToolCallId::new("call_1"), arguments_ref: BlobRef::from_bytes(b"{}"), execution_context_ref: None, completion_promises: Some(promises), @@ -2029,7 +2029,7 @@ mod tests { // A second push of the same invocation under a fresh emission id // is still the same invocation. let mut again = pushed.clone(); - again.emission_id = engine::EmissionId::for_source_resolution( + again.emission_id = harness::EmissionId::for_source_resolution( UNIVERSE, "x", "y", diff --git a/crates/temporal-workflow/src/workflows/bots/mod.rs b/crates/temporal-workflow/src/workflows/bots/mod.rs index 2d55a0b7c..755e9fde6 100644 --- a/crates/temporal-workflow/src/workflows/bots/mod.rs +++ b/crates/temporal-workflow/src/workflows/bots/mod.rs @@ -1,7 +1,7 @@ //! Bot workflows: the controller that owns a bot's managed sessions //! and the trigger fire started by Temporal Schedules. Both run in the //! `bots` worker role on its own task queue; their activities are defined in -//! [`activities`] and implemented in `temporal-server`. +//! [`activities`] and implemented in `temporal-runtime`. pub mod activities; mod controller; @@ -70,6 +70,7 @@ pub fn bot_activity_options() -> ActivityOptions { ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::StartToClose( BOT_ACTIVITY_START_TO_CLOSE, )) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(retry(BOT_ACTIVITY_MAX_ATTEMPTS)) .build() } @@ -78,6 +79,7 @@ pub fn bot_poll_activity_options() -> ActivityOptions { ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::StartToClose( BOT_POLL_START_TO_CLOSE, )) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(retry(BOT_POLL_MAX_ATTEMPTS)) .build() } diff --git a/crates/temporal-workflow/src/workflows/bots/trigger_fire.rs b/crates/temporal-workflow/src/workflows/bots/trigger_fire.rs index 6e0d38910..8b37bfe22 100644 --- a/crates/temporal-workflow/src/workflows/bots/trigger_fire.rs +++ b/crates/temporal-workflow/src/workflows/bots/trigger_fire.rs @@ -14,7 +14,7 @@ use super::{ /// Search attribute Temporal stamps on workflows started by a Schedule. pub const TEMPORAL_SCHEDULED_START_TIME: &str = "TemporalScheduledStartTime"; -#[workflow(name = "BotTriggerFireWorkflow")] +#[workflow] #[derive(Default)] pub struct BotTriggerFireWorkflow { outcome: Option, @@ -29,7 +29,7 @@ pub enum BotTriggerFireOutcome { #[workflow_methods] impl BotTriggerFireWorkflow { - #[run] + #[run(name = "BotTriggerFireWorkflow")] pub async fn run( ctx: &mut WorkflowContext, args: BotTriggerFireArgs, @@ -49,24 +49,32 @@ impl BotTriggerFireWorkflow { let outcome = match args.kind { BotTriggerFireKind::Schedule => { let result = ctx - .start_activity( + .execute_activity( BotActivities::admit_schedule_event, request, bot_activity_options(), ) .await - .map_err(|error| anyhow::anyhow!("schedule fire failed: {error}"))?; + .map_err(|error| { + temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "schedule fire failed: {error}" + )) + })?; BotTriggerFireOutcome::Schedule(result) } BotTriggerFireKind::Poll => { let result = ctx - .start_activity( + .execute_activity( BotActivities::poll_trigger, request, bot_poll_activity_options(), ) .await - .map_err(|error| anyhow::anyhow!("poll fire failed: {error}"))?; + .map_err(|error| { + temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "poll fire failed: {error}" + )) + })?; BotTriggerFireOutcome::Poll(result) } }; @@ -84,9 +92,7 @@ impl BotTriggerFireWorkflow { /// search attribute, when present. fn scheduled_start_time_ms(ctx: &WorkflowContext) -> Option { let attributes = ctx.search_attributes(); - let payload = attributes - .indexed_fields - .get(TEMPORAL_SCHEDULED_START_TIME)?; + let payload = attributes.raw_payload(TEMPORAL_SCHEDULED_START_TIME)?; parse_search_attribute_time_ms(&payload.data) } diff --git a/crates/temporal-workflow/src/workflows/bots/types.rs b/crates/temporal-workflow/src/workflows/bots/types.rs index 7cb412397..99e0c7ce2 100644 --- a/crates/temporal-workflow/src/workflows/bots/types.rs +++ b/crates/temporal-workflow/src/workflows/bots/types.rs @@ -4,7 +4,7 @@ use api::{BotEventOutcome, BotId, BotTriggerId, LlmUsageView, ProfileId}; use bots::{BotDeliveryPhase, BotEvent}; -use engine::WorkflowEndpointRef; +use harness::WorkflowEndpointRef; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/crates/temporal-workflow/src/workflows/cancellation.rs b/crates/temporal-workflow/src/workflows/cancellation.rs new file mode 100644 index 000000000..a8d7dbed4 --- /dev/null +++ b/crates/temporal-workflow/src/workflows/cancellation.rs @@ -0,0 +1,55 @@ +use std::time::Duration; + +use futures::{FutureExt, future::FusedFuture}; +use temporalio_sdk::{ + CancellableFuture, SignalWorkflowOptions, TimerOptions, TimerResult, WaitConditionOptions, + WorkflowCancellationToken, WorkflowContext, +}; + +// These workflows own cancellation through their control loops and explicitly cancel +// in-flight operations. Detached tokens keep cleanup activities, outbound signals, +// and their waits alive after the workflow cancellation notification arrives. +pub(crate) trait WorkflowContextExt { + fn wait_for_state<'a>( + &'a self, + condition: impl FnMut(&W) -> bool + 'a, + ) -> impl FusedFuture + 'a; + + fn timer_with_manual_cancellation( + &self, + duration: Duration, + ) -> impl CancellableFuture; +} + +impl WorkflowContextExt for WorkflowContext { + fn wait_for_state<'a>( + &'a self, + condition: impl FnMut(&W) -> bool + 'a, + ) -> impl FusedFuture + 'a { + self.wait_condition_with_options( + condition, + WaitConditionOptions::builder() + .cancellation_token(WorkflowCancellationToken::new()) + .build(), + ) + .map(|result| result.expect("detached wait token is never cancelled")) + .fuse() + } + + fn timer_with_manual_cancellation( + &self, + duration: Duration, + ) -> impl CancellableFuture { + self.timer( + TimerOptions::builder(duration) + .cancellation_token(WorkflowCancellationToken::new()) + .build(), + ) + } +} + +pub(crate) fn signal_options() -> SignalWorkflowOptions { + SignalWorkflowOptions::builder() + .cancellation_token(WorkflowCancellationToken::new()) + .build() +} diff --git a/crates/temporal-workflow/src/workflows/channels/activities.rs b/crates/temporal-workflow/src/workflows/channels/activities.rs index a97bce1b6..ced8182b1 100644 --- a/crates/temporal-workflow/src/workflows/channels/activities.rs +++ b/crates/temporal-workflow/src/workflows/channels/activities.rs @@ -1,5 +1,5 @@ //! Activity definitions of the conversation workflow: the core-side set -//! (implemented in `temporal-server::worker::channels`) and the +//! (implemented in `temporal-runtime::worker::channels`) and the //! connector-side set (implemented by the TypeScript connector host under //! these exact names on the account's task queue). diff --git a/crates/temporal-workflow/src/workflows/channels/conversation.rs b/crates/temporal-workflow/src/workflows/channels/conversation.rs index a5f9f5576..cd0cfdaf9 100644 --- a/crates/temporal-workflow/src/workflows/channels/conversation.rs +++ b/crates/temporal-workflow/src/workflows/channels/conversation.rs @@ -18,6 +18,7 @@ //! workflow's tool batches follow. Everything that needs no I/O lives in //! [`channels::state`] or in the pure functions at the end of this file. +use crate::workflows::WorkflowContextExt as _; use std::collections::VecDeque; use std::future::Future; use std::pin::Pin; @@ -41,12 +42,12 @@ use channels::state::{ InvocationStatus, MessageStatus, PolicyResponse, PolicyResponseKind, PolicyResponseStatus, ReceiptEffect, ReceivedMessage, }; -use engine::{ +use futures::future::{join_all, poll_fn}; +use futures::{pin_mut, select}; +use harness::{ BlobRef, EmissionBody, EmissionEnvelope, EmissionProducer, PromiseId, PromiseResolution, REPLY_COMPLETION_KEY, WorkflowEndpointRef, WorkflowToolInvocation, }; -use futures::future::{join_all, poll_fn}; -use futures::{pin_mut, select}; use serde::{Deserialize, Serialize}; use temporalio_common::ActivityDefinition; use temporalio_macros::{workflow, workflow_methods}; @@ -80,7 +81,7 @@ pub struct ChannelConversationArgs { /// steer the conversation; groups stay silent. const DENIED_TEXT: &str = "This channel identity is not authorized for this Lightspeed universe."; -#[workflow(name = "ChannelConversationWorkflow")] +#[workflow] pub struct ChannelConversationWorkflow { start: ConversationStart, state: ConversationState, @@ -126,7 +127,7 @@ impl ChannelConversationWorkflow { } } - #[run] + #[run(name = "ChannelConversationWorkflow")] pub async fn run(ctx: &mut WorkflowContext) -> WorkflowResult<()> { run_conversation(ctx).await } @@ -210,12 +211,15 @@ impl ChannelConversationWorkflow { async fn run_conversation(ctx: &mut Ctx) -> WorkflowResult<()> { let ctx: &Ctx = &*ctx; if let Some(message) = ctx.state(|wf| wf.start_error.clone()) { - return Err(anyhow::anyhow!("conversation start rejected: {message}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "conversation start rejected: {message}" + )) + .into()); } if ctx.state(|wf| wf.start.workflow_id()) != ctx.workflow_id() { - return Err(anyhow::anyhow!( + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( "conversation workflow id does not match the conversation it was started for" - ) + )) .into()); } ensure_tool_declarations(ctx).await?; @@ -252,7 +256,11 @@ async fn ensure_tool_declarations(ctx: &Ctx) -> Result<(), WorkflowTermination> channel_activity_options(), ) .await - .map_err(|message| anyhow::anyhow!("store chat tool declarations: {message}"))?; + .map_err(|message| { + temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "store chat tool declarations: {message}" + )) + })?; ctx.state_mut(|wf| wf.state.tools_ref = Some(declared.tools_ref)); Ok(()) } @@ -261,13 +269,13 @@ async fn ensure_tool_declarations(ctx: &Ctx) -> Result<(), WorkflowTermination> /// cancellation. Lanes keep running underneath. async fn park(ctx: &Ctx, lanes: &mut Vec) -> Result<(), WorkflowTermination> { let tick = ctx.state(|wf| wf.lane_tick); - let wait = ctx.wait_condition(move |wf| wf.wake_ready(tick)); + let wait = ctx.wait_for_state(move |wf| wf.wake_ready(tick)); let cancelled = ctx.cancelled(); with_lanes(lanes, async move { pin_mut!(wait, cancelled); select! { _ = wait => Ok(()), - _ = cancelled => Err(WorkflowTermination::Cancelled), + _ = cancelled => Err(WorkflowTermination::cancelled()), } }) .await @@ -304,7 +312,7 @@ fn request_continue_as_new(ctx: &Ctx) -> WorkflowResult<()> { start: wf.start.clone(), carry: Some(wf.state.compact_state()), }); - match ctx.continue_as_new(&args, ContinueAsNewOptions::default()) { + match ctx.continue_as_new(args, ContinueAsNewOptions::default()) { Ok(never) => match never {}, Err(termination) => Err(termination), } @@ -327,7 +335,7 @@ async fn activity( input: AD::Input, options: ActivityOptions, ) -> Result { - ctx.start_activity(definition, input, options) + ctx.execute_activity(definition, input, options) .await .map_err(|error| error.to_string()) } @@ -360,7 +368,7 @@ async fn step( start: impl FnOnce() -> F, ) -> Result where - F: CancellableFuture>, + F: CancellableFuture>, { let Some(invocation_id) = watch else { return start() @@ -371,7 +379,7 @@ where return Err(StepError::Cancelled); } let activity = start(); - let cancelled = ctx.wait_condition(|wf| wf.state.is_cancelled(invocation_id)); + let cancelled = ctx.wait_for_state(|wf| wf.state.is_cancelled(invocation_id)); pin_mut!(activity, cancelled); select! { result = activity => result.map_err(|error| StepError::Failed(error.to_string())), @@ -394,7 +402,7 @@ async fn assert_trigger_active(ctx: &Ctx, watch: Option<&str>) -> Result<(), Ste scope: wf.start.scope, }); match step(ctx, watch, || { - ctx.start_activity( + ctx.execute_activity( ChannelActivities::assert_trigger_active, request, channel_assert_active_options(), @@ -430,7 +438,7 @@ async fn deliver_planned( let mut message_ids = Vec::new(); for command in commands { let result = step(ctx, watch, || { - ctx.start_activity( + ctx.execute_activity( ConnectorActivities::deliver_channel_message, command, connector_delivery_options(queue.clone()), @@ -481,7 +489,11 @@ async fn resolve_promise( let emission_id = envelope.emission_id.as_str().to_owned(); match ctx .external_workflow(holder_workflow_id.to_owned(), None) - .signal(AgentSessionWorkflow::deliver_emission, envelope) + .signal( + AgentSessionWorkflow::deliver_emission, + envelope, + crate::workflows::signal_options(), + ) .await { Ok(_) => vec![emission_id], @@ -489,7 +501,7 @@ async fn resolve_promise( ctx.state_mut(|wf| { wf.state.protocol_errors.push(format!( "resolve invocation at {holder_workflow_id}: {}", - failure.message + failure )) }); Vec::new() @@ -620,7 +632,8 @@ async fn prepare_message_media( match view.status { api::TranscriptionStatus::Pending | api::TranscriptionStatus::Running => { let cancelled = { - let timer = ctx.timer(std::time::Duration::from_secs(2)); + let timer = + ctx.timer_with_manual_cancellation(std::time::Duration::from_secs(2)); let cancelled = ctx.cancelled(); pin_mut!(timer, cancelled); select! { _ = timer => false, _ = cancelled => true } @@ -631,7 +644,11 @@ async fn prepare_message_media( format!("{}/{}", request.active.universe_id, view.transcription_id), None, ) - .signal(crate::TranscriptionWorkflow::cancel, ()) + .signal( + crate::TranscriptionWorkflow::cancel, + (), + crate::workflows::signal_options(), + ) .await; return Err("Audio preparation cancelled.".into()); } @@ -675,7 +692,7 @@ async fn prepare_media( // with this task's context (no internal wakers below its small-set // threshold). let prepared = join_all(media.iter().map(|item| { - ctx.start_activity( + ctx.execute_activity( ConnectorActivities::prepare_channel_media, PrepareChannelMediaInput { universe_id, @@ -1024,7 +1041,7 @@ async fn deliver_invocation( assert_trigger_active(ctx, watch).await?; let universe_id = ctx.state(|wf| wf.start.universe_id); let arguments = step(ctx, watch, || { - ctx.start_activity( + ctx.execute_activity( ChannelActivities::read_json_blob, ChatReadJsonBlobRequest { universe_id, @@ -1059,7 +1076,7 @@ async fn deliver_invocation( reply_to, }); let stored = step(ctx, None, || { - ctx.start_activity( + ctx.execute_activity( ChannelActivities::store_chat_sent, request, channel_activity_options(), @@ -1105,7 +1122,7 @@ async fn resolve_handle(ctx: &Ctx, watch: Option<&str>, seq: u64) -> Result) { /// the `finished` receipt (recorded in state) cancels the activity. async fn run_typing(ctx: Ctx, delivery_id: String) { let (route, queue) = ctx.state(|wf| (wf.start.route(), wf.start.connector_task_queue.clone())); - let typing = ctx.start_activity( + let typing = ctx.execute_activity( ConnectorActivities::maintain_channel_typing, MaintainChannelTypingInput { route }, connector_typing_options(queue), ); - let finished = ctx.wait_condition(|wf| !typing_wanted(&wf.state, &delivery_id)); + let finished = ctx.wait_for_state(|wf| !typing_wanted(&wf.state, &delivery_id)); pin_mut!(typing, finished); select! { result = typing => match result { @@ -1445,7 +1462,7 @@ fn refusal_reason_name(reason: ChatRefusalReason) -> &'static str { } } -/// Project the engine envelope onto the facts the conversation state +/// Project the harness envelope onto the facts the conversation state /// records, keeping the full invocation (and its holder) for the lane. fn project_emission( envelope: EmissionEnvelope, @@ -1655,7 +1672,7 @@ mod tests { use channels::inbound::{ChannelAuthorization, NormalizedInbound}; use channels::state::MAX_CHANNEL_INBOUND_INBOX; use channels::tools::{CHANNEL_EDIT_TOOL_ID, CHANNEL_SEND_TOOL_ID}; - use engine::{ + use harness::{ EventSeq, RunId, SessionId, ToolBatchId, ToolCallId, TurnId, WorkflowToolId, WorkflowToolInvocationId, }; @@ -2014,7 +2031,7 @@ mod tests { } #[test] - fn projects_engine_envelopes_onto_conversation_emissions() { + fn projects_harness_envelopes_onto_conversation_emissions() { let pushed = EmissionEnvelope::tool_invocation( UNIVERSE, SessionId::new(SESSION_ID), diff --git a/crates/temporal-workflow/src/workflows/channels/mod.rs b/crates/temporal-workflow/src/workflows/channels/mod.rs index e23cf2f0c..690e21e86 100644 --- a/crates/temporal-workflow/src/workflows/channels/mod.rs +++ b/crates/temporal-workflow/src/workflows/channels/mod.rs @@ -1,7 +1,7 @@ //! Channels workflows: one conversation workflow per chat, the //! source of that conversation's bot events and the receiver of its //! `message_*` tools. Runs in the `channels` worker role on its own task -//! queue; its core-side activities are implemented in `temporal-server`, +//! queue; its core-side activities are implemented in `temporal-runtime`, //! its connector-side activities by the TypeScript connector host on the //! account's own task queue. @@ -61,6 +61,7 @@ pub fn channel_activity_options() -> ActivityOptions { ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::StartToClose( CHANNEL_ACTIVITY_START_TO_CLOSE, )) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(retry(CHANNEL_ACTIVITY_MAX_ATTEMPTS)) .build() } @@ -69,27 +70,30 @@ pub fn channel_assert_active_options() -> ActivityOptions { ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::StartToClose( CHANNEL_ASSERT_ACTIVE_START_TO_CLOSE, )) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(retry(3)) .build() } /// Delivery on the connector's task queue. pub fn connector_delivery_options(task_queue: impl Into) -> ActivityOptions { - ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close: CONNECTOR_DELIVERY_START_TO_CLOSE, schedule_to_close: CONNECTOR_DELIVERY_SCHEDULE_TO_CLOSE, }) .task_queue(task_queue.into()) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(retry(5)) .build() } pub fn connector_media_options(task_queue: impl Into) -> ActivityOptions { - ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close: CONNECTOR_MEDIA_START_TO_CLOSE, schedule_to_close: CONNECTOR_MEDIA_SCHEDULE_TO_CLOSE, }) .task_queue(task_queue.into()) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(retry(3)) .build() } @@ -100,6 +104,7 @@ pub fn connector_typing_options(task_queue: impl Into) -> ActivityOption )) .task_queue(task_queue.into()) .heartbeat_timeout(CONNECTOR_TYPING_HEARTBEAT) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy(retry(1)) .build() } diff --git a/crates/temporal-workflow/src/workflows/channels/types.rs b/crates/temporal-workflow/src/workflows/channels/types.rs index 16b4eea02..b6e282160 100644 --- a/crates/temporal-workflow/src/workflows/channels/types.rs +++ b/crates/temporal-workflow/src/workflows/channels/types.rs @@ -6,7 +6,7 @@ use api::{BotEventOutcome, BotId, BotTriggerId, ChannelAccountId, ChannelProvider, ChatScope}; use channels::{ConversationRef, media::PreparedMediaItem, state::ChatHandle}; -use engine::WorkflowEndpointRef; +use harness::WorkflowEndpointRef; use serde::{Deserialize, Serialize}; use uuid::Uuid; diff --git a/crates/temporal-workflow/src/workflows/environment_job.rs b/crates/temporal-workflow/src/workflows/environment_job.rs index c2414c69c..d948e7fb5 100644 --- a/crates/temporal-workflow/src/workflows/environment_job.rs +++ b/crates/temporal-workflow/src/workflows/environment_job.rs @@ -1,3 +1,4 @@ +use crate::workflows::WorkflowContextExt as _; use std::time::Duration; use futures::{FutureExt, pin_mut, select}; @@ -15,7 +16,7 @@ use crate::{ WorkflowToolRecoveryResult, compose_environment_job_workflow_id, }; -#[workflow(name = "EnvironmentJobWorkflow")] +#[workflow] #[derive(Default)] pub struct EnvironmentJobWorkflow { snapshot: EnvironmentJobWorkflowSnapshot, @@ -27,7 +28,7 @@ pub struct EnvironmentJobWorkflow { #[workflow_methods] impl EnvironmentJobWorkflow { - #[run] + #[run(name = "EnvironmentJobWorkflow")] pub async fn run( ctx: &mut WorkflowContext, input: EnvironmentJobWorkflowInput, @@ -38,18 +39,22 @@ impl EnvironmentJobWorkflow { if ctx.workflow_id() != start.execution_id || start.universe_id != start.invocation.session_universe_id { - return Err(anyhow::anyhow!( + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( "environment job workflow-tool execution identity is invalid" - ) + )) .into()); } - ctx.start_local_activity( + ctx.execute_local_activity( WorkflowActivities::environment_job_prepare_workflow_tool, crate::EnvironmentJobPrepareWorkflowToolRequest { start }, environment_job_activity_options(), ) .await - .map_err(|error| anyhow::anyhow!("prepare environment job workflow: {error}"))? + .map_err(|error| { + temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "prepare environment job workflow: {error}" + )) + })? } }; let expected_workflow_id = args @@ -64,11 +69,11 @@ impl EnvironmentJobWorkflow { ) }); if args.start.universe_id != args.universe_id || ctx.workflow_id() != expected_workflow_id { - return Err(anyhow::anyhow!( + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( "environment job workflow id does not match its universe and job identity: workflow_id={} expected={}", ctx.workflow_id(), expected_workflow_id - ) + )) .into()); } ctx.state_mut(|state| { @@ -90,7 +95,7 @@ impl EnvironmentJobWorkflow { if !ctx.state(|state| state.snapshot.started) { match ctx - .start_local_activity( + .execute_local_activity( WorkflowActivities::environment_job_start, args.start.clone(), environment_job_activity_options(), @@ -107,7 +112,10 @@ impl EnvironmentJobWorkflow { } Err(error) => { ctx.state_mut(|state| state.snapshot.last_error = Some(error.to_string())); - return Err(anyhow::anyhow!("environment job start failed: {error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "environment job start failed: {error}" + )) + .into()); } } } @@ -116,7 +124,7 @@ impl EnvironmentJobWorkflow { let cancels = ctx.state_mut(|state| std::mem::take(&mut state.pending_cancels)); for cancel in cancels { match ctx - .start_local_activity( + .execute_local_activity( WorkflowActivities::environment_job_cancel, EnvironmentJobCancelActivityRequest { universe_id: args.universe_id, @@ -150,7 +158,7 @@ impl EnvironmentJobWorkflow { if !ctx.state(|state| state.snapshot.terminal) { match ctx - .start_local_activity( + .execute_local_activity( WorkflowActivities::environment_job_poll, EnvironmentJobPollActivityRequest { universe_id: args.universe_id, @@ -199,7 +207,7 @@ impl EnvironmentJobWorkflow { }); next.poll_attempt = next.poll_attempt.saturating_add(1); ctx.continue_as_new( - &EnvironmentJobWorkflowInput::Job(next), + EnvironmentJobWorkflowInput::Job(next), ContinueAsNewOptions::default(), )?; } @@ -207,9 +215,9 @@ impl EnvironmentJobWorkflow { ctx.state_mut(|state| state.nudged = false); let was_cancelled = { let wait = - ctx.wait_condition(|state| state.nudged || !state.pending_cancels.is_empty()); + ctx.wait_for_state(|state| state.nudged || !state.pending_cancels.is_empty()); let timer = ctx - .timer(Duration::from_millis(args.poll_ms.max(250))) + .timer_with_manual_cancellation(Duration::from_millis(args.poll_ms.max(250))) .fuse(); let cancelled = ctx.cancelled().fuse(); pin_mut!(wait, timer, cancelled); @@ -221,7 +229,7 @@ impl EnvironmentJobWorkflow { }; if was_cancelled { cancel_workflow_jobs(ctx, &args).await; - return Err(temporalio_sdk::WorkflowTermination::Cancelled); + return Err(temporalio_sdk::WorkflowTermination::cancelled()); } } } @@ -241,7 +249,7 @@ impl EnvironmentJobWorkflow { pub fn deliver_emission( &mut self, _ctx: &mut SyncWorkflowContext, - envelope: engine::EmissionEnvelope, + envelope: harness::EmissionEnvelope, ) { queue_workflow_tool_cancellation(self, envelope); } @@ -284,7 +292,7 @@ async fn cancel_workflow_jobs( return; } let _ = ctx - .start_local_activity( + .execute_local_activity( WorkflowActivities::environment_job_cancel, EnvironmentJobCancelActivityRequest { universe_id: args.universe_id, @@ -303,29 +311,29 @@ async fn cancel_workflow_jobs( /// run as local activities: Temporal still records completion and retries, but /// does not route the calls through a separately versioned activity worker. fn environment_job_activity_options() -> LocalActivityOptions { - LocalActivityOptions { - schedule_to_close_timeout: Some(crate::config::DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT), - start_to_close_timeout: Some(crate::config::DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT), - ..Default::default() - } + LocalActivityOptions::builder() + .schedule_to_close_timeout(crate::config::DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT) + .start_to_close_timeout(crate::config::DEFAULT_ACTIVITY_START_TO_CLOSE_TIMEOUT) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) + .build() } fn queue_workflow_tool_cancellation( state: &mut EnvironmentJobWorkflow, - envelope: engine::EmissionEnvelope, + envelope: harness::EmissionEnvelope, ) { let Some(workflow_tool) = &state.workflow_tool else { return; }; let producer_workflow_id = match &envelope.producer { - engine::EmissionProducer::Session { + harness::EmissionProducer::Session { universe_id, session_id, .. } => crate::compose_workflow_id(*universe_id, session_id), - engine::EmissionProducer::Workflow { .. } => return, + harness::EmissionProducer::Workflow { .. } => return, }; - let engine::EmissionBody::InvocationCancellation { + let harness::EmissionBody::InvocationCancellation { invocation_id, completion_key, promise_id, @@ -367,7 +375,11 @@ async fn flush_terminal_emissions( for (receiver_workflow_id, envelope) in emissions { let _ = ctx .external_workflow(receiver_workflow_id, None) - .signal(AgentSessionWorkflow::deliver_emission, envelope) + .signal( + AgentSessionWorkflow::deliver_emission, + envelope, + crate::workflows::signal_options(), + ) .await; } } @@ -376,7 +388,7 @@ fn collect_terminal_emissions( state: &mut EnvironmentJobWorkflow, universe_id: uuid::Uuid, workflow_id: &str, -) -> Vec<(String, engine::EmissionEnvelope)> { +) -> Vec<(String, harness::EmissionEnvelope)> { let mut emissions = Vec::new(); for subscription in &mut state.subscriptions { if subscription.notified { @@ -391,22 +403,22 @@ fn collect_terminal_emissions( continue; }; let resolution = match result { - engine::PromiseSourceCheckResult::Pending => continue, - engine::PromiseSourceCheckResult::Resolved { payload_ref } => { - engine::PromiseResolution::Resolved { payload_ref } + harness::PromiseSourceCheckResult::Pending => continue, + harness::PromiseSourceCheckResult::Resolved { payload_ref } => { + harness::PromiseResolution::Resolved { payload_ref } } - engine::PromiseSourceCheckResult::Failed { error_ref } => { - engine::PromiseResolution::Failed { error_ref } + harness::PromiseSourceCheckResult::Failed { error_ref } => { + harness::PromiseResolution::Failed { error_ref } } }; - let Ok(promise_id) = engine::PromiseId::try_new(subscription.promise_id.clone()) else { + let Ok(promise_id) = harness::PromiseId::try_new(subscription.promise_id.clone()) else { continue; }; subscription.notified = true; let holder_workflow_id = subscription.holder_workflow_id.clone(); emissions.push(( holder_workflow_id.clone(), - engine::EmissionEnvelope::source_resolution( + harness::EmissionEnvelope::source_resolution( universe_id, workflow_id.to_owned(), &holder_workflow_id, @@ -425,14 +437,14 @@ fn workflow_tool_recovery(state: &EnvironmentJobWorkflow) -> WorkflowToolRecover continue; }; let resolution = match result { - engine::PromiseSourceCheckResult::Pending => continue, - engine::PromiseSourceCheckResult::Resolved { payload_ref } => { - engine::PromiseResolution::Resolved { + harness::PromiseSourceCheckResult::Pending => continue, + harness::PromiseSourceCheckResult::Resolved { payload_ref } => { + harness::PromiseResolution::Resolved { payload_ref: payload_ref.clone(), } } - engine::PromiseSourceCheckResult::Failed { error_ref } => { - engine::PromiseResolution::Failed { + harness::PromiseSourceCheckResult::Failed { error_ref } => { + harness::PromiseResolution::Failed { error_ref: error_ref.clone(), } } @@ -444,8 +456,8 @@ fn workflow_tool_recovery(state: &EnvironmentJobWorkflow) -> WorkflowToolRecover #[cfg(test)] mod tests { - use engine::{BlobRef, PromiseSourceCheckResult}; use environment_protocol::shared::JobId; + use harness::{BlobRef, PromiseSourceCheckResult}; use super::*; @@ -472,7 +484,7 @@ mod tests { ); assert!(matches!( workflow_tool_recovery(&workflow).resolutions.get("job_1"), - Some(engine::PromiseResolution::Resolved { + Some(harness::PromiseResolution::Resolved { payload_ref: Some(actual), }) if actual == &payload_ref )); @@ -486,16 +498,16 @@ mod tests { assert_eq!(first[0].0, "universe/session_1"); assert!(matches!( &first[0].1.body, - engine::EmissionBody::SourceResolution { + harness::EmissionBody::SourceResolution { promise_id, - resolution: engine::PromiseResolution::Resolved { + resolution: harness::PromiseResolution::Resolved { payload_ref: Some(actual), }, } if promise_id.as_str() == "promise_1" && actual == &payload_ref )); assert!(matches!( first[0].1.producer, - engine::EmissionProducer::Workflow { + harness::EmissionProducer::Workflow { universe_id: actual, ref workflow_id, } if actual == universe_id && workflow_id == "universe/envjob-job_1" @@ -506,9 +518,9 @@ mod tests { #[test] fn workflow_tool_cancellation_targets_only_the_matching_job() { let invocation_id = - engine::WorkflowToolInvocationId::new(format!("wti:sha256:{}", "a".repeat(64))); + harness::WorkflowToolInvocationId::new(format!("wti:sha256:{}", "a".repeat(64))); let universe_id = uuid::Uuid::from_u128(1); - let session_id = engine::SessionId::new("session_1"); + let session_id = harness::SessionId::new("session_1"); let mut workflow = EnvironmentJobWorkflow { workflow_tool: Some(EnvironmentJobWorkflowToolContext { execution_id: "execution_1".to_owned(), @@ -522,13 +534,13 @@ mod tests { queue_workflow_tool_cancellation( &mut workflow, - engine::EmissionEnvelope::invocation_cancellation( + harness::EmissionEnvelope::invocation_cancellation( universe_id, session_id.clone(), - engine::EventSeq::new(7), + harness::EventSeq::new(7), invocation_id.clone(), "job_1".to_owned(), - engine::PromiseId::new("promise_1"), + harness::PromiseId::new("promise_1"), ), ); @@ -538,13 +550,13 @@ mod tests { queue_workflow_tool_cancellation( &mut workflow, - engine::EmissionEnvelope::invocation_cancellation( + harness::EmissionEnvelope::invocation_cancellation( universe_id, session_id, - engine::EventSeq::new(8), + harness::EventSeq::new(8), invocation_id, "job_1".to_owned(), - engine::PromiseId::new("promise_1"), + harness::PromiseId::new("promise_1"), ), ); assert_eq!(workflow.pending_cancels.len(), 1); diff --git a/crates/temporal-workflow/src/workflows/mod.rs b/crates/temporal-workflow/src/workflows/mod.rs index 7780f2851..1104e9d56 100644 --- a/crates/temporal-workflow/src/workflows/mod.rs +++ b/crates/temporal-workflow/src/workflows/mod.rs @@ -1,10 +1,13 @@ pub mod bots; +mod cancellation; pub mod channels; mod environment_job; mod session; mod subagent_execution; mod transcriptions; +pub(crate) use cancellation::{WorkflowContextExt, signal_options}; + pub use bots::{BotControllerWorkflow, BotTriggerFireWorkflow}; pub use channels::ChannelConversationWorkflow; pub use environment_job::EnvironmentJobWorkflow; diff --git a/crates/temporal-workflow/src/workflows/session/activity_calls.rs b/crates/temporal-workflow/src/workflows/session/activity_calls.rs index 2550b59b6..4fc98ad3c 100644 --- a/crates/temporal-workflow/src/workflows/session/activity_calls.rs +++ b/crates/temporal-workflow/src/workflows/session/activity_calls.rs @@ -1,5 +1,6 @@ -use temporalio_common::{error::IncomingError, protos::temporal::api::enums::v1::TimeoutType}; +use temporalio_common::error::IncomingError; use temporalio_sdk::ActivityExecutionError; +use temporalio_sdk::TimeoutType; use super::*; @@ -19,16 +20,16 @@ const MAX_LLM_BOUNDARY_ERROR_BYTES: usize = 16 * 1024; /// /// Run the generation activity while client admissions keep landing. /// A cancel that makes the turn obsolete preempts the call; the -/// engine has already cancelled the turn by then. +/// harness has already cancelled the turn by then. pub(super) async fn call_llm_generate( ctx: &mut WorkflowContext, drive: &mut CoreAgentDrive, request: LlmGenerationRequest, -) -> anyhow::Result> { +) -> anyhow::Result> { let run_id = request.run_id; let turn_id = request.turn_id; let activity_ctx = ctx.clone(); - let activity = activity_ctx.start_activity( + let activity = activity_ctx.execute_activity( WorkflowActivities::llm_generate, LlmGenerateActivityRequest { request }, crate::llm_activity_options(), @@ -47,16 +48,16 @@ pub(super) async fn call_llm_generate( Some(failure) => { let failure_ref = put_llm_boundary_error_blob(ctx, "LLM generation", &failure).await; - Ok(control::Raced::Completed(engine::LlmGenerationResult { + Ok(control::Raced::Completed(harness::LlmGenerationResult { run_id, turn_id, - status: engine::LlmGenerationStatus::Failed, + status: harness::LlmGenerationStatus::Failed, failure_ref: Some(failure_ref), context_entries: Vec::new(), - facts: engine::LlmGenerationFacts { + facts: harness::LlmGenerationFacts { duration_ms: None, provider_response_id: None, - finish: engine::LlmFinish::Failed, + finish: harness::LlmFinish::Failed, usage: None, tool_calls: Vec::new(), approval_requests: Vec::new(), @@ -72,8 +73,8 @@ pub(super) async fn call_llm_generate( pub(super) async fn call_context_compact( ctx: &mut WorkflowContext, drive: &mut CoreAgentDrive, - request: engine::ContextCompactionRequest, -) -> anyhow::Result> { + request: harness::ContextCompactionRequest, +) -> anyhow::Result> { let session_id = request.session_id.clone(); let context_revision = request.request.context.context_revision; let run_id = drive @@ -83,7 +84,7 @@ pub(super) async fn call_context_compact( .pending_plan() .and_then(|plan| plan.run_id); let activity_ctx = ctx.clone(); - let activity = activity_ctx.start_activity( + let activity = activity_ctx.execute_activity( WorkflowActivities::context_compact, crate::ContextCompactActivityRequest { request }, crate::llm_activity_options(), @@ -109,15 +110,17 @@ pub(super) async fn call_context_compact( Some(failure) => { let failure_ref = put_llm_boundary_error_blob(ctx, "context compaction", &failure).await; - Ok(control::Raced::Completed(engine::ContextCompactionResult { - usage: None, - calls: 0, - session_id, - context_revision, - status: engine::ContextCompactionStatus::Failed, - failure_ref: Some(failure_ref), - context_entries: Vec::new(), - })) + Ok(control::Raced::Completed( + harness::ContextCompactionResult { + usage: None, + calls: 0, + session_id, + context_revision, + status: harness::ContextCompactionStatus::Failed, + failure_ref: Some(failure_ref), + context_entries: Vec::new(), + }, + )) } None => Err(anyhow::anyhow!("{error}")), }, @@ -192,6 +195,7 @@ fn timeout_type_label(timeout_type: TimeoutType) -> &'static str { TimeoutType::ScheduleToClose => "schedule-to-close", TimeoutType::Heartbeat => "heartbeat", TimeoutType::Unspecified => "unspecified", + _ => "unknown", } } @@ -230,7 +234,7 @@ fn llm_boundary_error_message(operation: &str, failure: &LlmBoundaryFailure) -> } /// Materialize the boundary failure text with bounded attempts; fall back -/// to the well-known engine blob so the failure path itself can never retry +/// to the well-known harness blob so the failure path itself can never retry /// unbounded. async fn put_llm_boundary_error_blob( ctx: &mut WorkflowContext, @@ -238,7 +242,7 @@ async fn put_llm_boundary_error_blob( failure: &LlmBoundaryFailure, ) -> BlobRef { let message = llm_boundary_error_message(operation, failure); - ctx.start_activity( + ctx.execute_activity( WorkflowActivities::put_blob, PutBlobRequest { bytes: message.into_bytes(), @@ -246,14 +250,14 @@ async fn put_llm_boundary_error_blob( crate::boundary_error_blob_activity_options(), ) .await - .unwrap_or_else(|_| engine::llm_runtime_boundary_failure_ref()) + .unwrap_or_else(|_| harness::llm_runtime_boundary_failure_ref()) } pub(super) async fn call_tool_prepare_promise_controls( ctx: &mut WorkflowContext, - request: engine::PromiseControlArgumentRequest, -) -> anyhow::Result { - ctx.start_activity( + request: harness::PromiseControlArgumentRequest, +) -> anyhow::Result { + ctx.execute_activity( WorkflowActivities::tool_prepare_promise_controls, ToolPreparePromiseControlsActivityRequest { request }, activity_options(), @@ -283,14 +287,14 @@ mod tests { /// Decode a proto failure exactly the way the SDK does for an activity /// resolution, so the recognizer is exercised against the real shape. fn activity_error(failure: Failure) -> ActivityExecutionError { - let incoming = DefaultFailureConverter + let incoming = DefaultFailureConverter::default() .to_error( failure, &PayloadConverter::default(), &SerializationContextData::None, ) .expect("failure decodes"); - ActivityExecutionDecodeHint { cancelled: false }.adapt(incoming) + ActivityExecutionDecodeHint::new(false).adapt(incoming) } fn activity_failure(retry_state: RetryState, cause: Failure) -> Failure { @@ -307,11 +311,21 @@ mod tests { } fn timeout_failure(timeout_type: TimeoutType, cause: Option) -> Failure { + use temporalio_common::protos::temporal::api::enums::v1::TimeoutType as WireTimeoutType; + Failure { message: format!("activity {} timeout", timeout_type_label(timeout_type)), cause: cause.map(Box::new), failure_info: Some(FailureInfo::TimeoutFailureInfo(TimeoutFailureInfo { - timeout_type: timeout_type.into(), + timeout_type: match timeout_type { + TimeoutType::Unspecified => WireTimeoutType::Unspecified, + TimeoutType::StartToClose => WireTimeoutType::StartToClose, + TimeoutType::ScheduleToStart => WireTimeoutType::ScheduleToStart, + TimeoutType::ScheduleToClose => WireTimeoutType::ScheduleToClose, + TimeoutType::Heartbeat => WireTimeoutType::Heartbeat, + _ => panic!("test requires a known timeout type"), + } + .into(), last_heartbeat_details: None, })), ..Default::default() @@ -405,8 +419,8 @@ mod tests { #[test] fn cancellation_and_unknown_application_failures_propagate() { - let cancelled = ActivityExecutionDecodeHint { cancelled: true }.adapt( - DefaultFailureConverter + let cancelled = ActivityExecutionDecodeHint::new(true).adapt( + DefaultFailureConverter::default() .to_error( Failure { message: "cancelled".to_owned(), diff --git a/crates/temporal-workflow/src/workflows/session/admissions.rs b/crates/temporal-workflow/src/workflows/session/admissions.rs index a2e5a9e9c..48ed88f66 100644 --- a/crates/temporal-workflow/src/workflows/session/admissions.rs +++ b/crates/temporal-workflow/src/workflows/session/admissions.rs @@ -315,7 +315,7 @@ pub(super) fn runtime_projection_request( vfs_prompt_roots, active_instruction_inputs: active_instruction_inputs(state), vfs_skills, - active_catalogs: engine::current_catalog_inputs(state), + active_catalogs: harness::current_catalog_inputs(state), subagents: state .lifecycle .config @@ -330,7 +330,7 @@ pub(super) async fn prepare_runtime_projection( request: RuntimeProjectionRefreshActivityRequest, ) -> anyhow::Result> { let activity_ctx = ctx.clone(); - let activity = activity_ctx.start_activity( + let activity = activity_ctx.execute_activity( WorkflowActivities::runtime_projection_refresh, request, preparation::activity_options(), diff --git a/crates/temporal-workflow/src/workflows/session/awaits.rs b/crates/temporal-workflow/src/workflows/session/awaits.rs index 5e84815ea..248b5d949 100644 --- a/crates/temporal-workflow/src/workflows/session/awaits.rs +++ b/crates/temporal-workflow/src/workflows/session/awaits.rs @@ -2,13 +2,13 @@ use super::*; /// The parked tool batch, if any, derived from typed core state. pub(super) struct ParkedToolBatch { - pub run_id: engine::RunId, - pub batch_id: engine::ToolBatchId, - pub suspension: engine::ToolBatchSuspension, + pub run_id: harness::RunId, + pub batch_id: harness::ToolBatchId, + pub suspension: harness::ToolBatchSuspension, } impl ParkedToolBatch { - pub(super) fn spec(&self) -> &engine::AwaitSpec { + pub(super) fn spec(&self) -> &harness::AwaitSpec { self.suspension.spec() } } @@ -39,10 +39,10 @@ pub(super) fn has_satisfied_await(state: &AgentSessionWorkflow) -> bool { .spec() .deadline_at_ms .map_or(u64::MAX, |deadline| deadline.saturating_sub(1)); - engine::await_wake(&state.core_state, non_timeout_ms).is_some() + harness::await_wake(&state.core_state, non_timeout_ms).is_some() } -fn parked_tool_batch_batch_id(core_state: &CoreAgentState) -> Option { +fn parked_tool_batch_batch_id(core_state: &CoreAgentState) -> Option { parked_tool_batch(core_state).map(|parked| parked.batch_id) } @@ -66,11 +66,11 @@ pub(super) async fn process_satisfied_await( { return None; } - let claim = engine::await_wake(&state.core_state, now)?; + let claim = harness::await_wake(&state.core_state, now)?; let outcome = match claim { - engine::WakeReason::Cancelled => AwaitOutcome::Cancelled, - engine::WakeReason::Timeout => AwaitOutcome::Timeout, - engine::WakeReason::Terminal => AwaitOutcome::Terminal, + harness::WakeReason::Cancelled => AwaitOutcome::Cancelled, + harness::WakeReason::Timeout => AwaitOutcome::Timeout, + harness::WakeReason::Terminal => AwaitOutcome::Terminal, }; let results = promise_snapshot(parked.spec(), &state.core_state); Some((parked, claim, outcome, results)) @@ -80,31 +80,31 @@ pub(super) async fn process_satisfied_await( }; // The runtime prepares what the resolved payloads supply beside the - // results (a sub-agent's linked images, for example); the engine only + // results (a sub-agent's linked images, for example); the harness only // records and sequences those entries. let has_resolved_payload = results .iter() .any(|result| result.status == "resolved" && result.payload_ref.is_some()); let resume_output = match &parked.suspension { - engine::ToolBatchSuspension::AwaitTool { .. } => { + harness::ToolBatchSuspension::AwaitTool { .. } => { let request = AwaitMaterializationRequest { outcome, results }; let materialized = ctx - .start_activity( + .execute_activity( WorkflowActivities::materialize_await_result, request, activity_options(), ) .await .map_err(|error| anyhow::anyhow!("{error}"))?; - engine::ToolBatchResumeOutput::AwaitTool { + harness::ToolBatchResumeOutput::AwaitTool { result_ref: materialized.result_ref, additional_context: materialized.additional_context, attachments: materialized.attachments, } } - engine::ToolBatchSuspension::JoinedWorkflowCalls { .. } => { + harness::ToolBatchSuspension::JoinedWorkflowCalls { .. } => { let additional_context = if has_resolved_payload { - ctx.start_activity( + ctx.execute_activity( WorkflowActivities::prepare_joined_context, JoinedContextPreparationRequest { results }, activity_options(), @@ -114,10 +114,10 @@ pub(super) async fn process_satisfied_await( } else { Vec::new() }; - engine::ToolBatchResumeOutput::JoinedWorkflowCalls { additional_context } + harness::ToolBatchResumeOutput::JoinedWorkflowCalls { additional_context } } }; - let command = engine::ResumeToolBatchCommand { + let command = harness::ResumeToolBatchCommand { run_id: parked.run_id, batch_id: parked.batch_id, claim, @@ -136,7 +136,7 @@ pub(super) async fn process_satisfied_await( } pub(super) fn promise_snapshot( - spec: &engine::AwaitSpec, + spec: &harness::AwaitSpec, core_state: &CoreAgentState, ) -> Vec { spec.promise_ids @@ -160,11 +160,11 @@ pub(super) fn promise_snapshot( .collect() } -pub(super) fn promise_status_name(status: engine::PromiseStatus) -> &'static str { +pub(super) fn promise_status_name(status: harness::PromiseStatus) -> &'static str { match status { - engine::PromiseStatus::Pending => "pending", - engine::PromiseStatus::Resolved => "resolved", - engine::PromiseStatus::Failed => "failed", - engine::PromiseStatus::Cancelled => "cancelled", + harness::PromiseStatus::Pending => "pending", + harness::PromiseStatus::Resolved => "resolved", + harness::PromiseStatus::Failed => "failed", + harness::PromiseStatus::Cancelled => "cancelled", } } diff --git a/crates/temporal-workflow/src/workflows/session/bootstrap.rs b/crates/temporal-workflow/src/workflows/session/bootstrap.rs index 8e848ddde..1f17cf189 100644 --- a/crates/temporal-workflow/src/workflows/session/bootstrap.rs +++ b/crates/temporal-workflow/src/workflows/session/bootstrap.rs @@ -29,7 +29,7 @@ pub(super) async fn initialize( // bootstrap path is bounded by active context plus retained run metadata, // rather than transcript-sized event history. let loaded = ctx - .start_activity( + .execute_activity( WorkflowActivities::create_or_load_session, CreateOrLoadSessionRequest { session_id: args.session_id.clone(), @@ -79,7 +79,7 @@ async fn open_new_session( args: AgentSessionArgs, ) -> anyhow::Result<()> { let instructions_ref = ctx - .start_activity( + .execute_activity( WorkflowActivities::put_blob, PutBlobRequest { bytes: default_instructions().as_bytes().to_vec(), @@ -119,7 +119,7 @@ pub(super) fn validate_session_creation_identity( universe_id: uuid::Uuid, state: &CoreAgentState, is_fresh_session: bool, - workflow_tools: Option<&engine::ManagedSessionWorkflowTools>, + workflow_tools: Option<&harness::ManagedSessionWorkflowTools>, ) -> anyhow::Result<()> { let admitted = workflow_tools .map(|tools| tools.admit(universe_id)) @@ -154,7 +154,7 @@ pub(super) fn validate_session_creation_identity( fn instruction_context_input(content_ref: BlobRef) -> ContextEntryInput { ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(content_ref), + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, diff --git a/crates/temporal-workflow/src/workflows/session/control.rs b/crates/temporal-workflow/src/workflows/session/control.rs index 97fbabe2e..f9c3550af 100644 --- a/crates/temporal-workflow/src/workflows/session/control.rs +++ b/crates/temporal-workflow/src/workflows/session/control.rs @@ -1,27 +1,28 @@ //! Active-run control: client admissions — cancel, steer, queue — -//! must reach the engine while the drive loop is executing an activity, not +//! must reach the harness while the drive loop is executing an activity, not //! after the run ends. This module holds the one primitive the drive loop and //! the tool-batch executor use to race an in-flight activity against pending //! admissions, admit them against the live drive, and abandon the activity -//! when the engine no longer wants its result. +//! when the harness no longer wants its result. +use crate::workflows::WorkflowContextExt as _; use temporalio_sdk::CancellableFuture; use super::*; /// Outcome of racing one activity against client admissions. pub(super) enum Raced { - /// The activity finished; its result is still wanted by the engine. + /// The activity finished; its result is still wanted by the harness. Completed(T), /// Admissions drained mid-flight made the work obsolete (the run is - /// cancelling, or the turn/batch is no longer the engine's active one). + /// cancelling, or the turn/batch is no longer the harness's active one). /// The activity was cancelled and its eventual result discarded; the /// caller re-plans from the drive. Preempted, } /// Await `activity` while draining client admissions as they arrive. After -/// each drain, `still_wanted` decides against the live engine state whether +/// each drain, `still_wanted` decides against the live harness state whether /// the activity's result still matters; if not, the activity is cancelled /// (`TryCancel`: the future resolves at once, the worker learns through its /// heartbeat) and `Preempted` is returned. @@ -34,12 +35,12 @@ pub(super) async fn race_activity_with_admissions( still_wanted: impl Fn(&CoreAgentState) -> bool, ) -> anyhow::Result> where - F: CancellableFuture, + F: CancellableFuture, { pin_mut!(activity); loop { let admissions_pending = { - let wait = ctx.wait_condition(admissions::has_admissible_admissions); + let wait = ctx.wait_for_state(admissions::has_admissible_admissions); pin_mut!(wait); select! { result = activity => return Ok(Raced::Completed(result)), @@ -65,11 +66,11 @@ where } } -/// The generation for `turn_id` of `run_id` is still what the engine wants. +/// The generation for `turn_id` of `run_id` is still what the harness wants. pub(super) fn generation_still_wanted( state: &CoreAgentState, - run_id: engine::RunId, - turn_id: engine::TurnId, + run_id: harness::RunId, + turn_id: harness::TurnId, ) -> bool { state.runs.active.as_ref().is_some_and(|run| { run.run_id == run_id @@ -78,11 +79,11 @@ pub(super) fn generation_still_wanted( }) } -/// The tool batch `batch_id` of `run_id` is still executing for the engine. +/// The tool batch `batch_id` of `run_id` is still executing for the harness. pub(super) fn tool_batch_still_wanted( state: &CoreAgentState, - run_id: engine::RunId, - batch_id: engine::ToolBatchId, + run_id: harness::RunId, + batch_id: harness::ToolBatchId, ) -> bool { state.runs.active.as_ref().is_some_and(|run| { run.run_id == run_id diff --git a/crates/temporal-workflow/src/workflows/session/drive.rs b/crates/temporal-workflow/src/workflows/session/drive.rs index a45d82012..a585d5a59 100644 --- a/crates/temporal-workflow/src/workflows/session/drive.rs +++ b/crates/temporal-workflow/src/workflows/session/drive.rs @@ -39,8 +39,8 @@ pub(super) async fn admit_and_append_command( || environment_attachment_catalog_publication_is_obsolete(drive.state(), &command) || vfs_skill_catalog_publication_is_obsolete(drive.state(), &command) { - let rejection = engine::CommandRejection::new( - engine::CommandRejectionKind::ActiveWork, + let rejection = harness::CommandRejection::new( + harness::CommandRejectionKind::ActiveWork, "context observation no longer matches the configured source", ); return Ok(CommandAdmissionResult::Rejected(AgentAdmissionFailure { @@ -173,7 +173,7 @@ pub(super) async fn drive_until_idle( Some(argument_request) => { let facts = call_tool_prepare_promise_controls(ctx, argument_request).await?; - engine::attach_promise_control_runtime(drive.state(), request, facts)? + harness::attach_promise_control_runtime(drive.state(), request, facts)? } None => request, }; @@ -216,7 +216,7 @@ async fn auto_reject_pending_approvals( } for approval in pending { let response = match &approval.continuation { - engine::ApprovalContinuation::OpenAiMcp { + harness::ApprovalContinuation::OpenAiMcp { provider_request_id, } => { let response = serde_json::json!({ @@ -231,7 +231,7 @@ async fn auto_reject_pending_approvals( approval_request_id: provider_request_id.clone(), approve: false, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("application/json".to_owned()), provider_kind: Some("openai.responses.mcp_approval_response".to_owned()), @@ -242,15 +242,15 @@ async fn auto_reject_pending_approvals( token_estimate: None, }) } - engine::ApprovalContinuation::NativeMcp { .. } => None, + harness::ApprovalContinuation::NativeMcp { .. } => None, }; match admit_and_append_command( ctx, drive, - CoreAgentCommand::DecideApproval(engine::ApprovalDecisionCommand { + CoreAgentCommand::DecideApproval(harness::ApprovalDecisionCommand { approval_id: approval.approval_id, run_id, - decision: engine::ApprovalDecision::Rejected, + decision: harness::ApprovalDecision::Rejected, note: Some(NOTE.to_owned()), decided_by: None, response, @@ -334,20 +334,20 @@ pub(super) fn should_close_on_terminal(args: &AgentSessionArgs, state: &CoreAgen && !state .promises .pending() - .any(|promise| promise.scope == engine::PromiseScope::Session) + .any(|promise| promise.scope == harness::PromiseScope::Session) } pub(super) async fn append_events( ctx: &mut WorkflowContext, drive: &mut CoreAgentDrive, expected_head: Option, - events: Vec, + events: Vec, ) -> anyhow::Result> { if events.is_empty() { return Ok(Vec::new()); } let appended = ctx - .start_activity( + .execute_activity( WorkflowActivities::append_events, AppendEventsRequest { session_id: drive.session_id().clone(), @@ -392,7 +392,7 @@ pub(super) async fn append_events( #[derive(Clone, Debug)] struct DetachedPromiseFollowup { - promise_id: engine::PromiseId, + promise_id: harness::PromiseId, status: &'static str, content_ref: Option, } @@ -439,12 +439,12 @@ async fn queue_detached_promise_followups( // replayed follow-up is a no-op. ctx.state_mut(|state| { state.queue_admission(AgentAdmission { - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: Some(submission_id), - source: engine::RunRequestSource::Input { input }, - run_config: engine::RunConfig::default(), + source: harness::RunRequestSource::Input { input }, + run_config: harness::RunConfig::default(), }), correlation_token: None, }); @@ -458,18 +458,18 @@ fn detached_promise_followup_for_entry( entry: &CoreAgentEntry, ) -> Option { let (promise_id, status, content_ref) = match &entry.event { - CoreAgentEvent::Promise(engine::PromiseEvent::Resolved { + CoreAgentEvent::Promise(harness::PromiseEvent::Resolved { promise_id, payload_ref, }) => (promise_id, "resolved", payload_ref.clone()), - CoreAgentEvent::Promise(engine::PromiseEvent::Failed { + CoreAgentEvent::Promise(harness::PromiseEvent::Failed { promise_id, error_ref, }) => (promise_id, "failed", error_ref.clone()), _ => return None, }; let promise = state.core_state.promises.promises.get(promise_id)?; - if promise.scope != engine::PromiseScope::Session || !promise.status.is_terminal() { + if promise.scope != harness::PromiseScope::Session || !promise.status.is_terminal() { return None; } if awaits::parked_tool_batch(&state.core_state).is_some_and(|parked| { @@ -506,7 +506,7 @@ async fn put_detached_followup_blob( ctx: &mut WorkflowContext, bytes: Vec, ) -> anyhow::Result { - ctx.start_activity( + ctx.execute_activity( WorkflowActivities::put_blob, PutBlobRequest { bytes }, activity_options(), @@ -515,7 +515,7 @@ async fn put_detached_followup_blob( .map_err(|error| anyhow::anyhow!("{error}")) } -fn detached_promise_submission_id(promise_id: &engine::PromiseId) -> SubmissionId { +fn detached_promise_submission_id(promise_id: &harness::PromiseId) -> SubmissionId { let digest = BlobRef::from_bytes(format!("detached_promise:{promise_id}").as_bytes()); let suffix = digest .as_str() @@ -532,7 +532,7 @@ fn workflow_user_message_input(content_ref: BlobRef, preview: Option) -> kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -592,7 +592,7 @@ pub(super) fn invalid_vfs_skill_catalog_command( state: &CoreAgentState, ) -> Option { let key = ContextEntryKey::new("runtime.catalog.skills.vfs"); - let entry = engine::current_context_entry(state, &key)?; + let entry = harness::current_context_entry(state, &key)?; (state.lifecycle.status == CoreAgentStatus::Open && entry.origin.as_deref() == Some("runtime.vfs.skills") && !vfs_skill_discovery_enabled(state)) @@ -622,7 +622,7 @@ pub(super) fn invalid_environment_prompt_command( state: &CoreAgentState, ) -> Option { let key = ContextEntryKey::new(ENVIRONMENT_PROMPT_KEY); - let entry = engine::current_context_entry(state, &key)?; + let entry = harness::current_context_entry(state, &key)?; let source = entry .origin .as_deref()? @@ -678,7 +678,7 @@ pub(super) fn environment_prompt_publication_is_obsolete( .map(|id| id.as_str()) != Some(source) || ((state.runs.active.is_some() || !state.runs.queued.is_empty()) - && engine::current_context_entry(state, &ContextEntryKey::new(ENVIRONMENT_PROMPT_KEY)) + && harness::current_context_entry(state, &ContextEntryKey::new(ENVIRONMENT_PROMPT_KEY)) .is_none_or(|current| current.content != entry.content)) } @@ -699,7 +699,7 @@ pub(super) fn invalid_environment_attachment_catalog_command( state: &CoreAgentState, ) -> Option { let key = ContextEntryKey::new(ENVIRONMENT_ATTACHMENT_CATALOG_KEY); - let entry = engine::current_context_entry(state, &key)?; + let entry = harness::current_context_entry(state, &key)?; (state.lifecycle.status == CoreAgentStatus::Open && !environment_attachment_catalog_matches(state, entry.origin.as_deref())) .then_some(CoreAgentCommand::RemoveContext { @@ -721,7 +721,7 @@ pub(super) fn invalid_environment_catalog_command( state: &CoreAgentState, ) -> Option { let key = ContextEntryKey::new("runtime.catalog.skills.environment"); - let entry = engine::current_context_entry(state, &key)?; + let entry = harness::current_context_entry(state, &key)?; let source = entry .origin .as_deref()? @@ -781,18 +781,18 @@ mod tests { #[test] fn detached_session_promise_resolution_produces_followup_candidate() { - let promise_id = engine::PromiseId::new("promise_1"); + let promise_id = harness::PromiseId::new("promise_1"); let payload_ref = BlobRef::from_bytes(b"child output"); let mut workflow = AgentSessionWorkflow::default(); workflow.core_state.lifecycle.status = CoreAgentStatus::Open; workflow.core_state.promises.promises.insert( promise_id.clone(), - engine::Promise { + harness::Promise { promise_id: promise_id.clone(), - source: engine::PromiseSource::Timer { fire_at_ms: 1 }, - scope: engine::PromiseScope::Session, - ownership: engine::PromiseOwnership::Model, - status: engine::PromiseStatus::Resolved, + source: harness::PromiseSource::Timer { fire_at_ms: 1 }, + scope: harness::PromiseScope::Session, + ownership: harness::PromiseOwnership::Model, + status: harness::PromiseStatus::Resolved, payload_ref: Some(payload_ref.clone()), error_ref: None, deadline_ms: None, @@ -800,11 +800,11 @@ mod tests { ); let entry = CoreAgentEntry { position: SessionPosition { - seq: engine::EventSeq::new(1), + seq: harness::EventSeq::new(1), }, observed_at_ms: 1, joins: Default::default(), - event: CoreAgentEvent::Promise(engine::PromiseEvent::Resolved { + event: CoreAgentEvent::Promise(harness::PromiseEvent::Resolved { promise_id: promise_id.clone(), payload_ref: Some(payload_ref.clone()), }), diff --git a/crates/temporal-workflow/src/workflows/session/mod.rs b/crates/temporal-workflow/src/workflows/session/mod.rs index 5522e79ab..221ef2e03 100644 --- a/crates/temporal-workflow/src/workflows/session/mod.rs +++ b/crates/temporal-workflow/src/workflows/session/mod.rs @@ -25,14 +25,14 @@ use std::{ time::UNIX_EPOCH, }; -use engine::{ +use futures::{FutureExt, pin_mut, select}; +use harness::{ BlobRef, CommandError, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextMessageRole, CoreAgentAction, CoreAgentCommand, CoreAgentDrive, CoreAgentDriveError, CoreAgentEntry, CoreAgentEvent, CoreAgentState, CoreAgentStatus, EmissionEnvelope, LlmGenerationRequest, RunEvent, RunStatus, SessionId, SessionPosition, SubmissionId, ToolInvocationBatchRequest, }; -use futures::{FutureExt, pin_mut, select}; use temporalio_macros::{workflow, workflow_methods}; use temporalio_sdk::{ ContinueAsNewOptions, SyncWorkflowContext, WorkflowContext, WorkflowContextView, WorkflowResult, @@ -63,7 +63,7 @@ use session_state::flush_pending_emissions; use wait_loop::{can_continue_as_new, wait_for_workflow_work, workflow_state_should_complete}; use watchdog::{process_cancelling_watchdog, reconcile_cancelling_watchdog}; -#[workflow(name = "AgentSessionWorkflow")] +#[workflow] pub struct AgentSessionWorkflow { universe_id: Option, session_id: Option, @@ -130,21 +130,23 @@ impl Default for AgentSessionWorkflow { #[workflow_methods] impl AgentSessionWorkflow { - #[run] + #[run(name = "AgentSessionWorkflow")] pub async fn run( ctx: &mut WorkflowContext, args: AgentSessionArgs, ) -> WorkflowResult<()> { if let Err(error) = initialize(ctx, args.clone()).await { record_bootstrap_error(ctx, &error); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!("{error}")).into()); } let preparation_ctx = ctx.clone(); let preparation = preparation::run_preparation_loop(preparation_ctx).fuse(); let session = async { loop { - preparation::prepare_initial_session(ctx, &args).await?; + preparation::prepare_initial_session(ctx, &args) + .await + .map_err(temporalio_sdk::ApplicationFailure::new)?; if workflow_state_should_complete(ctx) { return Ok(()); } @@ -153,24 +155,39 @@ impl AgentSessionWorkflow { wait_for_workflow_work(ctx).await; if let Err(error) = flush_pending_emissions(ctx).await { record_error(ctx, &error, "pending_emission"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } if let Err(error) = promise_sources::process_pending_source_resolutions(ctx).await { record_error(ctx, &error, "promise_source_resolution"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } if let Err(error) = workflow_starts::process_pending_starts(ctx).await { record_error(ctx, &error, "workflow_start"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } if let Err(error) = promise_sources::flush_pending_promise_cancellations(ctx).await { record_error(ctx, &error, "promise_cancellation"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } if let Err(error) = workflow_starts::process_execution_cancels(ctx).await { record_error(ctx, &error, "workflow_execution_cancel"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } match process_cancelling_watchdog(ctx, &args).await { Ok(DriveOutcome::ContinueAsNew) => { @@ -179,17 +196,26 @@ impl AgentSessionWorkflow { Ok(DriveOutcome::Idle | DriveOutcome::YieldForWorkflowWork) => {} Err(error) => { record_error(ctx, &error, "cancellation_watchdog"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } } if let Err(error) = awaits::process_satisfied_await(ctx).await { record_error(ctx, &error, "await_resolution"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } promise_sources::process_due_promise_deadlines(ctx); if let Err(error) = promise_sources::process_due(ctx).await { record_error(ctx, &error, "promise_source_poll"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } match process_pending_tool_batch_resumes(ctx, &args).await { Ok(DriveOutcome::ContinueAsNew) => { @@ -198,17 +224,26 @@ impl AgentSessionWorkflow { Ok(DriveOutcome::Idle | DriveOutcome::YieldForWorkflowWork) => {} Err(error) => { record_error(ctx, &error, "tool_batch_resume"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } } - let mut admission_drive = drive_from_state(ctx)?; - admissions::drain_pending_admissions(ctx, &mut admission_drive).await?; + let mut admission_drive = + drive_from_state(ctx).map_err(temporalio_sdk::ApplicationFailure::new)?; + admissions::drain_pending_admissions(ctx, &mut admission_drive) + .await + .map_err(temporalio_sdk::ApplicationFailure::new)?; if wait_loop::workflow_state_needs_core_drive(ctx) { let mut drive = match drive_from_state(ctx) { Ok(drive) => drive, Err(error) => { record_error(ctx, &error, "drive_rehydrate"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } }; match drive_until_idle(ctx, &args, &mut drive).await { @@ -218,7 +253,10 @@ impl AgentSessionWorkflow { Ok(DriveOutcome::Idle | DriveOutcome::YieldForWorkflowWork) => {} Err(error) => { record_error(ctx, &error, "core_drive"); - return Err(anyhow::anyhow!("{error}").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "{error}" + )) + .into()); } } } @@ -281,7 +319,7 @@ impl AgentSessionWorkflow { /// Fixed inbound funnel for cross-workflow facts. Promise-bearing /// emissions become ordinary `ResolvePromise` admissions, preserving the - /// engine's idempotent first-writer-wins semantics. + /// harness's idempotent first-writer-wins semantics. #[signal(name = "deliver_emission")] pub fn deliver_emission( &mut self, diff --git a/crates/temporal-workflow/src/workflows/session/observability.rs b/crates/temporal-workflow/src/workflows/session/observability.rs index ff6ba4f3f..271bd84b7 100644 --- a/crates/temporal-workflow/src/workflows/session/observability.rs +++ b/crates/temporal-workflow/src/workflows/session/observability.rs @@ -63,7 +63,7 @@ pub(super) fn request_continue_as_new( args: &AgentSessionArgs, ) -> WorkflowResult<()> { let next_args = continuation_args(ctx, args); - match ctx.continue_as_new(&next_args, ContinueAsNewOptions::default()) { + match ctx.continue_as_new(next_args, ContinueAsNewOptions::default()) { Ok(never) => match never {}, Err(termination @ temporalio_sdk::WorkflowTermination::ContinueAsNew(_)) => { log_continue_as_new(ctx, args); diff --git a/crates/temporal-workflow/src/workflows/session/preparation.rs b/crates/temporal-workflow/src/workflows/session/preparation.rs index 6ddeb555b..c84d39480 100644 --- a/crates/temporal-workflow/src/workflows/session/preparation.rs +++ b/crates/temporal-workflow/src/workflows/session/preparation.rs @@ -2,6 +2,7 @@ //! pass an outstanding observation; derived tools publish at a safe boundary. use super::preparation_candidate::PreparationCandidate; use super::*; +use crate::workflows::WorkflowContextExt as _; use crate::{ SessionOperation, SessionOperationOutcome, SessionOperationRequest, SessionToolsetPreparation, SessionToolsetSource, @@ -39,11 +40,12 @@ impl SessionAdmission { pub(super) fn activity_options() -> temporalio_sdk::ActivityOptions { temporalio_sdk::ActivityOptions::with_close_timeouts( - temporalio_sdk::ActivityCloseTimeouts::Both { + temporalio_sdk::ActivityCloseTimeouts::ScheduleAndStartToClose { start_to_close: Duration::from_secs(30), schedule_to_close: Duration::from_secs(90), }, ) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) .retry_policy( temporalio_common::protos::temporal::api::common::v1::RetryPolicy { maximum_attempts: 3, @@ -68,13 +70,13 @@ pub(super) async fn await_activity( activity: F, ) -> Result where - F: CancellableFuture, + F: CancellableFuture, { pin_mut!(activity); loop { { let wait = - ctx.wait_condition(|state| state.pending_admissions.iter().any(control_admission)); + ctx.wait_for_state(|state| state.pending_admissions.iter().any(control_admission)); pin_mut!(wait); futures::select_biased! { _ = wait => {}, @@ -164,7 +166,7 @@ pub(super) fn preparation_matches( // system bindings. This does not invalidate the desired tool observation. let mut source = prepared.source.clone(); for declaration in &prepared.declarations { - let Ok(binding) = engine::WorkflowToolBinding::admit( + let Ok(binding) = harness::WorkflowToolBinding::admit( universe_id, declaration.definition.clone(), declaration.target.clone(), @@ -228,7 +230,7 @@ pub(super) async fn publish_tools( pub(super) struct PendingToolset { pub prepared: SessionToolsetPreparation, - pub run_id: engine::RunId, + pub run_id: harness::RunId, pub admission: AgentAdmission, } @@ -292,7 +294,7 @@ fn admission_error(failure: AgentAdmissionFailure) -> AgentApiError { if failure .rejection .as_ref() - .is_some_and(|rejection| rejection.kind == engine::CommandRejectionKind::RevisionConflict) + .is_some_and(|rejection| rejection.kind == harness::CommandRejectionKind::RevisionConflict) { AgentApiError::conflict(failure.message) } else { @@ -420,16 +422,16 @@ async fn configure( ctx: &mut WorkflowContext, drive: &mut CoreAgentDrive, candidate: &mut PreparationCandidate, - config: engine::SessionConfig, + config: harness::SessionConfig, expected_revision: Option, ) -> Result<(), AgentApiError> { // Validate materialization before committing configuration. Registry reads - // belong to this activity; the engine remains the final state validator. + // belong to this activity; the harness remains the final state validator. let original = SessionToolsetSource::from_state(drive.state()).unwrap(); let mut source = original.clone(); source.config = config.clone(); let activity_ctx = ctx.clone(); - let activity = activity_ctx.start_activity( + let activity = activity_ctx.execute_activity( WorkflowActivities::prepare_session_toolset, crate::SessionToolsetRequest { source: source.clone(), @@ -483,7 +485,7 @@ async fn apply_profile( source: source.clone(), }; let activity_ctx = ctx.clone(); - let activity = activity_ctx.start_activity( + let activity = activity_ctx.execute_activity( WorkflowActivities::prepare_session_profile, request, activity_options(), @@ -538,7 +540,7 @@ async fn apply_profile( desired.remove(&ContextEntryKey::new("instructions.000.default")); if desired.is_empty() { let activity_ctx = ctx.clone(); - let activity = activity_ctx.start_activity( + let activity = activity_ctx.execute_activity( WorkflowActivities::put_blob, PutBlobRequest { bytes: default_instructions().as_bytes().to_vec(), @@ -552,7 +554,7 @@ async fn apply_profile( ContextEntryKey::new("instructions.000.default"), ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(reference), + content: harness::ContentRef::text(reference), preview: None, origin: None, provenance_ref: None, @@ -635,10 +637,10 @@ pub(super) fn begin_run_preparation( /// or tool activity is in flight. Only the driver publishes the observation. pub(super) async fn run_preparation_loop(ctx: WorkflowContext) { loop { - ctx.wait_condition(|state| state.run_preparation.is_some()) + ctx.wait_for_state(|state| state.run_preparation.is_some()) .await; let pending = ctx.state(|state| state.run_preparation.clone()).unwrap(); - let activity = ctx.start_activity( + let activity = ctx.execute_activity( WorkflowActivities::prepare_session_toolset, crate::SessionToolsetRequest { source: pending.source, @@ -646,7 +648,7 @@ pub(super) async fn run_preparation_loop(ctx: WorkflowContext result.map_err(|error| AgentApiError::internal(format!("tool preparation failed: {error}"))).and_then(|result| result), @@ -689,8 +691,8 @@ mod tests { use super::*; fn pending() -> PendingRunPreparation { - let config = crate::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + let config = crate::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".into(), model: "gpt-test".into(), }); @@ -698,10 +700,10 @@ mod tests { state.lifecycle.config = Some(config); PendingRunPreparation { admission: AgentAdmission { - command: CoreAgentCommand::RequestRun(engine::RunRequestCommand { + command: CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, submission_id: Some(SubmissionId::new("prepared")), - source: engine::RunRequestSource::Input { input: Vec::new() }, + source: harness::RunRequestSource::Input { input: Vec::new() }, run_config: crate::default_run_config(), notify_on_terminal: Vec::new(), }), @@ -723,8 +725,8 @@ mod tests { state.run_preparation = Some(pending); state.queue_admission(AgentAdmission { command: CoreAgentCommand::ReplaceSessionConfig { - config: crate::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + config: crate::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".into(), model: "gpt-test".into(), }), @@ -739,7 +741,7 @@ mod tests { state.queue_admission(AgentAdmission { command: CoreAgentCommand::CancelRun { requested_by: None, - run_id: engine::RunId::new(1), + run_id: harness::RunId::new(1), }, correlation_token: None, }); @@ -772,10 +774,10 @@ mod tests { ..Default::default() }; state.core_state.context.compaction.phase = - engine::ContextCompactionPhase::Pending(engine::ContextCompactionPlan { + harness::ContextCompactionPhase::Pending(harness::ContextCompactionPlan { run_id: None, - covered_entry_ids: vec![engine::ContextItemId::new(1)], - trigger: engine::ContextCompactionTrigger::Manual, + covered_entry_ids: vec![harness::ContextItemId::new(1)], + trigger: harness::ContextCompactionTrigger::Manual, }); assert!(!wait_loop::workflow_state_needs_core_drive_for_state( &state @@ -797,7 +799,7 @@ mod tests { state .workflow_tools .system_binding_ids - .insert(engine::WorkflowToolId::new("foreign")); + .insert(harness::WorkflowToolId::new("foreign")); assert!(!pending.source.matches(&state)); } } diff --git a/crates/temporal-workflow/src/workflows/session/preparation_candidate.rs b/crates/temporal-workflow/src/workflows/session/preparation_candidate.rs index 0b3c1d780..5524cb3e7 100644 --- a/crates/temporal-workflow/src/workflows/session/preparation_candidate.rs +++ b/crates/temporal-workflow/src/workflows/session/preparation_candidate.rs @@ -2,7 +2,7 @@ //! a fully prepared candidate can become one durable event batch. use super::*; use api::AgentApiError; -use engine::storage::{StoredSessionEntry, UncommittedStoredEvent}; +use harness::storage::{StoredSessionEntry, UncommittedStoredEvent}; pub(super) struct PreparationCandidate { drive: CoreAgentDrive, @@ -76,7 +76,7 @@ impl PreparationCandidate { })?; Ok(StoredSessionEntry { position: SessionPosition { - seq: engine::EventSeq::new(seq), + seq: harness::EventSeq::new(seq), }, observed_at_ms: event.observed_at_ms, joins: event.joins.clone(), @@ -166,7 +166,7 @@ mod tests { .enumerate() .map(|(index, event)| StoredSessionEntry { position: SessionPosition { - seq: engine::EventSeq::new(start + index as u64 + 1), + seq: harness::EventSeq::new(start + index as u64 + 1), }, observed_at_ms: event.observed_at_ms, joins: event.joins, @@ -186,8 +186,8 @@ mod tests { candidate .push( CoreAgentCommand::OpenSession { - config: crate::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + config: crate::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".into(), model: "test-model".into(), }), @@ -203,7 +203,7 @@ mod tests { fn instructions(text: &str) -> ContextEntryInput { ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(BlobRef::from_bytes(text.as_bytes())), + content: harness::ContentRef::text(BlobRef::from_bytes(text.as_bytes())), preview: None, origin: None, provenance_ref: None, @@ -211,11 +211,11 @@ mod tests { } } - fn attachment(id: &str) -> engine::EnvironmentAttachment { - engine::EnvironmentAttachment { + fn attachment(id: &str) -> harness::EnvironmentAttachment { + harness::EnvironmentAttachment { environment_id: id.to_owned(), default: false, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, } } @@ -227,7 +227,7 @@ mod tests { let mut config = live.state().lifecycle.config.clone().unwrap(); let mut environment = attachment("new-default"); environment.default = true; - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { environments: vec![environment], ..Default::default() }); @@ -244,7 +244,7 @@ mod tests { admissions::runtime_projection_request(live.session_id(), candidate.state()); assert_eq!( projection.active_environment_id, - Some(engine::EnvironmentId::new("new-default")) + Some(harness::EnvironmentId::new("new-default")) ); assert!(live.state().environment.active_environment_id.is_none()); let batch = candidate.finish(&live).unwrap(); @@ -257,16 +257,16 @@ mod tests { fn proposed(live: &CoreAgentDrive) -> PreparationCandidate { let mut candidate = PreparationCandidate::new(live); - let tool = engine::ToolSpec { - name: engine::ToolName::new("new_tool"), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + let tool = harness::ToolSpec { + name: harness::ToolName::new("new_tool"), + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: None, input_schema_ref: BlobRef::from_bytes(b"schema"), output_schema_ref: None, strict: None, provider_options_ref: None, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, execution: Default::default(), }; let tools = BTreeMap::from([(tool.name.clone(), tool)]); @@ -282,12 +282,12 @@ mod tests { ) .unwrap(); let mut config = live.state().lifecycle.config.clone().unwrap(); - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { environments: vec![attachment("selected")], ..Default::default() }); - config.generation.tool_choice = Some(engine::ToolChoice::Specific { - tool_name: engine::ToolName::new("new_tool"), + config.generation.tool_choice = Some(harness::ToolChoice::Specific { + tool_name: harness::ToolName::new("new_tool"), }); candidate .push( @@ -301,7 +301,7 @@ mod tests { candidate .push( CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("selected"), + environment_id: harness::EnvironmentId::new("selected"), }, 2, ) @@ -331,7 +331,7 @@ mod tests { assert!(request.environments.is_some()); assert_eq!( request.active_environment_id, - Some(engine::EnvironmentId::new("selected")) + Some(harness::EnvironmentId::new("selected")) ); assert_eq!( request.active_instruction_inputs[&ContextEntryKey::new("instructions.050.profile")], @@ -424,7 +424,7 @@ mod tests { let mut live = live(); let mut initial = PreparationCandidate::new(&live); let mut config = live.state().lifecycle.config.clone().unwrap(); - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { prompts: Some(Default::default()), environments: vec![attachment("old"), attachment("new")], ..Default::default() @@ -441,7 +441,7 @@ mod tests { initial .push( CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("old"), + environment_id: harness::EnvironmentId::new("old"), }, 2, ) @@ -482,7 +482,7 @@ mod tests { candidate .push( CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("new"), + environment_id: harness::EnvironmentId::new("new"), }, 3, ) @@ -497,7 +497,7 @@ mod tests { assert_eq!(batch.events.len(), 2); commit(&mut live, batch); assert!(drive::invalid_environment_prompt_command(live.state()).is_none()); - assert!(engine::current_context_entry(live.state(), &catalog_key).is_some()); + assert!(harness::current_context_entry(live.state(), &catalog_key).is_some()); let mut candidate = PreparationCandidate::new(&live); candidate.push(old_catalog, 4).unwrap(); let error = candidate diff --git a/crates/temporal-workflow/src/workflows/session/promise_sources.rs b/crates/temporal-workflow/src/workflows/session/promise_sources.rs index 51d668a16..d1bd1fee7 100644 --- a/crates/temporal-workflow/src/workflows/session/promise_sources.rs +++ b/crates/temporal-workflow/src/workflows/session/promise_sources.rs @@ -13,21 +13,21 @@ pub(super) fn reconcile_polls_for_state(state: &mut AgentSessionWorkflow, now_ms .promises .pending() .filter_map(|promise| match &promise.source { - engine::PromiseSource::Timer { .. } => Some(( + harness::PromiseSource::Timer { .. } => Some(( promise.promise_id.as_str().to_owned(), promise.source.clone(), )), // Started executions get a slow recovery poll as the backstop // for a terminal result whose emission was never observed; // bound-receiver promises resolve by pushed emission only. - engine::PromiseSource::Workflow { + harness::PromiseSource::Workflow { producer_workflow_kind, .. - } if producer_workflow_kind == engine::WORKFLOW_TOOL_EXECUTION_KIND => Some(( + } if producer_workflow_kind == harness::WORKFLOW_TOOL_EXECUTION_KIND => Some(( promise.promise_id.as_str().to_owned(), promise.source.clone(), )), - engine::PromiseSource::Workflow { .. } => None, + harness::PromiseSource::Workflow { .. } => None, }) .collect::>(); state @@ -82,10 +82,10 @@ pub(super) async fn process_due( for mut poll in due { let check = match &poll.source { - engine::PromiseSource::Timer { fire_at_ms } if *fire_at_ms <= now => { - engine::PromiseSourceCheckResult::Resolved { payload_ref: None } + harness::PromiseSource::Timer { fire_at_ms } if *fire_at_ms <= now => { + harness::PromiseSourceCheckResult::Resolved { payload_ref: None } } - engine::PromiseSource::Timer { .. } => { + harness::PromiseSource::Timer { .. } => { advance(&mut poll, now); ctx.state_mut(|state| { state @@ -94,14 +94,14 @@ pub(super) async fn process_due( }); continue; } - engine::PromiseSource::Workflow { + harness::PromiseSource::Workflow { producer_workflow_id, producer_workflow_kind, completion_key, .. - } if producer_workflow_kind == engine::WORKFLOW_TOOL_EXECUTION_KIND => { + } if producer_workflow_kind == harness::WORKFLOW_TOOL_EXECUTION_KIND => { let check = ctx - .start_activity( + .execute_activity( WorkflowActivities::check_workflow_tool_execution, crate::WorkflowToolExecutionCheckRequest { execution_id: producer_workflow_id.clone(), @@ -111,7 +111,7 @@ pub(super) async fn process_due( ) .await .map_err(|error| anyhow::anyhow!("{error}"))?; - if matches!(check, engine::PromiseSourceCheckResult::Pending) { + if matches!(check, harness::PromiseSourceCheckResult::Pending) { advance(&mut poll, now); ctx.state_mut(|state| { state @@ -122,11 +122,11 @@ pub(super) async fn process_due( } check } - engine::PromiseSource::Workflow { .. } => continue, + harness::PromiseSource::Workflow { .. } => continue, }; match check { - engine::PromiseSourceCheckResult::Pending => { - if matches!(poll.source, engine::PromiseSource::Timer { .. }) { + harness::PromiseSourceCheckResult::Pending => { + if matches!(poll.source, harness::PromiseSource::Timer { .. }) { advance(&mut poll, now); ctx.state_mut(|state| { state @@ -135,18 +135,18 @@ pub(super) async fn process_due( }); } } - engine::PromiseSourceCheckResult::Resolved { payload_ref } => { + harness::PromiseSourceCheckResult::Resolved { payload_ref } => { queue_resolution( ctx, poll.promise_id, - engine::PromiseResolution::Resolved { payload_ref }, + harness::PromiseResolution::Resolved { payload_ref }, ); } - engine::PromiseSourceCheckResult::Failed { error_ref } => { + harness::PromiseSourceCheckResult::Failed { error_ref } => { queue_resolution( ctx, poll.promise_id, - engine::PromiseResolution::Failed { error_ref }, + harness::PromiseResolution::Failed { error_ref }, ); } } @@ -161,7 +161,7 @@ pub(super) async fn process_due( Ok(()) } -/// Engine-owned hard promise deadlines: a pending promise whose +/// Harness-owned hard promise deadlines: a pending promise whose /// `deadline_ms` has passed fails through the ordinary `ResolvePromise` /// funnel (first-writer-wins keeps a racing real resolution harmless). An /// `await` timeout never changes the underlying promise; this is the @@ -190,7 +190,7 @@ pub(super) fn process_due_promise_deadlines(ctx: &mut WorkflowContext {} - engine::PromiseSource::Workflow { + harness::PromiseSource::Timer { .. } => {} + harness::PromiseSource::Workflow { producer_workflow_id, invocation_id, completion_key, @@ -218,21 +218,25 @@ pub(super) async fn flush_pending_promise_cancellations( let Some(session_id) = ctx.state(|state| state.session_id.clone()) else { continue; }; - let Ok(invocation_id) = engine::WorkflowToolInvocationId::try_new(invocation_id) + let Ok(invocation_id) = harness::WorkflowToolInvocationId::try_new(invocation_id) else { continue; }; let envelope = EmissionEnvelope::invocation_cancellation( universe_id, session_id, - engine::EventSeq::new(pending.log_seq), + harness::EventSeq::new(pending.log_seq), invocation_id, completion_key, - engine::PromiseId::new(pending.promise_id), + harness::PromiseId::new(pending.promise_id), ); let _ = ctx .external_workflow(producer_workflow_id, None) - .signal(AgentSessionWorkflow::deliver_emission, envelope) + .signal( + AgentSessionWorkflow::deliver_emission, + envelope, + crate::workflows::signal_options(), + ) .await; } } @@ -262,7 +266,7 @@ pub(super) async fn process_pending_source_resolutions( // which rejects them with the standard funnel semantics. return (true, None); }; - let engine::PromiseSource::Workflow { + let harness::PromiseSource::Workflow { producer_workflow_id, invocation_id, .. @@ -272,44 +276,45 @@ pub(super) async fn process_pending_source_resolutions( }; let producer_matches = matches!( &producer, - engine::EmissionProducer::Workflow { workflow_id, .. } + harness::EmissionProducer::Workflow { workflow_id, .. } if workflow_id == producer_workflow_id.as_str() ); if !producer_matches { return (false, None); } - let reply_schema_ref = engine::WorkflowToolInvocationId::try_new(invocation_id.clone()) - .ok() - .and_then(|invocation_id| { - state - .core_state - .workflow_tools - .emissions - .get(&invocation_id) - .or_else(|| { - state - .core_state - .workflow_tools - .start_requests - .get(&invocation_id) - }) - }) - .and_then(|invocation| { - state - .core_state - .workflow_tools - .bindings - .get(&invocation.tool_id) - }) - .and_then(|binding| match &binding.completion { - engine::WorkflowToolCompletion::Joined { - reply_schema_ref, .. - } - | engine::WorkflowToolCompletion::Promises { - reply_schema_ref, .. - } => reply_schema_ref.clone(), - engine::WorkflowToolCompletion::Accepted => None, - }); + let reply_schema_ref = + harness::WorkflowToolInvocationId::try_new(invocation_id.clone()) + .ok() + .and_then(|invocation_id| { + state + .core_state + .workflow_tools + .emissions + .get(&invocation_id) + .or_else(|| { + state + .core_state + .workflow_tools + .start_requests + .get(&invocation_id) + }) + }) + .and_then(|invocation| { + state + .core_state + .workflow_tools + .bindings + .get(&invocation.tool_id) + }) + .and_then(|binding| match &binding.completion { + harness::WorkflowToolCompletion::Joined { + reply_schema_ref, .. + } + | harness::WorkflowToolCompletion::Promises { + reply_schema_ref, .. + } => reply_schema_ref.clone(), + harness::WorkflowToolCompletion::Accepted => None, + }); (true, reply_schema_ref) }); if !authorized { @@ -321,9 +326,9 @@ pub(super) async fn process_pending_source_resolutions( continue; } let resolution = match (reply_schema_ref, resolution) { - (Some(reply_schema_ref), engine::PromiseResolution::Resolved { payload_ref }) => { + (Some(reply_schema_ref), harness::PromiseResolution::Resolved { payload_ref }) => { let validation = ctx - .start_activity( + .execute_activity( WorkflowActivities::validate_workflow_tool_reply, crate::WorkflowToolReplyValidationRequest { reply_schema_ref, @@ -335,10 +340,10 @@ pub(super) async fn process_pending_source_resolutions( .map_err(|error| anyhow::anyhow!("{error}"))?; match validation { crate::WorkflowToolReplyValidationResult::Valid => { - engine::PromiseResolution::Resolved { payload_ref } + harness::PromiseResolution::Resolved { payload_ref } } crate::WorkflowToolReplyValidationResult::Invalid { error_ref } => { - engine::PromiseResolution::Failed { + harness::PromiseResolution::Failed { error_ref: Some(error_ref), } } @@ -354,10 +359,10 @@ pub(super) async fn process_pending_source_resolutions( fn queue_resolution( ctx: &WorkflowContext, promise_id: String, - resolution: engine::PromiseResolution, + resolution: harness::PromiseResolution, ) { ctx.state_mut(|state| { - let promise_id = match engine::PromiseId::try_new(promise_id) { + let promise_id = match harness::PromiseId::try_new(promise_id) { Ok(promise_id) => promise_id, Err(error) => { state.last_error = Some(format!("cannot queue promise resolution: {error}")); @@ -378,17 +383,17 @@ fn queue_resolution( /// primary pushed-emission path, not a delivery mechanism. const WORKFLOW_EXECUTION_RECOVERY_POLL_MS: u64 = 10_000; -fn initial_check_at_ms(source: &engine::PromiseSource, now_ms: u64) -> u64 { +fn initial_check_at_ms(source: &harness::PromiseSource, now_ms: u64) -> u64 { match source { - engine::PromiseSource::Timer { fire_at_ms } => *fire_at_ms, - engine::PromiseSource::Workflow { .. } => now_ms + WORKFLOW_EXECUTION_RECOVERY_POLL_MS, + harness::PromiseSource::Timer { fire_at_ms } => *fire_at_ms, + harness::PromiseSource::Workflow { .. } => now_ms + WORKFLOW_EXECUTION_RECOVERY_POLL_MS, } } fn advance(poll: &mut PromiseSourcePoll, now_ms: u64) { poll.poll_attempt = poll.poll_attempt.saturating_add(1); poll.next_check_at_ms = match &poll.source { - engine::PromiseSource::Timer { fire_at_ms } => *fire_at_ms, - engine::PromiseSource::Workflow { .. } => now_ms + WORKFLOW_EXECUTION_RECOVERY_POLL_MS, + harness::PromiseSource::Timer { fire_at_ms } => *fire_at_ms, + harness::PromiseSource::Workflow { .. } => now_ms + WORKFLOW_EXECUTION_RECOVERY_POLL_MS, }; } diff --git a/crates/temporal-workflow/src/workflows/session/session_state.rs b/crates/temporal-workflow/src/workflows/session/session_state.rs index 59963fc66..b96b82f5b 100644 --- a/crates/temporal-workflow/src/workflows/session/session_state.rs +++ b/crates/temporal-workflow/src/workflows/session/session_state.rs @@ -19,7 +19,7 @@ impl AgentSessionWorkflow { return; } match envelope.body { - engine::EmissionBody::RunTerminal { .. } => { + harness::EmissionBody::RunTerminal { .. } => { // A receiving workflow interprets the typed run output and then // sends an authorized SourceResolution. Dropping its encoding // here would expose provider JSON as an ordinary tool result. @@ -28,7 +28,7 @@ impl AgentSessionWorkflow { .to_owned(), ); } - engine::EmissionBody::SourceResolution { + harness::EmissionBody::SourceResolution { promise_id, resolution, } => { @@ -42,13 +42,13 @@ impl AgentSessionWorkflow { producer: envelope.producer, }); } - engine::EmissionBody::ToolInvocation { invocation, .. } => { + harness::EmissionBody::ToolInvocation { invocation, .. } => { self.last_error = Some(format!( "session workflow cannot receive workflow tool invocation {}", invocation.invocation_id )); } - engine::EmissionBody::InvocationCancellation { invocation_id, .. } => { + harness::EmissionBody::InvocationCancellation { invocation_id, .. } => { self.last_error = Some(format!( "session workflow cannot receive workflow tool cancellation {invocation_id}" )); @@ -76,8 +76,9 @@ impl AgentSessionWorkflow { // pushed invocation enters the same durable Temporal delivery // spine after its admitting append commits; pull invocations are // consumed later through the receiver-authorized log read. - if let CoreAgentEvent::WorkflowTool(engine::WorkflowToolEvent::Emitted { invocation }) = - &entry.event + if let CoreAgentEvent::WorkflowTool(harness::WorkflowToolEvent::Emitted { + invocation, + }) = &entry.event { let Some(binding) = self .core_state @@ -91,9 +92,9 @@ impl AgentSessionWorkflow { ); }; match &binding.target { - engine::WorkflowToolTarget::Bound { + harness::WorkflowToolTarget::Bound { receiver, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, } => { self.pending_emissions.push(PendingEmission::immediate( receiver.workflow_id.clone(), @@ -107,11 +108,11 @@ impl AgentSessionWorkflow { )); continue; } - engine::WorkflowToolTarget::Bound { - dispatch: engine::BoundWorkflowToolDispatch::Pull, + harness::WorkflowToolTarget::Bound { + dispatch: harness::BoundWorkflowToolDispatch::Pull, .. } => {} - engine::WorkflowToolTarget::Start { .. } => { + harness::WorkflowToolTarget::Start { .. } => { anyhow::bail!( "emitted workflow tool invocation {} has a start-target binding", invocation.invocation_id @@ -155,7 +156,7 @@ impl AgentSessionWorkflow { pub(super) fn queue_promise_cancellations_for_entries(&mut self, entries: &[CoreAgentEntry]) { for entry in entries { - let CoreAgentEvent::Promise(engine::PromiseEvent::Cancelled { promise_id }) = + let CoreAgentEvent::Promise(harness::PromiseEvent::Cancelled { promise_id }) = &entry.event else { continue; @@ -239,7 +240,7 @@ impl AgentSessionWorkflow { } } -fn terminal_run_id_for_event(event: &CoreAgentEvent) -> Option { +fn terminal_run_id_for_event(event: &CoreAgentEvent) -> Option { match event { CoreAgentEvent::Run( RunEvent::Completed { run_id, .. } @@ -284,6 +285,7 @@ pub(super) async fn flush_pending_emissions( .signal( AgentSessionWorkflow::deliver_emission, pending.envelope.clone(), + crate::workflows::signal_options(), ) .await .is_ok(); @@ -292,7 +294,7 @@ pub(super) async fn flush_pending_emissions( } if !matches!( pending.envelope.body, - engine::EmissionBody::ToolInvocation { .. } + harness::EmissionBody::ToolInvocation { .. } ) { continue; } @@ -316,7 +318,7 @@ async fn terminal_tool_invocation_delivery_failure( ctx: &mut WorkflowContext, pending: &PendingEmission, ) -> anyhow::Result<()> { - let engine::EmissionBody::ToolInvocation { invocation, .. } = &pending.envelope.body else { + let harness::EmissionBody::ToolInvocation { invocation, .. } = &pending.envelope.body else { return Ok(()); }; let message = format!( @@ -324,7 +326,7 @@ async fn terminal_tool_invocation_delivery_failure( invocation.invocation_id, pending.receiver_workflow_id, pending.attempts ); let error_ref = ctx - .start_activity( + .execute_activity( WorkflowActivities::put_blob, PutBlobRequest { bytes: message.into_bytes(), diff --git a/crates/temporal-workflow/src/workflows/session/tests.rs b/crates/temporal-workflow/src/workflows/session/tests.rs index c2605a80c..f36cdac3b 100644 --- a/crates/temporal-workflow/src/workflows/session/tests.rs +++ b/crates/temporal-workflow/src/workflows/session/tests.rs @@ -1,5 +1,5 @@ use super::*; -use engine::{ +use harness::{ AwaitSpec, ContextEntryInput, ContextEntryKind, ContextMessageRole, CoreAgentEntry, CoreAgentJoins, EventSeq, PromiseScope, PromiseSource, PromiseStatus, RunId, RunRecord, RunStatus, RunTerminalNotifyIntent, SessionPosition, ToolBatchId, ToolCallId, TurnId, @@ -25,7 +25,7 @@ fn pending_admissions_are_fifo() { #[test] fn admission_failure_status_does_not_poison_later_admission() { let mut workflow = AgentSessionWorkflow::default(); - let rejection = engine::CommandRejection::context_revision_conflict(3, 4); + let rejection = harness::CommandRejection::context_revision_conflict(3, 4); workflow.admission_failures.push(AgentAdmissionFailure { preparation_error: None, submission_id: Some(SubmissionId::new("submit_rejected")), @@ -59,15 +59,15 @@ fn admission_failure_status_does_not_poison_later_admission() { #[test] fn source_resolution_emission_queues_pending_resolution_with_producer() { let mut workflow = AgentSessionWorkflow::default(); - let payload_ref = engine::BlobRef::from_bytes(b"job output"); + let payload_ref = harness::BlobRef::from_bytes(b"job output"); workflow.queue_emission( test_universe(), - engine::EmissionEnvelope::source_resolution( + harness::EmissionEnvelope::source_resolution( test_universe(), "universe/envjob-job_1".to_owned(), "universe/session_1", - engine::PromiseId::new("promise_1"), - engine::PromiseResolution::Resolved { + harness::PromiseId::new("promise_1"), + harness::PromiseResolution::Resolved { payload_ref: Some(payload_ref.clone()), }, ), @@ -80,13 +80,13 @@ fn source_resolution_emission_queues_pending_resolution_with_producer() { assert_eq!(pending.promise_id.as_str(), "promise_1"); assert!(matches!( &pending.resolution, - engine::PromiseResolution::Resolved { + harness::PromiseResolution::Resolved { payload_ref: Some(actual), } if actual == &payload_ref )); assert!(matches!( &pending.producer, - engine::EmissionProducer::Workflow { workflow_id, .. } + harness::EmissionProducer::Workflow { workflow_id, .. } if workflow_id == "universe/envjob-job_1" )); } @@ -96,16 +96,16 @@ fn duplicate_source_resolution_delivery_is_an_end_to_end_noop() { let mut workflow = AgentSessionWorkflow::default(); workflow.core_state.lifecycle.status = CoreAgentStatus::Open; workflow.core_state.promises.promises.insert( - engine::PromiseId::new("promise_1"), + harness::PromiseId::new("promise_1"), promise("promise_1", PromiseStatus::Pending), ); - let payload_ref = engine::BlobRef::from_bytes(b"job output"); - let envelope = engine::EmissionEnvelope::source_resolution( + let payload_ref = harness::BlobRef::from_bytes(b"job output"); + let envelope = harness::EmissionEnvelope::source_resolution( test_universe(), "universe/envjob-job_1".to_owned(), "universe/session_1", - engine::PromiseId::new("promise_1"), - engine::PromiseResolution::Resolved { + harness::PromiseId::new("promise_1"), + harness::PromiseResolution::Resolved { payload_ref: Some(payload_ref.clone()), }, ); @@ -131,7 +131,7 @@ fn duplicate_source_resolution_delivery_is_an_end_to_end_noop() { let mut appended = 0u64; for (index, admission) in admissions.into_iter().enumerate() { let proposals = - engine::admit_command(&workflow.core_state, admission.command, index as u64 + 1) + harness::admit_command(&workflow.core_state, admission.command, index as u64 + 1) .expect("admit duplicate emission"); appended += proposals.len() as u64; for proposal in proposals { @@ -140,7 +140,7 @@ fn duplicate_source_resolution_delivery_is_an_end_to_end_noop() { .reduced_to .as_ref() .map_or(1, |position| position.seq.as_u64() + 1); - engine::apply_event( + harness::apply_event( &mut workflow.core_state, &CoreAgentEntry { position: SessionPosition { @@ -160,7 +160,7 @@ fn duplicate_source_resolution_delivery_is_an_end_to_end_noop() { .core_state .promises .promises - .get(&engine::PromiseId::new("promise_1")) + .get(&harness::PromiseId::new("promise_1")) .expect("resolved promise"); assert_eq!(promise.status, PromiseStatus::Resolved); assert_eq!(promise.payload_ref.as_ref(), Some(&payload_ref)); @@ -172,12 +172,12 @@ fn cross_universe_emission_is_rejected_before_admission() { let producer_universe = uuid::Uuid::from_u128(2); workflow.queue_emission( test_universe(), - engine::EmissionEnvelope::source_resolution( + harness::EmissionEnvelope::source_resolution( producer_universe, "other-universe/envjob-job_1".to_owned(), "universe/session_1", - engine::PromiseId::new("promise_1"), - engine::PromiseResolution::Resolved { payload_ref: None }, + harness::PromiseId::new("promise_1"), + harness::PromiseResolution::Resolved { payload_ref: None }, ), ); @@ -205,7 +205,7 @@ fn close_on_terminal_requires_idle_open_session_with_completed_run() { status: RunStatus::Completed, submission_id: None, submission_digest: None, - source: engine::RunSource::Input { input: Vec::new() }, + source: harness::RunSource::Input { input: Vec::new() }, first_seq: EventSeq::new(1), terminal_seq: EventSeq::new(1), accepted_at_ms: 1, @@ -222,14 +222,14 @@ fn close_on_terminal_requires_idle_open_session_with_completed_run() { )); state.promises.promises.insert( - engine::PromiseId::new("promise_14"), + harness::PromiseId::new("promise_14"), promise("promise_14", PromiseStatus::Pending), ); assert!(!drive::should_close_on_terminal(&args, &state)); state .promises .promises - .get_mut(&engine::PromiseId::new("promise_14")) + .get_mut(&harness::PromiseId::new("promise_14")) .expect("promise") .status = PromiseStatus::Resolved; assert!(drive::should_close_on_terminal(&args, &state)); @@ -279,8 +279,8 @@ fn active_drive_rollover_outcome_is_typed_and_waits_for_transport_drain() { #[test] fn rehydrated_active_run_wakes_core_drive_without_a_new_signal() { let mut workflow = workflow_with_parked_tool_batch(AwaitSpec { - promise_ids: vec![engine::PromiseId::new("promise_1")], - mode: engine::AwaitMode::All, + promise_ids: vec![harness::PromiseId::new("promise_1")], + mode: harness::AwaitMode::All, deadline_at_ms: Some(50_000), }); assert!(!wait_loop::workflow_state_needs_core_drive_for_state( @@ -321,7 +321,7 @@ fn legacy_step_limit_decodes_but_is_never_serialized() { #[test] fn continuation_state_round_trips_admission_failure_correlation() { - let rejection = engine::CommandRejection::context_revision_conflict(3, 4); + let rejection = harness::CommandRejection::context_revision_conflict(3, 4); let continuation = AgentSessionContinuationState::v1(vec![AgentAdmissionFailure { preparation_error: None, submission_id: Some(SubmissionId::new("submit_rejected")), @@ -339,23 +339,23 @@ fn continuation_state_round_trips_admission_failure_correlation() { /// An input-bearing run request with a submission id: the generic admission /// used where a test only needs "some command carrying input". fn request_input_run(submission_id: &str) -> CoreAgentCommand { - CoreAgentCommand::RequestRun(engine::RunRequestCommand { + CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: Some(SubmissionId::new(submission_id)), - source: engine::RunRequestSource::Input { - input: user_input(engine::BlobRef::from_bytes(submission_id.as_bytes())), + source: harness::RunRequestSource::Input { + input: user_input(harness::BlobRef::from_bytes(submission_id.as_bytes())), }, run_config: crate::default_run_config(), }) } -fn user_input(content_ref: engine::BlobRef) -> Vec { +fn user_input(content_ref: harness::BlobRef) -> Vec { vec![ContextEntryInput { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -382,8 +382,8 @@ fn agent_session_args_with_close_on_terminal(close_on_terminal: bool) -> AgentSe session_id: SessionId::new("session_test"), display_name: None, delete_after_close_ms: None, - session_config: crate::default_session_config(engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + session_config: crate::default_session_config(harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".to_owned(), model: "gpt-test".to_owned(), }), @@ -400,9 +400,9 @@ fn test_universe() -> uuid::Uuid { uuid::Uuid::from_u128(1) } -fn managed_workflow_tools(controller_workflow_id: &str) -> engine::ManagedSessionWorkflowTools { - engine::ManagedSessionWorkflowTools::v1( - Some(engine::WorkflowEndpointRef { +fn managed_workflow_tools(controller_workflow_id: &str) -> harness::ManagedSessionWorkflowTools { + harness::ManagedSessionWorkflowTools::v1( + Some(harness::WorkflowEndpointRef { workflow_id: controller_workflow_id.to_owned(), workflow_kind: "agent_work".to_owned(), }), @@ -462,7 +462,7 @@ fn bootstrap_creation_identity_records_source_universe_and_is_immutable() { fn pending_run_emission() -> PendingEmission { PendingEmission::immediate( "universe/parent".to_owned(), - engine::EmissionEnvelope::run_terminal( + harness::EmissionEnvelope::run_terminal( test_universe(), SessionId::new("session_child"), EventSeq::new(1), @@ -478,13 +478,13 @@ fn pending_run_emission() -> PendingEmission { fn pending_resume(batch_id: u64) -> PendingToolBatchResume { PendingToolBatchResume { batch_id: ToolBatchId::new(batch_id), - command: engine::ResumeToolBatchCommand { + command: harness::ResumeToolBatchCommand { run_id: RunId::new(1), batch_id: ToolBatchId::new(batch_id), - claim: engine::WakeReason::Timeout, + claim: harness::WakeReason::Timeout, claim_observed_at_ms: 1_000, - output: engine::ToolBatchResumeOutput::AwaitTool { - result_ref: engine::BlobRef::from_bytes(b"await output"), + output: harness::ToolBatchResumeOutput::AwaitTool { + result_ref: harness::BlobRef::from_bytes(b"await output"), additional_context: Vec::new(), attachments: Vec::new(), }, @@ -500,7 +500,7 @@ fn pending_promise_cancellation(promise_id: &str) -> PendingPromiseCancellation } } -fn workflow_with_parked_tool_batch(spec: engine::AwaitSpec) -> AgentSessionWorkflow { +fn workflow_with_parked_tool_batch(spec: harness::AwaitSpec) -> AgentSessionWorkflow { let mut workflow = AgentSessionWorkflow { ready: true, setup_requested: false, @@ -513,33 +513,33 @@ fn workflow_with_parked_tool_batch(spec: engine::AwaitSpec) -> AgentSessionWorkf let mut tool_batches = std::collections::BTreeMap::new(); tool_batches.insert( batch_id, - engine::ActiveToolBatch { + harness::ActiveToolBatch { batch_id, run_id, turn_id, promise_id_base: 1, - calls: vec![engine::ToolCallState { - call: engine::ObservedToolCall { + calls: vec![harness::ToolCallState { + call: harness::ObservedToolCall { call_id: call_id.clone(), - tool_id: Some((engine::ToolName::new("await")).clone()), - tool_name: engine::ToolName::new("await"), + tool_id: Some((harness::ToolName::new("await")).clone()), + tool_name: harness::ToolName::new("await"), provider_kind: None, - arguments_ref: engine::BlobRef::from_bytes(b"{}"), + arguments_ref: harness::BlobRef::from_bytes(b"{}"), native_call_ref: None, }, - status: engine::ToolCallStatus::Pending, + status: harness::ToolCallStatus::Pending, execution_policy: None, result: None, }], }, ); - workflow.core_state.runs.active = Some(engine::ActiveRun { + workflow.core_state.runs.active = Some(harness::ActiveRun { context_recovery: Default::default(), run_id, status: RunStatus::Parked, submission_id: None, - source: engine::RunSource::Input { - input: user_input(engine::BlobRef::from_bytes(b"start")), + source: harness::RunSource::Input { + input: user_input(harness::BlobRef::from_bytes(b"start")), }, input_entry_ids: Vec::new(), input_consumed_by_turn_id: None, @@ -554,9 +554,9 @@ fn workflow_with_parked_tool_batch(spec: engine::AwaitSpec) -> AgentSessionWorkf active_turn_id: None, active_tool_batch_id: Some(batch_id), approvals: Default::default(), - parked_tool_batch: Some(engine::ParkedToolBatch { + parked_tool_batch: Some(harness::ParkedToolBatch { batch_id, - suspension: engine::ToolBatchSuspension::AwaitTool { call_id, spec }, + suspension: harness::ToolBatchSuspension::AwaitTool { call_id, spec }, }), tool_batches, completed_tool_batches: std::collections::BTreeMap::new(), @@ -626,15 +626,15 @@ fn run_terminal_notifications_cannot_drop_output_encoding_into_a_session_promise let mut workflow = AgentSessionWorkflow::default(); workflow.queue_emission( test_universe(), - engine::EmissionEnvelope::run_terminal( + harness::EmissionEnvelope::run_terminal( test_universe(), SessionId::new("child_a"), EventSeq::new(8), "promise_1".to_owned(), RunId::new(1), RunStatus::Completed, - Some(engine::ContentRef { - content_ref: engine::BlobRef::from_bytes(b"native output"), + Some(harness::ContentRef { + content_ref: harness::BlobRef::from_bytes(b"native output"), media_type: Some("application/json".to_owned()), provider_kind: Some("provider.message".to_owned()), }), @@ -654,50 +654,50 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { ..Default::default() }; - let binding = engine::WorkflowToolBinding::admit( + let binding = harness::WorkflowToolBinding::admit( test_universe(), - engine::WorkflowToolDefinition { - tool_id: engine::WorkflowToolId::new("approve"), + harness::WorkflowToolDefinition { + tool_id: harness::WorkflowToolId::new("approve"), revision: 1, semantic_type: "lightspeed.approval.request.v1".to_owned(), - tool: engine::ToolSpec { - name: engine::ToolName::new("request_approval"), + tool: harness::ToolSpec { + name: harness::ToolName::new("request_approval"), execution: Default::default(), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: None, - input_schema_ref: engine::BlobRef::from_bytes(b"{}"), + input_schema_ref: harness::BlobRef::from_bytes(b"{}"), output_schema_ref: None, strict: None, provider_options_ref: None, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, }, }, - engine::WorkflowToolTarget::Bound { - receiver: engine::WorkflowEndpointRef { + harness::WorkflowToolTarget::Bound { + receiver: harness::WorkflowEndpointRef { workflow_id: "approval plugin id".to_owned(), workflow_kind: "approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, - engine::WorkflowToolCompletion::Promises { + harness::WorkflowToolCompletion::Promises { reply_schema_ref: None, deadline_after_ms: None, max_promises: 1, - key_source: engine::WorkflowToolCompletionKeySource::Reply, + key_source: harness::WorkflowToolCompletionKeySource::Reply, }, ) .expect("binding"); - let invocation_id = engine::WorkflowToolInvocationId::for_call( + let invocation_id = harness::WorkflowToolInvocationId::for_call( test_universe(), &SessionId::new("child_session"), RunId::new(1), - engine::TurnId::new(1), + harness::TurnId::new(1), ToolBatchId::new(1), - &engine::ToolCallId::new("call-1"), + &harness::ToolCallId::new("call-1"), &binding.binding_fingerprint, ); - let invocation = engine::WorkflowToolInvocation { + let invocation = harness::WorkflowToolInvocation { invocation_id: invocation_id.clone(), tool_id: binding.definition.tool_id.clone(), semantic_type: binding.definition.semantic_type.clone(), @@ -706,14 +706,14 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { session_universe_id: test_universe(), session_id: SessionId::new("child_session"), run_id: RunId::new(1), - turn_id: engine::TurnId::new(1), + turn_id: harness::TurnId::new(1), tool_batch_id: ToolBatchId::new(1), - tool_call_id: engine::ToolCallId::new("call-1"), - arguments_ref: engine::BlobRef::from_bytes(b"{}"), + tool_call_id: harness::ToolCallId::new("call-1"), + arguments_ref: harness::BlobRef::from_bytes(b"{}"), execution_context_ref: None, completion_promises: Some(std::collections::BTreeMap::from([( - engine::REPLY_COMPLETION_KEY.to_owned(), - engine::PromiseId::from_number(1), + harness::REPLY_COMPLETION_KEY.to_owned(), + harness::PromiseId::from_number(1), )])), }; workflow @@ -722,13 +722,13 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { .bindings .insert(binding.definition.tool_id.clone(), binding.clone()); - let entry = engine::CoreAgentEntry { + let entry = harness::CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(9), }, observed_at_ms: 100, joins: CoreAgentJoins::default(), - event: CoreAgentEvent::WorkflowTool(engine::WorkflowToolEvent::Emitted { + event: CoreAgentEvent::WorkflowTool(harness::WorkflowToolEvent::Emitted { invocation: invocation.clone(), }), }; @@ -747,7 +747,7 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { ); assert!(matches!( &pending.envelope.body, - engine::EmissionBody::ToolInvocation { + harness::EmissionBody::ToolInvocation { invocation: delivered, .. } @@ -755,29 +755,29 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { )); // Accepted completion uses the same push path when dispatch says Push. - let accepted_binding = engine::WorkflowToolBinding::admit( + let accepted_binding = harness::WorkflowToolBinding::admit( test_universe(), binding.definition.clone(), - engine::WorkflowToolTarget::Bound { - receiver: engine::WorkflowEndpointRef { + harness::WorkflowToolTarget::Bound { + receiver: harness::WorkflowEndpointRef { workflow_id: "approval plugin id".to_owned(), workflow_kind: "approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, - engine::WorkflowToolCompletion::Accepted, + harness::WorkflowToolCompletion::Accepted, ) .expect("pushed Accepted binding"); - let accepted_invocation_id = engine::WorkflowToolInvocationId::for_call( + let accepted_invocation_id = harness::WorkflowToolInvocationId::for_call( test_universe(), &SessionId::new("child_session"), RunId::new(1), - engine::TurnId::new(1), + harness::TurnId::new(1), ToolBatchId::new(1), - &engine::ToolCallId::new("call-2"), + &harness::ToolCallId::new("call-2"), &accepted_binding.binding_fingerprint, ); - let accepted_invocation = engine::WorkflowToolInvocation { + let accepted_invocation = harness::WorkflowToolInvocation { invocation_id: accepted_invocation_id.clone(), tool_id: accepted_binding.definition.tool_id.clone(), semantic_type: accepted_binding.definition.semantic_type.clone(), @@ -786,10 +786,10 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { session_universe_id: test_universe(), session_id: SessionId::new("child_session"), run_id: RunId::new(1), - turn_id: engine::TurnId::new(1), + turn_id: harness::TurnId::new(1), tool_batch_id: ToolBatchId::new(1), - tool_call_id: engine::ToolCallId::new("call-2"), - arguments_ref: engine::BlobRef::from_bytes(b"{}"), + tool_call_id: harness::ToolCallId::new("call-2"), + arguments_ref: harness::BlobRef::from_bytes(b"{}"), execution_context_ref: None, completion_promises: None, }; @@ -797,13 +797,13 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { accepted_binding.definition.tool_id.clone(), accepted_binding.clone(), ); - let accepted_entry = engine::CoreAgentEntry { + let accepted_entry = harness::CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(10), }, observed_at_ms: 101, joins: CoreAgentJoins::default(), - event: CoreAgentEvent::WorkflowTool(engine::WorkflowToolEvent::Emitted { + event: CoreAgentEvent::WorkflowTool(harness::WorkflowToolEvent::Emitted { invocation: accepted_invocation.clone(), }), }; @@ -823,7 +823,7 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { status: RunStatus::Completed, submission_id: None, submission_digest: None, - source: engine::RunSource::Input { input: Vec::new() }, + source: harness::RunSource::Input { input: Vec::new() }, first_seq: EventSeq::new(1), terminal_seq: EventSeq::new(1), accepted_at_ms: 1, @@ -834,7 +834,7 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { failure: None, notify_on_terminal: Vec::new(), }); - let terminal_entry = engine::CoreAgentEntry { + let terminal_entry = harness::CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(11), }, @@ -852,29 +852,29 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { // Pull dispatch remains out of the push queue even with the same // Accepted completion contract. - let pull_binding = engine::WorkflowToolBinding::admit( + let pull_binding = harness::WorkflowToolBinding::admit( test_universe(), binding.definition, - engine::WorkflowToolTarget::Bound { - receiver: engine::WorkflowEndpointRef { + harness::WorkflowToolTarget::Bound { + receiver: harness::WorkflowEndpointRef { workflow_id: "approval plugin id".to_owned(), workflow_kind: "approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Pull, + dispatch: harness::BoundWorkflowToolDispatch::Pull, }, - engine::WorkflowToolCompletion::Accepted, + harness::WorkflowToolCompletion::Accepted, ) .expect("pull Accepted binding"); - let pull_invocation_id = engine::WorkflowToolInvocationId::for_call( + let pull_invocation_id = harness::WorkflowToolInvocationId::for_call( test_universe(), &SessionId::new("child_session"), RunId::new(1), - engine::TurnId::new(1), + harness::TurnId::new(1), ToolBatchId::new(1), - &engine::ToolCallId::new("call-3"), + &harness::ToolCallId::new("call-3"), &pull_binding.binding_fingerprint, ); - let pull_invocation = engine::WorkflowToolInvocation { + let pull_invocation = harness::WorkflowToolInvocation { invocation_id: pull_invocation_id, tool_id: pull_binding.definition.tool_id.clone(), semantic_type: pull_binding.definition.semantic_type.clone(), @@ -883,10 +883,10 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { session_universe_id: test_universe(), session_id: SessionId::new("child_session"), run_id: RunId::new(1), - turn_id: engine::TurnId::new(1), + turn_id: harness::TurnId::new(1), tool_batch_id: ToolBatchId::new(1), - tool_call_id: engine::ToolCallId::new("call-3"), - arguments_ref: engine::BlobRef::from_bytes(b"{}"), + tool_call_id: harness::ToolCallId::new("call-3"), + arguments_ref: harness::BlobRef::from_bytes(b"{}"), execution_context_ref: None, completion_promises: None, }; @@ -895,13 +895,13 @@ fn bound_dispatch_controls_push_delivery_independently_of_completion() { .workflow_tools .bindings .insert(pull_binding.definition.tool_id.clone(), pull_binding); - let pull_entry = engine::CoreAgentEntry { + let pull_entry = harness::CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(12), }, observed_at_ms: 103, joins: CoreAgentJoins::default(), - event: CoreAgentEvent::WorkflowTool(engine::WorkflowToolEvent::Emitted { + event: CoreAgentEvent::WorkflowTool(harness::WorkflowToolEvent::Emitted { invocation: pull_invocation, }), }; @@ -919,55 +919,55 @@ fn start_intents_recompute_pending_start_work_from_durable_state() { ..Default::default() }; - let start = engine::WorkflowStartRef { + let start = harness::WorkflowStartRef { recipe_format: 1, revision: 1, - recipe_ref: engine::BlobRef::from_bytes(b"recipe"), + recipe_ref: harness::BlobRef::from_bytes(b"recipe"), recipe_fingerprint: "wtr:sha256:recipe".to_owned(), }; - let binding = engine::WorkflowToolBinding::admit( + let binding = harness::WorkflowToolBinding::admit( test_universe(), - engine::WorkflowToolDefinition { - tool_id: engine::WorkflowToolId::new("launch"), + harness::WorkflowToolDefinition { + tool_id: harness::WorkflowToolId::new("launch"), revision: 1, semantic_type: "lightspeed.job.launch.v1".to_owned(), - tool: engine::ToolSpec { - name: engine::ToolName::new("launch_job"), + tool: harness::ToolSpec { + name: harness::ToolName::new("launch_job"), execution: Default::default(), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: None, - input_schema_ref: engine::BlobRef::from_bytes(b"{}"), + input_schema_ref: harness::BlobRef::from_bytes(b"{}"), output_schema_ref: None, strict: None, provider_options_ref: None, }), - parallelism: engine::ToolParallelism::ParallelSafe, + parallelism: harness::ToolParallelism::ParallelSafe, }, }, - engine::WorkflowToolTarget::Start { + harness::WorkflowToolTarget::Start { start: start.clone(), }, - engine::WorkflowToolCompletion::Promises { + harness::WorkflowToolCompletion::Promises { reply_schema_ref: None, deadline_after_ms: None, max_promises: 1, - key_source: engine::WorkflowToolCompletionKeySource::Reply, + key_source: harness::WorkflowToolCompletionKeySource::Reply, }, ) .expect("start binding"); - let invocation_id = engine::WorkflowToolInvocationId::for_call( + let invocation_id = harness::WorkflowToolInvocationId::for_call( test_universe(), &SessionId::new("child_session"), RunId::new(1), - engine::TurnId::new(1), + harness::TurnId::new(1), ToolBatchId::new(1), - &engine::ToolCallId::new("call-1"), + &harness::ToolCallId::new("call-1"), &binding.binding_fingerprint, ); - let promise_id = engine::PromiseId::from_number(1); + let promise_id = harness::PromiseId::from_number(1); let execution_id = - engine::workflow_tool_execution_id(&invocation_id, &start.recipe_fingerprint); - let invocation = engine::WorkflowToolInvocation { + harness::workflow_tool_execution_id(&invocation_id, &start.recipe_fingerprint); + let invocation = harness::WorkflowToolInvocation { invocation_id: invocation_id.clone(), tool_id: binding.definition.tool_id.clone(), semantic_type: binding.definition.semantic_type.clone(), @@ -976,13 +976,13 @@ fn start_intents_recompute_pending_start_work_from_durable_state() { session_universe_id: test_universe(), session_id: SessionId::new("child_session"), run_id: RunId::new(1), - turn_id: engine::TurnId::new(1), + turn_id: harness::TurnId::new(1), tool_batch_id: ToolBatchId::new(1), - tool_call_id: engine::ToolCallId::new("call-1"), - arguments_ref: engine::BlobRef::from_bytes(b"{}"), + tool_call_id: harness::ToolCallId::new("call-1"), + arguments_ref: harness::BlobRef::from_bytes(b"{}"), execution_context_ref: None, completion_promises: Some(std::collections::BTreeMap::from([( - engine::REPLY_COMPLETION_KEY.to_owned(), + harness::REPLY_COMPLETION_KEY.to_owned(), promise_id.clone(), )])), }; @@ -998,16 +998,16 @@ fn start_intents_recompute_pending_start_work_from_durable_state() { .insert(invocation_id.clone(), invocation); workflow.core_state.promises.promises.insert( promise_id.clone(), - engine::Promise { + harness::Promise { promise_id: promise_id.clone(), - source: engine::PromiseSource::Workflow { + source: harness::PromiseSource::Workflow { producer_workflow_id: execution_id.clone(), - producer_workflow_kind: engine::WORKFLOW_TOOL_EXECUTION_KIND.to_owned(), + producer_workflow_kind: harness::WORKFLOW_TOOL_EXECUTION_KIND.to_owned(), invocation_id: invocation_id.as_str().to_owned(), - completion_key: engine::REPLY_COMPLETION_KEY.to_owned(), + completion_key: harness::REPLY_COMPLETION_KEY.to_owned(), }, - scope: engine::PromiseScope::Session, - ownership: engine::PromiseOwnership::Model, + scope: harness::PromiseScope::Session, + ownership: harness::PromiseOwnership::Model, status: PromiseStatus::Pending, payload_ref: None, error_ref: None, @@ -1032,7 +1032,7 @@ fn start_intents_recompute_pending_start_work_from_durable_state() { .core_state .workflow_tools .start_failures - .insert(invocation_id.clone(), engine::BlobRef::from_bytes(b"err")); + .insert(invocation_id.clone(), harness::BlobRef::from_bytes(b"err")); assert!(!workflow_starts::has_immediate_work(&workflow)); workflow.core_state.workflow_tools.start_failures.clear(); @@ -1073,13 +1073,13 @@ fn terminal_run_with_notify_intent_queues_emission() { session_id: Some(SessionId::new("child_session")), ..Default::default() }; - let output_ref = engine::ContentRef::text(engine::BlobRef::from_bytes(b"done")); + let output_ref = harness::ContentRef::text(harness::BlobRef::from_bytes(b"done")); workflow.core_state.runs.completed.push(RunRecord { run_id: RunId::new(3), status: RunStatus::Completed, submission_id: None, submission_digest: None, - source: engine::RunSource::Input { input: Vec::new() }, + source: harness::RunSource::Input { input: Vec::new() }, first_seq: EventSeq::new(1), terminal_seq: EventSeq::new(1), accepted_at_ms: 1, @@ -1093,7 +1093,7 @@ fn terminal_run_with_notify_intent_queues_emission() { token: "promise_parent".to_owned(), }], }); - let entry = engine::CoreAgentEntry { + let entry = harness::CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(1), }, @@ -1114,7 +1114,7 @@ fn terminal_run_with_notify_intent_queues_emission() { assert_eq!(pending.receiver_workflow_id, "universe/parent_session"); assert!(matches!( &pending.envelope.producer, - engine::EmissionProducer::Session { + harness::EmissionProducer::Session { universe_id, session_id, log_seq, @@ -1124,7 +1124,7 @@ fn terminal_run_with_notify_intent_queues_emission() { )); assert!(matches!( &pending.envelope.body, - engine::EmissionBody::RunTerminal { + harness::EmissionBody::RunTerminal { token, run_id, status: RunStatus::Completed, @@ -1145,7 +1145,7 @@ fn terminal_run_with_notify_intent_queues_emission() { assert!(workflow.pending_emissions.is_empty()); } -fn promise(id: &str, status: PromiseStatus) -> engine::Promise { +fn promise(id: &str, status: PromiseStatus) -> harness::Promise { promise_with_source( id, status, @@ -1161,7 +1161,7 @@ fn bound_workflow_source(peer: &str) -> PromiseSource { producer_workflow_id: format!("universe/{peer}"), producer_workflow_kind: "bound_receiver".to_owned(), invocation_id: format!("wti_{peer}"), - completion_key: engine::REPLY_COMPLETION_KEY.to_owned(), + completion_key: harness::REPLY_COMPLETION_KEY.to_owned(), } } @@ -1170,12 +1170,12 @@ fn promise_with_source( status: PromiseStatus, source: PromiseSource, scope: PromiseScope, -) -> engine::Promise { - engine::Promise { - promise_id: engine::PromiseId::new(id), +) -> harness::Promise { + harness::Promise { + promise_id: harness::PromiseId::new(id), source, scope, - ownership: engine::PromiseOwnership::Model, + ownership: harness::PromiseOwnership::Model, status, payload_ref: None, error_ref: None, @@ -1183,7 +1183,7 @@ fn promise_with_source( } } -fn add_promises(workflow: &mut AgentSessionWorkflow, promises: Vec) { +fn add_promises(workflow: &mut AgentSessionWorkflow, promises: Vec) { for promise in promises { workflow .core_state @@ -1195,11 +1195,11 @@ fn add_promises(workflow: &mut AgentSessionWorkflow, promises: Vec, -) -> engine::AwaitSpec { - engine::AwaitSpec { - promise_ids: ids.iter().map(|id| engine::PromiseId::new(*id)).collect(), +) -> harness::AwaitSpec { + harness::AwaitSpec { + promise_ids: ids.iter().map(|id| harness::PromiseId::new(*id)).collect(), mode, deadline_at_ms, } @@ -1209,7 +1209,7 @@ fn await_spec( fn workflow_await_waits_for_every_promise_in_all_mode() { let mut workflow = workflow_with_parked_tool_batch(await_spec( &["promise_1", "promise_2"], - engine::AwaitMode::All, + harness::AwaitMode::All, None, )); add_promises( @@ -1233,13 +1233,13 @@ fn workflow_await_waits_for_every_promise_in_all_mode() { #[test] fn parked_join_reconstructs_wake_from_runtime_owned_terminal_promises() { - let promise_id = engine::PromiseId::new("promise_15"); - let mut workflow = workflow_with_parked_tool_batch(engine::AwaitSpec { + let promise_id = harness::PromiseId::new("promise_15"); + let mut workflow = workflow_with_parked_tool_batch(harness::AwaitSpec { promise_ids: vec![promise_id.clone()], - mode: engine::AwaitMode::All, + mode: harness::AwaitMode::All, deadline_at_ms: None, }); - let invocation_id = engine::WorkflowToolInvocationId::for_call( + let invocation_id = harness::WorkflowToolInvocationId::for_call( test_universe(), &SessionId::new("child_session"), RunId::new(1), @@ -1257,34 +1257,34 @@ fn parked_join_reconstructs_wake_from_runtime_owned_terminal_promises() { .parked_tool_batch .as_mut() .expect("parked batch") - .suspension = engine::ToolBatchSuspension::JoinedWorkflowCalls { - calls: vec![engine::JoinedWorkflowCall { + .suspension = harness::ToolBatchSuspension::JoinedWorkflowCalls { + calls: vec![harness::JoinedWorkflowCall { call_id: ToolCallId::new("call_await"), invocation_id, promise_id: promise_id.clone(), }], - spec: engine::AwaitSpec { + spec: harness::AwaitSpec { promise_ids: vec![promise_id.clone()], - mode: engine::AwaitMode::All, + mode: harness::AwaitMode::All, deadline_at_ms: None, }, }; workflow.core_state.promises.promises.insert( promise_id.clone(), - engine::Promise { + harness::Promise { promise_id, source: PromiseSource::Workflow { producer_workflow_id: "channels".to_owned(), producer_workflow_kind: "channels.session".to_owned(), invocation_id: "joined".to_owned(), - completion_key: engine::REPLY_COMPLETION_KEY.to_owned(), + completion_key: harness::REPLY_COMPLETION_KEY.to_owned(), }, scope: PromiseScope::Run { run_id: RunId::new(1), }, - ownership: engine::PromiseOwnership::Runtime, + ownership: harness::PromiseOwnership::Runtime, status: PromiseStatus::Resolved, - payload_ref: Some(engine::BlobRef::from_bytes(b"receipt")), + payload_ref: Some(harness::BlobRef::from_bytes(b"receipt")), error_ref: None, deadline_ms: Some(50_000), }, @@ -1299,7 +1299,7 @@ fn parked_join_reconstructs_wake_from_runtime_owned_terminal_promises() { fn workflow_await_resolves_any_mode_on_first_terminal_promise() { let mut workflow = workflow_with_parked_tool_batch(await_spec( &["promise_1", "promise_2"], - engine::AwaitMode::Any, + harness::AwaitMode::Any, None, )); add_promises( @@ -1316,7 +1316,7 @@ fn workflow_await_resolves_any_mode_on_first_terminal_promise() { fn workflow_await_deadline_uses_timer_not_state_condition() { let mut workflow = workflow_with_parked_tool_batch(await_spec( &["promise_1"], - engine::AwaitMode::All, + harness::AwaitMode::All, Some(1_000), )); add_promises( @@ -1329,7 +1329,7 @@ fn workflow_await_deadline_uses_timer_not_state_condition() { #[test] fn promise_snapshot_reports_pending_promise() { - let spec = await_spec(&["promise_1"], engine::AwaitMode::All, Some(1_000)); + let spec = await_spec(&["promise_1"], harness::AwaitMode::All, Some(1_000)); let mut workflow = workflow_with_parked_tool_batch(spec.clone()); add_promises( &mut workflow, @@ -1341,14 +1341,14 @@ fn promise_snapshot_reports_pending_promise() { #[test] fn continue_as_new_allows_pending_sources_and_parked_tool_batches() { - let mut workflow = workflow_with_parked_tool_batch(engine::AwaitSpec { + let mut workflow = workflow_with_parked_tool_batch(harness::AwaitSpec { promise_ids: vec![ - engine::PromiseId::new("promise_11"), - engine::PromiseId::new("promise_12"), - engine::PromiseId::new("promise_13"), - engine::PromiseId::new("promise_14"), + harness::PromiseId::new("promise_11"), + harness::PromiseId::new("promise_12"), + harness::PromiseId::new("promise_13"), + harness::PromiseId::new("promise_14"), ], - mode: engine::AwaitMode::All, + mode: harness::AwaitMode::All, deadline_at_ms: Some(50_000), }); let promises = [ @@ -1495,7 +1495,7 @@ fn continue_as_new_is_blocked_by_non_reconstructible_workflow_state() { // Log-derived state (pending promises) never blocks continue-as-new. workflow.core_state.promises.promises.insert( - engine::PromiseId::new("promise_1"), + harness::PromiseId::new("promise_1"), promise("promise_1", PromiseStatus::Pending), ); assert!(wait_loop::workflow_state_allows_continue_as_new(&workflow)); @@ -1542,7 +1542,7 @@ fn attachment_catalog_survives_selection_changes_and_replays() { log: &mut Vec, command: CoreAgentCommand, ) { - for proposal in engine::admit_command(state, command, 1).unwrap() { + for proposal in harness::admit_command(state, command, 1).unwrap() { let entry = CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(log.len() as u64 + 1), @@ -1551,7 +1551,7 @@ fn attachment_catalog_survives_selection_changes_and_replays() { joins: proposal.joins, event: proposal.event, }; - engine::apply_event(state, &entry).unwrap(); + harness::apply_event(state, &entry).unwrap(); log.push(entry); } } @@ -1564,7 +1564,7 @@ fn attachment_catalog_survives_selection_changes_and_replays() { kind: ContextEntryKind::Catalog { title: "Catalog".into(), }, - content: engine::ContentRef::text(BlobRef::from_bytes(b"catalog")), + content: harness::ContentRef::text(BlobRef::from_bytes(b"catalog")), preview: None, provenance_ref: None, token_estimate: None, @@ -1574,13 +1574,13 @@ fn attachment_catalog_survives_selection_changes_and_replays() { let mut state = CoreAgentState::new(); let mut log = Vec::new(); let mut config = agent_session_args_with_close_on_terminal(false).session_config; - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { environments: ["first", "second"] .into_iter() - .map(|id| engine::EnvironmentAttachment { + .map(|id| harness::EnvironmentAttachment { environment_id: id.into(), default: false, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }) .collect(), @@ -1596,7 +1596,7 @@ fn attachment_catalog_survives_selection_changes_and_replays() { &mut log, publication("runtime.catalog.vfs", None), ); - let vfs = engine::current_context_entry(&state, &ContextEntryKey::new("runtime.catalog.vfs")) + let vfs = harness::current_context_entry(&state, &ContextEntryKey::new("runtime.catalog.vfs")) .unwrap() .clone(); let tools = state.tooling.clone(); @@ -1605,19 +1605,21 @@ fn attachment_catalog_survives_selection_changes_and_replays() { let observed = publication(key.as_str(), Some("runtime.environments".into())); assert!(!drive::environment_attachment_catalog_publication_is_obsolete(&state, &observed)); append(&mut state, &mut log, observed.clone()); - let before = engine::current_context_entry(&state, &key).unwrap().clone(); + let before = harness::current_context_entry(&state, &key) + .unwrap() + .clone(); let command = match next { Some(id) => CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new(id), + environment_id: harness::EnvironmentId::new(id), }, None => CoreAgentCommand::ClearActiveEnvironment, }; append(&mut state, &mut log, command); assert!(!drive::environment_attachment_catalog_publication_is_obsolete(&state, &observed)); assert!(drive::invalid_environment_attachment_catalog_command(&state).is_none()); - assert_eq!(engine::current_context_entry(&state, &key), Some(&before)); + assert_eq!(harness::current_context_entry(&state, &key), Some(&before)); assert_eq!( - engine::current_context_entry(&state, &ContextEntryKey::new("runtime.catalog.vfs")), + harness::current_context_entry(&state, &ContextEntryKey::new("runtime.catalog.vfs")), Some(&vfs) ); assert_eq!(state.tooling, tools); @@ -1638,7 +1640,7 @@ fn attachment_catalog_survives_selection_changes_and_replays() { append(&mut state, &mut log, removal); let mut replayed = CoreAgentState::new(); for entry in &log { - engine::apply_event(&mut replayed, entry).unwrap(); + harness::apply_event(&mut replayed, entry).unwrap(); } assert_eq!(state, replayed); } @@ -1650,7 +1652,7 @@ fn environment_catalog_switch_removal_replays_without_mutating_vfs() { log: &mut Vec, command: CoreAgentCommand, ) { - for proposal in engine::admit_command(state, command, 1).unwrap() { + for proposal in harness::admit_command(state, command, 1).unwrap() { let entry = CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(log.len() as u64 + 1), @@ -1659,21 +1661,21 @@ fn environment_catalog_switch_removal_replays_without_mutating_vfs() { joins: proposal.joins, event: proposal.event, }; - engine::apply_event(state, &entry).unwrap(); + harness::apply_event(state, &entry).unwrap(); log.push(entry); } } let mut state = CoreAgentState::new(); let mut log = Vec::new(); let mut config = agent_session_args_with_close_on_terminal(false).session_config; - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { skills: Some(Default::default()), environments: ["first", "second"] .into_iter() - .map(|id| engine::EnvironmentAttachment { + .map(|id| harness::EnvironmentAttachment { environment_id: id.to_owned(), default: false, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }) .collect(), @@ -1688,7 +1690,7 @@ fn environment_catalog_switch_removal_replays_without_mutating_vfs() { &mut state, &mut log, CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("first"), + environment_id: harness::EnvironmentId::new("first"), }, ); // The gateway can submit the first run before any skill catalog exists. @@ -1719,7 +1721,7 @@ fn environment_catalog_switch_removal_replays_without_mutating_vfs() { kind: ContextEntryKind::Catalog { title: "Skills".into(), }, - content: engine::ContentRef::text(BlobRef::from_bytes(b"menu")), + content: harness::ContentRef::text(BlobRef::from_bytes(b"menu")), preview: None, provenance_ref: None, token_estimate: None, @@ -1727,13 +1729,13 @@ fn environment_catalog_switch_removal_replays_without_mutating_vfs() { }, ); } - let vfs = engine::current_context_entry(&state, &vfs_key) + let vfs = harness::current_context_entry(&state, &vfs_key) .unwrap() .clone(); let environment_publication = CoreAgentCommand::UpsertContext { expected_revision: None, key: env_key.clone(), - entry: engine::current_catalog_inputs(&state)[&env_key].clone(), + entry: harness::current_catalog_inputs(&state)[&env_key].clone(), }; assert!(!drive::environment_catalog_publication_is_obsolete( &state, @@ -1752,7 +1754,7 @@ fn environment_catalog_switch_removal_replays_without_mutating_vfs() { .skills = None; assert!(drive::invalid_environment_catalog_command(&disabled).is_some()); assert_eq!( - engine::current_context_entry(&disabled, &vfs_key), + harness::current_context_entry(&disabled, &vfs_key), Some(&vfs) ); disabled @@ -1793,18 +1795,18 @@ fn environment_catalog_switch_removal_replays_without_mutating_vfs() { &mut state, &mut log, CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("second"), + environment_id: harness::EnvironmentId::new("second"), }, ); let removal = drive::invalid_environment_catalog_command(&state).unwrap(); assert!(matches!(&removal, CoreAgentCommand::RemoveContext { key, .. } if key == &env_key)); assert!(!admissions::should_refresh_runtime_projection_before_admitting(&state, &removal)); append(&mut state, &mut log, removal); - assert!(engine::current_context_entry(&state, &env_key).is_none()); - assert_eq!(engine::current_context_entry(&state, &vfs_key), Some(&vfs)); + assert!(harness::current_context_entry(&state, &env_key).is_none()); + assert_eq!(harness::current_context_entry(&state, &vfs_key), Some(&vfs)); let mut replayed = CoreAgentState::new(); for entry in &log { - engine::apply_event(&mut replayed, entry).unwrap(); + harness::apply_event(&mut replayed, entry).unwrap(); } assert_eq!(state, replayed); } @@ -1816,7 +1818,7 @@ fn environment_prompt_switch_removal_replays_without_mutating_vfs() { log: &mut Vec, command: CoreAgentCommand, ) { - for proposal in engine::admit_command(state, command, 1).unwrap() { + for proposal in harness::admit_command(state, command, 1).unwrap() { let entry = CoreAgentEntry { position: SessionPosition { seq: EventSeq::new(log.len() as u64 + 1), @@ -1825,21 +1827,21 @@ fn environment_prompt_switch_removal_replays_without_mutating_vfs() { joins: proposal.joins, event: proposal.event, }; - engine::apply_event(state, &entry).unwrap(); + harness::apply_event(state, &entry).unwrap(); log.push(entry); } } let mut state = CoreAgentState::new(); let mut log = Vec::new(); let mut config = agent_session_args_with_close_on_terminal(false).session_config; - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { prompts: Some(Default::default()), environments: ["first", "second"] .into_iter() - .map(|id| engine::EnvironmentAttachment { + .map(|id| harness::EnvironmentAttachment { environment_id: id.to_owned(), default: false, - access: engine::EnvironmentAccess::Read, + access: harness::EnvironmentAccess::Read, working_directory: None, }) .collect(), @@ -1854,7 +1856,7 @@ fn environment_prompt_switch_removal_replays_without_mutating_vfs() { &mut state, &mut log, CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("first"), + environment_id: harness::EnvironmentId::new("first"), }, ); // Prompt discovery also runs when the gateway has not published instructions. @@ -1883,7 +1885,7 @@ fn environment_prompt_switch_removal_replays_without_mutating_vfs() { entry: ContextEntryInput { origin, kind: ContextEntryKind::Instructions, - content: engine::ContentRef::text(BlobRef::from_bytes(b"menu")), + content: harness::ContentRef::text(BlobRef::from_bytes(b"menu")), preview: None, provenance_ref: None, token_estimate: None, @@ -1891,7 +1893,7 @@ fn environment_prompt_switch_removal_replays_without_mutating_vfs() { }, ); } - let vfs = engine::current_context_entry(&state, &vfs_key) + let vfs = harness::current_context_entry(&state, &vfs_key) .unwrap() .clone(); let mut disabled = state.clone(); @@ -1907,7 +1909,7 @@ fn environment_prompt_switch_removal_replays_without_mutating_vfs() { .prompts = None; assert!(drive::invalid_environment_prompt_command(&disabled).is_some()); assert_eq!( - engine::current_context_entry(&disabled, &vfs_key), + harness::current_context_entry(&disabled, &vfs_key), Some(&vfs) ); disabled @@ -1942,18 +1944,18 @@ fn environment_prompt_switch_removal_replays_without_mutating_vfs() { &mut state, &mut log, CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("second"), + environment_id: harness::EnvironmentId::new("second"), }, ); let removal = drive::invalid_environment_prompt_command(&state).unwrap(); assert!(matches!(&removal, CoreAgentCommand::RemoveContext { key, .. } if key == &env_key)); assert!(!admissions::should_refresh_runtime_projection_before_admitting(&state, &removal)); append(&mut state, &mut log, removal); - assert!(engine::current_context_entry(&state, &env_key).is_none()); - assert_eq!(engine::current_context_entry(&state, &vfs_key), Some(&vfs)); + assert!(harness::current_context_entry(&state, &env_key).is_none()); + assert_eq!(harness::current_context_entry(&state, &vfs_key), Some(&vfs)); let mut replayed = CoreAgentState::new(); for entry in &log { - engine::apply_event(&mut replayed, entry).unwrap(); + harness::apply_event(&mut replayed, entry).unwrap(); } assert_eq!(state, replayed); } @@ -1965,7 +1967,7 @@ fn catalog_discovery_is_never_scheduled_for_continuation_or_tool_controls() { for command in [ CoreAgentCommand::ClearActiveEnvironment, CoreAgentCommand::SetActiveEnvironment { - environment_id: engine::EnvironmentId::new("machine"), + environment_id: harness::EnvironmentId::new("machine"), }, CoreAgentCommand::RemoveContext { expected_revision: None, @@ -1983,7 +1985,7 @@ fn vfs_skill_revocation_is_source_scoped_and_replays() { log: &mut Vec, command: CoreAgentCommand, ) { - let proposals = engine::admit_command(state, command, 1).unwrap(); + let proposals = harness::admit_command(state, command, 1).unwrap(); for proposal in proposals { let entry = CoreAgentEntry { position: SessionPosition { @@ -1993,25 +1995,25 @@ fn vfs_skill_revocation_is_source_scoped_and_replays() { joins: proposal.joins, event: proposal.event, }; - engine::apply_event(state, &entry).unwrap(); + harness::apply_event(state, &entry).unwrap(); log.push(entry); } } let mut state = CoreAgentState::new(); let mut log = Vec::new(); let mut config = agent_session_args_with_close_on_terminal(false).session_config; - config.features.vfs = Some(engine::VfsFeature { - workspaces: vec![engine::WorkspaceAttachment { + config.features.vfs = Some(harness::VfsFeature { + workspaces: vec![harness::WorkspaceAttachment { path: "/skills".into(), - target: engine::WorkspaceAttachmentTarget::Workspace { + target: harness::WorkspaceAttachmentTarget::Workspace { workspace_id: "skills".into(), }, - access: engine::WorkspaceAccess::Read, + access: harness::WorkspaceAccess::Read, }], - skills: Some(engine::VfsSkillsConfig::default()), + skills: Some(harness::VfsSkillsConfig::default()), ..Default::default() }); - config.features.environments = Some(engine::EnvironmentsFeature { + config.features.environments = Some(harness::EnvironmentsFeature { skills: Some(Default::default()), ..Default::default() }); @@ -2027,7 +2029,7 @@ fn vfs_skill_revocation_is_source_scoped_and_replays() { kind: ContextEntryKind::Catalog { title: "VFS skills".into(), }, - content: engine::ContentRef::text(BlobRef::from_bytes(b"menu")), + content: harness::ContentRef::text(BlobRef::from_bytes(b"menu")), preview: None, provenance_ref: None, token_estimate: None, @@ -2053,7 +2055,7 @@ fn vfs_skill_revocation_is_source_scoped_and_replays() { entry: environment_entry, }, ); - let environment = engine::current_context_entry(&state, &env_key) + let environment = harness::current_context_entry(&state, &env_key) .unwrap() .clone(); assert!(drive::invalid_vfs_skill_catalog_command(&state).is_none()); @@ -2081,9 +2083,9 @@ fn vfs_skill_revocation_is_source_scoped_and_replays() { )); let removal = drive::invalid_vfs_skill_catalog_command(&state).unwrap(); append(&mut state, &mut log, removal); - assert!(engine::current_context_entry(&state, &key).is_none()); + assert!(harness::current_context_entry(&state, &key).is_none()); assert_eq!( - engine::current_context_entry(&state, &env_key), + harness::current_context_entry(&state, &env_key), Some(&environment) ); assert!( @@ -2101,7 +2103,7 @@ fn vfs_skill_revocation_is_source_scoped_and_replays() { ); let mut replayed = CoreAgentState::new(); for entry in &log { - engine::apply_event(&mut replayed, entry).unwrap(); + harness::apply_event(&mut replayed, entry).unwrap(); } assert_eq!(state, replayed); let mut external = match publication { @@ -2124,7 +2126,7 @@ fn vfs_skill_revocation_is_source_scoped_and_replays() { #[test] fn accepted_submission_skips_new_policy_observations_even_after_config_is_removed() { let mut workflow = - workflow_with_parked_tool_batch(await_spec(&["promise_1"], engine::AwaitMode::All, None)); + workflow_with_parked_tool_batch(await_spec(&["promise_1"], harness::AwaitMode::All, None)); workflow .core_state .runs diff --git a/crates/temporal-workflow/src/workflows/session/tool_batches.rs b/crates/temporal-workflow/src/workflows/session/tool_batches.rs index 324ee7bd3..5cb97800b 100644 --- a/crates/temporal-workflow/src/workflows/session/tool_batches.rs +++ b/crates/temporal-workflow/src/workflows/session/tool_batches.rs @@ -5,14 +5,15 @@ //! on its own, so a slow or failed call never restarts a completed sibling. //! Batches that need batch-level orchestration (an `await` call or admitted //! workflow-tool calls) still execute as one unit behind the same -//! progressive-completion engine contract. +//! progressive-completion harness contract. +use crate::workflows::WorkflowContextExt as _; use std::pin::Pin; use std::task::{Context, Poll}; -use engine::{ToolCallStatus, ToolExecutionSpec, ToolInvocationResult, ToolName, ToolParallelism}; use futures::FutureExt; use futures::future::poll_fn; +use harness::{ToolCallStatus, ToolExecutionSpec, ToolInvocationResult, ToolName, ToolParallelism}; use temporalio_sdk::{ActivityExecutionError, CancellableFuture}; use crate::{ @@ -38,7 +39,7 @@ pub(super) async fn invoke_tool_batch( } for group in execution_groups(drive.state(), &request) { if !control::tool_batch_still_wanted(drive.state(), request.run_id, request.batch_id) { - // A cancel landed while an earlier group ran; the engine has + // A cancel landed while an earlier group ran; the harness has // resolved the rest of the batch itself. break; } @@ -69,7 +70,7 @@ async fn invoke_tool_batch_as_unit( let run_id = request.run_id; let batch_id = request.batch_id; let activity_ctx = ctx.clone(); - let activity = activity_ctx.start_activity( + let activity = activity_ctx.execute_activity( WorkflowActivities::tool_invoke_batch, ToolInvokeBatchActivityRequest { request: request.clone(), @@ -102,7 +103,7 @@ async fn invoke_tool_batch_as_unit( .collect(); drive .resume_tool_batch( - engine::ToolInvocationBatchResult { + harness::ToolInvocationBatchResult { run_id: request.run_id, turn_id: request.turn_id, batch_id: request.batch_id, @@ -144,7 +145,7 @@ type CallActivityOutcome = Result { index: usize, - activity: Pin + 'a>>, + activity: Pin + 'a>>, } /// Resolve the first ready in-flight call, removing it from `inflight`. @@ -162,7 +163,7 @@ async fn first_ready_call(inflight: &mut Vec>) -> (usize, CallA } /// Cancel every in-flight call (`TryCancel`) and let the futures resolve; -/// their results are discarded — the engine already recorded the calls as +/// their results are discarded — the harness already recorded the calls as /// cancelled. async fn abandon_inflight_calls(inflight: Vec>) { for call in inflight { @@ -200,7 +201,7 @@ async fn execute_call_group( // queued run is admitted and execution continues; a cancel that // ends this batch abandons every in-flight call. let ready = { - let wait = ctx.wait_condition(admissions::has_admissible_admissions); + let wait = ctx.wait_for_state(admissions::has_admissible_admissions); let next = first_ready_call(&mut inflight).fuse(); pin_mut!(wait, next); select! { @@ -244,19 +245,19 @@ fn call_activity<'a>( state: &CoreAgentState, request: &ToolInvocationBatchRequest, index: usize, -) -> impl CancellableFuture + use<'a> { +) -> impl CancellableFuture + use<'a> { let call = &request.calls[index]; - // The engine materialized the native MCP routing facts on the call when + // The harness materialized the native MCP routing facts on the call when // it built this dispatch; the workflow only selects the execution class. let execution = if call.remote_mcp.is_some() { - ToolExecutionSpec::new(engine::ToolExecutionClass::RemoteInteractive, false) + ToolExecutionSpec::new(harness::ToolExecutionClass::RemoteInteractive, false) } else { call_execution_spec(state, call.tool_id.as_ref()) }; let call_request = request .call_request(index, execution) .expect("group indices come from this batch request"); - activity_ctx.start_activity( + activity_ctx.execute_activity( WorkflowActivities::tool_invoke_call, ToolInvokeCallActivityRequest { request: call_request, @@ -283,7 +284,7 @@ async fn resume_call( if let Ok(ToolInvokeCallActivityResult::NeedsApproval { subject }) = &outcome { let action = drive.request_native_mcp_approvals( request.batch_id, - vec![engine::NativeMcpApprovalRequest { + vec![harness::NativeMcpApprovalRequest { call_id: request.calls[index].call_id.clone(), subject: subject.clone(), }], @@ -307,7 +308,7 @@ async fn resume_call( .await? { Some(outcome) => outcome, - // Preempted by a cancel: the engine recorded the call as + // Preempted by a cancel: the harness recorded the call as // cancelled; nothing to resume. None => return Ok(()), } @@ -381,7 +382,7 @@ async fn await_environment_then_redispatch( let still_wanted = |state: &CoreAgentState| control::tool_batch_still_wanted(state, run_id, batch_id); let activity_ctx = ctx.clone(); - let readiness = activity_ctx.start_activity( + let readiness = activity_ctx.execute_activity( WorkflowActivities::await_environment_ready, AwaitEnvironmentReadyActivityRequest { session_id: request.session_id.clone(), @@ -465,7 +466,7 @@ fn call_parallelism(state: &CoreAgentState, tool_name: Option<&ToolName>) -> Too /// Materialize the boundary error text with bounded attempts. This path must /// never reintroduce unlimited retries: when the bounded put fails, fall back -/// to the engine's well-known boundary-failure blob, which every runtime +/// to the harness's well-known boundary-failure blob, which every runtime /// guarantees exists. async fn put_boundary_error_blob( ctx: &mut WorkflowContext, @@ -479,7 +480,7 @@ async fn put_boundary_error_blob( } message.truncate(end); } - ctx.start_activity( + ctx.execute_activity( WorkflowActivities::put_blob, PutBlobRequest { bytes: message.into_bytes(), @@ -487,11 +488,11 @@ async fn put_boundary_error_blob( boundary_error_blob_activity_options(), ) .await - .unwrap_or_else(|_| engine::tool_runtime_boundary_failure_ref()) + .unwrap_or_else(|_| harness::tool_runtime_boundary_failure_ref()) } fn boundary_call_result( - call_id: engine::ToolCallId, + call_id: harness::ToolCallId, status: ToolCallStatus, error_ref: BlobRef, ) -> ToolInvocationResult { @@ -515,7 +516,7 @@ fn boundary_call_result( #[cfg(test)] mod tests { - use engine::{BlobRef, ToolCallId, ToolInvocationRequest, ToolSpec}; + use harness::{BlobRef, ToolCallId, ToolInvocationRequest, ToolSpec}; use super::*; @@ -540,9 +541,9 @@ mod tests { ToolInvocationBatchRequest { vfs_working_directory: None, session_id: SessionId::new("session-a"), - run_id: engine::RunId::new(1), - turn_id: engine::TurnId::new(1), - batch_id: engine::ToolBatchId::new(1), + run_id: harness::RunId::new(1), + turn_id: harness::TurnId::new(1), + batch_id: harness::ToolBatchId::new(1), promise_id_base: 1, workspace_attachments: Vec::new(), active_environment_id: None, @@ -559,7 +560,7 @@ mod tests { ToolName::new(name), ToolSpec { name: ToolName::new(name), - kind: engine::ToolKind::Function(engine::FunctionToolSpec { + kind: harness::ToolKind::Function(harness::FunctionToolSpec { description_ref: None, input_schema_ref: BlobRef::from_bytes(b"{}"), output_schema_ref: None, diff --git a/crates/temporal-workflow/src/workflows/session/wait_loop.rs b/crates/temporal-workflow/src/workflows/session/wait_loop.rs index d4cf44f02..46407d80d 100644 --- a/crates/temporal-workflow/src/workflows/session/wait_loop.rs +++ b/crates/temporal-workflow/src/workflows/session/wait_loop.rs @@ -1,4 +1,5 @@ use super::*; +use crate::workflows::WorkflowContextExt as _; pub(super) const ACTIVE_RUN_ROLLOVER_PATCH: &str = "p105_active_run_rollover_v1"; @@ -9,7 +10,7 @@ pub(super) async fn wait_for_workflow_work(ctx: &mut WorkflowContext WorkflowWake::State, @@ -68,7 +69,7 @@ pub(super) fn workflow_state_needs_core_drive_for_state(state: &AgentSessionWork || state.core_state.context.compaction.is_pending() || state.core_state.runs.active.as_ref().is_some_and(|run| { awaits::parked_tool_batch(&state.core_state).is_none() - && !(run.status == engine::RunStatus::Parked + && !(run.status == harness::RunStatus::Parked && run.pending_approvals().next().is_some()) })) } diff --git a/crates/temporal-workflow/src/workflows/session/watchdog.rs b/crates/temporal-workflow/src/workflows/session/watchdog.rs index 044a14c8c..df4a26c7b 100644 --- a/crates/temporal-workflow/src/workflows/session/watchdog.rs +++ b/crates/temporal-workflow/src/workflows/session/watchdog.rs @@ -71,7 +71,7 @@ pub(super) async fn process_cancelling_watchdog( }; let mut drive = drive_from_state(ctx)?; let command = CoreAgentCommand::ForceCancelRun { - run_id: engine::RunId::new(run_id), + run_id: harness::RunId::new(run_id), }; match admit_and_append_command(ctx, &mut drive, command, None).await? { CommandAdmissionResult::Accepted => {} diff --git a/crates/temporal-workflow/src/workflows/session/workflow_starts.rs b/crates/temporal-workflow/src/workflows/session/workflow_starts.rs index 12e623ad6..9a93231d1 100644 --- a/crates/temporal-workflow/src/workflows/session/workflow_starts.rs +++ b/crates/temporal-workflow/src/workflows/session/workflow_starts.rs @@ -9,9 +9,9 @@ const WORKFLOW_START_RETRY_BACKOFF_MS: u64 = 2_000; /// so replay and continue-as-new rebuild it without transport bookkeeping; /// the deterministic execution id makes re-issuing safe. struct StartCandidate { - invocation: engine::WorkflowToolInvocation, + invocation: harness::WorkflowToolInvocation, execution_id: String, - start: engine::WorkflowStartRef, + start: harness::WorkflowStartRef, } fn start_candidates(state: &AgentSessionWorkflow) -> Vec { @@ -45,7 +45,7 @@ fn start_candidates(state: &AgentSessionWorkflow) -> Vec { .promises .promises .get(promise_id) - .is_some_and(|promise| promise.status == engine::PromiseStatus::Pending) + .is_some_and(|promise| promise.status == harness::PromiseStatus::Pending) }); if !has_pending_promise { return None; @@ -55,12 +55,12 @@ fn start_candidates(state: &AgentSessionWorkflow) -> Vec { .workflow_tools .bindings .get(&invocation.tool_id)?; - let engine::WorkflowToolTarget::Start { start } = &binding.target else { + let harness::WorkflowToolTarget::Start { start } = &binding.target else { return None; }; Some(StartCandidate { invocation: invocation.clone(), - execution_id: engine::workflow_tool_execution_id( + execution_id: harness::workflow_tool_execution_id( &invocation.invocation_id, &start.recipe_fingerprint, ), @@ -120,7 +120,7 @@ pub(super) async fn process_pending_starts( for (invocation, execution_id, start) in due { let invocation_key = invocation.invocation_id.as_str().to_owned(); let result = ctx - .start_activity( + .execute_activity( WorkflowActivities::start_workflow_tool_execution, crate::WorkflowToolStartActivityRequest { execution_id, @@ -176,7 +176,7 @@ pub(super) async fn process_pending_starts( async fn terminal_start_failure( ctx: &mut WorkflowContext, - invocation: &engine::WorkflowToolInvocation, + invocation: &harness::WorkflowToolInvocation, attempts: u32, message: String, ) -> anyhow::Result<()> { @@ -185,7 +185,7 @@ async fn terminal_start_failure( invocation.invocation_id ); let error_ref = ctx - .start_activity( + .execute_activity( WorkflowActivities::put_blob, PutBlobRequest { bytes: detail.into_bytes(), @@ -246,10 +246,10 @@ pub(super) async fn process_execution_cancels( .workflow_tools .bindings .get(&invocation.tool_id)?; - let engine::WorkflowToolTarget::Start { start } = &binding.target else { + let harness::WorkflowToolTarget::Start { start } = &binding.target else { return None; }; - let execution_id = engine::workflow_tool_execution_id( + let execution_id = harness::workflow_tool_execution_id( &invocation.invocation_id, &start.recipe_fingerprint, ); @@ -260,7 +260,7 @@ pub(super) async fn process_execution_cancels( }); for execution_id in due { if let Err(error) = ctx - .start_activity( + .execute_activity( WorkflowActivities::cancel_workflow_tool_execution, crate::WorkflowToolExecutionCancelRequest { execution_id: execution_id.clone(), diff --git a/crates/temporal-workflow/src/workflows/subagent_execution.rs b/crates/temporal-workflow/src/workflows/subagent_execution.rs index 9bc364901..400fb436f 100644 --- a/crates/temporal-workflow/src/workflows/subagent_execution.rs +++ b/crates/temporal-workflow/src/workflows/subagent_execution.rs @@ -6,6 +6,7 @@ //! closes the child. To the parent this is indistinguishable from an //! environment job; the session workflow carries no sub-agent code. +use crate::workflows::WorkflowContextExt as _; use std::time::Duration; use futures::{FutureExt, pin_mut, select}; @@ -19,15 +20,15 @@ use crate::{ WorkflowToolRecoveryResult, WorkflowToolStartArgs, activity_options, }; -#[workflow(name = "SubagentExecutionWorkflow")] +#[workflow] #[derive(Default)] pub struct SubagentExecutionWorkflow { snapshot: SubagentExecutionSnapshot, /// Identity fixed at start: which promise this execution resolves and /// which holder to tell. - reply_promise_id: Option, + reply_promise_id: Option, holder_workflow_id: Option, - invocation_id: Option, + invocation_id: Option, universe_id: Option, pending_terminal: Option, holder_cancelled: bool, @@ -36,7 +37,7 @@ pub struct SubagentExecutionWorkflow { #[workflow_methods] impl SubagentExecutionWorkflow { - #[run] + #[run(name = "SubagentExecutionWorkflow")] pub async fn run( ctx: &mut WorkflowContext, start: WorkflowToolStartArgs, @@ -44,21 +45,21 @@ impl SubagentExecutionWorkflow { if ctx.workflow_id() != start.execution_id || start.universe_id != start.invocation.session_universe_id { - return Err(anyhow::anyhow!( + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( "subagent execution identity is invalid: workflow id or universe mismatch" - ) + )) .into()); } let Some(reply_promise_id) = start .invocation .completion_promises .as_ref() - .and_then(|promises| promises.get(engine::REPLY_COMPLETION_KEY)) + .and_then(|promises| promises.get(harness::REPLY_COMPLETION_KEY)) .cloned() else { - return Err(anyhow::anyhow!( + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( "subagent execution invocation is missing its reply completion promise" - ) + )) .into()); }; ctx.state_mut(|state| { @@ -72,7 +73,7 @@ impl SubagentExecutionWorkflow { // A. prepare: validate the pinned grant, reserve the tree slot, // create the child from the pinned profile, start its run. let prepared = ctx - .start_activity( + .execute_activity( WorkflowActivities::subagent_prepare, SubagentPrepareActivityRequest { start: start.clone(), @@ -80,11 +81,15 @@ impl SubagentExecutionWorkflow { activity_options(), ) .await - .map_err(|error| anyhow::anyhow!("subagent prepare failed: {error}"))?; + .map_err(|error| { + temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "subagent prepare failed: {error}" + )) + })?; let (child, deadline_ms) = match prepared { SubagentPrepareActivityResult::Prepared { child, deadline_ms } => (child, deadline_ms), SubagentPrepareActivityResult::Rejected { error_ref } => { - let resolution = engine::PromiseResolution::Failed { + let resolution = harness::PromiseResolution::Failed { error_ref: Some(error_ref), }; ctx.state_mut(|state| { @@ -110,8 +115,10 @@ impl SubagentExecutionWorkflow { break WaitOutcome::HolderCancelled; } ctx.state_mut(|state| state.nudged = false); - let wait = ctx.wait_condition(|state| state.nudged); - let deadline = ctx.timer(Duration::from_millis(deadline_ms.max(1))).fuse(); + let wait = ctx.wait_for_state(|state| state.nudged); + let deadline = ctx + .timer_with_manual_cancellation(Duration::from_millis(deadline_ms.max(1))) + .fuse(); let cancelled = ctx.cancelled().fuse(); pin_mut!(wait, deadline, cancelled); select! { @@ -126,7 +133,7 @@ impl SubagentExecutionWorkflow { // C. resolve: build the envelope, close the child, tell the // holder. let resolution = ctx - .start_activity( + .execute_activity( WorkflowActivities::subagent_resolve, SubagentResolveActivityRequest { universe_id: start.universe_id, @@ -136,7 +143,11 @@ impl SubagentExecutionWorkflow { activity_options(), ) .await - .map_err(|error| anyhow::anyhow!("subagent resolve failed: {error}"))?; + .map_err(|error| { + temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "subagent resolve failed: {error}" + )) + })?; ctx.state_mut(|state| { state.snapshot.phase = SubagentExecutionPhase::Resolved; state.snapshot.resolution = Some(resolution.clone()); @@ -154,7 +165,7 @@ impl SubagentExecutionWorkflow { WaitOutcome::Cancelled => { close_child(ctx, start.universe_id, &child).await; ctx.state_mut(|state| state.snapshot.phase = SubagentExecutionPhase::Cancelled); - Err(temporalio_sdk::WorkflowTermination::Cancelled) + Err(temporalio_sdk::WorkflowTermination::cancelled()) } } } @@ -165,7 +176,7 @@ impl SubagentExecutionWorkflow { pub fn deliver_emission( &mut self, _ctx: &mut SyncWorkflowContext, - envelope: engine::EmissionEnvelope, + envelope: harness::EmissionEnvelope, ) { let identity = SignalIdentity { reply_promise_id: self.reply_promise_id.as_ref(), @@ -201,9 +212,9 @@ impl SubagentExecutionWorkflow { /// but `child` is fixed at start; `child` is known only once the prepare /// activity's result has been recorded. pub(crate) struct SignalIdentity<'a> { - pub reply_promise_id: Option<&'a engine::PromiseId>, + pub reply_promise_id: Option<&'a harness::PromiseId>, pub holder_workflow_id: Option<&'a str>, - pub invocation_id: Option<&'a engine::WorkflowToolInvocationId>, + pub invocation_id: Option<&'a harness::WorkflowToolInvocationId>, pub child: Option<&'a SubagentChildRef>, } @@ -217,10 +228,10 @@ pub(crate) enum SignalEffect { /// is not addressed to this execution and is dropped. pub(crate) fn classify_emission( identity: &SignalIdentity<'_>, - envelope: engine::EmissionEnvelope, + envelope: harness::EmissionEnvelope, ) -> Option { match envelope.body { - engine::EmissionBody::RunTerminal { + harness::EmissionBody::RunTerminal { token, run_id, status, @@ -235,11 +246,11 @@ pub(crate) fn classify_emission( // child. let expected_token = identity.reply_promise_id.map(|promise| promise.as_str()); let from_child = match (&envelope.producer, identity.child) { - (engine::EmissionProducer::Session { session_id, .. }, Some(child)) => { + (harness::EmissionProducer::Session { session_id, .. }, Some(child)) => { session_id.as_str() == child.session_id && run_id.as_u64() == child.run_id } - (engine::EmissionProducer::Session { .. }, None) => true, - (engine::EmissionProducer::Workflow { .. }, _) => false, + (harness::EmissionProducer::Session { .. }, None) => true, + (harness::EmissionProducer::Workflow { .. }, _) => false, }; (expected_token == Some(token.as_str()) && from_child).then_some( SignalEffect::Terminal(SubagentTerminal::Run { @@ -249,13 +260,13 @@ pub(crate) fn classify_emission( }), ) } - engine::EmissionBody::InvocationCancellation { + harness::EmissionBody::InvocationCancellation { invocation_id, completion_key, .. } => { let from_holder = match &envelope.producer { - engine::EmissionProducer::Session { + harness::EmissionProducer::Session { universe_id, session_id, .. @@ -263,15 +274,15 @@ pub(crate) fn classify_emission( identity.holder_workflow_id == Some(crate::compose_workflow_id(*universe_id, session_id).as_str()) } - engine::EmissionProducer::Workflow { .. } => false, + harness::EmissionProducer::Workflow { .. } => false, }; (from_holder && identity.invocation_id == Some(&invocation_id) - && completion_key == engine::REPLY_COMPLETION_KEY) + && completion_key == harness::REPLY_COMPLETION_KEY) .then_some(SignalEffect::HolderCancelled) } - engine::EmissionBody::SourceResolution { .. } - | engine::EmissionBody::ToolInvocation { .. } => None, + harness::EmissionBody::SourceResolution { .. } + | harness::EmissionBody::ToolInvocation { .. } => None, } } @@ -279,7 +290,7 @@ pub(crate) fn classify_emission( pub(crate) fn recovery_result(snapshot: &SubagentExecutionSnapshot) -> WorkflowToolRecoveryResult { let mut resolutions = std::collections::BTreeMap::new(); if let Some(resolution) = &snapshot.resolution { - resolutions.insert(engine::REPLY_COMPLETION_KEY.to_owned(), resolution.clone()); + resolutions.insert(harness::REPLY_COMPLETION_KEY.to_owned(), resolution.clone()); } WorkflowToolRecoveryResult { resolutions } } @@ -293,13 +304,13 @@ enum WaitOutcome { async fn emit_resolution( ctx: &mut WorkflowContext, universe_id: uuid::Uuid, - reply_promise_id: &engine::PromiseId, - resolution: engine::PromiseResolution, + reply_promise_id: &harness::PromiseId, + resolution: harness::PromiseResolution, ) { let Some(holder) = ctx.state(|state| state.holder_workflow_id.clone()) else { return; }; - let envelope = engine::EmissionEnvelope::source_resolution( + let envelope = harness::EmissionEnvelope::source_resolution( universe_id, ctx.workflow_id().to_owned(), &holder, @@ -308,7 +319,11 @@ async fn emit_resolution( ); let _ = ctx .external_workflow(holder, None) - .signal(AgentSessionWorkflow::deliver_emission, envelope) + .signal( + AgentSessionWorkflow::deliver_emission, + envelope, + crate::workflows::signal_options(), + ) .await; } @@ -318,7 +333,7 @@ async fn close_child( child: &SubagentChildRef, ) { let _ = ctx - .start_activity( + .execute_activity( WorkflowActivities::subagent_close, SubagentCloseActivityRequest { universe_id, @@ -331,7 +346,7 @@ async fn close_child( #[cfg(test)] mod tests { - use engine::{ + use harness::{ BlobRef, EmissionEnvelope, EventSeq, PromiseId, PromiseResolution, REPLY_COMPLETION_KEY, RunId, RunStatus, SessionId, WorkflowToolInvocationId, }; @@ -372,7 +387,7 @@ mod tests { token.to_owned(), RunId::new(run_id), RunStatus::Completed, - Some(engine::ContentRef::text(BlobRef::from_bytes(b"\"done\""))), + Some(harness::ContentRef::text(BlobRef::from_bytes(b"\"done\""))), None, ) } @@ -413,7 +428,7 @@ mod tests { fn expected_terminal() -> SignalEffect { SignalEffect::Terminal(SubagentTerminal::Run { status: RunStatus::Completed, - output: Some(engine::ContentRef::text(BlobRef::from_bytes(b"\"done\""))), + output: Some(harness::ContentRef::text(BlobRef::from_bytes(b"\"done\""))), failure_message_ref: None, }) } @@ -462,7 +477,7 @@ mod tests { None ); let mut from_workflow = run_terminal("agent_child", 1, reply_promise().as_str()); - from_workflow.producer = engine::EmissionProducer::Workflow { + from_workflow.producer = harness::EmissionProducer::Workflow { universe_id: UNIVERSE, workflow_id: "wte:other".to_owned(), }; diff --git a/crates/temporal-workflow/src/workflows/transcriptions.rs b/crates/temporal-workflow/src/workflows/transcriptions.rs index 4f1c1c4b9..b92f91a32 100644 --- a/crates/temporal-workflow/src/workflows/transcriptions.rs +++ b/crates/temporal-workflow/src/workflows/transcriptions.rs @@ -1,5 +1,6 @@ //! Session-independent transcription. Temporal owns request identity and state; //! activities store audio and transcript content in CAS. +use crate::workflows::WorkflowContextExt as _; use api::{ Attribution, ModelConfig, TranscriptionFailure, TranscriptionFailureKind, TranscriptionStartParams, TranscriptionStatus, TranscriptionView, @@ -69,7 +70,7 @@ impl TranscriptionWorkflowArgs { } } -#[workflow(name = "TranscriptionWorkflow")] +#[workflow] #[derive(Default)] pub struct TranscriptionWorkflow { snapshot: Option, @@ -78,13 +79,16 @@ pub struct TranscriptionWorkflow { #[workflow_methods] impl TranscriptionWorkflow { - #[run] + #[run(name = "TranscriptionWorkflow")] pub async fn run( ctx: &mut WorkflowContext, args: TranscriptionWorkflowArgs, ) -> WorkflowResult<()> { if ctx.workflow_id() != transcription_workflow_id(&args) { - return Err(anyhow::anyhow!("transcription workflow identity mismatch").into()); + return Err(temporalio_sdk::ApplicationFailure::new(anyhow::anyhow!( + "transcription workflow identity mismatch" + )) + .into()); } let mut view = args.pending(); view.status = TranscriptionStatus::Running; @@ -94,27 +98,29 @@ impl TranscriptionWorkflow { view, }) }); - let options = ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::Both { - start_to_close: Duration::from_secs(360), - schedule_to_close: Duration::from_secs(900), - }) - .heartbeat_timeout(Duration::from_secs(15)) - .cancellation_type(ActivityCancellationType::WaitCancellationCompleted) - .retry_policy(RetryPolicy { - initial_interval: Some(Duration::from_secs(2).try_into().unwrap()), - maximum_interval: Some(Duration::from_secs(15).try_into().unwrap()), - backoff_coefficient: 2.0, - maximum_attempts: 3, - non_retryable_error_types: vec![], - }) - .build(); - let mut activity = ctx.start_activity( + let options = + ActivityOptions::with_close_timeouts(ActivityCloseTimeouts::ScheduleAndStartToClose { + start_to_close: Duration::from_secs(360), + schedule_to_close: Duration::from_secs(900), + }) + .heartbeat_timeout(Duration::from_secs(15)) + .cancellation_type(ActivityCancellationType::WaitCancellationCompleted) + .cancellation_token(temporalio_sdk::WorkflowCancellationToken::new()) + .retry_policy(RetryPolicy { + initial_interval: Some(Duration::from_secs(2).try_into().unwrap()), + maximum_interval: Some(Duration::from_secs(15).try_into().unwrap()), + backoff_coefficient: 2.0, + maximum_attempts: 3, + non_retryable_error_types: vec![], + }) + .build(); + let mut activity = ctx.execute_activity( crate::WorkflowActivities::execute_transcription, args, options, ); let result = { - let cancellation = ctx.wait_condition(|state| state.cancel_requested).fuse(); + let cancellation = ctx.wait_for_state(|state| state.cancel_requested).fuse(); let external_cancel = ctx.cancelled().fuse(); let mut work = (&mut activity).fuse(); futures::pin_mut!(cancellation, external_cancel); diff --git a/crates/temporal-workflow/tests/workflow_contract.rs b/crates/temporal-workflow/tests/workflow_contract.rs index 23fbee746..a60dbf30a 100644 --- a/crates/temporal-workflow/tests/workflow_contract.rs +++ b/crates/temporal-workflow/tests/workflow_contract.rs @@ -39,7 +39,7 @@ fn assert_validates(bundle: &Value, definition: &str, instance: &Value) { let validator = jsonschema::validator_for(&schema).expect("workflow schema compiles"); let errors: Vec = validator .iter_errors(instance) - .map(|error| format!("{} at {}", error, error.instance_path)) + .map(|error| format!("{} at {}", error, error.instance_path())) .collect(); assert!( errors.is_empty(), @@ -89,7 +89,7 @@ fn vectors_cover_all_derivations_and_round_trips() { vectors["inputs"]["sessionId"] ); for envelope in vectors["envelopes"].as_array().expect("envelope vectors") { - let decoded: engine::EmissionEnvelope = + let decoded: harness::EmissionEnvelope = serde_json::from_value(envelope.clone()).expect("vector envelope decodes"); assert_eq!( serde_json::to_value(decoded).expect("vector re-encodes"), diff --git a/crates/test-support/Cargo.toml b/crates/test-support/Cargo.toml index 1319a0909..9026a07d2 100644 --- a/crates/test-support/Cargo.toml +++ b/crates/test-support/Cargo.toml @@ -5,10 +5,10 @@ edition = "2024" [dependencies] async-trait = "0.1" -engine = { path = "../engine" } +harness = { path = "../harness" } serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" tools = { path = "../tools" } vfs = { path = "../vfs" } diff --git a/crates/test-support/src/runner/drive.rs b/crates/test-support/src/runner/drive.rs index 595cf95d9..1ade99d29 100644 --- a/crates/test-support/src/runner/drive.rs +++ b/crates/test-support/src/runner/drive.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; -use engine::{ +use harness::{ BlobRef, ContextCompactionRequest, ContextCompactionResult, ContextCompactionStatus, CoreAgentAction, CoreAgentCommand, CoreAgentDrive, CoreAgentDriveError, CoreAgentIoError, CoreAgentLlm, CoreAgentState, CoreAgentTools, EventSeq, LlmFinish, LlmGenerationFacts, @@ -66,7 +66,7 @@ impl SessionRunner { &self, drive: &mut CoreAgentDrive, observed_at_ms: u64, - emitted_entries: &mut Vec, + emitted_entries: &mut Vec, ) -> Result<(), RunnerError> { let Some(command) = self .refresh_prompt_instructions_command(drive.session_id(), drive.state()) @@ -88,7 +88,7 @@ impl SessionRunner { &self, drive: &mut CoreAgentDrive, observed_at_ms: u64, - emitted_entries: &mut Vec, + emitted_entries: &mut Vec, command: CoreAgentCommand, label: &'static str, ) -> Result<(), RunnerError> { @@ -197,14 +197,14 @@ impl SessionRunner { } Ok(Some(CoreAgentCommand::ReplaceContextPrefix { expected_revision: Some(state.context.revision), - key_prefix: engine::ContextEntryKey::new("instructions"), + key_prefix: harness::ContextEntryKey::new("instructions"), entries: desired, })) } pub async fn drive_command(&self, request: DriveCommand) -> Result { let max_steps = resolve_max_steps(request.max_steps)?; - engine::storage::ensure_engine_blobs(self.stores.blobs.as_ref()).await?; + harness::storage::ensure_harness_blobs(self.stores.blobs.as_ref()).await?; let mut drive = self.load_drive(&request.session_id).await?; let mut emitted_entries = Vec::new(); @@ -231,7 +231,7 @@ impl SessionRunner { let action = match drive.admit_command(request.command, request.observed_at_ms) { Ok(action) => action, - Err(CoreAgentDriveError::Command(engine::CommandError::Rejected(rejection))) => { + Err(CoreAgentDriveError::Command(harness::CommandError::Rejected(rejection))) => { let quiescence = classify_quiescence(drive.state()); return Ok(DriveOutcome { session_id: request.session_id, @@ -271,7 +271,7 @@ impl SessionRunner { &self, drive: &mut CoreAgentDrive, observed_at_ms: u64, - emitted_entries: &mut Vec, + emitted_entries: &mut Vec, ) -> Result<(), RunnerError> { let commands = self .refresh_environment_projection_commands(drive.session_id(), drive.state()) @@ -318,7 +318,7 @@ impl SessionRunner { }) .then(|| CoreAgentCommand::RemoveContext { expected_revision: None, - key: engine::ContextEntryKey::new(VFS_CATALOG_CONTEXT_KEY), + key: harness::ContextEntryKey::new(VFS_CATALOG_CONTEXT_KEY), }) .into_iter() .collect()); @@ -331,8 +331,8 @@ impl SessionRunner { let publication = prepare_vfs_catalog_publication( self.stores.blobs.as_ref(), None, - engine::current_catalog_inputs(state) - .get(&engine::ContextEntryKey::new(VFS_CATALOG_CONTEXT_KEY)), + harness::current_catalog_inputs(state) + .get(&harness::ContextEntryKey::new(VFS_CATALOG_CONTEXT_KEY)), catalog, ) .await @@ -346,7 +346,7 @@ impl SessionRunner { &self, drive: &mut CoreAgentDrive, observed_at_ms: u64, - emitted_entries: &mut Vec, + emitted_entries: &mut Vec, ) -> Result<(), RunnerError> { let Some(command) = self .refresh_skill_catalog_command(drive.session_id(), drive.state()) @@ -369,8 +369,8 @@ impl SessionRunner { _session_id: &SessionId, state: &CoreAgentState, ) -> Result, RunnerError> { - let catalogs = engine::current_catalog_inputs(state); - let current = catalogs.get(&engine::ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY)); + let catalogs = harness::current_catalog_inputs(state); + let current = catalogs.get(&harness::ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY)); if current.is_some_and(|entry| entry.origin.as_deref() != Some("runtime.vfs.skills")) { return Ok(None); } @@ -491,7 +491,7 @@ impl SessionRunner { pub async fn load_state(&self, session_id: &SessionId) -> Result { let mut state = CoreAgentState::new(); let mut after: Option = None; - let codec = engine::CoreAgentCodec; + let codec = harness::CoreAgentCodec; loop { let page = self .stores @@ -504,7 +504,7 @@ impl SessionRunner { .await?; for entry in page.entries.iter().map(|entry| codec.decode_entry(entry)) { let entry = entry?; - engine::apply_event(&mut state, &entry)?; + harness::apply_event(&mut state, &entry)?; } if page.complete { return Ok(state); @@ -529,7 +529,7 @@ impl SessionRunner { mut action: CoreAgentAction, observed_at_ms: u64, max_steps: usize, - emitted_entries: &mut Vec, + emitted_entries: &mut Vec, ) -> Result { loop { match action { @@ -624,23 +624,23 @@ fn should_refresh_run_context_before_admitting( async fn effective_prompt_instruction_inputs( blobs: &dyn BlobStore, state: &CoreAgentState, - source_entries: BTreeMap, -) -> Result, RunnerError> { + source_entries: BTreeMap, +) -> Result, RunnerError> { let mut desired = active_instruction_inputs(state); desired.retain(|key, _| { !context_key_is_in_prefix(key, tools::prompts::PROMPT_INSTRUCTIONS_CONTEXT_KEY_PREFIX) }); desired.extend(source_entries); - desired.remove(&engine::ContextEntryKey::new("instructions.000.default")); + desired.remove(&harness::ContextEntryKey::new("instructions.000.default")); if desired.is_empty() { let content_ref = blobs .put_bytes(TEST_PRODUCT_DEFAULT_INSTRUCTIONS.to_vec()) .await?; desired.insert( - engine::ContextEntryKey::new("instructions.000.default"), - engine::ContextEntryInput { - kind: engine::ContextEntryKind::Instructions, - content: engine::ContentRef::text(content_ref), + harness::ContextEntryKey::new("instructions.000.default"), + harness::ContextEntryInput { + kind: harness::ContextEntryKind::Instructions, + content: harness::ContentRef::text(content_ref), preview: None, origin: None, provenance_ref: None, @@ -653,12 +653,12 @@ async fn effective_prompt_instruction_inputs( fn active_instruction_inputs( state: &CoreAgentState, -) -> BTreeMap { +) -> BTreeMap { state .context .entries .iter() - .filter(|entry| matches!(entry.kind, engine::ContextEntryKind::Instructions)) + .filter(|entry| matches!(entry.kind, harness::ContextEntryKind::Instructions)) .filter_map(|entry| { let key = entry.key.clone()?; if !context_key_is_in_prefix(&key, "instructions") { @@ -666,7 +666,7 @@ fn active_instruction_inputs( } Some(( key, - engine::ContextEntryInput { + harness::ContextEntryInput { kind: entry.kind.clone(), content: entry.content.clone(), preview: entry.preview.clone(), @@ -679,7 +679,7 @@ fn active_instruction_inputs( .collect() } -fn context_key_is_in_prefix(key: &engine::ContextEntryKey, prefix: &str) -> bool { +fn context_key_is_in_prefix(key: &harness::ContextEntryKey, prefix: &str) -> bool { key.as_str() == prefix || key .as_str() @@ -698,7 +698,7 @@ fn resolve_max_steps(max_steps: Option) -> Result { } fn classify_quiescence(state: &CoreAgentState) -> RunnerQuiescence { - match engine::classify_core_agent_action(state) { + match harness::classify_core_agent_action(state) { CoreAgentAction::Closed => RunnerQuiescence::Closed, _ => RunnerQuiescence::Idle, } @@ -708,7 +708,7 @@ async fn failed_generation_result_from_error( blobs: &dyn BlobStore, request: LlmGenerationRequest, error: CoreAgentIoError, -) -> Result { +) -> Result { // Mirrors the hosted activity: a rejection keeps the provider's message // word for word. let context_limit = matches!(error, CoreAgentIoError::ContextLimit { .. }); @@ -751,7 +751,7 @@ async fn failed_context_compaction_result_from_error( blobs: &dyn BlobStore, request: ContextCompactionRequest, error: CoreAgentIoError, -) -> Result { +) -> Result { let context_revision = compaction_request_context_revision(&request); let failure_ref = write_error_blob( blobs, @@ -780,7 +780,7 @@ async fn failed_tool_batch_result( blobs: &dyn BlobStore, request: &ToolInvocationBatchRequest, error: impl AsRef, -) -> Result { +) -> Result { let mut results = Vec::with_capacity(request.calls.len()); for call in &request.calls { let error_ref = write_error_blob( @@ -824,7 +824,7 @@ async fn failed_tool_batch_result( async fn write_error_blob( blobs: &dyn BlobStore, message: impl Into, -) -> Result { +) -> Result { blobs.put_bytes(message.into().into_bytes()).await } @@ -836,7 +836,7 @@ mod tests { }; use async_trait::async_trait; - use engine::{ + use harness::{ CompactionPolicy, ContextCompactionRequest, ContextCompactionResult, ContextCompactionStatus, ContextConfig, ContextEntryInput, ContextEntryKey, ContextEntryKind, ContextMessageRole, CoreAgentCommand, CoreAgentEvent, FunctionToolSpec, @@ -1073,7 +1073,7 @@ mod tests { usage: None, approval_requests: Vec::new(), tool_calls: vec![ObservedToolCall { - call_id: engine::ToolCallId::new("call-1"), + call_id: harness::ToolCallId::new("call-1"), tool_id: Some(ToolName::new("test_tool")), tool_name: ToolName::new("test_tool"), provider_kind: None, @@ -1129,7 +1129,7 @@ mod tests { usage: None, approval_requests: Vec::new(), tool_calls: vec![ObservedToolCall { - call_id: engine::ToolCallId::new(self.call_id.clone()), + call_id: harness::ToolCallId::new(self.call_id.clone()), tool_id: Some(ToolName::new("vfs.read_file")), tool_name: ToolName::new("vfs_read_file"), provider_kind: None, @@ -1168,7 +1168,7 @@ mod tests { kind: ContextEntryKind::Message { role: ContextMessageRole::Assistant, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: BlobRef::from_bytes(b"assistant output"), media_type: None, provider_kind: None, @@ -1195,7 +1195,7 @@ mod tests { kind: ContextEntryKind::Message { role: ContextMessageRole::User, }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: None, provider_kind: None, @@ -1208,11 +1208,11 @@ mod tests { } fn request_run_command(content_ref: BlobRef) -> CoreAgentCommand { - CoreAgentCommand::RequestRun(engine::RunRequestCommand { + CoreAgentCommand::RequestRun(harness::RunRequestCommand { requested_by: None, notify_on_terminal: Vec::new(), submission_id: None, - source: engine::RunRequestSource::Input { + source: harness::RunRequestSource::Input { input: user_input(content_ref), }, run_config: run_config(), @@ -1239,12 +1239,12 @@ mod tests { fn vfs_config(prompts: bool, skills: bool) -> SessionConfig { let mut config = config(); - config.features.vfs = Some(engine::VfsFeature { - prompts: prompts.then_some(engine::VfsPromptsConfig::default()), - skills: skills.then_some(engine::VfsSkillsConfig { + config.features.vfs = Some(harness::VfsFeature { + prompts: prompts.then_some(harness::VfsPromptsConfig::default()), + skills: skills.then_some(harness::VfsSkillsConfig { roots: Some(vec!["/skills/system".into()]), }), - ..engine::VfsFeature::default() + ..harness::VfsFeature::default() }); config } @@ -1303,10 +1303,10 @@ mod tests { } } - async fn runner_with(llm: Arc) -> (SessionRunner, engine::SessionId) { + async fn runner_with(llm: Arc) -> (SessionRunner, harness::SessionId) { let sessions = Arc::new(InMemorySessionStore::new()); let stores = RunnerStores::new(sessions.clone(), Arc::new(InMemoryBlobStore::new())); - let session_id = engine::SessionId::new("session-a"); + let session_id = harness::SessionId::new("session-a"); sessions .create_session(CreateSession { metadata: Default::default(), @@ -1363,7 +1363,7 @@ mod tests { key: ContextEntryKey::new("client.native"), entry: ContextEntryInput { kind: ContextEntryKind::ProviderOpaque, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: BlobRef::from_bytes(br#"{"type":"input"}"#), media_type: Some("application/json".to_owned()), provider_kind: None, @@ -1393,7 +1393,7 @@ mod tests { assert!(!outcome.state.context.compaction.is_pending()); assert!(outcome.emitted_entries.iter().any(|entry| matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::CompactionFinished { + CoreAgentEvent::Context(harness::ContextEvent::CompactionFinished { status: ContextCompactionStatus::Failed, failure_ref: Some(_), .. @@ -1528,8 +1528,8 @@ mod tests { .load_state(&source_id) .await .expect("load source state"); - let fork_seq = engine::storage::largest_safe_fork_seq_from_state(&source_state); - assert_eq!(fork_seq, engine::EventSeq::new(1)); + let fork_seq = harness::storage::largest_safe_fork_seq_from_state(&source_state); + assert_eq!(fork_seq, harness::EventSeq::new(1)); sessions .create_forked_session(CreateForkedSession { source_session_id: source_id, @@ -1564,7 +1564,7 @@ mod tests { .unwrap() .context .compaction, - Some(engine::CompactionPolicy::ProviderStandalone { .. }) + Some(harness::CompactionPolicy::ProviderStandalone { .. }) )); assert!(outcome.state.runs.active.is_none()); assert_eq!(outcome.state.runs.completed.len(), 1); @@ -1581,7 +1581,7 @@ mod tests { .expect("child emitted entries") .position .seq, - engine::EventSeq::new(2) + harness::EventSeq::new(2) ); assert_eq!(llm.requests.lock().expect("requests").len(), 1); } @@ -1603,15 +1603,15 @@ mod tests { .unwrap() .is_none() ); - state.context.entries.push(engine::ContextEntry { - entry_id: engine::ContextEntryId::new(1), - key: Some(engine::ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY)), + state.context.entries.push(harness::ContextEntry { + entry_id: harness::ContextEntryId::new(1), + key: Some(harness::ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY)), origin: Some("runtime.vfs.skills".into()), kind: ContextEntryKind::Catalog { title: "Skills".into(), }, - source: engine::ContextEntrySource::ContextEdit, - content: engine::ContentRef::text(BlobRef::from_bytes(b"menu")), + source: harness::ContextEntrySource::ContextEdit, + content: harness::ContentRef::text(BlobRef::from_bytes(b"menu")), preview: None, provenance_ref: None, token_estimate: None, @@ -1619,7 +1619,7 @@ mod tests { }); for vfs in [ None, - Some(engine::VfsFeature { + Some(harness::VfsFeature { prompts: Some(Default::default()), ..Default::default() }), @@ -1707,9 +1707,9 @@ mod tests { .await .expect("drive request"); - let catalog_ref = engine::current_context_entry( + let catalog_ref = harness::current_context_entry( &outcome.state, - &engine::ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY), + &harness::ContextEntryKey::new(SKILL_CATALOG_CONTEXT_KEY), ) .expect("skill catalog") .provenance_ref @@ -1735,7 +1735,7 @@ mod tests { assert!(outcome.emitted_entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::EntriesApplied { entries, .. }) + CoreAgentEvent::Context(harness::ContextEvent::EntriesApplied { entries, .. }) if entries.iter().any(|entry| { matches!(entry.kind, ContextEntryKind::Catalog { .. }) && entry.key.as_ref().is_some_and(|key| key.as_str() == SKILL_CATALOG_CONTEXT_KEY) }) @@ -1851,7 +1851,7 @@ mod tests { assert!(first_outcome.emitted_entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::KeyPrefixReplaced { + CoreAgentEvent::Context(harness::ContextEvent::KeyPrefixReplaced { key_prefix, entries, .. @@ -1920,7 +1920,7 @@ mod tests { assert!(second_outcome.emitted_entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::KeyPrefixReplaced { + CoreAgentEvent::Context(harness::ContextEvent::KeyPrefixReplaced { key_prefix, entries, .. @@ -1988,7 +1988,7 @@ mod tests { assert!(third_outcome.emitted_entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Context(engine::ContextEvent::KeyPrefixReplaced { + CoreAgentEvent::Context(harness::ContextEvent::KeyPrefixReplaced { key_prefix, entries, .. @@ -2299,7 +2299,7 @@ mod tests { .emitted_entries .iter() .find_map(|entry| match &entry.event { - CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { result, .. }) + CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { result, .. }) if result.call_id.as_str() == call_id => { result.output_ref.clone() @@ -2314,7 +2314,7 @@ mod tests { serde_json::from_slice(&bytes).expect("decode read_file result") } - fn assert_prompt_entry_metadata(entries: &[&engine::ContextEntry]) { + fn assert_prompt_entry_metadata(entries: &[&harness::ContextEntry]) { for entry in entries { assert!(matches!(entry.kind, ContextEntryKind::Instructions)); assert!(entry.key.as_ref().is_some_and(|key| { @@ -2329,7 +2329,7 @@ mod tests { } } - fn prompt_content_refs(entries: &[&engine::ContextEntry]) -> Vec { + fn prompt_content_refs(entries: &[&harness::ContextEntry]) -> Vec { let mut refs = entries .iter() .map(|entry| entry.content.content_ref.clone()) @@ -2338,7 +2338,7 @@ mod tests { refs } - fn prompt_report_ref_from_entries(entries: &[&engine::ContextEntry]) -> BlobRef { + fn prompt_report_ref_from_entries(entries: &[&harness::ContextEntry]) -> BlobRef { let first = entries .first() .and_then(|entry| entry.provenance_ref.as_ref()) @@ -2352,7 +2352,7 @@ mod tests { async fn prompt_entry_texts( blobs: &dyn BlobStore, - entries: &[&engine::ContextEntry], + entries: &[&harness::ContextEntry], ) -> Vec { let mut texts = Vec::with_capacity(entries.len()); for entry in entries { @@ -2368,18 +2368,18 @@ mod tests { fn prompt_instruction_entries_in_request( request: &LlmGenerationRequest, - ) -> Vec<&engine::ContextEntry> { + ) -> Vec<&harness::ContextEntry> { request_context_entries(request) .iter() .filter(|entry| is_prompt_instruction_entry(entry)) .collect() } - fn request_context_entries(request: &LlmGenerationRequest) -> &[engine::ContextEntry] { + fn request_context_entries(request: &LlmGenerationRequest) -> &[harness::ContextEntry] { &request.request.context.entries } - fn is_prompt_instruction_entry(entry: &engine::ContextEntry) -> bool { + fn is_prompt_instruction_entry(entry: &harness::ContextEntry) -> bool { matches!(entry.kind, ContextEntryKind::Instructions) && entry.key.as_ref().is_some_and(|key| { key.as_str() @@ -2434,7 +2434,7 @@ mod tests { let run = &driven.state.runs.completed[0]; assert_eq!(run.status, RunStatus::Failed); let failure = run.failure.as_ref().expect("run failure"); - assert_eq!(failure.kind, engine::RunFailureKind::RequestRejected); + assert_eq!(failure.kind, harness::RunFailureKind::RequestRejected); let message_ref = failure.message_ref.as_ref().expect("provider message"); let message = runner .stores @@ -2477,7 +2477,7 @@ mod tests { matches!( &entry.event, CoreAgentEvent::Turn(TurnEvent::Completed { - outcome: engine::TurnOutcome::Failed { + outcome: harness::TurnOutcome::Failed { failure_ref: Some(_) }, .. @@ -2545,7 +2545,7 @@ mod tests { assert!(outcome.emitted_entries.iter().any(|entry| { matches!( &entry.event, - CoreAgentEvent::Tool(engine::ToolEvent::CallCompleted { + CoreAgentEvent::Tool(harness::ToolEvent::CallCompleted { result: ToolCallResult { duration_ms: None, output_bytes: None, diff --git a/crates/test-support/src/runner/error.rs b/crates/test-support/src/runner/error.rs index 6583a78a6..82c6e088e 100644 --- a/crates/test-support/src/runner/error.rs +++ b/crates/test-support/src/runner/error.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ CodecError, CommandError, CommandRejection, CoreAgentDriveError, CoreAgentIoError, DomainError, PlanningError, storage::{BlobStoreError, SessionStoreError}, diff --git a/crates/test-support/src/runner/protocol.rs b/crates/test-support/src/runner/protocol.rs index 25e2852b5..8a1a50149 100644 --- a/crates/test-support/src/runner/protocol.rs +++ b/crates/test-support/src/runner/protocol.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use engine::{ +use harness::{ CommandRejection, CoreAgentCommand, CoreAgentEntry, CoreAgentState, SessionId, SessionPosition, storage::{BlobStore, SessionStore}, }; diff --git a/crates/test-support/src/tool_calls.rs b/crates/test-support/src/tool_calls.rs index 23919e398..582b3cc35 100644 --- a/crates/test-support/src/tool_calls.rs +++ b/crates/test-support/src/tool_calls.rs @@ -1,6 +1,6 @@ //! Resolve names emitted by scripted models against their admitted request. -use engine::{LlmGenerationRequest, RemoteMcpExecution, RemoteMcpExposure, ToolKind, ToolName}; +use harness::{LlmGenerationRequest, RemoteMcpExecution, RemoteMcpExposure, ToolKind, ToolName}; /// Scripted tests supply their own MCP inventory. Built-in names still come /// from the real resolver, so test models cannot accidentally rely on registry @@ -15,7 +15,7 @@ pub fn scripted_tool_id(request: &LlmGenerationRequest, name: &str) -> Option tool.name.as_str() == name, ToolKind::ProviderNative(spec) => { - spec.execution == engine::ProviderNativeToolExecution::ClientEffect + spec.execution == harness::ProviderNativeToolExecution::ClientEffect && tool.name.as_str() == name } ToolKind::RemoteMcp(spec) => { diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index 279b1f126..c7eaf0a0b 100644 --- a/crates/tools/Cargo.toml +++ b/crates/tools/Cargo.toml @@ -6,18 +6,18 @@ edition = "2024" [dependencies] api = { path = "../api" } async-trait = "0.1" -engine = { path = "../engine" } +harness = { path = "../harness" } futures-util = "0.3" glob = "0.3" environment-client = { path = "../environment-client" } environment-protocol = { path = "../environment-protocol" } -jsonschema = { version = "0.33", default-features = false } +jsonschema = { version = "0.58", default-features = false } regex = "1" reqwest = { version = "0.13", default-features = false, features = ["rustls", "stream"] } serde = { version = "1", features = ["derive"] } serde_json = "1" serde_yaml = "0.9" -thiserror = "1" +thiserror = "2" tokio = { version = "1", features = ["fs", "net", "rt", "sync"] } uuid = { version = "1", features = ["v4"] } vfs = { path = "../vfs" } diff --git a/crates/tools/src/attachments.rs b/crates/tools/src/attachments.rs index 3f264e099..cada48764 100644 --- a/crates/tools/src/attachments.rs +++ b/crates/tools/src/attachments.rs @@ -1,5 +1,5 @@ //! Selection of explicitly linked attachments for session results. -pub use engine::{Attachment, AttachmentSource, FileAttachment}; +pub use harness::{Attachment, AttachmentSource, FileAttachment}; use std::collections::BTreeMap; /// File links have a budget independent of native media admission. pub const MAX_FILE_ATTACHMENTS: usize = 128; @@ -55,7 +55,7 @@ pub fn linked_attachments( .into_iter() .filter_map(|(_, attachment)| { let (count, limit) = match &attachment { - Attachment::Media(_) => (&mut media_count, engine::media::MAX_TOOL_MEDIA_ITEMS), + Attachment::Media(_) => (&mut media_count, harness::media::MAX_TOOL_MEDIA_ITEMS), Attachment::File(_) => (&mut file_count, MAX_FILE_ATTACHMENTS), }; *count += 1; @@ -69,7 +69,7 @@ pub fn linked_attachments( struct ReferenceArgs { path: crate::fs::FsPath, #[serde(default)] - snapshot_ref: Option, + snapshot_ref: Option, } /// Origin is navigation metadata, independent of the immutable content identity. @@ -165,7 +165,7 @@ pub(crate) async fn invoke_reference( #[cfg(test)] mod tests { use super::*; - use engine::{ + use harness::{ BlobRef, storage::{BlobStore, InMemoryBlobStore}, }; @@ -214,13 +214,13 @@ mod tests { async fn put_bytes( &self, bytes: Vec, - ) -> Result { + ) -> Result { self.inner.put_bytes(bytes).await } async fn read_bytes( &self, reference: &BlobRef, - ) -> Result, engine::storage::BlobStoreError> { + ) -> Result, harness::storage::BlobStoreError> { assert_ne!( reference, &self.file, "reference creation must not read file contents" @@ -230,13 +230,13 @@ mod tests { async fn has_blob( &self, reference: &BlobRef, - ) -> Result { + ) -> Result { self.inner.has_blob(reference).await } async fn stat_blob( &self, reference: &BlobRef, - ) -> Result { + ) -> Result { self.inner.stat_blob(reference).await } } diff --git a/crates/tools/src/builtin/mod.rs b/crates/tools/src/builtin/mod.rs index d78b59e1d..bc3332ff1 100644 --- a/crates/tools/src/builtin/mod.rs +++ b/crates/tools/src/builtin/mod.rs @@ -7,7 +7,7 @@ //! and `KillShell` are both `continue_process`), and a toolset may restrict //! the process tools to a one-shot shape that omits the handle path. -use engine::{ToolExecutionClass, ToolExecutionSpec, ToolName, ToolParallelism}; +use harness::{ToolExecutionClass, ToolExecutionSpec, ToolName, ToolParallelism}; use serde_json::Value; use crate::{ @@ -171,7 +171,7 @@ impl<'a> BuiltinToolContext<'a> { } } - pub fn blobs(self) -> &'a std::sync::Arc { + pub fn blobs(self) -> &'a std::sync::Arc { match self { Self::Vfs { filesystem: ctx, .. @@ -191,7 +191,7 @@ impl<'a> BuiltinToolContext<'a> { } } - pub fn drain_tool_effects(self) -> Vec { + pub fn drain_tool_effects(self) -> Vec { match self { Self::Vfs { filesystem: ctx, .. @@ -808,7 +808,7 @@ impl BuiltinToolOperation { #[cfg(test)] mod tests { - use engine::ProviderApiKind; + use harness::ProviderApiKind; use serde_json::json; use super::*; diff --git a/crates/tools/src/catalog.rs b/crates/tools/src/catalog.rs index bc3a2f551..8d683ffa0 100644 --- a/crates/tools/src/catalog.rs +++ b/crates/tools/src/catalog.rs @@ -1,7 +1,7 @@ //! Publication of runtime-owned catalogs as immutable text with structured provenance. -use engine::storage::{BlobStore, BlobStoreError}; -use engine::{BlobRef, ContextEntryInput, ContextEntryKey, ContextEntryKind, CoreAgentCommand}; +use harness::storage::{BlobStore, BlobStoreError}; +use harness::{BlobRef, ContextEntryInput, ContextEntryKey, ContextEntryKind, CoreAgentCommand}; pub const VFS_CATALOG_CONTEXT_KEY: &str = "runtime.catalog.vfs"; pub const SKILL_CATALOG_CONTEXT_KEY: &str = "runtime.catalog.skills.vfs"; @@ -20,7 +20,7 @@ pub async fn catalog_context_input( kind: ContextEntryKind::Catalog { title: title.to_owned(), }, - content: engine::ContentRef { + content: harness::ContentRef { content_ref: blobs.put_bytes(body.into_bytes()).await?, media_type: Some("text/markdown".to_owned()), provider_kind: None, @@ -57,7 +57,7 @@ pub fn clear_catalog_command( #[cfg(test)] mod tests { use super::*; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; #[tokio::test(flavor = "current_thread")] async fn publication_tracks_text_and_provenance_independently() { diff --git a/crates/tools/src/concurrency.rs b/crates/tools/src/concurrency.rs index 1712b16ef..9decc35be 100644 --- a/crates/tools/src/concurrency.rs +++ b/crates/tools/src/concurrency.rs @@ -1,6 +1,6 @@ //! Generic promise/concurrency tool contracts. -use engine::{ +use harness::{ PromiseControlCallRuntime, PromiseControlStateRuntime, PromiseId, PromiseOwnership, PromiseScope, PromiseStatus, RunId, ToolEffect, ToolName, promise_cancel_effect, promise_detach_effect, @@ -169,7 +169,7 @@ impl PromiseControlError { fn supplied_promise_controls<'a>( requested_ids: &[PromiseId], runtime: Option<&'a PromiseControlCallRuntime>, -) -> Result<&'a [engine::PromiseControlRuntime], PromiseControlError> { +) -> Result<&'a [harness::PromiseControlRuntime], PromiseControlError> { let runtime = runtime .ok_or_else(|| PromiseControlError::new("promise control runtime facts are missing"))?; if runtime.version != PromiseControlCallRuntime::VERSION { @@ -391,7 +391,7 @@ fn validated_non_empty_promise_ids( /// Parse the model's promise id list: every entry must be a `promise_` /// handle as returned by a promise-creating tool. A malformed entry is an /// ordinary tool error, so a mistyped id costs the model one turn and -/// never reaches the engine. +/// never reaches the harness. fn validated_promise_ids( promises: &[String], max_promises: usize, @@ -527,9 +527,9 @@ mod tests { ownership: PromiseOwnership, scope: PromiseScope, promise_status: PromiseStatus, - ) -> engine::PromiseControlRuntime { - engine::PromiseControlRuntime { - promise_id: engine::PromiseId::new(id), + ) -> harness::PromiseControlRuntime { + harness::PromiseControlRuntime { + promise_id: harness::PromiseId::new(id), state: PromiseControlStateRuntime::Known { ownership, scope, @@ -538,7 +538,7 @@ mod tests { } } - fn runtime(controls: Vec) -> PromiseControlCallRuntime { + fn runtime(controls: Vec) -> PromiseControlCallRuntime { PromiseControlCallRuntime::v1(controls) } @@ -579,7 +579,7 @@ mod tests { ] ); assert_eq!(effects.len(), 1); - assert_eq!(effects[0].kind, engine::PROMISE_CANCEL_EFFECT_KIND); + assert_eq!(effects[0].kind, harness::PROMISE_CANCEL_EFFECT_KIND); let runtime_owned = runtime(vec![known_control( "promise_1", @@ -605,8 +605,8 @@ mod tests { let args = CancelArgs { promises: vec!["promise_99".to_owned()], }; - let unknown = runtime(vec![engine::PromiseControlRuntime { - promise_id: engine::PromiseId::new("promise_99"), + let unknown = runtime(vec![harness::PromiseControlRuntime { + promise_id: harness::PromiseId::new("promise_99"), state: PromiseControlStateRuntime::Unknown, }]); assert_eq!( @@ -621,8 +621,8 @@ mod tests { .to_string(), "promise control runtime facts are missing" ); - let mismatched = runtime(vec![engine::PromiseControlRuntime { - promise_id: engine::PromiseId::new("promise_98"), + let mismatched = runtime(vec![harness::PromiseControlRuntime { + promise_id: harness::PromiseId::new("promise_98"), state: PromiseControlStateRuntime::Unknown, }]); assert_eq!( @@ -670,7 +670,7 @@ mod tests { ] ); assert_eq!(effects.len(), 1); - assert_eq!(effects[0].kind, engine::PROMISE_DETACH_EFFECT_KIND); + assert_eq!(effects[0].kind, harness::PROMISE_DETACH_EFFECT_KIND); for (facts, expected) in [ ( diff --git a/crates/tools/src/definitions.rs b/crates/tools/src/definitions.rs index 7f2666e62..646286e20 100644 --- a/crates/tools/src/definitions.rs +++ b/crates/tools/src/definitions.rs @@ -1,6 +1,6 @@ //! Code-owned definitions resolved from admitted logical identities. -use engine::{ +use harness::{ BuiltinToolSpec, ProviderApiKind, ToolExecutionSpec, ToolKind, ToolName, ToolParallelism, ToolSpec, }; diff --git a/crates/tools/src/environment.rs b/crates/tools/src/environment.rs index 745e74250..959cebfc6 100644 --- a/crates/tools/src/environment.rs +++ b/crates/tools/src/environment.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use engine::storage::BlobStore; +use harness::storage::BlobStore; use crate::{ environment::{jobs::JobExecutor, process::ProcessExecutor}, diff --git a/crates/tools/src/environment/attachments.rs b/crates/tools/src/environment/attachments.rs index 9c7428998..7034f294f 100644 --- a/crates/tools/src/environment/attachments.rs +++ b/crates/tools/src/environment/attachments.rs @@ -3,8 +3,8 @@ //! Built from the admitted grant and registry records, never from a live //! machine, and published like the sub-agent catalog. -use engine::storage::{BlobStore, BlobStoreError}; -use engine::{ +use harness::storage::{BlobStore, BlobStoreError}; +use harness::{ BlobRef, ContextEntryInput, CoreAgentCommand, EnvironmentAccess, EnvironmentsFeature, }; use serde::{Deserialize, Serialize}; @@ -160,7 +160,7 @@ pub async fn prepare_environment_catalog_publication( #[cfg(test)] mod tests { use super::*; - use engine::EnvironmentAttachment; + use harness::EnvironmentAttachment; fn feature() -> EnvironmentsFeature { EnvironmentsFeature { @@ -218,7 +218,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn publication_is_a_no_op_when_unchanged() { - let blobs = engine::storage::InMemoryBlobStore::new(); + let blobs = harness::storage::InMemoryBlobStore::new(); let snapshot = EnvironmentCatalogSnapshot::new(&feature(), |_| EnvironmentCatalogRecord::default()); let first = prepare_environment_catalog_publication(&blobs, None, &snapshot) diff --git a/crates/tools/src/environment/catalog_text.rs b/crates/tools/src/environment/catalog_text.rs index d14e6056e..cd6ff3d28 100644 --- a/crates/tools/src/environment/catalog_text.rs +++ b/crates/tools/src/environment/catalog_text.rs @@ -71,11 +71,11 @@ mod tests { assert!(!text.contains("workspace_1")); let mut first = catalog.clone(); first.routes[0].source = FsRouteSource::VfsSnapshot { - snapshot_ref: engine::BlobRef::from_bytes(b"first snapshot"), + snapshot_ref: harness::BlobRef::from_bytes(b"first snapshot"), }; let mut second = first.clone(); second.routes[0].source = FsRouteSource::VfsSnapshot { - snapshot_ref: engine::BlobRef::from_bytes(b"second snapshot"), + snapshot_ref: harness::BlobRef::from_bytes(b"second snapshot"), }; assert_eq!(vfs_catalog_text(&first), vfs_catalog_text(&second)); } diff --git a/crates/tools/src/environment/control.rs b/crates/tools/src/environment/control.rs index 1af76dc0f..b064265db 100644 --- a/crates/tools/src/environment/control.rs +++ b/crates/tools/src/environment/control.rs @@ -1,6 +1,6 @@ //! Live universe-environment discovery and session selection tool contracts. -use engine::ToolName; +use harness::ToolName; use serde::{Deserialize, Serialize}; use serde_json::{Value, json}; diff --git a/crates/tools/src/environment/handles.rs b/crates/tools/src/environment/handles.rs index 2c5a443b9..115b2cbea 100644 --- a/crates/tools/src/environment/handles.rs +++ b/crates/tools/src/environment/handles.rs @@ -1,6 +1,6 @@ //! Compact model references; canonical IDs remain the routing and storage identity. -use engine::{BlobRef, EnvironmentId}; +use harness::{BlobRef, EnvironmentId}; pub fn environment_handle(id: &str) -> String { if id.len() <= 24 && !id.starts_with("env:") { diff --git a/crates/tools/src/environment/jobs.rs b/crates/tools/src/environment/jobs.rs index ca3e6b8ca..dca6ed25e 100644 --- a/crates/tools/src/environment/jobs.rs +++ b/crates/tools/src/environment/jobs.rs @@ -15,7 +15,7 @@ use environment_protocol::{ use serde::{Deserialize, Serialize}; use thiserror::Error; -use engine::{ +use harness::{ BlobRef, storage::{BlobEdge, BlobGraphStore, BlobStore, BlobStoreError}, }; @@ -209,7 +209,7 @@ impl JobSubmitSpecArgs { // The model's job id keys the job's promise, so it must fit the // completion-key shape; checking here keeps key derivation from // ever failing on an accepted job. - engine::validate_completion_key(job_id.as_str()).map_err(|error| { + harness::validate_completion_key(job_id.as_str()).map_err(|error| { JobError::InvalidRequest { message: format!("job_id {:?} is invalid: {error}", job_id.as_str()), } @@ -464,8 +464,10 @@ mod tests { use std::sync::{Arc, Mutex}; use async_trait::async_trait; - use engine::storage::{BlobEdge, BlobGraphStore, BlobStore, BlobStoreError, InMemoryBlobStore}; use environment_protocol::data::jobs::{JobOutputStream, JobStatus}; + use harness::storage::{ + BlobEdge, BlobGraphStore, BlobStore, BlobStoreError, InMemoryBlobStore, + }; use serde_json::json; use super::*; diff --git a/crates/tools/src/environment/projection.rs b/crates/tools/src/environment/projection.rs index 0f014da6a..aa0ec9305 100644 --- a/crates/tools/src/environment/projection.rs +++ b/crates/tools/src/environment/projection.rs @@ -2,7 +2,7 @@ use std::collections::BTreeSet; -use engine::{ +use harness::{ BlobRef, ContextEntryInput, CoreAgentCommand, WorkspaceAccess, WorkspaceAttachmentTarget, storage::{BlobGraphStore, BlobStore, BlobStoreError, record_contains_edges}, }; @@ -230,7 +230,7 @@ fn stable_revision(bytes: &[u8]) -> u64 { #[cfg(test)] mod tests { - use engine::{WorkspaceAccess, storage::InMemoryBlobStore}; + use harness::{WorkspaceAccess, storage::InMemoryBlobStore}; use vfs::{ ResolvedWorkspaceAttachment, ResolvedWorkspaceAttachmentTarget, VfsPath, VfsWorkspaceId, }; @@ -261,7 +261,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn projection_writes_record_an_edge_for_every_embedded_ref() { let blobs = InMemoryBlobStore::new(); - let snapshot_ref = engine::storage::BlobStore::put_bytes(&blobs, b"snapshot".to_vec()) + let snapshot_ref = harness::storage::BlobStore::put_bytes(&blobs, b"snapshot".to_vec()) .await .expect("put snapshot"); let catalog = VfsCatalog::new( @@ -291,7 +291,7 @@ mod tests { .await .expect("publication"); - let embedded = engine::storage::collect_blob_refs( + let embedded = harness::storage::collect_blob_refs( &serde_json::from_slice(&publication.snapshot_bytes).expect("catalog json"), ); let recorded: BTreeSet = blobs diff --git a/crates/tools/src/environment/tools/continue_process.rs b/crates/tools/src/environment/tools/continue_process.rs index 1b22f8d43..c1a764ce1 100644 --- a/crates/tools/src/environment/tools/continue_process.rs +++ b/crates/tools/src/environment/tools/continue_process.rs @@ -71,7 +71,7 @@ mod tests { use std::sync::{Arc, Mutex}; use async_trait::async_trait; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::{ diff --git a/crates/tools/src/environment/tools/run_process.rs b/crates/tools/src/environment/tools/run_process.rs index f53106506..0d3774efe 100644 --- a/crates/tools/src/environment/tools/run_process.rs +++ b/crates/tools/src/environment/tools/run_process.rs @@ -91,7 +91,7 @@ mod tests { }; use async_trait::async_trait; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::{ diff --git a/crates/tools/src/environment_protocol/conformance.rs b/crates/tools/src/environment_protocol/conformance.rs index 47329290b..872a5ed0b 100644 --- a/crates/tools/src/environment_protocol/conformance.rs +++ b/crates/tools/src/environment_protocol/conformance.rs @@ -2,12 +2,12 @@ use std::sync::Arc; -use engine::storage::InMemoryBlobStore; use environment_client::{EnvironmentClientError, EnvironmentDataClient, JsonRpcTransport}; use environment_protocol::{ data::handshake::{InitializeParams, InitializedParams}, shared::{CURRENT_PROTOCOL_VERSION, EnvironmentCapabilities}, }; +use harness::storage::InMemoryBlobStore; use thiserror::Error; use crate::{ diff --git a/crates/tools/src/environment_protocol/remote.rs b/crates/tools/src/environment_protocol/remote.rs index c2ab084a5..d8e54afdc 100644 --- a/crates/tools/src/environment_protocol/remote.rs +++ b/crates/tools/src/environment_protocol/remote.rs @@ -9,7 +9,6 @@ use std::{ }; use async_trait::async_trait; -use engine::storage::BlobStore; use environment_client::{EnvironmentClientError, EnvironmentDataClient, JsonRpcTransport}; use environment_protocol::{ data::{ @@ -22,6 +21,7 @@ use environment_protocol::{ error::EnvironmentProtocolErrorCode, shared::{ByteChunk, EnvironmentCapabilities, EnvironmentPath, ProcessId}, }; +use harness::storage::BlobStore; use tokio::sync::Mutex as AsyncMutex; use crate::{ @@ -794,8 +794,8 @@ mod tests { sync::{Arc, Mutex}, }; - use engine::storage::InMemoryBlobStore; use environment_client::EnvironmentClientResult; + use harness::storage::InMemoryBlobStore; use serde_json::{Value, json}; use super::*; diff --git a/crates/tools/src/error.rs b/crates/tools/src/error.rs index d91600d78..cb27e2341 100644 --- a/crates/tools/src/error.rs +++ b/crates/tools/src/error.rs @@ -1,6 +1,6 @@ use thiserror::Error; -use engine::storage::BlobStoreError; +use harness::storage::BlobStoreError; use crate::{environment::jobs::JobError, environment::process::ProcessError, fs::FsError}; diff --git a/crates/tools/src/fs/mod.rs b/crates/tools/src/fs/mod.rs index e4070db65..2c3b67760 100644 --- a/crates/tools/src/fs/mod.rs +++ b/crates/tools/src/fs/mod.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use engine::{ToolEffect, storage::BlobStore}; +use harness::{ToolEffect, storage::BlobStore}; pub mod access; pub mod apply_patch; @@ -231,7 +231,7 @@ pub struct FsRangedRead { /// any environment bytes move; commit never merges concurrent workspace edits. #[async_trait] pub trait VfsCaptureTarget: Send + Sync { - fn blob_graph(&self) -> Option> { + fn blob_graph(&self) -> Option> { None } async fn commit(&self, entry: ::vfs::VfsEntry) -> FsResult<()>; diff --git a/crates/tools/src/fs/read_only.rs b/crates/tools/src/fs/read_only.rs index ad15be0dc..9f7a246cf 100644 --- a/crates/tools/src/fs/read_only.rs +++ b/crates/tools/src/fs/read_only.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use async_trait::async_trait; -use engine::ToolEffect; +use harness::ToolEffect; use crate::fs::{ CopyOptions, CreateDirectoryOptions, FileAccessPolicy, FileMetadata, FileSystem, FsError, diff --git a/crates/tools/src/fs/scoped.rs b/crates/tools/src/fs/scoped.rs index 41bbe2b83..6a6e91f50 100644 --- a/crates/tools/src/fs/scoped.rs +++ b/crates/tools/src/fs/scoped.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use async_trait::async_trait; -use engine::ToolEffect; +use harness::ToolEffect; use crate::fs::{ CopyOptions, CreateDirectoryOptions, FileAccessPolicy, FileMetadata, FileSystem, FsError, diff --git a/crates/tools/src/fs/tools/apply_patch.rs b/crates/tools/src/fs/tools/apply_patch.rs index dafcf5e2e..32638c550 100644 --- a/crates/tools/src/fs/tools/apply_patch.rs +++ b/crates/tools/src/fs/tools/apply_patch.rs @@ -54,7 +54,7 @@ pub async fn invoke_apply_patch( mod tests { use std::sync::Arc; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::fs::{FileSystem, InMemoryFileSystem}; diff --git a/crates/tools/src/fs/tools/edit_file.rs b/crates/tools/src/fs/tools/edit_file.rs index c8426cbbd..fa79c7d1d 100644 --- a/crates/tools/src/fs/tools/edit_file.rs +++ b/crates/tools/src/fs/tools/edit_file.rs @@ -74,7 +74,7 @@ pub async fn invoke_edit_file( mod tests { use std::sync::Arc; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::{ diff --git a/crates/tools/src/fs/tools/glob.rs b/crates/tools/src/fs/tools/glob.rs index 4fe8bdfad..d733e2e3e 100644 --- a/crates/tools/src/fs/tools/glob.rs +++ b/crates/tools/src/fs/tools/glob.rs @@ -127,7 +127,7 @@ fn glob_matches(pattern: &Pattern, pattern_text: &str, path: &FsPath, root: &FsP mod tests { use std::sync::Arc; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::fs::{CreateDirectoryOptions, FileSystem, InMemoryFileSystem}; diff --git a/crates/tools/src/fs/tools/grep.rs b/crates/tools/src/fs/tools/grep.rs index 601716c15..560fd688f 100644 --- a/crates/tools/src/fs/tools/grep.rs +++ b/crates/tools/src/fs/tools/grep.rs @@ -222,7 +222,7 @@ fn path_matches_include(pattern: &Pattern, path: &FsPath, root: &FsPath) -> bool mod tests { use std::sync::Arc; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::{ diff --git a/crates/tools/src/fs/tools/list_dir.rs b/crates/tools/src/fs/tools/list_dir.rs index 4295710ba..2f3caec8f 100644 --- a/crates/tools/src/fs/tools/list_dir.rs +++ b/crates/tools/src/fs/tools/list_dir.rs @@ -55,7 +55,7 @@ pub async fn invoke_list_dir(ctx: &FsToolContext, args: ListDirArgs) -> ToolResu mod tests { use std::sync::Arc; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::fs::{CreateDirectoryOptions, FileSystem, InMemoryFileSystem}; diff --git a/crates/tools/src/fs/tools/read_file.rs b/crates/tools/src/fs/tools/read_file.rs index a9cd8d172..d9b9f13dd 100644 --- a/crates/tools/src/fs/tools/read_file.rs +++ b/crates/tools/src/fs/tools/read_file.rs @@ -1,6 +1,6 @@ //! Canonical read-file operation. -use engine::{ +use harness::{ BlobRef, media::{ MediaDescriptor, MediaKind, admit_tool_media, media_handle, sniff_media_type, @@ -199,7 +199,7 @@ pub async fn invoke_read_file( mod tests { use std::sync::Arc; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::{ @@ -591,7 +591,7 @@ mod tests { async fn oversized_media_is_an_error_result_with_its_size() { let (fs, ctx) = media_context().await; let mut png = b"\x89PNG\r\n\x1a\n".to_vec(); - png.resize(engine::media::MAX_TOOL_MEDIA_BYTES as usize + 1, 0); + png.resize(harness::media::MAX_TOOL_MEDIA_BYTES as usize + 1, 0); write(&fs, "/huge.png", png).await; let error = read(&ctx, "/huge.png").await.expect_err("too large"); let message = error.to_string(); diff --git a/crates/tools/src/fs/tools/write_file.rs b/crates/tools/src/fs/tools/write_file.rs index 92f10a7b4..152280698 100644 --- a/crates/tools/src/fs/tools/write_file.rs +++ b/crates/tools/src/fs/tools/write_file.rs @@ -50,7 +50,7 @@ pub async fn invoke_write_file( mod tests { use std::sync::Arc; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::{ diff --git a/crates/tools/src/fs/vfs.rs b/crates/tools/src/fs/vfs.rs index a62c5cd95..06474db89 100644 --- a/crates/tools/src/fs/vfs.rs +++ b/crates/tools/src/fs/vfs.rs @@ -7,7 +7,7 @@ use std::{ }; use async_trait::async_trait; -use engine::{ +use harness::{ BlobRef, ToolEffect, storage::{BlobGraphStore, BlobStore, BlobStoreError}, }; @@ -1031,7 +1031,7 @@ mod tests { use ::vfs::VfsWorkspaceStore; use async_trait::async_trait; - use engine::{ + use harness::{ CoreAgentTools, RunId, SessionId, ToolBatchId, ToolCallId, ToolCallStatus, ToolInvocationBatchRequest, ToolInvocationRequest, ToolName, TurnId, storage::{BlobStore, InMemoryBlobStore}, @@ -1464,7 +1464,7 @@ mod tests { fn resolved_attachment( path: &str, target: ::vfs::ResolvedWorkspaceAttachmentTarget, - access: engine::WorkspaceAccess, + access: harness::WorkspaceAccess, ) -> ::vfs::ResolvedWorkspaceAttachment { ::vfs::ResolvedWorkspaceAttachment { path: ::vfs::VfsPath::parse(path).unwrap(), @@ -1510,12 +1510,12 @@ mod tests { ::vfs::ResolvedWorkspaceAttachmentTarget::AvailableSnapshot { snapshot_ref: skill_snapshot.snapshot_ref, }, - engine::WorkspaceAccess::Read, + harness::WorkspaceAccess::Read, ), resolved_attachment( "/workspace", ::vfs::ResolvedWorkspaceAttachmentTarget::AvailableWorkspace { workspace }, - engine::WorkspaceAccess::Edit, + harness::WorkspaceAccess::Edit, ), ], ) @@ -1542,24 +1542,24 @@ mod tests { .with_cwd(FsPath::new("/workspace/docs").unwrap()); let mut catalog = ToolCatalog::new(); catalog.insert(ToolBinding::new( - engine::ToolName::new("vfs_reference"), + harness::ToolName::new("vfs_reference"), "vfs.reference", )); let runtime = InlineToolRuntime::with_vfs_filesystem(ctx, catalog).with_vfs_attachments(mounts); let result = runtime .invoke_json( - &engine::ToolName::new("vfs_reference"), + &harness::ToolName::new("vfs_reference"), serde_json::json!({"path":"report.md"}), ) .await .unwrap(); - let engine::Attachment::File(file) = &result.attachments[0] else { + let harness::Attachment::File(file) = &result.attachments[0] else { panic!("file attachment") }; assert_eq!( file.source, - Some(engine::AttachmentSource { + Some(harness::AttachmentSource { kind: "vfs_workspace".into(), id: workspace_id.to_string(), path: "docs/report.md".into(), @@ -1573,12 +1573,12 @@ mod tests { ); let snapshot = runtime .invoke_json( - &engine::ToolName::new("vfs_reference"), + &harness::ToolName::new("vfs_reference"), serde_json::json!({"path":"/skills/rust/SKILL.md"}), ) .await .unwrap(); - let engine::Attachment::File(file) = &snapshot.attachments[0] else { + let harness::Attachment::File(file) = &snapshot.attachments[0] else { panic!("file attachment") }; let source = file.source.as_ref().unwrap(); @@ -1869,7 +1869,7 @@ mod tests { let (blobs, fs, workspace_id, _base_snapshot_ref) = test_workspace_fs(store.clone(), Vec::new()).await; let ctx = FsToolContext::new(Arc::new(fs), blobs.clone()); - let target = ToolTarget::api_kind(engine::ProviderApiKind::OpenAiResponses); + let target = ToolTarget::api_kind(harness::ProviderApiKind::OpenAiResponses); let toolset = register_toolset(&ToolsetConfig::workspace()).expect("toolset"); let runtime = InlineToolRuntime::with_vfs_filesystem(ctx, crate::runtime::ToolCatalog::new()); @@ -1892,12 +1892,12 @@ mod tests { subagents_policy: None, workspace_attachments: Vec::new(), calls: vec![ToolInvocationRequest { - builtin: Some(engine::BuiltinToolCallRuntime { + builtin: Some(harness::BuiltinToolCallRuntime { spec: match &toolset.tools[&ToolName::new("vfs.write_file")].kind { - engine::ToolKind::Builtin(spec) => spec.clone(), + harness::ToolKind::Builtin(spec) => spec.clone(), _ => panic!("built-in spec"), }, - model: engine::ModelSelection { + model: harness::ModelSelection { api_kind: target.api_kind, provider_id: "test".into(), model: "test".into(), @@ -2146,12 +2146,12 @@ mod tests { ::vfs::ResolvedWorkspaceAttachmentTarget::AvailableWorkspace { workspace: workspace.clone(), }, - engine::WorkspaceAccess::Edit, + harness::WorkspaceAccess::Edit, ), resolved_attachment( "/workspace", ::vfs::ResolvedWorkspaceAttachmentTarget::AvailableWorkspace { workspace }, - engine::WorkspaceAccess::Edit, + harness::WorkspaceAccess::Edit, ), ]; assert!(matches!( @@ -2165,14 +2165,14 @@ mod tests { ::vfs::ResolvedWorkspaceAttachmentTarget::AvailableSnapshot { snapshot_ref: snapshot_ref.clone(), }, - engine::WorkspaceAccess::Read, + harness::WorkspaceAccess::Read, ), resolved_attachment( "/skills/rust", ::vfs::ResolvedWorkspaceAttachmentTarget::AvailableSnapshot { snapshot_ref: snapshot_ref.clone(), }, - engine::WorkspaceAccess::Read, + harness::WorkspaceAccess::Read, ), ]; assert!(matches!( @@ -2183,7 +2183,7 @@ mod tests { let writable_snapshot = vec![resolved_attachment( "/skills/rust", ::vfs::ResolvedWorkspaceAttachmentTarget::AvailableSnapshot { snapshot_ref }, - engine::WorkspaceAccess::Edit, + harness::WorkspaceAccess::Edit, )]; assert!(matches!( AttachedVfsFileSystem::new(blobs, store, writable_snapshot), diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index 09367f419..9174c778b 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs @@ -1,7 +1,7 @@ -//! Optional standard agent tools for `engine`. +//! Optional standard agent tools for `harness`. //! //! This crate owns optional tool packages, model-visible tool contracts, -//! and protocol/runtime adapters. The deterministic `engine` core stays +//! and protocol/runtime adapters. The deterministic `harness` core stays //! independent from this crate. pub mod attachments; diff --git a/crates/tools/src/limits.rs b/crates/tools/src/limits.rs index 06cde702a..5decc3429 100644 --- a/crates/tools/src/limits.rs +++ b/crates/tools/src/limits.rs @@ -9,7 +9,7 @@ pub struct ToolLimits { /// Deployment-owned ceiling on a requested `run_process` timeout. A caller /// may request a lower timeout but can never raise it above this bound; /// the hosted runtime derives its process activity deadline from the same - /// ceiling (asserted by a temporal-server test). + /// ceiling (asserted by a temporal-runtime test). pub max_process_timeout_ms: u64, /// Deployment-owned bounds on recursive text search. The same /// bounds are sent to a native host search and enforced by the generic diff --git a/crates/tools/src/prompts/assembler.rs b/crates/tools/src/prompts/assembler.rs index 727896329..314a9f53e 100644 --- a/crates/tools/src/prompts/assembler.rs +++ b/crates/tools/src/prompts/assembler.rs @@ -3,7 +3,7 @@ use std::{ collections::{BTreeMap, BTreeSet}, }; -use engine::{ +use harness::{ BlobRef, ContextEntry, ContextEntryInput, ContextEntryKey, ContextEntryKind, CoreAgentState, storage::{BlobGraphStore, BlobStore, BlobStoreError, record_contains_edges}, }; @@ -246,7 +246,7 @@ pub fn prompt_source_instructions_context_input( ) -> ContextEntryInput { ContextEntryInput { kind: ContextEntryKind::Instructions, - content: engine::ContentRef { + content: harness::ContentRef { content_ref, media_type: Some("text/markdown".to_owned()), provider_kind: Some(PROMPT_INSTRUCTIONS_PROVIDER_KIND.to_owned()), @@ -396,7 +396,7 @@ async fn read_prompt_source( content_ref, text, bytes: bytes.len() as u64, - writable: input.root.access == engine::WorkspaceAccess::Edit, + writable: input.root.access == harness::WorkspaceAccess::Edit, warnings: Vec::new(), })) } @@ -854,8 +854,8 @@ struct SourceFingerprintPayload<'a> { mod tests { use std::sync::Arc; - use engine::WorkspaceAccess; - use engine::storage::{BlobStore, InMemoryBlobStore}; + use harness::WorkspaceAccess; + use harness::storage::{BlobStore, InMemoryBlobStore}; use super::*; use crate::fs::{CreateDirectoryOptions, InMemoryFileSystem}; @@ -971,7 +971,7 @@ mod tests { assert_eq!(build.entries.len(), 1, "the long source is truncated"); assert_eq!(build.report.sources.len(), 2); - let embedded = engine::storage::collect_blob_refs( + let embedded = harness::storage::collect_blob_refs( &serde_json::from_slice(&build.report_bytes).expect("report json"), ); let recorded: BTreeSet = blobs diff --git a/crates/tools/src/prompts/environment.rs b/crates/tools/src/prompts/environment.rs index af2f01f41..9a74784cd 100644 --- a/crates/tools/src/prompts/environment.rs +++ b/crates/tools/src/prompts/environment.rs @@ -1,9 +1,9 @@ //! Bounded environment prompt assembly from a complete filesystem observation. -use engine::{ +use environment_protocol::data::inventory::ScanResponse; +use harness::{ ContentRef, ContextEntryInput, ContextEntryKey, ContextEntryKind, storage::{BlobStore, BlobStoreError}, }; -use environment_protocol::data::inventory::ScanResponse; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; diff --git a/crates/tools/src/prompts/model.rs b/crates/tools/src/prompts/model.rs index 3750b7b4f..dbf9a6d3f 100644 --- a/crates/tools/src/prompts/model.rs +++ b/crates/tools/src/prompts/model.rs @@ -1,4 +1,4 @@ -use engine::{BlobRef, ContextEntryKey, WorkspaceAccess}; +use harness::{BlobRef, ContextEntryKey, WorkspaceAccess}; use serde::{Deserialize, Serialize}; use vfs::{VfsPath, VfsWorkspaceId}; diff --git a/crates/tools/src/prompts/vfs.rs b/crates/tools/src/prompts/vfs.rs index 1ff7ca93c..882fd4b35 100644 --- a/crates/tools/src/prompts/vfs.rs +++ b/crates/tools/src/prompts/vfs.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeSet, sync::Arc}; -use engine::storage::BlobStore; +use harness::storage::BlobStore; use thiserror::Error; use vfs::{ ResolvedWorkspaceAttachment, ResolvedWorkspaceAttachmentTarget, VfsPath, VfsWorkspaceId, @@ -309,7 +309,7 @@ mod tests { use std::collections::BTreeMap; use async_trait::async_trait; - use engine::{BlobRef, WorkspaceAccess, storage::InMemoryBlobStore}; + use harness::{BlobRef, WorkspaceAccess, storage::InMemoryBlobStore}; use vfs::{ CompareAndSetVfsWorkspaceHead, CreateInlineSnapshotRequest, CreateVfsWorkspaceRecord, InlineFile, ResolvedWorkspaceAttachment, ResolvedWorkspaceAttachmentTarget, @@ -408,7 +408,7 @@ mod tests { resolved_attachment( "/skills/system", ResolvedWorkspaceAttachmentTarget::AvailableSnapshot { - snapshot_ref: engine::BlobRef::from_bytes(b"snapshot"), + snapshot_ref: harness::BlobRef::from_bytes(b"snapshot"), }, WorkspaceAccess::Read, ), diff --git a/crates/tools/src/runtime/inline.rs b/crates/tools/src/runtime/inline.rs index c3bf3eaf3..7370dfeec 100644 --- a/crates/tools/src/runtime/inline.rs +++ b/crates/tools/src/runtime/inline.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use async_trait::async_trait; -use engine::{ +use harness::{ CoreAgentIoError, CoreAgentTools, ToolBatchOutcome, ToolCallStatus, ToolInvocationBatchRequest, ToolInvocationBatchResult, ToolInvocationRequest, ToolInvocationResult, ToolName, storage::BlobStore, @@ -117,7 +117,7 @@ impl InlineToolRuntime { ); Some(format!( "tool-{}", - engine::BlobRef::from_bytes(identity.as_bytes()) + harness::BlobRef::from_bytes(identity.as_bytes()) .as_str() .trim_start_matches("sha256:") )) @@ -387,14 +387,14 @@ impl InlineToolRuntime { &self, ctx: BuiltinToolContext<'_>, bytes: Vec, - ) -> Result { + ) -> Result { ctx.blobs() .put_bytes(bytes) .await .map_err(|error| io_error(format!("failed to write tool blob: {error}"))) } - async fn put_blob_bytes(&self, bytes: Vec) -> Result { + async fn put_blob_bytes(&self, bytes: Vec) -> Result { self.blobs .put_bytes(bytes) .await @@ -485,10 +485,10 @@ struct ProjectedText { /// The tool result entry followed by one media entry per admitted asset, in /// the order the visible text announces them. fn model_visible_entries( - call_id: &engine::ToolCallId, - model_visible_ref: engine::BlobRef, + call_id: &harness::ToolCallId, + model_visible_ref: harness::BlobRef, attachments: &[crate::attachments::Attachment], -) -> Vec { +) -> Vec { let mut entries = Vec::with_capacity(1 + attachments.len()); entries.push(ToolInvocationResult::tool_result_context_entry( call_id, @@ -537,7 +537,7 @@ mod tests { use std::sync::{Arc, Mutex}; use async_trait::async_trait; - use engine::{ + use harness::{ BlobRef, ContextEntryKind, RunId, SessionId, ToolBatchId, ToolCallId, ToolInvocationRequest, ToolInvocationResult, ToolName, TurnId, storage::{BlobStore, InMemoryBlobStore}, @@ -621,12 +621,12 @@ mod tests { fn call(arguments_ref: BlobRef, tool_name: &str) -> ToolInvocationRequest { ToolInvocationRequest { - builtin: Some(engine::BuiltinToolCallRuntime { - spec: engine::BuiltinToolSpec { + builtin: Some(harness::BuiltinToolCallRuntime { + spec: harness::BuiltinToolSpec { settings: json!({"presentation": "canonical"}), }, - model: engine::ModelSelection { - api_kind: engine::ProviderApiKind::OpenAiResponses, + model: harness::ModelSelection { + api_kind: harness::ProviderApiKind::OpenAiResponses, provider_id: "openai".to_owned(), model: "test-model".to_owned(), }, @@ -662,7 +662,7 @@ mod tests { } } - fn workspace_catalog(api_kind: engine::ProviderApiKind) -> ToolCatalog { + fn workspace_catalog(api_kind: harness::ProviderApiKind) -> ToolCatalog { let target = ToolTarget::api_kind(api_kind); ToolCatalog::from_registrations( ®ister_toolset(&ToolsetConfig::workspace()) @@ -674,7 +674,7 @@ mod tests { } fn catalog_for_operations_with_presentation( - api_kind: engine::ProviderApiKind, + api_kind: harness::ProviderApiKind, presentation: BuiltinToolPresentation, operations: impl IntoIterator, ) -> ToolCatalog { @@ -699,7 +699,7 @@ mod tests { } fn web_fetch_catalog() -> ToolCatalog { - let target = ToolTarget::api_kind(engine::ProviderApiKind::OpenAiResponses); + let target = ToolTarget::api_kind(harness::ProviderApiKind::OpenAiResponses); let mut config = ToolsetConfig::empty(); config.web.fetch = true; ToolCatalog::from_registrations(®ister_toolset(&config).expect("toolset").tools, &target) @@ -724,7 +724,7 @@ mod tests { fs.write_file(&FsPath::new("/file.txt").expect("path"), b"hello".to_vec()) .await .expect("write file"); - let catalog = workspace_catalog(engine::ProviderApiKind::OpenAiResponses); + let catalog = workspace_catalog(harness::ProviderApiKind::OpenAiResponses); let runtime = runtime_with_vfs(fs, blobs.clone(), catalog); let output = runtime @@ -746,7 +746,7 @@ mod tests { fs.write_file(&FsPath::new("/file.txt").expect("path"), b"hello".to_vec()) .await .expect("write file"); - let target = ToolTarget::api_kind(engine::ProviderApiKind::AnthropicMessages); + let target = ToolTarget::api_kind(harness::ProviderApiKind::AnthropicMessages); let mut config = ToolsetConfig::empty(); config.builtin = BuiltinToolsetConfig { presentation: BuiltinToolPresentation::ClaudeCodeLike, @@ -789,7 +789,7 @@ mod tests { .await .expect("environment write"); - let target = ToolTarget::api_kind(engine::ProviderApiKind::OpenAiResponses); + let target = ToolTarget::api_kind(harness::ProviderApiKind::OpenAiResponses); let mut config = ToolsetConfig::workspace(); config.builtin.environment = crate::toolset::EnvironmentToolsetConfig::basic(); let catalog = ToolCatalog::from_registrations( @@ -831,7 +831,7 @@ mod tests { async fn environment_filesystem_failures_distinguish_missing_and_read_only() { let blobs: Arc = Arc::new(InMemoryBlobStore::new()); let catalog = catalog_for_operations_with_presentation( - engine::ProviderApiKind::OpenAiResponses, + harness::ProviderApiKind::OpenAiResponses, BuiltinToolPresentation::Canonical, [BuiltinToolOperation::WriteFile], ); @@ -874,7 +874,7 @@ mod tests { fs.write_file(&FsPath::new("/file.txt").expect("path"), b"hello".to_vec()) .await .expect("write file"); - let catalog = workspace_catalog(engine::ProviderApiKind::OpenAiResponses); + let catalog = workspace_catalog(harness::ProviderApiKind::OpenAiResponses); let runtime = runtime_with_vfs(fs, blobs.clone(), catalog); let args_ref = blobs .put_bytes(br#"{"path":"/file.txt","offset":null,"limit":null}"#.to_vec()) @@ -905,7 +905,7 @@ mod tests { fs.write_file(&FsPath::new("/render.png").expect("path"), png.clone()) .await .expect("write file"); - let catalog = workspace_catalog(engine::ProviderApiKind::OpenAiResponses); + let catalog = workspace_catalog(harness::ProviderApiKind::OpenAiResponses); let runtime = runtime_with_vfs(fs, blobs.clone(), catalog); let args_ref = blobs .put_bytes(br#"{"path":"/render.png","offset":null,"limit":null}"#.to_vec()) @@ -928,14 +928,14 @@ mod tests { .read_text(&entries[0].content.content_ref) .await .expect("visible text"); - let handle = engine::media::media_handle(&BlobRef::from_bytes(&png)); + let handle = harness::media::media_handle(&BlobRef::from_bytes(&png)); assert!(visible.contains(&handle), "{visible}"); assert!(visible.contains("render.png"), "{visible}"); let media = &entries[1]; assert!(matches!( media.kind, ContextEntryKind::Message { - role: engine::ContextMessageRole::User + role: harness::ContextMessageRole::User } )); assert_eq!(media.content.media_type.as_deref(), Some("image/png")); @@ -956,7 +956,7 @@ mod tests { fs.write_file(&FsPath::new("/file.txt").expect("path"), b"hello".to_vec()) .await .expect("write file"); - let catalog = workspace_catalog(engine::ProviderApiKind::OpenAiResponses); + let catalog = workspace_catalog(harness::ProviderApiKind::OpenAiResponses); let runtime = runtime_with_vfs(fs, blobs.clone(), catalog); let args_ref = blobs .put_bytes(br#"{"path":"/file.txt","offset":null,"limit":null}"#.to_vec()) @@ -1028,7 +1028,7 @@ mod tests { let process_ctx: Arc = process.clone(); let env_ctx = EnvironmentToolContext::new(Some(process_ctx), blobs.clone()); let catalog = catalog_for_operations_with_presentation( - engine::ProviderApiKind::OpenAiResponses, + harness::ProviderApiKind::OpenAiResponses, BuiltinToolPresentation::Canonical, [BuiltinToolOperation::RunProcess], ); @@ -1064,7 +1064,7 @@ mod tests { let process_ctx: Arc = process.clone(); let env_ctx = EnvironmentToolContext::new(Some(process_ctx), blobs.clone()); let catalog = catalog_for_operations_with_presentation( - engine::ProviderApiKind::AnthropicMessages, + harness::ProviderApiKind::AnthropicMessages, BuiltinToolPresentation::ProviderDefault, [ BuiltinToolOperation::RunProcess, @@ -1112,8 +1112,8 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn shell_execution_and_polling_are_the_responses_and_completions_defaults() { for api_kind in [ - engine::ProviderApiKind::OpenAiResponses, - engine::ProviderApiKind::OpenAiCompletions, + harness::ProviderApiKind::OpenAiResponses, + harness::ProviderApiKind::OpenAiCompletions, ] { let blobs = Arc::new(InMemoryBlobStore::new()); let process = Arc::new(RecordingProcessExecutor::default()); @@ -1203,7 +1203,7 @@ mod tests { request.tool_name = ToolName::new(name); request.tool_id = Some(ToolName::new(id)); let builtin = request.builtin.as_mut().unwrap(); - builtin.model.api_kind = engine::ProviderApiKind::OpenAiCompletions; + builtin.model.api_kind = harness::ProviderApiKind::OpenAiCompletions; builtin.spec.settings = settings; let restored = serde_json::from_slice(&serde_json::to_vec(&request).unwrap()).unwrap(); let result = runtime.invoke_call(&restored).await.unwrap(); @@ -1243,7 +1243,7 @@ mod tests { .await .unwrap(); } - let target = ToolTarget::api_kind(engine::ProviderApiKind::OpenAiCompletions); + let target = ToolTarget::api_kind(harness::ProviderApiKind::OpenAiCompletions); let description = BuiltinTool::environment_canonical(BuiltinToolOperation::ApplyPatch) .definition(&target, false) .unwrap() @@ -1279,7 +1279,7 @@ mod tests { request.tool_id = Some(ToolName::new(id)); request.tool_name = ToolName::new(name); let builtin = request.builtin.as_mut().unwrap(); - builtin.model.api_kind = engine::ProviderApiKind::OpenAiCompletions; + builtin.model.api_kind = harness::ProviderApiKind::OpenAiCompletions; builtin.spec.settings = json!({}); let restored = serde_json::from_slice(&serde_json::to_vec(&request).unwrap()).unwrap(); let result = runtime.invoke_call(&restored).await.unwrap(); @@ -1301,7 +1301,7 @@ mod tests { async fn core_tools_fail_process_tools_without_active_environment() { let blobs = Arc::new(InMemoryBlobStore::new()); let catalog = catalog_for_operations_with_presentation( - engine::ProviderApiKind::OpenAiResponses, + harness::ProviderApiKind::OpenAiResponses, BuiltinToolPresentation::Canonical, [BuiltinToolOperation::RunProcess], ); @@ -1394,7 +1394,7 @@ mod tests { request.tool_id = Some(ToolName::new("env.continue_process")); request.tool_name = ToolName::new(name); request.builtin.as_mut().unwrap().model.api_kind = - engine::ProviderApiKind::AnthropicMessages; + harness::ProviderApiKind::AnthropicMessages; request.builtin.as_mut().unwrap().spec.settings = json!({}); let restored = serde_json::from_slice(&serde_json::to_vec(&request).unwrap()).unwrap(); let result = runtime.invoke_call(&restored).await.unwrap(); diff --git a/crates/tools/src/runtime/mod.rs b/crates/tools/src/runtime/mod.rs index 6ce2d973b..04aff1309 100644 --- a/crates/tools/src/runtime/mod.rs +++ b/crates/tools/src/runtime/mod.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use async_trait::async_trait; -use engine::{ToolEffect, ToolName}; +use harness::{ToolEffect, ToolName}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -49,12 +49,12 @@ pub struct ToolCatalog { impl ToolCatalog { pub fn from_registrations( - tools: &BTreeMap, + tools: &BTreeMap, target: &ToolTarget, ) -> ToolResult { let mut catalog = Self::new(); for tool in tools.values() { - if let engine::ToolKind::Builtin(spec) = &tool.kind { + if let harness::ToolKind::Builtin(spec) = &tool.kind { for resolved in crate::definitions::resolve(&tool.name, spec, target)? { if let Some(binding) = resolved.binding { if catalog.get(&binding.tool_name).is_some() { @@ -131,7 +131,7 @@ pub struct ToolInvocationOutput { } impl ToolInvocationOutput { - pub fn with_media(mut self, media: Vec) -> Self { + pub fn with_media(mut self, media: Vec) -> Self { self.attachments .extend(media.into_iter().map(crate::attachments::Attachment::Media)); self diff --git a/crates/tools/src/runtime/target.rs b/crates/tools/src/runtime/target.rs index 7590d0672..b97c85994 100644 --- a/crates/tools/src/runtime/target.rs +++ b/crates/tools/src/runtime/target.rs @@ -1,6 +1,6 @@ //! Model and provider target for model-visible tool shaping. -use engine::{ModelSelection, ProviderApiKind}; +use harness::{ModelSelection, ProviderApiKind}; #[derive(Clone, Debug, Eq, PartialEq)] pub struct ToolTarget { diff --git a/crates/tools/src/skills/catalog.rs b/crates/tools/src/skills/catalog.rs index 477c95188..459a87013 100644 --- a/crates/tools/src/skills/catalog.rs +++ b/crates/tools/src/skills/catalog.rs @@ -4,7 +4,7 @@ use super::SkillId; use crate::catalog::{ SKILL_CATALOG_CONTEXT_KEY, catalog_context_input, catalog_publication_command, }; -use engine::{ +use harness::{ BlobRef, ContextEntryInput, CoreAgentCommand, storage::{BlobGraphStore, BlobStore, BlobStoreError, record_contains_edges}, }; @@ -534,7 +534,7 @@ impl RootReadDirectory for SkillCatalogRoot { mod tests { use std::sync::Arc; - use engine::{ + use harness::{ BlobRef, storage::{BlobStore, InMemoryBlobStore}, }; @@ -639,7 +639,7 @@ mod tests { .await .expect("build catalog"); - let embedded = engine::storage::collect_blob_refs( + let embedded = harness::storage::collect_blob_refs( &serde_json::from_slice(&build.catalog_bytes).expect("catalog json"), ); let recorded: std::collections::BTreeSet = blobs @@ -882,7 +882,7 @@ mod tests { assert_eq!(key.as_str(), SKILL_CATALOG_CONTEXT_KEY); assert_eq!( entry.kind, - engine::ContextEntryKind::Catalog { + harness::ContextEntryKind::Catalog { title: "VFS skill catalog".to_owned() } ); diff --git a/crates/tools/src/skills/environment.rs b/crates/tools/src/skills/environment.rs index 54c9a1db6..bbb38b6a7 100644 --- a/crates/tools/src/skills/environment.rs +++ b/crates/tools/src/skills/environment.rs @@ -1,10 +1,10 @@ //! Environment discovery consumes generic endpoint observations independently of VFS. use super::{SkillId, parse_skill_frontmatter}; -use engine::{ +use environment_protocol::data::inventory::{ScanParams, ScanResponse}; +use harness::{ BlobRef, ContextEntryInput, CoreAgentCommand, EnvironmentSkillsConfig, storage::{BlobStore, BlobStoreError}, }; -use environment_protocol::data::inventory::{ScanParams, ScanResponse}; use serde::{Deserialize, Serialize}; use std::{collections::BTreeSet, path::Path}; @@ -164,11 +164,11 @@ mod tests { fs::{CreateDirectoryOptions, FileSystem, FsPath, InMemoryFileSystem}, skills::*, }; - use engine::storage::InMemoryBlobStore; use environment_protocol::{ data::inventory::{ScanContent, ScanEntry}, shared::EnvironmentPath, }; + use harness::storage::InMemoryBlobStore; #[test] fn scope_defaults_and_overrides_are_independent_of_home() { diff --git a/crates/tools/src/skills/id.rs b/crates/tools/src/skills/id.rs index 9fae7bc1a..8408b042e 100644 --- a/crates/tools/src/skills/id.rs +++ b/crates/tools/src/skills/id.rs @@ -1,8 +1,8 @@ -use engine::{StringIdError, validate_general_string_id}; +use harness::{StringIdError, validate_general_string_id}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use std::fmt; -/// Runtime catalog identity. The deterministic engine does not interpret skills. +/// Runtime catalog identity. The deterministic harness does not interpret skills. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SkillId(String); diff --git a/crates/tools/src/skills/model.rs b/crates/tools/src/skills/model.rs index eac5f0165..96abdbcd3 100644 --- a/crates/tools/src/skills/model.rs +++ b/crates/tools/src/skills/model.rs @@ -1,5 +1,5 @@ use super::SkillId; -use engine::BlobRef; +use harness::BlobRef; use serde::{Deserialize, Serialize}; use vfs::{VfsPath, VfsWorkspaceId}; diff --git a/crates/tools/src/skills/vfs.rs b/crates/tools/src/skills/vfs.rs index b76ec7ee0..3084a67ce 100644 --- a/crates/tools/src/skills/vfs.rs +++ b/crates/tools/src/skills/vfs.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeSet, sync::Arc}; -use engine::storage::BlobStore; +use harness::storage::BlobStore; use thiserror::Error; use vfs::{ ResolvedWorkspaceAttachment, ResolvedWorkspaceAttachmentTarget, VfsPath, VfsWorkspaceId, @@ -311,7 +311,7 @@ mod tests { use std::collections::BTreeMap; use async_trait::async_trait; - use engine::{WorkspaceAccess, WorkspaceAttachmentTarget, storage::InMemoryBlobStore}; + use harness::{WorkspaceAccess, WorkspaceAttachmentTarget, storage::InMemoryBlobStore}; use vfs::{ CompareAndSetVfsWorkspaceHead, CreateInlineSnapshotRequest, CreateVfsWorkspaceRecord, InlineFile, ResolvedWorkspaceAttachment, ResolvedWorkspaceAttachmentTarget, @@ -530,7 +530,7 @@ mod tests { resolved_attachment( path, ResolvedWorkspaceAttachmentTarget::AvailableSnapshot { - snapshot_ref: engine::BlobRef::from_bytes(b"snapshot"), + snapshot_ref: harness::BlobRef::from_bytes(b"snapshot"), }, WorkspaceAccess::Read, ) @@ -565,7 +565,7 @@ mod tests { let attachments = vec![resolved_attachment( "/skills/system", ResolvedWorkspaceAttachmentTarget::Unavailable { - declared_target: engine::WorkspaceAttachmentTarget::Workspace { + declared_target: harness::WorkspaceAttachmentTarget::Workspace { workspace_id: "skills".into(), }, reason: "deleted".into(), diff --git a/crates/tools/src/subagent_catalog_text.rs b/crates/tools/src/subagent_catalog_text.rs index 9ba33bdfd..a25aa5b47 100644 --- a/crates/tools/src/subagent_catalog_text.rs +++ b/crates/tools/src/subagent_catalog_text.rs @@ -67,7 +67,7 @@ mod tests { revision: None, }, ], - engine::SubagentLimits::default(), + harness::SubagentLimits::default(), ); let text = subagent_catalog_text(&catalog); assert!(text.contains("- reviewer (Reviewer)")); diff --git a/crates/tools/src/subagents.rs b/crates/tools/src/subagents.rs index a6b1cb456..d9c799951 100644 --- a/crates/tools/src/subagents.rs +++ b/crates/tools/src/subagents.rs @@ -7,7 +7,7 @@ use crate::catalog::{ SUBAGENT_CATALOG_CONTEXT_KEY, catalog_context_input, catalog_publication_command, }; -use engine::{ +use harness::{ BlobRef, ContextEntryInput, CoreAgentCommand, SubagentLimits, storage::{BlobStore, BlobStoreError}, }; diff --git a/crates/tools/src/toolset.rs b/crates/tools/src/toolset.rs index e178a4c4a..ddcd564a8 100644 --- a/crates/tools/src/toolset.rs +++ b/crates/tools/src/toolset.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; -use engine::{ProviderApiKind, ToolName, ToolSpec, WorkflowToolBinding}; +use harness::{ProviderApiKind, ToolName, ToolSpec, WorkflowToolBinding}; use crate::{ builtin::{BuiltinTool, BuiltinToolDomain, BuiltinToolOperation, BuiltinToolSurface}, @@ -399,7 +399,7 @@ pub fn register_workflow_tools<'a>( } pub fn register_toolset(config: &ToolsetConfig) -> ToolResult { - use engine::{ToolExecutionClass, ToolExecutionSpec, ToolParallelism}; + use harness::{ToolExecutionClass, ToolExecutionSpec, ToolParallelism}; let mut tools = BTreeMap::new(); let mut add = |tool: ToolSpec| -> ToolResult<()> { let name = tool.name.clone(); @@ -531,7 +531,7 @@ mod tests { let registry = super::register_toolset(config)?; let mut tools = BTreeMap::new(); for tool in registry.tools.values() { - let engine::ToolKind::Builtin(spec) = &tool.kind else { + let harness::ToolKind::Builtin(spec) = &tool.kind else { panic!("built-in registration"); }; for resolved in crate::definitions::resolve(&tool.name, spec, target)? { diff --git a/crates/tools/src/transfer.rs b/crates/tools/src/transfer.rs index a99c1ecdd..d8f644171 100644 --- a/crates/tools/src/transfer.rs +++ b/crates/tools/src/transfer.rs @@ -2,14 +2,14 @@ //! File payloads never enter model arguments or tool results. use crate::error::{ToolError, ToolResult}; use async_trait::async_trait; -use engine::{ - BlobRef, - storage::{BlobSource, BlobStore, BlobStoreError}, -}; use environment_protocol::{ data::{inventory::*, transfer::TransferOnExisting, transfer_session::*}, shared::{ByteChunk, EnvironmentPath}, }; +use harness::{ + BlobRef, + storage::{BlobSource, BlobStore, BlobStoreError}, +}; use std::{collections::BTreeMap, sync::Arc}; #[async_trait] @@ -265,7 +265,7 @@ pub struct CapturedSelection { pub async fn capture( remote: &dyn EnvironmentTransfer, blobs: &dyn BlobStore, - graph: Option<&dyn engine::storage::BlobGraphStore>, + graph: Option<&dyn harness::storage::BlobGraphStore>, id: &str, source: EnvironmentPath, ) -> ToolResult { @@ -551,17 +551,17 @@ pub async fn invoke_capture( async fn persist_capture_result( blobs: &dyn BlobStore, - graph: Option<&dyn engine::storage::BlobGraphStore>, + graph: Option<&dyn harness::storage::BlobGraphStore>, output: &crate::runtime::ToolInvocationOutput, ) -> ToolResult<()> { // The session retains the tool output. Its containment edge must retain the // snapshot too, especially when concurrent workspace edits prevent publication. let bytes = serde_json::to_vec(&output.output_json).map_err(blob_error)?; let output_ref = blobs.put_bytes(bytes).await.map_err(blob_error)?; - engine::storage::record_contains_edges( + harness::storage::record_contains_edges( graph, &output_ref, - engine::storage::collect_blob_refs(&output.output_json), + harness::storage::collect_blob_refs(&output.output_json), ) .await .map_err(blob_error) @@ -573,7 +573,7 @@ mod tests { #[tokio::test(flavor = "current_thread")] async fn unpublished_capture_is_retained_through_its_tool_result() { - let store = engine::storage::InMemoryBlobStore::new(); + let store = harness::storage::InMemoryBlobStore::new(); let file = store.put_bytes(b"captured bytes".to_vec()).await.unwrap(); let mut manifest = vfs::VfsSnapshotManifest::empty(); vfs::write_manifest_file_ref( @@ -598,11 +598,11 @@ mod tests { .unwrap(); let output_ref = BlobRef::from_bytes(&serde_json::to_vec(&output.output_json).unwrap()); let edges = store.edges(); - assert!(edges.contains(&engine::storage::BlobEdge::contains( + assert!(edges.contains(&harness::storage::BlobEdge::contains( output_ref, snapshot.snapshot_ref.clone(), ))); - assert!(edges.contains(&engine::storage::BlobEdge::contains( + assert!(edges.contains(&harness::storage::BlobEdge::contains( snapshot.snapshot_ref, file, ))); diff --git a/crates/tools/src/web/fetch.rs b/crates/tools/src/web/fetch.rs index 699cf8468..b5ebb88f3 100644 --- a/crates/tools/src/web/fetch.rs +++ b/crates/tools/src/web/fetch.rs @@ -2,8 +2,8 @@ use std::time::Duration; -use engine::BlobRef; use futures_util::StreamExt; +use harness::BlobRef; use reqwest::{ StatusCode, Url, header::{CONTENT_TYPE, LOCATION}, diff --git a/crates/tools/src/workflow_tool.rs b/crates/tools/src/workflow_tool.rs index 57d39938e..0fb06ce39 100644 --- a/crates/tools/src/workflow_tool.rs +++ b/crates/tools/src/workflow_tool.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; -use engine::{ +use harness::{ BlobRef, PromiseId, PromiseIdAllocator, REPLY_COMPLETION_KEY, RunId, SessionId, ToolBatchId, ToolInvocationRequest, ToolKind, TurnId, WorkflowToolBinding, WorkflowToolCompletion, WorkflowToolCompletionKeySource, WorkflowToolDefinition, WorkflowToolInvocation, @@ -23,7 +23,7 @@ pub async fn validate_workflow_tool_definition_documents( ) -> ToolResult<()> { if let ToolKind::Builtin(spec) = &definition.tool.kind { let target = - crate::runtime::ToolTarget::api_kind(engine::ProviderApiKind::OpenAiCompletions); + crate::runtime::ToolTarget::api_kind(harness::ProviderApiKind::OpenAiCompletions); let resolved = crate::definitions::resolve(&definition.tool.name, spec, &target)?; if resolved.is_empty() || resolved @@ -192,7 +192,7 @@ pub async fn invoke_workflow_tool( deadline_after_ms, .. } => { let promises = BTreeMap::from([( - engine::REPLY_COMPLETION_KEY.to_owned(), + harness::REPLY_COMPLETION_KEY.to_owned(), promise_ids.allocate(), )]); ( @@ -291,7 +291,7 @@ fn derive_completion_keys( .. } => (*max_promises, key_source), WorkflowToolCompletion::Joined { .. } => { - return Ok(vec![engine::REPLY_COMPLETION_KEY.to_owned()]); + return Ok(vec![harness::REPLY_COMPLETION_KEY.to_owned()]); } WorkflowToolCompletion::Accepted => return Ok(Vec::new()), }; @@ -304,14 +304,16 @@ fn derive_completion_keys( } fn derive_completion_keys_from_source( - tool_id: &engine::WorkflowToolId, + tool_id: &harness::WorkflowToolId, max_promises: u32, - source: &engine::WorkflowToolCompletionKeySource, + source: &harness::WorkflowToolCompletionKeySource, arguments: &Value, ) -> ToolResult> { match source { - engine::WorkflowToolCompletionKeySource::Reply => Ok(vec![REPLY_COMPLETION_KEY.to_owned()]), - engine::WorkflowToolCompletionKeySource::StringArray { pointer } => { + harness::WorkflowToolCompletionKeySource::Reply => { + Ok(vec![REPLY_COMPLETION_KEY.to_owned()]) + } + harness::WorkflowToolCompletionKeySource::StringArray { pointer } => { let Some(Value::Array(entries)) = arguments.pointer(pointer) else { return Err(ToolError::InvalidRequest { message: format!( @@ -350,7 +352,7 @@ fn derive_completion_keys_from_source( } Ok(keys) } - engine::WorkflowToolCompletionKeySource::ArrayItemField { pointer, field } => { + harness::WorkflowToolCompletionKeySource::ArrayItemField { pointer, field } => { let Some(Value::Array(entries)) = arguments.pointer(pointer) else { return Err(ToolError::InvalidRequest { message: format!( @@ -391,7 +393,7 @@ fn derive_completion_keys_from_source( } Ok(keys) } - engine::WorkflowToolCompletionKeySource::ArrayIndices { pointer, prefix } => { + harness::WorkflowToolCompletionKeySource::ArrayIndices { pointer, prefix } => { let Some(Value::Array(entries)) = arguments.pointer(pointer) else { return Err(ToolError::InvalidRequest { message: format!( @@ -433,7 +435,7 @@ async fn read_json(blobs: &dyn BlobStore, blob_ref: &BlobRef, kind: &str) -> Too mod tests { use std::sync::Arc; - use engine::{ + use harness::{ FunctionToolSpec, ToolCallId, ToolKind, ToolName, ToolParallelism, ToolSpec, WorkflowEndpointRef, WorkflowToolId, storage::{BlobStore, InMemoryBlobStore}, @@ -535,14 +537,14 @@ mod tests { assert_eq!(first.effects.len(), 1); assert_eq!( first.effects[0].kind, - engine::WORKFLOW_TOOL_EMIT_EFFECT_KIND + harness::WORKFLOW_TOOL_EMIT_EFFECT_KIND ); } async fn promise_bearing_binding( blobs: &dyn BlobStore, max_promises: u32, - key_source: engine::WorkflowToolCompletionKeySource, + key_source: harness::WorkflowToolCompletionKeySource, ) -> WorkflowToolBinding { let schema_ref = blobs .put_bytes(serde_json::to_vec(&json!({ "type": "object" })).expect("schema")) @@ -572,7 +574,7 @@ mod tests { workflow_id: "approval plugin id".to_owned(), workflow_kind: "approvals".to_owned(), }, - dispatch: engine::BoundWorkflowToolDispatch::Push, + dispatch: harness::BoundWorkflowToolDispatch::Push, }, WorkflowToolCompletion::Promises { reply_schema_ref: None, @@ -590,7 +592,7 @@ mod tests { let binding = promise_bearing_binding( blobs.as_ref(), 1, - engine::WorkflowToolCompletionKeySource::Reply, + harness::WorkflowToolCompletionKeySource::Reply, ) .await; let arguments_ref = blobs @@ -641,7 +643,7 @@ mod tests { let explicit = promise_bearing_binding( blobs.as_ref(), 1, - engine::WorkflowToolCompletionKeySource::Reply, + harness::WorkflowToolCompletionKeySource::Reply, ) .await; let binding = WorkflowToolBinding::admit( @@ -697,7 +699,7 @@ mod tests { .data .get("completion_promises") .expect("internal reply map"); - assert!(encoded_promises.contains(engine::REPLY_COMPLETION_KEY)); + assert!(encoded_promises.contains(harness::REPLY_COMPLETION_KEY)); assert!(encoded_promises.contains("promise_1")); } @@ -707,7 +709,7 @@ mod tests { let binding = promise_bearing_binding( blobs.as_ref(), 4, - engine::WorkflowToolCompletionKeySource::StringArray { + harness::WorkflowToolCompletionKeySource::StringArray { pointer: "/jobs".to_owned(), }, ) @@ -796,7 +798,7 @@ mod tests { let binding = promise_bearing_binding( blobs.as_ref(), 4, - engine::WorkflowToolCompletionKeySource::ArrayIndices { + harness::WorkflowToolCompletionKeySource::ArrayIndices { pointer: "/jobs".to_owned(), prefix: "job-".to_owned(), }, @@ -846,7 +848,7 @@ mod tests { let binding = promise_bearing_binding( blobs.as_ref(), 4, - engine::WorkflowToolCompletionKeySource::ArrayItemField { + harness::WorkflowToolCompletionKeySource::ArrayItemField { pointer: "/jobs".to_owned(), field: "job_id".to_owned(), }, @@ -937,7 +939,7 @@ mod tests { }, }, WorkflowToolTarget::Start { - start: engine::WorkflowStartRef { + start: harness::WorkflowStartRef { recipe_format: 1, revision: 1, recipe_ref: BlobRef::from_bytes(b"recipe"), @@ -948,7 +950,7 @@ mod tests { reply_schema_ref: None, deadline_after_ms: None, max_promises: 1, - key_source: engine::WorkflowToolCompletionKeySource::Reply, + key_source: harness::WorkflowToolCompletionKeySource::Reply, }, ) .expect("start binding"); diff --git a/crates/vfs/Cargo.toml b/crates/vfs/Cargo.toml index 70dd871c0..715a27a58 100644 --- a/crates/vfs/Cargo.toml +++ b/crates/vfs/Cargo.toml @@ -5,10 +5,10 @@ edition = "2024" [dependencies] async-trait = "0.1" -engine = { path = "../engine" } +harness = { path = "../harness" } serde = { version = "1", features = ["derive"] } serde_json = "1" -thiserror = "1" +thiserror = "2" [dev-dependencies] tokio = { version = "1", features = ["macros", "rt"] } diff --git a/crates/vfs/src/attachment.rs b/crates/vfs/src/attachment.rs index 6199dbb65..9066fab80 100644 --- a/crates/vfs/src/attachment.rs +++ b/crates/vfs/src/attachment.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use engine::{ +use harness::{ BlobRef, WorkspaceAccess, WorkspaceAttachment, WorkspaceAttachmentTarget, storage::BlobStore, }; @@ -126,7 +126,7 @@ mod tests { use std::sync::Mutex; use async_trait::async_trait; - use engine::storage::InMemoryBlobStore; + use harness::storage::InMemoryBlobStore; use super::*; use crate::{ diff --git a/crates/vfs/src/catalog.rs b/crates/vfs/src/catalog.rs index b97671468..533b83328 100644 --- a/crates/vfs/src/catalog.rs +++ b/crates/vfs/src/catalog.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use engine::{BlobRef, StringIdError, validate_general_string_id}; +use harness::{BlobRef, StringIdError, validate_general_string_id}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; use std::{fmt, str::FromStr}; use thiserror::Error; @@ -235,7 +235,7 @@ mod tests { use super::*; #[test] - fn vfs_workspace_id_uses_engine_string_id_rules() { + fn vfs_workspace_id_uses_harness_string_id_rules() { let id = VfsWorkspaceId::new("workspace-1"); assert_eq!(id.as_str(), "workspace-1"); diff --git a/crates/vfs/src/manifest.rs b/crates/vfs/src/manifest.rs index 7c6db6558..208660d91 100644 --- a/crates/vfs/src/manifest.rs +++ b/crates/vfs/src/manifest.rs @@ -1,4 +1,4 @@ -use engine::{BlobRef, storage::BlobStoreError}; +use harness::{BlobRef, storage::BlobStoreError}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use thiserror::Error; diff --git a/crates/vfs/src/snapshot.rs b/crates/vfs/src/snapshot.rs index 983293ad1..852e173e2 100644 --- a/crates/vfs/src/snapshot.rs +++ b/crates/vfs/src/snapshot.rs @@ -1,4 +1,4 @@ -use engine::{ +use harness::{ BlobRef, storage::{BlobGraphStore, BlobStore, record_contains_edges}, }; @@ -799,7 +799,7 @@ fn path_starts_with(path: &VfsPath, base: &VfsPath) -> bool { mod tests { use super::*; use crate::manifest::{VFS_SNAPSHOT_SCHEMA_VERSION, VfsTotals}; - use engine::{ + use harness::{ BlobRef, storage::{BlobStore, InMemoryBlobStore}, }; @@ -869,7 +869,7 @@ mod tests { .await .unwrap(); let embedded = - engine::storage::collect_blob_refs(&serde_json::to_value(&result.manifest).unwrap()); + harness::storage::collect_blob_refs(&serde_json::to_value(&result.manifest).unwrap()); let recorded = recorded_children(&blobs, &result.snapshot_ref); assert_eq!(recorded, embedded); assert_eq!(recorded.len(), 2); @@ -890,7 +890,7 @@ mod tests { .await .unwrap(); let embedded = - engine::storage::collect_blob_refs(&serde_json::to_value(&manifest).unwrap()); + harness::storage::collect_blob_refs(&serde_json::to_value(&manifest).unwrap()); assert_eq!(recorded_children(&blobs, &committed.snapshot_ref), embedded); assert_eq!(embedded.len(), 3); } diff --git a/docs/documentation/access-and-security/api-keys-and-service-access.md b/docs/documentation/access-and-security/api-keys-and-service-access.md index 4e94c7942..77462d1d7 100644 --- a/docs/documentation/access-and-security/api-keys-and-service-access.md +++ b/docs/documentation/access-and-security/api-keys-and-service-access.md @@ -53,7 +53,7 @@ authorization decisions. ## Bootstrap without Platform -Use `lightspeed-server api-key provision` on the server host after migrations +Use `lightspeed-runtime api-key provision` on the server host after migrations to generate a deployment administrator key, or supply its secret through `LIGHTSPEED_BOOTSTRAP_API_KEY`. The command prints JSON for protected capture. The key uses the ordinary hash store and remains revocable. Repeated @@ -75,12 +75,12 @@ first configure the stores and apply migrations as described in from the server host: ```bash -lightspeed-server api-key create \ +lightspeed-runtime api-key create \ --deployment --assert-actor --name "Platform" ``` -From a source checkout, replace `lightspeed-server` with -`cargo run -p temporal-server --` in these commands. +From a source checkout, replace `lightspeed-runtime` with +`cargo run -p temporal-runtime --` in these commands. Omitting `--group` grants every group allowed by the scope. This is intentional for the Platform, which manages universes and keys as well as member requests. @@ -98,7 +98,7 @@ then create a universe and add members as described in [People and roles](people-and-roles.md). If provisioning a universe directly through the server host, use -`lightspeed-server universe create --slug acorn` and retain its +`lightspeed-runtime universe create --slug acorn` and retain its printed UUID. Platform-created universes are provisioned through its deployment key. See [People and roles](people-and-roles.md) for account administration. @@ -128,7 +128,7 @@ The host CLI provides the same controls. For example, to restrict a key to profile operations in an existing universe: ```bash -lightspeed-server api-key create \ +lightspeed-runtime api-key create \ --universe-id "" --name "Profile automation" --group profiles ``` @@ -150,7 +150,7 @@ Both CLIs support rotation by the current prefix: ```bash lightspeed api-key rotate "" -lightspeed-server api-key rotate "" +lightspeed-runtime api-key rotate "" ``` The first command uses the configured connection; the second accesses the @@ -163,8 +163,8 @@ create a replacement, update and verify its consumer, then revoke the old key in the UI or by prefix: ```bash -lightspeed-server api-key list -lightspeed-server api-key revoke "" +lightspeed-runtime api-key list +lightspeed-runtime api-key revoke "" ``` Rotation and revocation reject subsequent requests using the old secret. diff --git a/docs/documentation/access-and-security/single-sign-on.md b/docs/documentation/access-and-security/single-sign-on.md index 554880e32..afc08c1c7 100644 --- a/docs/documentation/access-and-security/single-sign-on.md +++ b/docs/documentation/access-and-security/single-sign-on.md @@ -18,7 +18,7 @@ uses the same flow in both cases; those requirements belong to provider policy. This guide covers deployment setup, emergency access and acceptance checks. For a runnable development provider, use [local Keycloak](../development/local-development.md#company-sign-in-with-local-keycloak). -The [environment-variable reference](../reference/environment-variables.md#platform-server) +The [environment-variable reference](../reference/environment-variables.md#platform-backend) is the complete settings reference. ## Configure the provider and Platform @@ -88,7 +88,7 @@ scopes such as `allatclaims` or a target `RESOURCE` parameter. If entitlements are supplied only in a JWT access token, set `CLAIMS_TOKEN=access` and the expected resource `AUDIENCE`. Resource selection and audience verification are separate settings. All these names use the `LIGHTSPEED_PLATFORM_OIDC_` prefix; -see the [complete variable reference](../reference/environment-variables.md#platform-server). +see the [complete variable reference](../reference/environment-variables.md#platform-backend). UserInfo alone is insufficient, and offline access is unsupported. A company account is bound to the exact issuer and subject. Email and display diff --git a/docs/documentation/deployment/operations.md b/docs/documentation/deployment/operations.md index 272f7796f..2df16ae7e 100644 --- a/docs/documentation/deployment/operations.md +++ b/docs/documentation/deployment/operations.md @@ -60,7 +60,7 @@ docker logs --tail 100 lightspeed-platform The runtime supports `compact`, `pretty`, and `json` through `LIGHTSPEED_LOG_FORMAT`. JSON is useful when collecting logs from several roles. `RUST_LOG` controls detail; for a focused investigation, a filter such -as `warn,temporal_server=debug,temporal_workflow=info` adds runtime detail. +as `warn,temporal_runtime=debug,temporal_workflow=info` adds runtime detail. Restart the affected process to apply an environment-file change. Session logs can include `universe_id`, `session_id`, `workflow_id`, @@ -100,7 +100,7 @@ Prometheus endpoint; use their logs and the infrastructure's own monitoring. payloads as unreferenced CAS blobs and logs their references at debug level. Credentials are redacted, but requests include the conversation context. Include `llm_runtime=debug` in `RUST_LOG` to see the dump references; for example, -`warn,temporal_server=debug,temporal_workflow=info,llm_runtime=debug`. Enable +`warn,temporal_runtime=debug,temporal_workflow=info,llm_runtime=debug`. Enable this for a focused investigation, restrict access to the collected material, and disable it afterward. These dumps are subject to blob collection; they are not a permanent audit archive. @@ -127,11 +127,8 @@ agree on stores, secrets, namespace, task queues, and environment routing. Every process without `environment-gateway` needs its internal URL and token. [Configuration](configuration.md) describes that shared setup. -Workers can also separate workflow and activity polling with -`LIGHTSPEED_WORKER_TASK_TYPES=workflows` or `activities`, or the matching -`--task-types` argument. Local activities stay with workflow execution. Keep -both required types of pollers available on each subsystem's queue; a workflow -poller alone cannot execute remote activities. +Each worker role runs its workflows and activities together. Add replicas of +the role that needs more capacity; each replica polls that role's task queue. Use pending tasks, activity duration/failures, provider limits, and storage load to decide which capacity is missing. Adding session workers does not @@ -183,7 +180,7 @@ docker run --rm --network lightspeed --env-file runtime.env \ This continues the self-hosting recipe: run it from the deployment directory with `LIGHTSPEED_RELEASE_ID` set to the deployed image's revision-specific tag. -The standalone binary equivalent is `lightspeed-server cas-sweep --dry-run`. +The standalone binary equivalent is `lightspeed-runtime cas-sweep --dry-run`. The report includes `rows_scanned`, `candidates`, `rows_deleted`, `bytes_freed`, `objects_deleted`, and errors/conflicts. A pass is bounded, so its candidate diff --git a/docs/documentation/deployment/overview.md b/docs/documentation/deployment/overview.md index 21b3d6a44..976742383 100644 --- a/docs/documentation/deployment/overview.md +++ b/docs/documentation/deployment/overview.md @@ -13,10 +13,10 @@ roles when you need to scale or operate them independently. | Component | Responsibility | Needed for | | --- | --- | --- | -| `lightspeed-server` | JSON-RPC gateway, environment gateway, and Temporal workers for sessions, bots, and channels | Every hosted Lightspeed installation | +| `lightspeed-runtime` | JSON-RPC gateway, environment gateway, and Temporal workers for sessions, bots, and channels | Every hosted Lightspeed installation | | Temporal | Durable workflow execution and coordination | The hosted runtime | | Runtime PostgreSQL database | Session events, blobs, workspaces, credentials, profiles, bots, channels, and environment records | The hosted runtime | -| Platform server and web app | Sign-in, membership and role enforcement, universe management, and browser access | The full web product | +| Platform backend and web app | Sign-in, membership and role enforcement, universe management, and browser access | The full web product | | Platform PostgreSQL database | Accounts, memberships, roles, and universe display/routing records | The Platform | | S3-compatible object storage | Stores blobs larger than the 64 KiB inline limit | Required for larger payloads; small blobs remain in PostgreSQL | | Configurator MCP | Exposes Lightspeed management operations to an MCP client | Managing Lightspeed through MCP | @@ -30,7 +30,7 @@ persistence requirements, managed as part of the Temporal deployment. ```mermaid flowchart TD Browser[Browser] --> Edge[HTTPS reverse proxy] - Edge --> Platform[Platform server and web app] + Edge --> Platform[Platform backend and web app] Platform --> PlatformDB[(Platform PostgreSQL)] Platform --> Runtime[Private Lightspeed runtime] Runtime <--> Temporal[Temporal service] @@ -69,7 +69,7 @@ for shared infrastructure and isolation limits. ## Runtime roles and scaling -One `lightspeed-server` executable supplies five roles: +One `lightspeed-runtime` executable supplies five roles: | Role | Work it owns | | --- | --- | @@ -79,8 +79,9 @@ One `lightspeed-server` executable supplies five roles: | `bots` | Bot controllers, trigger work, and bot activities | | `channels` | Chat conversation workflows and core channel activities | -By default, all five run in one process. Worker roles use their own task queues, -and a role can be split further into workflow and activity workers. +By default, all five run in one process. Each worker role runs its workflows +and activities together on its own task queue. Select roles to deploy them +separately and add replicas of the worker roles that need more capacity. Cross-component work reaches other workflows through starts and signals. Run exactly one `environment-gateway` process per deployment. It owns live diff --git a/docs/documentation/deployment/self-hosting.md b/docs/documentation/deployment/self-hosting.md index 8a3783ccd..300d3f340 100644 --- a/docs/documentation/deployment/self-hosting.md +++ b/docs/documentation/deployment/self-hosting.md @@ -85,7 +85,7 @@ installation. If you need an unreleased change or your own build, use the source path below. In addition to Docker and the utilities above, it needs GNU Make, Git, and -Node.js 24 or newer. The release build container supplies the Rust compiler +Node.js 24.21.0 or newer. The release build container supplies the Rust compiler and package-build dependencies. Use a fresh release checkout. Replace `RELEASE_REF` below with the exact tag @@ -409,15 +409,15 @@ for LIGHTSPEED_COMPONENT in server cli; do done ``` -This extracts `lightspeed-server` and `lightspeed` into the current directory. +This extracts `lightspeed-runtime` and `lightspeed` into the current directory. Their `--help` output lists the commands. The release page also provides archives for the Incus provider and environment daemon; choose those from the release matching your runtime when you need them. A native server needs the same runtime configuration, PostgreSQL migrations, and Temporal service as the container. Supply its environment through your -process supervisor, run `lightspeed-server migrate`, and then start -`lightspeed-server` with the configured roles. The `runtime.env` example above +process supervisor, run `lightspeed-runtime migrate`, and then start +`lightspeed-runtime` with the configured roles. The `runtime.env` example above uses container addresses; adapt those to the native process's network. Platform remains a separate application for the web app and authentication. Use [Configuration](configuration.md) for the runtime settings and diff --git a/docs/documentation/development/changing-contracts.md b/docs/documentation/development/changing-contracts.md index 53e134df1..02e6d6063 100644 --- a/docs/documentation/development/changing-contracts.md +++ b/docs/documentation/development/changing-contracts.md @@ -15,7 +15,7 @@ before choosing an exporter or changing a version. | Boundary | Authored source | Outputs to keep aligned | | --- | --- | --- | | Public JSON-RPC API | DTOs, method metadata, and service interfaces in `crates/api/src/` | Rust-exported schema, method manifest, OpenRPC, and API reference; TypeScript client, Configurator tools, Platform method-role map, and profile-editor reference. | -| Workflow integration | Engine emission types, workflow recipes and recovery types, Channels DTOs, and `crates/temporal-workflow/src/workflow_contract.rs` | Workflow schema, manifest, reference, TypeScript types, and known-answer vectors used by client helpers. | +| Workflow integration | Harness emission types, workflow recipes and recovery types, Channels DTOs, and `crates/temporal-workflow/src/workflow_contract.rs` | Workflow schema, manifest, reference, TypeScript types, and known-answer vectors used by client helpers. | | Environment control and data | `crates/environment-protocol` | Rust serde fixtures, daemon and provider implementations, and explicit protocol versions. There is no schema exporter for this boundary today. | | Runtime database | SQL migrations and their embedded registry in `crates/store-pg` | Migration ledger, required schema revision, table ownership list, and release metadata. | | Platform database | Schema modules and Drizzle configuration in `platform/db` | SQL migrations, snapshots, journal, and the separate Platform release revision and upgrade baseline. | @@ -111,8 +111,8 @@ consumers: ```bash cargo run -p api --bin export-schema npm install -npm run generate --workspace @lightspeed-ai/agent-client -npm run generate --workspace @lightspeed/configurator-mcp +npm run generate --workspace @lightspeed-ai/sdk +npm run generate --workspace @lightspeed-ai/configurator-mcp node platform/scripts/generate-config-reference.mjs node platform/scripts/generate-method-roles.mjs ``` @@ -130,7 +130,7 @@ and schema copies under `clients/typescript/schema/`. Configurator generates uses to describe configuration fields. Generate the client before that reference so its installed schema is current. -The method-role generator updates `platform/server/src/routes/method-roles.ts`: +The method-role generator updates `platform/backend/src/routes/method-roles.ts`: minimum member roles, session-target checks, and methods unavailable to member calls. Keep this generated policy map with the API change. @@ -163,7 +163,7 @@ that boundary with: ```bash cargo run -p temporal-workflow --bin export-workflow-contract -npm run generate --workspace @lightspeed-ai/agent-client +npm run generate --workspace @lightspeed-ai/sdk ``` This writes `workflow.schema.json`, `workflow.json`, and @@ -179,7 +179,7 @@ workflow helpers are therefore tested against the generated vectors: ```bash cargo test -p temporal-workflow --test workflow_contract -npm run test --workspace @lightspeed-ai/agent-client -- test/workflow.test.ts +npm run test --workspace @lightspeed-ai/sdk -- test/workflow.test.ts ``` `WORKFLOW_CONTRACT_VERSION` versions the manifest layout. It does not @@ -197,7 +197,7 @@ explains the two histories involved, and external receiver and controller contract. Channel delivery and prepared-media DTOs are included in the workflow export -and reach connectors through `@lightspeed-ai/agent-client/workflow`. Some +and reach connectors through `@lightspeed-ai/sdk/workflow`. Some checks remain authored on both sides: `CHANNEL_DELIVERY_VERSION` exists in [`crates/channels/src/delivery.rs`](../../../crates/channels/src/delivery.rs) and the connector's @@ -268,8 +268,8 @@ Normal Rust startup verifies the ledger. Apply migrations explicitly before starting the upgraded runtime: ```bash -cargo run -p temporal-server -- migrate -cargo run -p temporal-server -- schema-version +cargo run -p temporal-runtime -- migrate +cargo run -p temporal-runtime -- schema-version ``` `schema-version` is diagnostic; it does not apply changes. The local launcher @@ -292,7 +292,7 @@ Edit the appropriate schema module under `platform/db/src/schema/`, then generate the migration: ```bash -npm run generate --workspace @lightspeed/platform-db +npm run generate --workspace @lightspeed-ai/platform-db ``` Review and commit the SQL, snapshot, and Drizzle journal together. Platform diff --git a/docs/documentation/development/contributing-and-releasing.md b/docs/documentation/development/contributing-and-releasing.md index 08281ddc9..5e59460d5 100644 --- a/docs/documentation/development/contributing-and-releasing.md +++ b/docs/documentation/development/contributing-and-releasing.md @@ -19,7 +19,7 @@ edits out of the contribution so a reviewer can follow the behavior and its evidence together. Before implementation, identify the owning layer. The -[architecture guide](../how-it-works/architecture.md) explains why the engine +[architecture guide](../how-it-works/architecture.md) explains why the harness decides deterministically, adapters perform I/O, clients depend on the public API, and compute remains separate from VFS. The short repository rules in [`AGENTS.md`](../../../AGENTS.md) preserve those boundaries. A new provider @@ -165,7 +165,7 @@ The outputs have distinct jobs: | Output | Purpose | | --- | --- | | `dist/bin/` and `dist/archives/` | Four Linux executables and their archives, plus the static demo and docs archives. | -| `dist/npm/` | The publishable `@lightspeed-ai/agent-client` package. | +| `dist/npm/` | The publishable `@lightspeed-ai/sdk` package. | | `dist/contracts/` | Generated public API contracts. | | `dist/configurator-mcp/` and `dist/runtime/` | Staged inputs for component images. | | `dist/release-manifest.json` and `dist/envd.json` | Release identity, compatibility and component references, plus daemon discovery metadata. | diff --git a/docs/documentation/development/local-development.md b/docs/documentation/development/local-development.md index b8a7d1770..fecebd795 100644 --- a/docs/documentation/development/local-development.md +++ b/docs/documentation/development/local-development.md @@ -13,7 +13,7 @@ find the code that owns a behavior, and keep local state useful while developing ## Prepare the checkout Run the commands below from the repository root. The complete local product -needs Rust and Cargo through rustup, Node.js 24 or newer with npm, and a running +needs Rust and Cargo through rustup, Node.js 24.21.0 or newer with npm, and a running Docker daemon with Docker Compose v2. The checked-in [Rust toolchain](../../../rust-toolchain.toml) selects the compiler. Rust dependencies also need a native build toolchain and `protoc`, including its @@ -113,7 +113,7 @@ Run the explicit live authentication check once Keycloak has started: ```bash LIGHTSPEED_PLATFORM_OIDC_TEST_ISSUER=http://localhost:18090/realms/lightspeed \ - npm run test:sso --workspace @lightspeed/platform-server + npm run test:sso --workspace @lightspeed-ai/platform-backend ``` This uses a disposable in-process PostgreSQL database and the real provider's @@ -186,11 +186,11 @@ those pieces have different responsibilities. | If you are changing… | Start here | | --- | --- | -| Agent decisions, scheduling, or replayed session state | `crates/engine`; keep decisions deterministic and represent effects as intents. | +| Agent decisions, scheduling, or replayed session state | `crates/harness`; keep decisions deterministic and represent effects as intents. | | Public operation names, request fields, or response shapes | `crates/api`; follow [Changing contracts](changing-contracts.md) through generated consumers. | -| Durable execution, activities, or gateway behavior | `crates/temporal-workflow` and `crates/temporal-server`; distinguish workflow decisions from activity I/O. | +| Durable execution, activities, or gateway behavior | `crates/temporal-workflow` and `crates/temporal-runtime`; distinguish workflow decisions from activity I/O. | | Provider transport, tool execution, or persistence | The relevant adapter under `crates/`, such as `llm-runtime`, `tools`, or `store-pg`. | -| Product accounts, management routes, or the web experience | `platform/server`, `platform/db`, and `platform/web`; shared product types live in `platform/shared`. | +| Product accounts, management routes, or the web experience | `platform/backend`, `platform/db`, and `platform/web`; shared product types live in `platform/shared`. | | Machine execution or provisioning | The environment protocol, daemon, client, or provider; see [Environment providers](../integrating-and-extending/environment-providers.md). | Use [Architecture](../how-it-works/architecture.md) to understand those @@ -207,7 +207,7 @@ trace tells you where the regression test belongs. ## Edit, check, and restart -Vite updates the web UI as you edit. The Platform server runs through `tsx +Vite updates the web UI as you edit. The Platform backend runs through `tsx watch` and restarts on relevant source changes. The Rust runtime and daemon run through ordinary `cargo run`; the supervisor does not watch and rebuild them. Configurator and the optional connector host also run without watch @@ -217,12 +217,12 @@ For a Rust change, run the focused test first, then stop and restart the profile to exercise the new executable: ```bash -cargo test -p engine +cargo test -p harness ./dev.sh stop ./dev.sh ``` -Replace `engine` with the crate you changed. Restarting recompiles changed +Replace `harness` with the crate you changed. Restarting recompiles changed Rust code and repeats startup migrations while retaining the infrastructure and its data. After changing startup environment variables, restart the relevant processes too. @@ -230,8 +230,8 @@ relevant processes too. For a web change, use its own checks while the development server stays open: ```bash -npm run typecheck --workspace @lightspeed/platform-web -npm run test --workspace @lightspeed/platform-web +npm run typecheck --workspace @lightspeed-ai/platform-web +npm run test --workspace @lightspeed-ai/platform-web ``` The demo backend makes many visual and interaction changes easy to inspect @@ -246,8 +246,8 @@ startup needs an explicit migration first: ```bash source scripts/dev/env.sh -cargo run -p temporal-server -- migrate -cargo run -p temporal-server +cargo run -p temporal-runtime -- migrate +cargo run -p temporal-runtime ``` Do this with the supervised runtime stopped so both processes don't claim @@ -277,9 +277,13 @@ Stopping the application and deleting its data are separate operations: | Ctrl+C in the launcher, or `./dev.sh stop` | Stops tracked host processes; leaves Docker services and durable state available. | | `./dev.sh down` | Stops host processes and tears down the Compose services; retains their volumes. | | `./dev.sh down --volumes` | Also removes the Compose volumes and the data in them. | -| `./dev.sh reset` | Recreates both local databases, migrates the runtime database, and clears the Lightspeed MinIO prefix. Stop the supervisor first. | +| `./dev.sh reset` | Recreates both local databases, migrates the runtime database, and clears the Lightspeed MinIO prefix. On success, also clears the launcher's saved development credentials and CLI handoff. Stop the supervisor first. | Use reset for disposable development data when that is the intended outcome. +After a successful reset, start `./dev.sh` to provision development keys again, +then run `target/debug/lightspeed connect dev` to refresh the CLI connection. +Manual database resets leave the launcher's saved credentials in place and +require [explicit key repair](../using-lightspeed/cli.md#connect-to-local-development). A changed migration checksum requires understanding the schema history; deleting rows does not repair a ledger mismatch. See [Changing contracts](changing-contracts.md#database-migrations) before editing diff --git a/docs/documentation/development/testing-and-evaluation.md b/docs/documentation/development/testing-and-evaluation.md index ea74a3bba..1dc9f7b9c 100644 --- a/docs/documentation/development/testing-and-evaluation.md +++ b/docs/documentation/development/testing-and-evaluation.md @@ -25,9 +25,9 @@ tests from the repository root. Rust tests can select a crate, a test target, and a name filter: ```bash -cargo test -p engine +cargo test -p harness cargo test -p temporal-workflow --lib every_checkpoint_cut_reduces_to_the_same_state -cargo test -p temporal-server --lib checkpoint_plus_tail_matches_full_replay +cargo test -p temporal-runtime --lib checkpoint_plus_tail_matches_full_replay ``` The two named tests use local fixtures and in-memory state; they don't need @@ -38,9 +38,9 @@ test output will help diagnose a failure. TypeScript workspaces have their own test and typecheck scripts. For example: ```bash -npm run test --workspace @lightspeed/platform-web -- src/lib/subscriptions.test.ts -npm run test --workspace @lightspeed-ai/agent-client -npm run typecheck --workspace @lightspeed/connectors +npm run test --workspace @lightspeed-ai/platform-web -- src/lib/subscriptions.test.ts +npm run test --workspace @lightspeed-ai/sdk +npm run typecheck --workspace @lightspeed-ai/connectors ``` Read the nearest `package.json` before choosing a script. A package may use @@ -62,7 +62,7 @@ message wording. If a prerequisite is missing, fail with a useful explanation; external and credentialed tests should be explicitly `#[ignore]`, rather than silently returning success when an environment variable is absent. -For deterministic engine changes, include replay coverage. A useful pattern +For deterministic harness changes, include replay coverage. A useful pattern is to apply commands, retain the committed events, reconstruct state from those events, and compare it with the original result. When checkpoints are involved, compare a full reduction with checkpoint-plus-tail recovery. The @@ -70,11 +70,11 @@ existing [rehydration test](../../../crates/temporal-workflow/src/rehydrate.rs) checks every cut in a small opened/closed fixture. That demonstrates the technique; a new behavior needs a history that actually exercises it. -The engine's -[native-output replay test](../../../crates/engine/src/core/drive.rs) also +The harness's +[native-output replay test](../../../crates/harness/src/core/drive.rs) also checks that recorded provider-neutral facts reconstruct the result without reading provider blobs. The -[checkpoint tests](../../../crates/temporal-server/src/checkpoint.rs) cover +[checkpoint tests](../../../crates/temporal-runtime/src/checkpoint.rs) cover equivalent recovery and falling back to the authoritative log when a checkpoint is malformed. These correspond to the durability model explained in [Agent loop and durability](../how-it-works/agent-loop-and-durability.md). @@ -156,7 +156,7 @@ a fake model provider: ```bash ./dev.sh infra source scripts/dev/env.sh -cargo test -p temporal-server --test sessions_live \ +cargo test -p temporal-runtime --test sessions_live \ temporal_live_session_start_then_run_start_completes_fake_runs \ -- --ignored --test-threads=1 --nocapture ``` @@ -173,7 +173,7 @@ provider's tool presentation without a model key. On Linux or macOS, run: ```bash source scripts/dev/env.sh -cargo test -p temporal-server --test vfs_transfer_live -- --ignored --test-threads=1 +cargo test -p temporal-runtime --test vfs_transfer_live -- --ignored --test-threads=1 cargo test -p store-pg --test store_pg_live \ pg_live_streamed_blobs_verify_ranges_reuse_and_reject_corruption \ -- --ignored --test-threads=1 diff --git a/docs/documentation/getting-started/quickstart.md b/docs/documentation/getting-started/quickstart.md index a0cb4d5e2..23152b66e 100644 --- a/docs/documentation/getting-started/quickstart.md +++ b/docs/documentation/getting-started/quickstart.md @@ -31,7 +31,7 @@ you provide those services and an HTTPS reverse proxy. You can also [download the standalone binaries](../deployment/self-hosting.md#download-standalone-binaries) directly from the release assets. The server archive contains -`lightspeed-server`; the CLI archive contains `lightspeed`. The server still +`lightspeed-runtime`; the CLI archive contains `lightspeed`. The server still needs PostgreSQL and Temporal, and the web app runs in the separate Platform application. Downloading the server alone does not start the complete product. @@ -49,7 +49,7 @@ You need: - A Lightspeed source checkout, with a terminal open at its root. - Rust and Cargo through rustup. The repository's `rust-toolchain.toml` selects the required compiler version. -- Node.js 24 or newer, including npm. +- Node.js 24.21.0 or newer, including npm. - Docker running, with Docker Compose v2. - A native build toolchain and the Protocol Buffers compiler (`protoc`), including its standard `.proto` include files, for the Rust dependencies. diff --git a/docs/documentation/how-it-works/agent-loop-and-durability.md b/docs/documentation/how-it-works/agent-loop-and-durability.md index 39ca76ba6..a94901716 100644 --- a/docs/documentation/how-it-works/agent-loop-and-durability.md +++ b/docs/documentation/how-it-works/agent-loop-and-durability.md @@ -28,11 +28,11 @@ that should result. It may instead reject the command or recognize that an equivalent request was already admitted. Planning examines the resulting state and determines which internal transition or external operation should follow. -Those are deterministic operations. Time is passed into the engine explicitly; -the hosted workflow supplies its workflow clock. The engine does not read the +Those are deterministic operations. Time is passed into the harness explicitly; +the hosted workflow supplies its workflow clock. The harness does not read the wall clock, open a database connection, or ask a provider what happened last time. -The [drive machine](../../../crates/engine/src/core/drive.rs) first emits an +The [drive machine](../../../crates/harness/src/core/drive.rs) first emits an append action with an expected session head. The host commits that append and returns the committed entries. Only then does the reducer apply them. It checks their sequence and advances the state to the committed position. @@ -115,7 +115,7 @@ records the history needed for its own responsibility: | Temporal workflow history | Workflow starts, delivered signals, activity results, timers, and orchestration progress. | The execution of the workflow code coordinating that work. | Temporal replay lets workflow code encounter the recorded result of an activity -without executing that completed activity again. Session replay lets the engine +without executing that completed activity again. Session replay lets the harness reconstruct its state from the committed domain events without asking the model to reproduce its old answer. @@ -147,7 +147,7 @@ the workflow. It does not send the entire event history through the activity result. The same distinction lets a transcript reader load a bounded event range without reconstructing the full execution state first. -The [checkpoint loader](../../../crates/temporal-server/src/checkpoint.rs) +The [checkpoint loader](../../../crates/temporal-runtime/src/checkpoint.rs) validates checkpoints and checks that the required history is complete. ## Continue with a new Temporal execution diff --git a/docs/documentation/how-it-works/architecture.md b/docs/documentation/how-it-works/architecture.md index 5c7a6cbe7..e10d69b2d 100644 --- a/docs/documentation/how-it-works/architecture.md +++ b/docs/documentation/how-it-works/architecture.md @@ -44,7 +44,8 @@ wake-up where the provider supports it; an offline registered machine must reconnect. Closing or deleting the session leaves the environment available for other work. -The core represents a session as events reduced into state. Admission checks +The `harness` crate is the deterministic agent core. It represents a session +as events reduced into state. Admission checks whether a command is valid against that state. Planning decides which fact or effect comes next. The effect might be a model request, a tool invocation, or context compaction. The core emits an intent describing the work; an adapter @@ -56,7 +57,7 @@ result reconstructs the state from which the next decision was made. This also m possible to test the agent loop with controlled effect results, independently of a provider or workflow service. -The [core drive machine](../../../crates/engine/src/core/drive.rs) expresses +The [core drive machine](../../../crates/harness/src/core/drive.rs) expresses this separation in code: it asks the host to append events or execute effects, then resumes from the committed entries or results. @@ -136,7 +137,7 @@ A bot adds continuing behavior around the session loop. It receives events, applies routing and admission policy, and creates or drives sessions for work. A channel conversation handles a chat's pairing, inbound messages, and outbound delivery. Neither responsibility has to become another branch inside -the deterministic session engine. +the deterministic session harness. Controllers instead communicate through workflow starts and signals. Workflow-backed tools let a session ask another workflow to do work and receive @@ -190,7 +191,7 @@ and operate those resources. ## Share infrastructure through runtime roles -The hosted runtime remains one executable, `lightspeed-server`, with selectable +The hosted runtime remains one executable, `lightspeed-runtime`, with selectable roles. Combining roles in one process is convenient for a first installation; separating them lets the deployment give different work different capacity. @@ -225,8 +226,8 @@ The important source boundaries follow the same model: | Responsibility | Starting point | | --- | --- | -| Deterministic state and decisions | [Engine](../../../crates/engine/README.md) | -| Durable orchestration and effect execution | [Workflow code](../../../crates/temporal-workflow/src/lib.rs) and [runtime composition](../../../crates/temporal-server/src/main.rs) | +| Deterministic state and decisions | [Harness](../../../crates/harness/README.md) | +| Durable orchestration and effect execution | [Workflow code](../../../crates/temporal-workflow/src/lib.rs) and [runtime composition](../../../crates/temporal-runtime/src/main.rs) | | Provider-native requests and results | [LLM runtime](../../../crates/llm-runtime/src/lib.rs) and [provider clients](../../../crates/llm-clients/README.md) | | Persistent records and payloads | [PostgreSQL store](../../../crates/store-pg/src/lib.rs) and [VFS](../../../crates/vfs/src/lib.rs) | | Client contracts and display projections | [API crate](../../../crates/api/src/lib.rs) and [API projections](../../../crates/api-projection/src/lib.rs) | diff --git a/docs/documentation/how-it-works/context-and-storage.md b/docs/documentation/how-it-works/context-and-storage.md index 0e5fe1e68..f4bf8393a 100644 --- a/docs/documentation/how-it-works/context-and-storage.md +++ b/docs/documentation/how-it-works/context-and-storage.md @@ -40,7 +40,7 @@ message would require inventing a common representation for all of that data, then reconstructing the provider's representation later. Lightspeed keeps the native payload and extracts the smaller facts needed by -the core. The engine needs to know that generation completed, which tool calls +the core. The harness needs to know that generation completed, which tool calls were admitted, and what context entries resulted. The provider adapter owns the decoding and request construction. @@ -63,7 +63,7 @@ API kinds. A session's API kind is fixed; start a new session to change it. Durable model selection contains the provider ID, API kind, and model name. The endpoint, authentication, and transport headers are resolved outside the -engine immediately before provider I/O. This allows credentials to change +harness immediately before provider I/O. This allows credentials to change without storing their secret values in the session's deterministic state. See [Models and credentials](../using-lightspeed/models-and-credentials.md) for the resolution rules. diff --git a/docs/documentation/how-it-works/tools-and-controller-workflows.md b/docs/documentation/how-it-works/tools-and-controller-workflows.md index aa16debda..8d8112f80 100644 --- a/docs/documentation/how-it-works/tools-and-controller-workflows.md +++ b/docs/documentation/how-it-works/tools-and-controller-workflows.md @@ -157,7 +157,7 @@ The session records one terminal outcome, so a late success cannot revive an already cancelled promise. This protocol keeps feature-specific transports out of the stable session -worker. Adding a workflow tool does not require teaching the engine a new +worker. Adding a workflow tool does not require teaching the harness a new kind of external system. The [generated workflow contract](../../../crates/temporal-workflow/contract/workflow-contract.md) defines the actual envelopes and signals. @@ -244,7 +244,7 @@ environment inheritance require the relevant attachments; an `inherit` environment attachment is resolved against the parent's active machine captured at admission and stored on the child as a concrete id. Root-scoped limits constrain depth, total descendants, concurrent open descendants, and deadlines. -These policies live around normal session execution; the engine does not +These policies live around normal session execution; the harness does not need a delegation-specific transport. An independent bot contacted through federation is a different relationship. diff --git a/docs/documentation/integrating-and-extending/api-and-typescript.md b/docs/documentation/integrating-and-extending/api-and-typescript.md index 77b30f120..313b178ec 100644 --- a/docs/documentation/integrating-and-extending/api-and-typescript.md +++ b/docs/documentation/integrating-and-extending/api-and-typescript.md @@ -32,12 +32,12 @@ Create the `release-editor` profile and `release-notes` workspace from to prepare the Acorn 1.2 notes from an application. Use Node.js 24 or newer and a client version corresponding to your deployed -Lightspeed release. Tagged releases publish `@lightspeed-ai/agent-client`; +Lightspeed release. Tagged releases publish `@lightspeed-ai/sdk`; pin the release's package version in your application. Inside this repository, the package is also available as a workspace dependency. ```bash -npm install --save-exact "@lightspeed-ai/agent-client@" +npm install --save-exact "@lightspeed-ai/sdk@" ``` Replace `` with the actual package version before running the @@ -52,7 +52,7 @@ Save this as `release-notes.mts`. The session and submission IDs allow the same script to find the same work after a network failure: ```ts -import { LightspeedClient } from "@lightspeed-ai/agent-client"; +import { LightspeedClient } from "@lightspeed-ai/sdk"; function required(name: string): string { const value = process.env[name]; diff --git a/docs/documentation/integrating-and-extending/channel-connectors.md b/docs/documentation/integrating-and-extending/channel-connectors.md index ec54c9f0a..f565f95bc 100644 --- a/docs/documentation/integrating-and-extending/channel-connectors.md +++ b/docs/documentation/integrating-and-extending/channel-connectors.md @@ -62,7 +62,7 @@ provide starting points. Reuse the shared account runner and admission code instead of creating a separate worker supervision or routing system. If the Platform should offer a first-class connection form, extend its -[account setup route](../../../platform/server/src/routes/channel-accounts.ts) +[account setup route](../../../platform/backend/src/routes/channel-accounts.ts) and [Channels page](../../../platform/web/src/pages/ChannelsPage.tsx) as well. That flow should validate the provider account identity and store credentials through the credential API. A new core wire field or operation requires contract @@ -136,7 +136,7 @@ Import their names from `CHANNEL_CONNECTOR_ACTIVITIES` and derive the account queue with the shared helper, rather than copying the hashing algorithm: ```ts -import { connectorTaskQueue } from "@lightspeed-ai/agent-client/workflow"; +import { connectorTaskQueue } from "@lightspeed-ai/sdk/workflow"; const queue = connectorTaskQueue( "00000000-0000-0000-0000-000000000001", @@ -219,7 +219,7 @@ cancellation, reconnects, and account revision changes. The existing suite runs without real chat credentials: ```bash -npm run test --workspace @lightspeed/connectors +npm run test --workspace @lightspeed-ai/connectors ``` Then enable one controlled account. Verify discovery and readiness, pairing, diff --git a/docs/documentation/integrating-and-extending/configurator-mcp.md b/docs/documentation/integrating-and-extending/configurator-mcp.md index 4d30f7234..d9f95dfb0 100644 --- a/docs/documentation/integrating-and-extending/configurator-mcp.md +++ b/docs/documentation/integrating-and-extending/configurator-mcp.md @@ -33,12 +33,12 @@ See [API keys and service access](../access-and-security/api-keys-and-service-ac ## Run the service Use a Configurator artifact from the same release as the runtime. For source -development, build it from the repository root with Node.js 24 or newer: +development, build it from the repository root with Node.js 24.21.0 or newer: ```bash npm install -npm run build --workspace @lightspeed-ai/agent-client -npm run build --workspace @lightspeed/configurator-mcp +npm run build --workspace @lightspeed-ai/sdk +npm run build --workspace @lightspeed-ai/configurator-mcp ``` For a local Configurator connected to your existing API-key gateway, set diff --git a/docs/documentation/integrating-and-extending/custom-tools-and-model-providers.md b/docs/documentation/integrating-and-extending/custom-tools-and-model-providers.md index 8fd89c515..45c9bb499 100644 --- a/docs/documentation/integrating-and-extending/custom-tools-and-model-providers.md +++ b/docs/documentation/integrating-and-extending/custom-tools-and-model-providers.md @@ -71,9 +71,9 @@ These code locations explain how the existing paths fit together: | [Toolset](../../../crates/tools/src/toolset.rs) | Construct the selected tool surface and provider-specific presentation. | | [Tool runtime interfaces](../../../crates/tools/src/runtime/mod.rs) | Typed invocation/output helpers and runtime contracts. | | [Inline dispatch](../../../crates/tools/src/runtime/inline.rs) | Execute supported compiled operations with the correct context. | -| [Session tool preparation](../../../crates/temporal-server/src/gateway/service/session_preparation.rs) | Materialize the desired tools from session capabilities and current registry records. | +| [Session tool preparation](../../../crates/temporal-runtime/src/gateway/service/session_preparation.rs) | Materialize the desired tools from session capabilities and current registry records. | | [Workflow preparation](../../../crates/temporal-workflow/src/workflows/session/preparation.rs) | Order preparation and publish tool changes at safe session boundaries. | -| [Hosted tool execution](../../../crates/temporal-server/src/worker/session_tools.rs) | Assemble runtime adapters for session tool batches. | +| [Hosted tool execution](../../../crates/temporal-runtime/src/worker/session_tools.rs) | Assemble runtime adapters for session tool batches. | The provider-facing function name is not necessarily the logical ID. Existing tool presentations differ by model API, and returned model calls must resolve @@ -101,11 +101,11 @@ necessary. Cancellation can stop waiting or interrupt an activity without undoing effects already completed. Return enough structured information for the caller to reconcile an ambiguous outcome. -The deterministic engine records facts and emits intents; it performs no +The deterministic harness records facts and emits intents; it performs no network, shell, filesystem, database, or workflow I/O. If a new capability requires reducer-visible state or branching, keep that state provider-neutral and add replay coverage. A tool that can use existing execution semantics -does not need a new engine-specific transport. +does not need a new harness-specific transport. ## Configure another compatible model service @@ -180,8 +180,8 @@ Use the existing implementation layers as the source map: | [Runtime executor](../../../crates/llm-runtime/src/executor.rs) | Generation and compaction adapter implementations and retry classification. | | [Provider credentials](../../../crates/llm-runtime/src/provider_keys.rs) and [endpoint admission](../../../crates/auth/src/providers.rs) | Admit supported endpoint/API kinds and resolve the configured connection and credentials at the effectful boundary. | | [Tool catalog materialization](../../../crates/llm-runtime/src/tool_catalog.rs) | Render admitted tool definitions and map model calls back to their identities. | -| [API route conversion](../../../crates/temporal-server/src/gateway/service/api_config.rs) | Validate the public model route against supported kinds. | -| [Hosted adapter assembly](../../../crates/temporal-server/src/worker/activities/state.rs) | Register generation and compaction implementations used by workers. | +| [API route conversion](../../../crates/temporal-runtime/src/gateway/service/api_config.rs) | Validate the public model route against supported kinds. | +| [Hosted adapter assembly](../../../crates/temporal-runtime/src/worker/activities/state.rs) | Register generation and compaction implementations used by workers. | The compiled `ProviderApiKind` and public/generated consumers must agree with the new kind. Custom endpoint admission currently permits only Responses and @@ -193,9 +193,9 @@ a new kind solely for another service endpoint. Preserve native assistant, tool, and reasoning payloads in CAS. The runtime loads context and tool definitions, builds the provider request, sends it, -stores native output, and returns only the facts the deterministic engine +stores native output, and returns only the facts the deterministic harness needs to branch. Endpoints, keys, and transport headers belong outside durable -session state and provider-neutral engine facts. +session state and provider-neutral harness facts. Define behavior for tool results, multimodal input, usage, prompt caching, compaction, and failures. If a feature is unsupported, make that explicit @@ -217,7 +217,7 @@ For a tool, test rejected arguments, missing grants, bounded output, retry policy, and provider name mapping. For a model integration, use captured request/response fixtures to check native payload preservation, tool-call admission, endpoint selection, credential isolation, and failure classification. -Add engine replay coverage if deterministic behavior changes. +Add harness replay coverage if deterministic behavior changes. The existing tool-definition, provider-key, catalog-parity, materialization, and endpoint-override tests provide focused starting points. Use local fixtures diff --git a/docs/documentation/integrating-and-extending/environment-providers.md b/docs/documentation/integrating-and-extending/environment-providers.md index 792b24d13..9f7a6fa72 100644 --- a/docs/documentation/integrating-and-extending/environment-providers.md +++ b/docs/documentation/integrating-and-extending/environment-providers.md @@ -6,7 +6,7 @@ closing an environment into the infrastructure it controls, then makes that environment's filesystem and process service reachable. The provider implements the environment protocol. It does not need Lightspeed's -database, API implementation, engine, or Temporal runtime. The included Incus +database, API implementation, harness, or Temporal runtime. The included Incus provider demonstrates that separation. If you only need to connect an existing machine, [outbound daemon registration](../environments/bring-your-own-compute.md) already provides that path without implementing a provisioning controller. diff --git a/docs/documentation/integrating-and-extending/workflow-tools.md b/docs/documentation/integrating-and-extending/workflow-tools.md index f41dfaf87..246759302 100644 --- a/docs/documentation/integrating-and-extending/workflow-tools.md +++ b/docs/documentation/integrating-and-extending/workflow-tools.md @@ -60,8 +60,8 @@ The following function runs in an application process or Temporal activity, using a `LightspeedClient` with `session` and `blobs/put` access in that universe: ```ts -import { LightspeedClient } from "@lightspeed-ai/agent-client"; -import { recipeFingerprint } from "@lightspeed-ai/agent-client/workflow"; +import { LightspeedClient } from "@lightspeed-ai/sdk"; +import { recipeFingerprint } from "@lightspeed-ai/sdk/workflow"; export async function createReviewSession(client: LightspeedClient) { async function putJsonBytes(json: string): Promise { @@ -151,7 +151,7 @@ import { WORKFLOW_TOOL_RECOVERY_QUERY, replyPromiseId, sourceResolutionEnvelope, type PromiseResolution, type WorkflowToolRecoveryResult, type WorkflowToolStartArgs, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; const activities = proxyActivities<{ reviewRelease(input: { diff --git a/docs/documentation/reference/environment-variables.md b/docs/documentation/reference/environment-variables.md index 80488b0b0..f03a7baad 100644 --- a/docs/documentation/reference/environment-variables.md +++ b/docs/documentation/reference/environment-variables.md @@ -30,9 +30,9 @@ and then applies the defaults from `scripts/dev/env.sh`. ## Core runtime -These variables configure `lightspeed-server`, including its JSON-RPC gateway, +These variables configure `lightspeed-runtime`, including its JSON-RPC gateway, Temporal worker, PostgreSQL stores, CAS, provider clients, and preprocessing. -They do not configure the TypeScript Platform server. +They do not configure the TypeScript Platform backend. ### Gateway, Temporal, and storage @@ -42,7 +42,6 @@ They do not configure the TypeScript Platform server. | `LIGHTSPEED_PG_UNIVERSE_ID` | **Required in `single` auth mode** | UUID of the sole universe in a single-tenant deployment. Not used to auto-create universes in multi-tenant modes. | | `LIGHTSPEED_ROLES` | `gateway,environment-gateway,sessions,bots,channels` | Roles this process runs, a comma-separated subset of `gateway` (JSON-RPC, OAuth callbacks, webhook hooks), `environment-gateway` (worker environment routes, the public daemon registration routes, the lifecycle reconciler, and the power reaper), `sessions` (session workflows plus the promise-repair reaper, the session-retention reaper, both every five minutes, and the hourly CAS blob sweeper), `bots`, `channels` (also `--roles`). Each worker role polls its own task queue with that subsystem's workflows, activities, and background loops. Run exactly one `environment-gateway` process per deployment. | | `LIGHTSPEED_ENVIRONMENT_PUBLIC_URL` | Unset | Base URL outbound daemons are told to dial for data connections when it differs from `LIGHTSPEED_PUBLIC_BASE_URL`, for example a dedicated hostname in front of the environment gateway. | -| `LIGHTSPEED_WORKER_TASK_TYPES` | `all` | What the worker roles poll: `all`, `workflows`, or `activities` (also `--task-types`). | | `LIGHTSPEED_TASK_QUEUE` | `lightspeed-sessions` | Sessions task queue shared by the gateway and the `sessions` role. Deployments sharing a Temporal namespace must use distinct queues. | | `LIGHTSPEED_TASK_QUEUE_BOTS` | `lightspeed-bots` | Task queue of the `bots` role (bot controllers, trigger fires, bot activities). | | `LIGHTSPEED_TASK_QUEUE_CHANNELS` | `lightspeed-channels` | Task queue of the `channels` role (conversation workflows and core channel activities). Connector activities run on the per-account `lightspeed-connector-*` queues served by the connector host. | @@ -57,14 +56,14 @@ They do not configure the TypeScript Platform server. | `LIGHTSPEED_AUTH_MODE` | **Required** | `single` (no credential check, ordinary methods use one configured universe; local development only) or `authenticated` (bearer keys with a scope and allowed method groups). There is no default: the process refuses to start without it. Configurator uses the same mode. | | `LIGHTSPEED_SECRETS_MASTER_KEY` | Unset | Base64-encoded 32-byte AES key for encrypted secret values and grant tokens. Required before encrypted secret material can be persisted or resolved. Keep stable across restarts. | | `LIGHTSPEED_BLOB_CACHE_BYTES` | `268435456` | Per-process CAS blob-cache budget. `0` disables the cache. | -| `LIGHTSPEED_CAS_SWEEP_GRACE_MS` | `604800000` (seven days) | Minimum time since a blob's last put or API admission before an unheld blob is eligible for collection; reads do not refresh it. `0` disables background collection. One elected `sessions` process examines up to 100,000 old catalog rows per universe per hourly pass in pages of at most 1,024 rows, resuming its cursor next time. Passes have a soft 10-minute budget between pages; database statements have a five-second timeout and a one-second lock timeout. `lightspeed-server cas-sweep [--dry-run]` runs one bounded pass; deletion yields to an active background leader. Profiles and uncommitted workflow handoffs do not retain blobs; a handoff stalled beyond grace may require resubmission. | +| `LIGHTSPEED_CAS_SWEEP_GRACE_MS` | `604800000` (seven days) | Minimum time since a blob's last put or API admission before an unheld blob is eligible for collection; reads do not refresh it. `0` disables background collection. One elected `sessions` process examines up to 100,000 old catalog rows per universe per hourly pass in pages of at most 1,024 rows, resuming its cursor next time. Passes have a soft 10-minute budget between pages; database statements have a five-second timeout and a one-second lock timeout. `lightspeed-runtime cas-sweep [--dry-run]` runs one bounded pass; deletion yields to an active background leader. Profiles and uncommitted workflow handoffs do not retain blobs; a handoff stalled beyond grace may require resubmission. | | `LIGHTSPEED_LLM_DEBUG_DUMPS` | `false` | Store every generation's raw provider request (credentials redacted) and raw response as unreferenced CAS blobs and log their refs at debug level. Nothing references the dumps, so they are collected after one grace period. Each request carries the whole context; leave this off outside debugging. | | `LIGHTSPEED_ALLOW_UNLEDGERED_SCHEMA` | `false` | Allows runtime startup against externally managed Lightspeed tables without a migration ledger. It does not relax `migrate` or schema diagnostics. | | `LIGHTSPEED_LOG_FORMAT` | `compact` | Log renderer: `compact`, `pretty`, or `json`. | -| `RUST_LOG` | Built-in service filter | Standard tracing filter override, for example `temporal_server=debug`. | +| `RUST_LOG` | Built-in service filter | Standard tracing filter override, for example `temporal_runtime=debug`. | `LIGHTSPEED_UNIVERSE_AUTO_CREATE` is retired. Setting it is an error; create -universes explicitly through the deployment API or `lightspeed-server universe +universes explicitly through the deployment API or `lightspeed-runtime universe create`. In authenticated mode, the gateway checks the key's status, scope, and allowed @@ -80,7 +79,7 @@ See [API keys and service access](../access-and-security/api-keys-and-service-ac | Variable | Default | Purpose | | --- | --- | --- | -| `LIGHTSPEED_BOOTSTRAP_API_KEY` | Unset (generate a key) | Secret input to `lightspeed-server api-key provision`, also accepted on first development setup. Must be `lsk_` plus 32 random bytes in unpadded base64url. Stores the hash in the normal key store; does not bypass revocation or enable provisioning on ordinary production startup. | +| `LIGHTSPEED_BOOTSTRAP_API_KEY` | Unset (generate a key) | Secret input to `lightspeed-runtime api-key provision`, also accepted on first development setup. Must be `lsk_` plus 32 random bytes in unpadded base64url. Stores the hash in the normal key store; does not bypass revocation or enable provisioning on ordinary production startup. | The development opt-out is the launcher option `--no-api-key-bootstrap`, not an environment variable. It skips API-key provisioning without disabling @@ -163,7 +162,7 @@ are given together. | Variable | Requirement/default | Purpose | | --- | --- | --- | -| `LIGHTSPEED_API_URL` | Required unless a saved connection or `--api-url` supplies it | Lightspeed JSON-RPC endpoint, normally ending in `/rpc`. Also used as the Platform server's fallback gateway URL. | +| `LIGHTSPEED_API_URL` | Required unless a saved connection or `--api-url` supplies it | Lightspeed JSON-RPC endpoint, normally ending in `/rpc`. Also used as the Platform backend's fallback gateway URL. | | `LIGHTSPEED_API_KEY` | Unset | Bearer key sent to an authenticated gateway. | | `LIGHTSPEED_UNIVERSE` | Unset | Universe UUID or core slug overriding saved selection. Only deployment keys may switch universes; slugs require universe-list permission. | | `LIGHTSPEED_CONFIG_DIR` | `$XDG_CONFIG_HOME/lightspeed`, otherwise `$HOME/.config/lightspeed` | Saved CLI connection metadata and protected owned credential files. | @@ -246,16 +245,16 @@ machines without Incus. | --- | --- | --- | | `LIGHTSPEED_INCUS_PROVIDER_CONFIG` | **Required unless `--config` is supplied** | Path to the provider's JSON configuration. Incus credentials, templates, network policy, and ingress settings live in that file rather than separate environment variables. | -## Platform server +## Platform backend These variables configure the TypeScript management API/web server under -`platform/server`. Its database and authentication are separate concerns from +`platform/backend`. Its database and authentication are separate concerns from the Rust runtime database and gateway authentication. For provider setup and acceptance checks, follow [Company sign-in (SSO)](../access-and-security/single-sign-on.md). | Variable | Requirement/default | Purpose | | --- | --- | --- | -| `LIGHTSPEED_PLATFORM_API_KEY` | Unset | The Platform's deployment key: every method group and allowed to assert actors. Create with `lightspeed-server api-key create --deployment --assert-actor`. Interactive calls name the universe and assert the signed-in user as the actor after Platform permission checks. Full development provisions a key when omitted. | +| `LIGHTSPEED_PLATFORM_API_KEY` | Unset | The Platform's deployment key: every method group and allowed to assert actors. Create with `lightspeed-runtime api-key create --deployment --assert-actor`. Interactive calls name the universe and assert the signed-in user as the actor after Platform permission checks. Full development provisions a key when omitted. | | `LIGHTSPEED_PLATFORM_DATABASE_URL` | **Required** | Platform PostgreSQL connection URL. | | `LIGHTSPEED_PLATFORM_AUTH_SECRET` | **Required** | Better Auth signing/encryption secret. Use a strong, stable deployment secret. | | `LIGHTSPEED_PLATFORM_BASE_URL` | `http://localhost:3000` | Public Platform origin used by authentication and trusted-origin checks. | @@ -355,7 +354,7 @@ Never reuse their credentials in a deployed environment. | --- | --- | --- | | `LIGHTSPEED_AUTH_MODE` | `authenticated` | Both `full` and `runtime` provision a CLI key and connection handoff by default; full also provisions a separate Platform key when needed. Explicit `single` remains supported for runtime-only local use. | | `LIGHTSPEED_CHANNELS_CONNECTORS` | Empty | Providers the `full` development profile hands to one connector host process (`LIGHTSPEED_CONNECTOR_PROVIDERS`). Values: `telegram`, `whatsapp`, or both. WhatsApp additionally needs `LIGHTSPEED_CONNECTOR_WHATSAPP_MEDIA_LOCATOR_KEY`; the session directory defaults to `.lightspeed-dev/whatsapp-auth`. | -| `PORT` | `3000` | Platform server port. | +| `PORT` | `3000` | Platform backend port. | | `LIGHTSPEED_CONFIGURATOR_MCP_BIND_PORT` | `18081` | Configurator port used by the supervisor. | | `LIGHTSPEED_CONFIGURATOR_MCP_INTERNAL_TRUSTED_HEADER_URL` | Unset | Retired; a nonempty value fails startup. Use a scoped service key. | | `LIGHTSPEED_PLATFORM_CONFIGURATOR_MCP_INTERNAL_TRUSTED_HEADER` | `false` | Retired; `true` fails startup. | @@ -451,7 +450,7 @@ them on services. | `LIGHTSPEED_GIT_SHA` | Full source revision embedded in binaries and image labels. | | `LIGHTSPEED_RELEASE_BUILD_IMAGE` | Digest-pinned build environment recorded in the manifest. | | `SOURCE_DATE_EPOCH` | Reproducible SBOM/archive timestamp. | -| `LIGHTSPEED_BINARY_URL_SERVER` | Published server archive URL recorded in the manifest. | +| `LIGHTSPEED_BINARY_URL_RUNTIME` | Published runtime archive URL recorded in the manifest. | | `LIGHTSPEED_BINARY_URL_PROVIDER_INCUS` | Published Incus-provider archive URL. | | `LIGHTSPEED_BINARY_URL_ENVD` | Published environment-daemon archive URL. | | `LIGHTSPEED_BINARY_URL_CLI` | Published CLI archive URL. | diff --git a/docs/documentation/using-lightspeed/cli.md b/docs/documentation/using-lightspeed/cli.md index 0a6b14ade..3c206b8d6 100644 --- a/docs/documentation/using-lightspeed/cli.md +++ b/docs/documentation/using-lightspeed/cli.md @@ -33,7 +33,10 @@ selection on subsequent imports. Starting the launcher alone does not change your selected CLI connection. Ordinary restarts reuse the keys. Adding Platform does not rotate the CLI key. -Revoked keys, missing saved secrets or keys absent after a database reset +After a successful `./dev.sh reset`, the launcher clears its saved credentials +and handoff. The next startup provisions development keys again; run +`lightspeed connect dev` afterward to refresh the CLI connection. +Revoked keys, missing saved secrets or keys absent after a manual database reset require explicit repair; startup does not silently issue another administrator key. To replace a key, provision a new one with the server command described below, put its secret into the corresponding protected `.lightspeed/cli/cli.key` @@ -61,12 +64,12 @@ On the server host, configure the runtime stores and secrets as described in [Self-hosting](../deployment/self-hosting.md), then run: ```bash -lightspeed-server migrate -lightspeed-server api-key provision --name "Initial operator" +lightspeed-runtime migrate +lightspeed-runtime api-key provision --name "Initial operator" ``` -From source, replace `lightspeed-server` with -`cargo run -p temporal-server --`. The provision command prints JSON containing +From source, replace `lightspeed-runtime` with +`cargo run -p temporal-runtime --`. The provision command prints JSON containing the secret; capture it securely. It creates a deployment key with every method group and no actor assertion. No universe is needed yet. diff --git a/docs/releasing.md b/docs/releasing.md index 7d026896c..c43efc4cd 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -1,7 +1,7 @@ # Build and release Lightspeed owns and publishes a coherent release containing the hosted runtime, -the Incus provider, envd, the CLI, Configurator MCP, the platform server/web +the Incus provider, envd, the CLI, Configurator MCP, the platform backend/web image, the connector-host image (published as `platform-workers`), the generated TypeScript client, the static in-browser demo and documentation site, API contracts, checksums, an SPDX SBOM, and a release manifest. A consumer should @@ -15,13 +15,13 @@ retains the detailed packaging and publication procedures. ## Database migrations -PostgreSQL migrations are embedded in `lightspeed-server`. Apply them before +PostgreSQL migrations are embedded in `lightspeed-runtime`. Apply them before starting any gateway or worker process: ```bash -lightspeed-server migrate -lightspeed-server schema-version -lightspeed-server +lightspeed-runtime migrate +lightspeed-runtime schema-version +lightspeed-runtime ``` The migrate command uses `LIGHTSPEED_POSTGRES_URL` (falling back to the test @@ -48,7 +48,7 @@ LIGHTSPEED_ALLOW_UNLEDGERED_SCHEMA=true This permits gateway and worker startup only when Lightspeed detects its tables without ledger entries. It emits a warning and makes the operator responsible for schema compatibility. It does not fabricate migration records, bypass a -stale or corrupted ledger, or make `lightspeed-server migrate` accept an +stale or corrupted ledger, or make `lightspeed-runtime migrate` accept an unledgered database. Never edit a migration after an official release. Add the next contiguous SQL @@ -57,7 +57,7 @@ file under `crates/store-pg/migrations/`, register it in `release/metadata.env`. The TypeScript platform owns a separate Drizzle migration history under -`platform/db/migrations/` and applies it when the platform server starts. CI +`platform/db/migrations/` and applies it when the platform backend starts. CI tests both an empty installation and an upgrade from the supported baseline in `LIGHTSPEED_PLATFORM_UPGRADE_FROM` against real PostgreSQL. The manifest records that baseline and `LIGHTSPEED_PLATFORM_SCHEMA_REVISION`. Run the same @@ -115,13 +115,14 @@ invoke Cargo or rebuild the web UI. The `platform-workers` image is the connector host (`platform/connectors`) with every provider dependency; it keeps its name so image references and manifest keys stay stable while Bots and Channels core run inside the `runtime` image. Image smoke tests compare -the runtime's `lightspeed-server` executable byte-for-byte, start the platform +the runtime's `lightspeed-runtime` executable byte-for-byte, start the platform image against PostgreSQL, check its health and SPA, and load the connector host's configuration and task-queue derivation from the staged runtime. The Rust container is named `runtime` because it is the hosted product core, -not merely an HTTP server. Its executable and standalone archive remain named -`lightspeed-server` and `server-bundle` during the compatibility window. +not merely an HTTP server. Its executable is `lightspeed-runtime`; standalone +archives use +`lightspeed-runtime--.tar.gz` and publish as `runtime-bundle`. The runtime tarballs are intermediate image inputs and are removed before the release bundle is finalized; the published images carry their own digest, diff --git a/docs/roadmap/archive/maintenance-report.md b/docs/roadmap/archive/maintenance-report.md index 742e84dbb..874556b13 100644 --- a/docs/roadmap/archive/maintenance-report.md +++ b/docs/roadmap/archive/maintenance-report.md @@ -22,7 +22,7 @@ All 521 per-file category sums reconcile exactly with the baseline `cloc` code c | Crate | Non-test | Tests and support | |---|---:|---:| -| temporal-server | 33,812 | 29,897 | +| temporal-runtime | 33,812 | 29,897 | | engine | 16,344 | 10,545 | | tools | 15,390 | 8,270 | | cli | 12,233 | 3,872 | @@ -32,7 +32,7 @@ All 521 per-file category sums reconcile exactly with the baseline `cloc` code c | api | 7,096 | 3,913 | | llm-runtime | 5,700 | 16,034 | -The most misleading whole-file count is [engine/core/drive.rs](/Users/lukas/dev/lightspeed/crates/engine/src/core/drive.rs): 8,081 code lines become **1,968 non-test code lines** after excluding its test module. By contrast, [gateway/service/mod.rs](/Users/lukas/dev/lightspeed/crates/temporal-server/src/gateway/service/mod.rs) remains **4,365 non-test code lines**. +The most misleading whole-file count is [engine/core/drive.rs](/Users/lukas/dev/lightspeed/crates/harness/src/core/drive.rs): 8,081 code lines become **1,968 non-test code lines** after excluding its test module. By contrast, [gateway/service/mod.rs](/Users/lukas/dev/lightspeed/crates/temporal-runtime/src/gateway/service/mod.rs) remains **4,365 non-test code lines**. Complete crate totals, the top 20 complex functions, the largest production files, and file churn are in [inventory.md](inventory.md). Raw results are in `summary.json` and `production-functions.json`. @@ -50,13 +50,13 @@ These are descriptive thresholds, not pass/fail rules. PLOC is rust-code-analysi |---|---:|---:|---:|---:| | [scan](/Users/lukas/dev/lightspeed/crates/environment-daemon/src/filesystem/scan.rs:17) | 289 | 191 | 115 | 2 | | [Operation::execute](/Users/lukas/dev/lightspeed/crates/environment-daemon/src/filesystem/transfer/session.rs:720) | 349 | 134 | 114 | 1 | -| [admit_command](/Users/lukas/dev/lightspeed/crates/engine/src/core/admit.rs:15) | 820 | 130 | 164 | 15 | -| [tool_call_completed_proposals](/Users/lukas/dev/lightspeed/crates/engine/src/core/drive.rs:1638) | 327 | 107 | 56 | 35 | +| [admit_command](/Users/lukas/dev/lightspeed/crates/harness/src/core/admit.rs:15) | 820 | 130 | 164 | 15 | +| [tool_call_completed_proposals](/Users/lukas/dev/lightspeed/crates/harness/src/core/drive.rs:1638) | 327 | 107 | 56 | 35 | | [Scanner::advance](/Users/lukas/dev/lightspeed/crates/environment-daemon/src/filesystem/transfer/session.rs:102) | 137 | 69 | 41 | 1 | | [TransferManager::execute](/Users/lukas/dev/lightspeed/crates/environment-daemon/src/filesystem/transfer/session.rs:409) | 253 | 67 | 82 | 1 | -| [visible_mcp_result](/Users/lukas/dev/lightspeed/crates/temporal-server/src/worker/mcp.rs:962) | 170 | 48 | 31 | 6 | -| [invoke_batch](/Users/lukas/dev/lightspeed/crates/temporal-server/src/worker/session_tools.rs:1435) | 233 | 38 | 59 | 54 | -| [start_session_internal](/Users/lukas/dev/lightspeed/crates/temporal-server/src/gateway/service/mod.rs:1071) | 208 | 32 | 81 | 68 | +| [visible_mcp_result](/Users/lukas/dev/lightspeed/crates/temporal-runtime/src/worker/mcp.rs:962) | 170 | 48 | 31 | 6 | +| [invoke_batch](/Users/lukas/dev/lightspeed/crates/temporal-runtime/src/worker/session_tools.rs:1435) | 233 | 38 | 59 | 54 | +| [start_session_internal](/Users/lukas/dev/lightspeed/crates/temporal-runtime/src/gateway/service/mod.rs:1071) | 208 | 32 | 81 | 68 | | [project_event_kind](/Users/lukas/dev/lightspeed/crates/api-projection/src/lib.rs:658) | 450 | 29 | 91 | 41 | **Maintenance priority:** gateway lifecycle handling, session tool dispatch, and core tool-result/admission handling combine substantive responsibilities with frequent containing-file changes. Filesystem scanning/transfer has the highest static complexity even though its current files have little recorded churn. @@ -82,8 +82,8 @@ Masked files preserve original line positions using whitespace. Consequently, js 1. **Live-test environment/client setup — high confidence.** There are 13 `dotenv_var` definitions under `llm-runtime/tests`, including an existing shared implementation in [support/mod.rs](/Users/lukas/dev/lightspeed/crates/llm-runtime/tests/support/mod.rs:66). Exact matches between Responses caching/prompts/skills setup extend to approximately 169–170 physical lines. The copies have already diverged: [the skills copy](/Users/lukas/dev/lightspeed/crates/llm-runtime/tests/openai_responses_skills_live.rs:75) uses `split_once('=')?`, so a nonempty noncomment line without `=` ends lookup before subsequent keys. The shared helper explicitly skips that line. Some copies also strip quotes differently. This is observed control-flow divergence; no real `.env` was read to investigate it. 2. **Daemon secret-redaction helpers — high confidence.** [jobs.rs](/Users/lukas/dev/lightspeed/crates/environment-daemon/src/jobs.rs:946) and [process.rs](/Users/lukas/dev/lightspeed/crates/environment-daemon/src/process.rs:1122) repeat `redactions_for_secret_env`, `redact_bytes`, and `find_subslice`. The detector found a 32-line/246-token match. Both callers live in one crate and use the same algorithm. Sharing a private helper would make future fixes consistent without unifying process/job lifecycle logic. 3. **Native MCP inventory policy — high confidence.** [Responses](/Users/lukas/dev/lightspeed/crates/llm-runtime/src/openai_responses.rs:588), [Completions](/Users/lukas/dev/lightspeed/crates/llm-runtime/src/openai_completions.rs:777), and [Anthropic](/Users/lukas/dev/lightspeed/crates/llm-runtime/src/anthropic_messages.rs:914) repeat inventory retrieval, ordering, exposed-name filtering, omitted-name logging, and per-request cap accounting. These are shared policy operations. The construction of native provider request types afterward should remain separate. -4. **Worker universe resolution — high confidence, small extraction.** [bots.rs](/Users/lukas/dev/lightspeed/crates/temporal-server/src/worker/bots.rs:45) and [channels.rs](/Users/lukas/dev/lightspeed/crates/temporal-server/src/worker/channels.rs:41) repeat the fixed-versus-runtime universe resolver, wrong-universe rejection, and retryability mapping. The normalized detector reports a much larger 156-line cluster that also includes activity wrappers. Share the resolver, not the role-specific activity transport. -5. **ID macros — real duplication, lower priority.** The two `string_id!` definitions in [engine/session/ids.rs](/Users/lukas/dev/lightspeed/crates/engine/src/session/ids.rs:6) and [engine/core/components/ids.rs](/Users/lukas/dev/lightspeed/crates/engine/src/core/components/ids.rs:9) account for the largest exact production match, about 80 lines. A private engine-local macro could serve both. Similar macros across auth/MCP/VFS/domain crates are less compelling: adding a cross-domain dependency solely to eliminate wrappers may make the architecture worse. +4. **Worker universe resolution — high confidence, small extraction.** [bots.rs](/Users/lukas/dev/lightspeed/crates/temporal-runtime/src/worker/bots.rs:45) and [channels.rs](/Users/lukas/dev/lightspeed/crates/temporal-runtime/src/worker/channels.rs:41) repeat the fixed-versus-runtime universe resolver, wrong-universe rejection, and retryability mapping. The normalized detector reports a much larger 156-line cluster that also includes activity wrappers. Share the resolver, not the role-specific activity transport. +5. **ID macros — real duplication, lower priority.** The two `string_id!` definitions in [engine/session/ids.rs](/Users/lukas/dev/lightspeed/crates/harness/src/session/ids.rs:6) and [engine/core/components/ids.rs](/Users/lukas/dev/lightspeed/crates/harness/src/core/components/ids.rs:9) account for the largest exact production match, about 80 lines. A private engine-local macro could serve both. Similar macros across auth/MCP/VFS/domain crates are less compelling: adding a cross-domain dependency solely to eliminate wrappers may make the architecture worse. 6. **Prompt/skill VFS root resolution — mixed.** [prompts/vfs.rs](/Users/lukas/dev/lightspeed/crates/tools/src/prompts/vfs.rs:223) and [skills/vfs.rs](/Users/lukas/dev/lightspeed/crates/tools/src/skills/vfs.rs:222) share path-derived IDs, duplicate-ID validation, attachment selection, and snapshot/workspace inspection. However, prompt revision tracking and skill trust/scope differ. Consider sharing attachment/path primitives; do not create one generic prompt/skill subsystem just because the source looks similar. 7. **Rust API service/client forwarding — mostly mechanical.** Large identifier-normalized matches in [api/service.rs](/Users/lukas/dev/lightspeed/crates/api/src/service.rs:84) and [cli/api_client.rs](/Users/lukas/dev/lightspeed/crates/cli/src/api_client.rs:145) include regular typed method wrappers, sometimes overlapping within one file. These could be candidates for existing-manifest-driven generation in a separate design review, but are not evidence of duplicated business policy. 8. **OpenAI client configuration — plausible small shared helper.** Audio, Completions, and Responses clients repeat environment overrides and organization/project header construction. Endpoint defaults and request types differ. A private OpenAI header/config utility is more appropriate than merging clients. diff --git a/docs/roadmap/archive/p100-workflow-tool-ports.md b/docs/roadmap/archive/p100-workflow-tool-ports.md index cf94cf8e1..067ea925e 100644 --- a/docs/roadmap/archive/p100-workflow-tool-ports.md +++ b/docs/roadmap/archive/p100-workflow-tool-ports.md @@ -10,7 +10,7 @@ messaging migration was demoted from committed second topology to a candidate with an explicit burden of proof. - Slice 1 transport refactor implemented 2026-07-24: the neutral, - universe-scoped emission envelope and deterministic ids live in `engine`; + universe-scoped emission envelope and deterministic ids live in `harness`; run-terminal and environment-job source resolutions now use the single `deliver_emission` signal; both promise-specific signal/DTO families and the promise-named outbound queue are deleted. @@ -57,7 +57,7 @@ Confirmed: both promise-specific signal families are grep-clean with no transitional dual funnel; envelope/ids are deterministic, domain-separated, and - substrate-neutral (`engine` gained no transport or Temporal dependency); + substrate-neutral (`harness` gained no transport or Temporal dependency); binding and creation fingerprints now use an explicit canonical v1 field encoding rather than serde output; pull reads replay the ordinary reducer, so durable binding, canonical id, joins, arguments ref, and successful @@ -81,7 +81,7 @@ `WorkflowToolEvent`, `WorkflowToolConfigEvent`/`WorkflowToolState`, `ToolDispatchMode::WorkflowTool`, `EmissionBody::ToolInvocation`, invocation ids `wti:sha256:`). Code rename executed 2026-07-26 across - engine/tools/temporal-workflow/temporal-server/api/api-projection/cli: + engine/tools/temporal-workflow/temporal-runtime/api/api-projection/cli: modules renamed to `workflow_tool.rs`, binding fingerprints now `wtb:sha256:`, fingerprint hash domains renamed to `lightspeed.workflow-tool.{binding,invocation}.v1` with golden digests @@ -942,7 +942,7 @@ The first draft specified Temporal signals normatively. The contract is narrower than Temporal and must be stated that way, because the engine and this substrate are meant to outlive any single durable-workflow engine: -- **Engine (substrate-neutral, `crates/engine`):** the emission envelope and +- **Engine (substrate-neutral, `crates/harness`):** the emission envelope and deterministic ids, tool/binding DTOs, the `WorkflowToolEvent` and `WorkflowToolConfigEvent` families, deterministic reducer state, and the invariants above. The engine holds no transport state and performs no @@ -954,7 +954,7 @@ this substrate are meant to outlive any single durable-workflow engine: I/O adapters. Receiver-side envelope helpers remain plain library code with no workflow-substrate dependency; the ordered-stream high-water helper is deferred with that mode. -- **Temporal adapter (`temporal-workflow` / `temporal-server`):** the fixed +- **Temporal adapter (`temporal-workflow` / `temporal-runtime`):** the fixed `deliver_emission` signal, endpoint resolution/ensure-start policy, replay-rebuilt flush queues, and continue-as-new gating. Signals target the stable workflow id, never a run id. A shared Temporal helper or pump may @@ -1209,7 +1209,7 @@ workflow ids. Expected changes: ```text -crates/engine/ +crates/harness/ EmissionEnvelope / EmissionProducer / EmissionBody and deterministic ids workflow-tool ids, endpoint/binding DTOs WorkflowToolConfigEvent + WorkflowToolEvent and deterministic reducer state @@ -1227,7 +1227,7 @@ crates/temporal-workflow/ shared delivery-spine pump (generalized from promise notifications) receiver workflow integration -crates/temporal-server/ +crates/temporal-runtime/ trusted workflow-plugin managed-session creation path effective config/toolset materialization delivery retry/failure projection @@ -1236,7 +1236,7 @@ crates/api/ and api-projection/ read-only tool and emission views if exposed through session reads ``` -P100 does not add domain handlers to `engine`. A receiver workflow imports +P100 does not add domain handlers to `harness`. A receiver workflow imports the envelope type and owns its typed payload DTO. ## Implementation Plan @@ -1251,7 +1251,7 @@ change so no transitional dual-funnel state ever ships. - [x] Add the neutral, universe-scoped `EmissionEnvelope`, `EmissionProducer`, existing `EmissionBody` variants, and deterministic - `EmissionId` derivation in `engine`. + `EmissionId` derivation in `harness`. - [x] Replace the `resolve_promise` signal with the fixed generic `deliver_emission` signal carrying `RunTerminal` bodies; delete the promise-specific DTO/signal names. diff --git a/docs/roadmap/archive/p100b-workflow-backed-tools.md b/docs/roadmap/archive/p100b-workflow-backed-tools.md index bfd89e6a2..8e46d0d23 100644 --- a/docs/roadmap/archive/p100b-workflow-backed-tools.md +++ b/docs/roadmap/archive/p100b-workflow-backed-tools.md @@ -358,7 +358,7 @@ durable semantics are normative: definition fields; - every field is immutable for the managed session's lifetime. -`WorkflowStartRef` is substrate-neutral in `engine`. A Temporal adapter +`WorkflowStartRef` is substrate-neutral in `harness`. A Temporal adapter validates and resolves a versioned recipe containing the workflow type and task queue. `recipe_format` identifies the generic recipe codec, never a feature, service, or workflow plugin. P100b v1 has one Temporal recipe @@ -930,7 +930,7 @@ P100b does not add: Expected changes: ```text -crates/engine/ +crates/harness/ keyed completion and start ids, binding contracts, deterministic per-key promise-id derivation unified PromiseSource::Workflow @@ -947,7 +947,7 @@ crates/temporal-workflow/ per-key cancellation and reply emission helpers unified workflow Promise source handling -crates/temporal-server/ +crates/temporal-runtime/ trusted start-recipe admission and resolution bounded reply-schema validation activities generic start failure/retry integration @@ -1008,7 +1008,7 @@ types, task queues, signals, activities, and clients stay outside it. ### B4. Start-on-call workflow tools - [x] Admit versioned substrate-neutral start references and resolve Temporal - recipes outside `engine`. + recipes outside `harness`. - [x] Derive one deterministic execution id per invocation and binding. - [x] Atomically append `StartRequested + Promise::Created × N` with ordinary tool completion. @@ -1026,7 +1026,7 @@ types, task queues, signals, activities, and clients stay outside it. ### B5. Generic plugin proofs Implemented 2026-07-26 as the live suite -`crates/temporal-server/tests/workflow_tool_plugins_live.rs`: minimal +`crates/temporal-runtime/tests/workflow_tool_plugins_live.rs`: minimal generic plugin workflows (`TestBoundPluginWorkflow`, `TestStartPluginWorkflow`, `TestSilentStartPluginWorkflow`) registered on a **second worker with its own task queue**; the session worker uses the @@ -1097,9 +1097,9 @@ Live Temporal tests must source `scripts/dev/env.sh` and run serially: ```bash source scripts/dev/env.sh -cargo test -p temporal-server --test workflow_tool_plugins_live -- --ignored --test-threads=1 -cargo test -p temporal-server --test sessions_live --test runs_live --test subagents_live --test profiles_live --test tenancy_live --test mcp_live -- --ignored --test-threads=1 -cargo test -p temporal-server --test environment_provider_live -- --ignored --test-threads=1 +cargo test -p temporal-runtime --test workflow_tool_plugins_live -- --ignored --test-threads=1 +cargo test -p temporal-runtime --test sessions_live --test runs_live --test subagents_live --test profiles_live --test tenancy_live --test mcp_live -- --ignored --test-threads=1 +cargo test -p temporal-runtime --test environment_provider_live -- --ignored --test-threads=1 ``` ### B7. Lifecycle-controller self-receiver diff --git a/docs/roadmap/archive/p101-durable-work-workflow.md b/docs/roadmap/archive/p101-durable-work-workflow.md index cd52a79da..e525be503 100644 --- a/docs/roadmap/archive/p101-durable-work-workflow.md +++ b/docs/roadmap/archive/p101-durable-work-workflow.md @@ -919,7 +919,7 @@ crates/temporal-workflow/ generic RunTerminalNotification work-cycle activity DTOs -crates/temporal-server/ +crates/temporal-runtime/ workflow registration Work gateway service shared session-run request runtime beneath Fleet and Work diff --git a/docs/roadmap/archive/p109-runtime-state-handoff.md b/docs/roadmap/archive/p109-runtime-state-handoff.md index 7860482e8..f2bec2b71 100644 --- a/docs/roadmap/archive/p109-runtime-state-handoff.md +++ b/docs/roadmap/archive/p109-runtime-state-handoff.md @@ -587,6 +587,6 @@ P109 does not: reads across the covered hot paths, including activity retry tests. - [x] Existing bootstrap, continue-as-new, reaper/recovery, gateway projection, and explicit history-read behavior remains intact. -- [x] Engine, temporal-workflow, temporal-server, tools, and Fleet suites pass; +- [x] Engine, temporal-workflow, temporal-runtime, tools, and Fleet suites pass; relevant opt-in Temporal live paths pass serially against the local Temporal/Postgres/host-bridge stack. diff --git a/docs/roadmap/archive/p110-universe-owned-mcp-auth.md b/docs/roadmap/archive/p110-universe-owned-mcp-auth.md index 6a7674321..86167cea9 100644 --- a/docs/roadmap/archive/p110-universe-owned-mcp-auth.md +++ b/docs/roadmap/archive/p110-universe-owned-mcp-auth.md @@ -131,7 +131,7 @@ whole-document MCP server record and changes through `mcp/servers/put` with ## Session Config And Profiles -Remove `authGrantId` from `McpServerLink` in both `engine` and `api`. The final +Remove `authGrantId` from `McpServerLink` in both `harness` and `api`. The final session declaration is: ```text @@ -394,7 +394,7 @@ stale clients fail clearly. Delete or rewrite: -- `McpServerLink.auth_grant_id` in `engine` and `api`; +- `McpServerLink.auth_grant_id` in `harness` and `api`; - config validation for non-empty link grant ids; - API projection and config conversion of the link field; - gateway loading of grants from session MCP links; diff --git a/docs/roadmap/archive/p111-promise-result-materialization.md b/docs/roadmap/archive/p111-promise-result-materialization.md index c40a88f3e..20f02a9b9 100644 --- a/docs/roadmap/archive/p111-promise-result-materialization.md +++ b/docs/roadmap/archive/p111-promise-result-materialization.md @@ -401,7 +401,7 @@ P111 does not: - recursively materialize manifest child blobs; - inject returned media into model context automatically; - change raw host/control-plane job DTOs; or -- introduce job-specific logic into `engine` or the generic `await` +- introduce job-specific logic into `harness` or the generic `await` materializer. ## Implementation Plan diff --git a/docs/roadmap/archive/p113-explicit-vfs-and-environment-tool-domains.md b/docs/roadmap/archive/p113-explicit-vfs-and-environment-tool-domains.md index e7333361d..8654f46b3 100644 --- a/docs/roadmap/archive/p113-explicit-vfs-and-environment-tool-domains.md +++ b/docs/roadmap/archive/p113-explicit-vfs-and-environment-tool-domains.md @@ -54,7 +54,7 @@ Offline verification completed on 2026-08-02: ```bash cargo fmt --all -- --check cargo check --workspace -cargo test -p engine -p tools -p llm-runtime -p temporal-workflow -p temporal-server -p api --no-fail-fast +cargo test -p harness -p tools -p llm-runtime -p temporal-workflow -p temporal-runtime -p api --no-fail-fast cargo test -p eval cargo run -p api --bin export-schema cd clients/typescript && npm run typecheck && npm run test && npm run build @@ -67,8 +67,8 @@ local Temporal/PostgreSQL/host-bridge stack: ```bash source scripts/dev/env.sh -cargo test -p temporal-server --test environment_provider_live -- --ignored --test-threads=1 --nocapture -cargo test -p temporal-server --test sessions_live temporal_live_session_start_then_run_start_completes_fake_runs -- --ignored --test-threads=1 --nocapture +cargo test -p temporal-runtime --test environment_provider_live -- --ignored --test-threads=1 --nocapture +cargo test -p temporal-runtime --test sessions_live temporal_live_session_start_then_run_start_completes_fake_runs -- --ignored --test-threads=1 --nocapture ``` The environment-provider suite includes a focused P113 case that writes and @@ -773,11 +773,11 @@ current. Run at least: ```bash -cargo test -p engine +cargo test -p harness cargo test -p tools cargo test -p llm-runtime cargo test -p temporal-workflow -cargo test -p temporal-server +cargo test -p temporal-runtime cargo test -p api ``` diff --git a/docs/roadmap/archive/p114-per-call-tool-activities-and-host-search.md b/docs/roadmap/archive/p114-per-call-tool-activities-and-host-search.md index ea53c816c..ef5545f76 100644 --- a/docs/roadmap/archive/p114-per-call-tool-activities-and-host-search.md +++ b/docs/roadmap/archive/p114-per-call-tool-activities-and-host-search.md @@ -11,7 +11,7 @@ workflow-boundary conversion of activity failures into terminal failed call results; and the deployment-owned `run_process` timeout ceiling (`ToolLimits::max_process_timeout_ms`, asserted equal to - `PROCESS_TIMEOUT_CEILING` by a temporal-server test). Await batches and + `PROCESS_TIMEOUT_CEILING` by a temporal-runtime test). Await batches and workflow-tool batches still execute as one bounded batch-unit activity, as designed. One deliberate reshape: the environment-selection batch rule now fails only the participating calls, not unrelated siblings. diff --git a/docs/roadmap/archive/p116-llm-provider-transient-retry.md b/docs/roadmap/archive/p116-llm-provider-transient-retry.md index ad0f78ce0..0b5d1af64 100644 --- a/docs/roadmap/archive/p116-llm-provider-transient-retry.md +++ b/docs/roadmap/archive/p116-llm-provider-transient-retry.md @@ -374,5 +374,5 @@ overloading a semantic turn event. - Automatic provider/model failover. - Unlimited retry or waiting indefinitely for a provider recovery. - A generic failure-category taxonomy or separate `RetryDisposition` in - `engine`. + `harness`. - Durable per-attempt session events or exact client-visible retry progress. diff --git a/docs/roadmap/archive/p118-environment-domain-and-lifecycle.md b/docs/roadmap/archive/p118-environment-domain-and-lifecycle.md index 819ab74da..f6370dd82 100644 --- a/docs/roadmap/archive/p118-environment-domain-and-lifecycle.md +++ b/docs/roadmap/archive/p118-environment-domain-and-lifecycle.md @@ -154,7 +154,7 @@ environment records. ## Lifecycle reconciliation Lightspeed Postgres is authoritative for lifecycle intent and the current -incarnation. One reconciliation loop in `temporal-server` scans pending and +incarnation. One reconciliation loop in `temporal-runtime` scans pending and closing rows, calls the provider controller with stable IDs, and records the provider target ID plus the logical lifecycle status. diff --git a/docs/roadmap/archive/p123-build-and-release.md b/docs/roadmap/archive/p123-build-and-release.md index 51cfee64b..cd9fca4d2 100644 --- a/docs/roadmap/archive/p123-build-and-release.md +++ b/docs/roadmap/archive/p123-build-and-release.md @@ -14,7 +14,7 @@ Implemented here: - deterministic standalone archives, checksums, release manifest schema, SPDX SBOM, and artifact smoke tests; - runtime and Configurator images that consume prebuilt `dist/` output; -- publishable `@lightspeed-ai/agent-client` release metadata; +- publishable `@lightspeed-ai/sdk` release metadata; - separate coherent workflows: successful `main` CI automatically builds and publishes only SHA snapshot references, while SemVer tags independently test and build their exact commit before publishing version aliases, npm, and a diff --git a/docs/roadmap/archive/p124-first-party-platform-monorepo.md b/docs/roadmap/archive/p124-first-party-platform-monorepo.md index b39fa573f..727020f9c 100644 --- a/docs/roadmap/archive/p124-first-party-platform-monorepo.md +++ b/docs/roadmap/archive/p124-first-party-platform-monorepo.md @@ -16,10 +16,10 @@ Implemented repository slice 2026-08-15: MCP to `platform/configurator-mcp`; - moved committed generated API artifacts to their owner at `crates/api/contract`; -- imported the platform server, web UI, operator CLI, shared inputs, database, +- imported the platform backend, web UI, operator CLI, shared inputs, database, Channels, and mechanically preserved Foundry package under `platform/`; - established the private root npm workspace, in-tree client dependencies, - `@lightspeed/*` package names, and Node 24 baseline; + `@lightspeed-ai/*` package names, and Node 24 baseline; - updated generators, CI, release staging, SBOM inputs, documentation, and development commands for the new paths; - extended the P123 manifest and release workflows with digest-pinned Rust @@ -95,7 +95,7 @@ public Lightspeed repository private deployment repository runtime and API release-manifest pin generated clients deployment topology -platform server and web UI encrypted secrets +platform backend and web UI encrypted secrets channel workers DNS/TLS and ingress policy database schema and migrations product-specific runtime config images and release manifest deploy/rollback scripts @@ -127,7 +127,7 @@ cross-repository coordination that P124 is intended to remove. The workspace moves as a unit because the current server and database still reference Foundry. P124 does not redesign, extract, promote, or add release -work for Foundry while its product future is undecided. The platform server/UI, +work for Foundry while its product future is undecided. The platform backend/UI, Channels roles, Telegram connector, and WhatsApp connector remain independently buildable and deployable components. @@ -140,7 +140,7 @@ The current repository split does not correspond to an independent domain: - web types and configuration references derive from the Lightspeed contract; - Channels creates Lightspeed sessions and uses Lightspeed workflow tools directly; -- the platform server and Channels share one application database schema and +- the platform backend and Channels share one application database schema and migration history; and - server routes import contracts from the worker packages. @@ -164,7 +164,7 @@ identifiable as the public client and place the cohesive product plane under ```text clients/ - typescript/ generated @lightspeed-ai/agent-client + typescript/ generated @lightspeed-ai/sdk platform/ server/ management API and static web host @@ -192,12 +192,12 @@ required to enforce that boundary. The existing `interop/` directory is removed because it mixes a public client, a deployable service, and generated Rust API output. -The generated `@lightspeed-ai/agent-client` remains the sole stable TypeScript +The generated `@lightspeed-ai/sdk` remains the sole stable TypeScript contract boundary. In-tree consumers use the workspace source directly during development and CI. Tagged releases may continue publishing the client to npm for external consumers through P123. -Rename imported internal packages to the `@lightspeed/*` scope. Keep the +Rename imported internal packages to the `@lightspeed-ai/*` scope. Keep the workspace root and application-only packages marked `"private": true` unless a package is intentionally supported as a public npm artifact. Open source does not imply npm publication. @@ -209,7 +209,7 @@ were removed. Leave Foundry's internal shape untouched until the feature is retained or removed; do not introduce another platform-local copy of Rust wire vocabulary. -The imported code remains outside the deterministic `engine` crate. Platform +The imported code remains outside the deterministic `harness` crate. Platform HTTP, authentication, database access, connectors, and Temporal workers are side-effecting product-plane components and must continue to communicate through the public `api` and generic workflow-tool protocols. @@ -285,7 +285,7 @@ The Baileys-backed WhatsApp connector remains an explicit, default-off role with its unofficial status and operational risk documented. It shares the Platform workers image to keep the release topology small; enabling it is still a deployment choice, and it can be removed later without changing the -platform server image. +platform backend image. ## Coherent public release @@ -294,10 +294,10 @@ artifact built from the same source revision and generated contract. The public repository owns builds and publishes immutable artifacts. At minimum, the release manifest identifies as applicable: -- Rust runtime image plus provider, envd, server-bundle, and CLI artifacts; +- Rust runtime image plus provider, envd, runtime-bundle, and CLI artifacts; - Configurator MCP image; -- `@lightspeed-ai/agent-client` package and contract revision; -- platform server/web image; and +- `@lightspeed-ai/sdk` package and contract revision; +- platform backend/web image; and - one Platform workers image startable with granular Channels/Bots roles, `channels`, `bots`, `telegram`, `whatsapp`, or `all`. diff --git a/docs/roadmap/archive/p125-profile-provisioned-environments.md b/docs/roadmap/archive/p125-profile-provisioned-environments.md index fadced344..efece74eb 100644 --- a/docs/roadmap/archive/p125-profile-provisioned-environments.md +++ b/docs/roadmap/archive/p125-profile-provisioned-environments.md @@ -48,7 +48,7 @@ activeEnvironmentId? EnvironmentId # must already exist and be reachable ``` `crates/api/src/profiles.rs`, `crates/profiles/src/lib.rs`, and the applier in -`crates/temporal-server/src/gateway/service/profiles.rs` implement exactly +`crates/temporal-runtime/src/gateway/service/profiles.rs` implement exactly that: at `session/start` (after the workflow is started) or `profiles/apply`, the applier calls the same path as `session/environments/activate`, which requires `features.environments`, an allowed provider, and a live end-to-end @@ -277,7 +277,7 @@ lifecycle reconciler with session commands, and races with the first run). Environment filesystem tools (`read_file`, `write_file`, `edit_file`, `apply_patch`, search, glob, …) currently fail against every environment while `exec_command` and `environment_read` work. Cause: -`RuntimeEnvironment::from_resource` in `crates/temporal-server/src/environment.rs` +`RuntimeEnvironment::from_resource` in `crates/temporal-runtime/src/environment.rs` still contains the pre-P119 safety gate ```rust @@ -333,7 +333,7 @@ deployment, no provider or VM change): `crates/profiles`: validate the new document shape (non-empty ids, metadata rules shared with `environments/create`). -## Runtime changes (`crates/temporal-server`) +## Runtime changes (`crates/temporal-runtime`) - Profile applier: `apply_profile_environment` handles `existing` (as today) and `provision` (resolve the enabled binding for `providerId` → derive @@ -398,7 +398,7 @@ rules shared with `environments/create`). `RuntimeEnvironment::from_resource` (and its `fs_context` parameter); `into_contexts` attaches a filesystem only when `filesystem_read` was negotiated; capability-negotiation tests in `tools` and - `temporal-server`. The remote read/write path is covered by + `temporal-runtime`. The remote read/write path is covered by `existing_file_tools_work_through_remote_context`; a session-level live assertion needs a real envd data plane (the fake provider has none) and belongs to the Incus smoke test. Runtime build and deployment pending. @@ -412,7 +412,7 @@ rules shared with `environments/create`). the deployment reconciler scan now also selects universes holding such environments whose session is closed. - [x] `profiles`: document validation for both variants. -- [x] `temporal-server`: applier `provision` path with derived request id and +- [x] `temporal-runtime`: applier `provision` path with derived request id and origin provenance, pre-start binding/grant checks, status-aware `selectable`/`activatable`, `NotReady` per-call outcome, hosted `await_environment_ready`, reconciler sweep, eager close on diff --git a/docs/roadmap/archive/p126-environment-power-and-idle-policy.md b/docs/roadmap/archive/p126-environment-power-and-idle-policy.md index c988b6430..7d2cd00b1 100644 --- a/docs/roadmap/archive/p126-environment-power-and-idle-policy.md +++ b/docs/roadmap/archive/p126-environment-power-and-idle-policy.md @@ -130,7 +130,7 @@ one place to map, and keeps the enum the single point of extension. `EnvironmentStatus` gains `Paused` and `Suspended`; `Offline` keeps meaning "observed stopped". -The lifecycle reconciler in `temporal-server` already scans pending and +The lifecycle reconciler in `temporal-runtime` already scans pending and closing rows and converges them through the controller. It gains one more rule: for a provisioned environment whose observed status is not `Closing` / `Closed` / `Failed` and whose observed power state differs from @@ -195,7 +195,7 @@ idle threshold is far above any single call. `environments/power/put`. Templates may carry a default policy in metadata that `environments/create` copies when the caller passes none. - A power reaper loop in `temporal-server` (sibling of the P92 + A power reaper loop in `temporal-runtime` (sibling of the P92 `PromiseReaper`, single active instance like the reconciler; every 60 s) selects `Ready` provisioned environments with a policy, asks each daemon for its idle report, and sets `desired_power` (or requests close) when a @@ -306,7 +306,7 @@ freeze/resume/stop, `set_target_power` capability. Stateful stop (`suspended`) is not advertised. P122 pool accounting for paused RAM is not changed (paused VMs still count as running instances there). -`crates/temporal-server`: +`crates/temporal-runtime`: - Reconciler: `reconcile_environment_power` (decision 2) with one `record_target_observation` path shared with create/adopt; observed status @@ -331,7 +331,7 @@ changed (paused VMs still count as running instances there). `crates/temporal-workflow`: no changes; the existing `await_environment_ready` path covers wake. -Consumers: TypeScript client and Configurator regenerated; Platform server +Consumers: TypeScript client and Configurator regenerated; Platform backend routes `PUT /environments/:id/power` and `/idle-policy`; environments page shows power/idle policy details and offers Resume/Pause/Suspend/Stop for the states the provider reported; profile editor gains idle-policy stages under diff --git a/docs/roadmap/archive/p127-openai-oauth-login.md b/docs/roadmap/archive/p127-openai-oauth-login.md index 82df87ea8..c6023f6f9 100644 --- a/docs/roadmap/archive/p127-openai-oauth-login.md +++ b/docs/roadmap/archive/p127-openai-oauth-login.md @@ -9,7 +9,7 @@ migration, no core method. Subscription credentials are ordinary `static_bearer` grants imported through `auth/grants/import` (which gained a generic `metadata` field) with `metadata.subscription = claudeCode | - codex`; Platform parses/normalises the paste (`platform/server/src/ + codex`; Platform parses/normalises the paste (`platform/backend/src/ subscriptions.ts`), and the worker injects the stored value verbatim. The Integrations cards (Anthropic, OpenAI), Codex bootstrap snippet, and the environment "Assign credential" env-name suggestions are in place; the @@ -207,7 +207,7 @@ Platform: `model:openai` `modelApiKey` row (needs `auth/providers/update` with credential replace, also wanted for GitHub App key rotation). -Tokens transit the Platform server in memory during the flow (as pastes do +Tokens transit the Platform backend in memory during the flow (as pastes do today) and are never stored there. Refresh: Codex refreshes itself inside the environment; if Lightspeed's copy goes stale the card shows *Reconnect*. Core-side refresh is only needed if core consumes the token at runtime (D6), @@ -286,7 +286,7 @@ loop is the API-key outcome of D3. ## Security Invariants 1. Platform never persists tokens: pastes (and, in S3, device-flow tokens) - pass through the Platform server in memory only, are handed to core in + pass through the Platform backend in memory only, are handed to core in one request, and are encrypted on receipt; reads return ids/status/ metadata only. 2. Device `user_code` is bound to the starting universe and a TTL. @@ -329,7 +329,7 @@ loop is the API-key outcome of D3. ### S3: OpenAI device flow + API-key outcome (Platform) -- Device flow in the Platform server, polling from the server, normalise + +- Device flow in the Platform backend, polling from the server, normalise + import; API-key exchange → `model:openai` (+ `auth/providers/update` in core, generic); card gets *Sign in with OpenAI*. Live measurement of refresh-token rotation → decide the D4 follow-up. diff --git a/docs/roadmap/archive/p128-openai-completions-runtime.md b/docs/roadmap/archive/p128-openai-completions-runtime.md index cae7042b0..8137935c6 100644 --- a/docs/roadmap/archive/p128-openai-completions-runtime.md +++ b/docs/roadmap/archive/p128-openai-completions-runtime.md @@ -106,13 +106,13 @@ Two phases, shipped in order: extra }` and `validate_provider_params` accepts it, so a completions params body already passes admission — and then fails at generation with `no LLM generation adapter registered for OpenAiCompletions`. -- `engine` already treats `OpenAiCompletions` as a first-class +- `harness` already treats `OpenAiCompletions` as a first-class `ProviderApiKind`: sessions pin it, `remote_mcp_supported_by_provider` returns `false` for it, `validate_context_config` rejects `ProviderTriggered` and `ProviderStandalone` compaction for it, and `tools/toolset.rs` maps it to the `CodexLike` built-in surface next to Responses. `api-projection` maps `"openai:completions"` both ways. -- `temporal-server/gateway/service/api_config.rs::validate_reasoning_effort` +- `temporal-runtime/gateway/service/api_config.rs::validate_reasoning_effort` rejects any `reasoningEffort` for `openai:completions`; `models_api.rs` emits OpenAI models only as `openai:responses`; `worker/activities/state.rs ::llm_runtime_with_clients` registers Responses and Anthropic adapters @@ -345,7 +345,7 @@ Phase 1 (in dependency order): (copy of the Responses pattern), constants `OPENAI_COMPLETIONS_API_KIND` re-export; unit tests for header/auth selection. Keep `create` as the `None`-auth wrapper. -2. `engine`: allow `ProviderStandalone` compaction for `OpenAiCompletions` +2. `harness`: allow `ProviderStandalone` compaction for `OpenAiCompletions` in `validate_context_config`; unit tests. 3. `llm-runtime/src/openai_completions.rs`: `OpenAiCompletionsApi` trait (`create`, with `auth`), impl for `oai_c::Client`, @@ -360,7 +360,7 @@ Phase 1 (in dependency order): caption); PDF; assistant+tool_calls fold; tool result; skill/VFS system messages; tool_choice variants; params passthrough; refusal; usage and finish mapping; kind mismatch errors. -4. Registration: `temporal-server/worker/activities/state.rs` +4. Registration: `temporal-runtime/worker/activities/state.rs` (`default_llm_runtime` builds a third client from `oai_c::Config::from_env_allow_missing_key`; `llm_runtime_with_clients` registers generation + compaction for `OpenAiCompletions`), `eval/main.rs`, @@ -381,7 +381,7 @@ Phase 1 (in dependency order): `openai_completions_prompts_live.rs`, `openai_completions_skills_live.rs` — mirror the Responses files; `support/mod.rs` gains a completions model/client helper honouring `OPENAI_COMPLETIONS_MODEL/API_KEY/BASE_URL`. - `temporal-server/tests/sessions_live.rs` gets one end-to-end managed + `temporal-runtime/tests/sessions_live.rs` gets one end-to-end managed session on `openai:completions` (tool call + reply). All `#[ignore]`, fail loudly without keys. @@ -395,7 +395,7 @@ Phase 2: `ModelProviderResolver`, `ResolvedModelProvider`, `ResolvedEndpoint`, `Static*` test resolver; keep `ProviderKeyResolver` name only if the diff is otherwise unwieldy — prefer the rename (greenfield). - `temporal-server/worker/secrets.rs::StoredProviderKeyResolver` reads + `temporal-runtime/worker/secrets.rs::StoredProviderKeyResolver` reads the row's `endpoint` and returns it alongside auth; validates the request's `api_kind` against `endpoint.api_kinds` (mismatch → `ProviderKeyError::NotUsable`). @@ -426,12 +426,12 @@ Phase 2: Phase 1 done when: -- `cargo test -p llm-clients -p llm-runtime -p engine -p temporal-server +- `cargo test -p llm-clients -p llm-runtime -p harness -p temporal-runtime -p api -p eval` green; contract artifacts regenerated; `npm run check` green. - `cargo test -p llm-runtime --test openai_completions_live -- --ignored` (+ compaction/prompts/skills) pass against OpenAI with `OPENAI_API_KEY`. -- `source scripts/dev/env.sh && cargo test -p temporal-server --test +- `source scripts/dev/env.sh && cargo test -p temporal-runtime --test temporal_live openai_completions -- --ignored --test-threads=1` passes. - `models/list` returns both OpenAI kinds; a Platform session created with `apiKind: openai:completions` runs a tool round-trip end to end. @@ -449,7 +449,7 @@ Phase 2 done when: - Removing the row makes the next generation fail with a typed `ProviderKeyResolution` error, not a fall-through to `api.openai.com`. - `openai` sessions without a row still use `OPENAI_BASE_URL` (regression - test in `temporal-server` unit tests with a fake resolver). + test in `temporal-runtime` unit tests with a fake resolver). ## Resolved questions diff --git a/docs/roadmap/archive/p129-active-run-control.md b/docs/roadmap/archive/p129-active-run-control.md index a937d14ef..2c351ee1f 100644 --- a/docs/roadmap/archive/p129-active-run-control.md +++ b/docs/roadmap/archive/p129-active-run-control.md @@ -45,7 +45,7 @@ cancellation UI. ## Today -### Engine (`crates/engine`) — mostly complete +### Engine (`crates/harness`) — mostly complete - `CancelRun` → `CancellationRequested` → `Cancelling`; the planner waits for the open turn/tool batch to drain, then `CancellationGraceStarted` → @@ -93,7 +93,7 @@ cancellation UI. `CancellationRequested` event exists, which is the part that never happens in time. -### Gateway / API (`crates/api`, `crates/temporal-server`) +### Gateway / API (`crates/api`, `crates/temporal-runtime`) - `session/runs/cancel` pre-validates against store state, signals `CancelRun`, then polls until the run leaves `Active` or a 90 s @@ -112,7 +112,7 @@ cancellation UI. queueing through the gateway. The only workflow-level steering test uses it as a guaranteed-rejecting command (`runs_live.rs`). -### Platform UI (`platform/web`, `platform/server`) +### Platform UI (`platform/web`, `platform/backend`) - Stop: `SessionsPage.tsx:738-751` → `POST …/runs/:runId/cancel` → `gateway.ts:644-657` → `session/runs/cancel`. Wired, but: @@ -382,13 +382,13 @@ stop it, talk to it, or line up the next thing — with honest feedback. - Enter = **Queue as next run** (default); - ⌘/Ctrl+Enter = **Steer** ("send now, into the current run"; shown in the transcript as a steering message attached to the run); - - both call platform server routes → `session/runs/start` / + - both call platform backend routes → `session/runs/start` / `session/runs/steer`. - **Queued display.** A queued list under the transcript (source text, ×), fed by `SessionView.runs` + `runAccepted`; collapses as runs start. - **Transcript.** Render steering entries distinctly inside the run they steered; render `cancelling`/`cancelled` states on the run header. -- **Platform server.** Add `POST …/runs/:runId/steer` and make +- **Platform backend.** Add `POST …/runs/:runId/steer` and make `…/messages` accept a `mode: "queue"` (or a dedicated `…/runs` route) that returns the queued `RunView`; return the cancel response body instead of `{ ok: true }`. @@ -455,7 +455,7 @@ stop it, talk to it, or line up the next thing — with honest feedback. await (await resolves `cancelled`, child run cancelled through the promise cascade). Existing fake-run, parallel-batch, admission-failure, and await-parks scenarios still pass. -5. **[DONE]** Platform UI (`platform/web`, `platform/server`): the +5. **[DONE]** Platform UI (`platform/web`, `platform/backend`): the transcript reducer tracks `activeRun` (with `cancelling`), `queuedRuns`, per-run phases, and a `runRevision`; `reconcileRuns` folds the authoritative `SessionView.runs` into the tail forward-only (heals a diff --git a/docs/roadmap/archive/p130-bots.md b/docs/roadmap/archive/p130-bots.md index cf07e3a0a..957ac9db4 100644 --- a/docs/roadmap/archive/p130-bots.md +++ b/docs/roadmap/archive/p130-bots.md @@ -126,7 +126,7 @@ - Slice 2 implemented 2026-08-20, end to end: - Triggers reshaped to per-kind `spec` jsonb + `filter` (CEL) + `route` columns (backfilling migration). Boot-time schedule reconcile in the - platform server converges Temporal Schedules to the rows. + platform backend converges Temporal Schedules to the rows. - **Webhook ingress**: `POST /api/v1/hooks/bots/:triggerId/:token` outside session auth; URL-token + optional generic HMAC-SHA256 verification; 1 MiB cap; credential headers redacted; raw payload preserved in the @@ -221,10 +221,10 @@ declaration-mismatch failure from `session/managed/start`, rotates the main session to `-g2`, `-g3`, … (`session_rotated` activity) — the planned workaround made real. - - **Shared config module** (`@lightspeed/bots/config`): trigger + - **Shared config module** (`@lightspeed-ai/bots/config`): trigger validation + create/update/delete + schedule reconcile, used by both the API routes and the bot's tools — one code path. Webhook helpers moved - to `@lightspeed/bots/webhooks`. + to `@lightspeed-ai/bots/webhooks`. - **One-shot schedules**: `spec.at` (ISO instant) as an alternative to cron, realized as a Temporal calendar spec with explicit year; the trigger disables itself and drops its schedule after firing. UI offers @@ -247,7 +247,7 @@ durable** — `admitBotEvent` inserted the row and then signalled the controller; if the signal failed, the sender's retry hit the duplicate path and returned without signalling, stranding the event. FIXED - 2026-08-25 with one shared `wakeBotController` (`@lightspeed/bots/events`) + 2026-08-25 with one shared `wakeBotController` (`@lightspeed-ai/bots/events`) used by the server route, schedule fires, polls, and `bot_emit`: a duplicate admission wakes the controller again (it dedupes by event id), and a wake that fails right after this call stored the row deletes the @@ -615,8 +615,8 @@ state-query template, generalized. **Where it lives:** `platform/bots/` — a TypeScript Temporal application exactly like Channels: bot records in Platform Postgres (the `foundryPacks` -shape), ingest routes in `platform/server`, one controller workflow type, -activities over `@lightspeed-ai/agent-client`. Alternatives considered and set +shape), ingest routes in `platform/backend`, one controller workflow type, +activities over `@lightspeed-ai/sdk`. Alternatives considered and set aside: a core Rust crate (wrong tier — this is product logic that will iterate weekly, and the core's job is to stay still) and new core API methods for bot CRUD (unnecessary — Channels and Foundry both live entirely on the diff --git a/docs/roadmap/archive/p132-workflow-contract-export.md b/docs/roadmap/archive/p132-workflow-contract-export.md index d896e13f9..a79f2f27b 100644 --- a/docs/roadmap/archive/p132-workflow-contract-export.md +++ b/docs/roadmap/archive/p132-workflow-contract-export.md @@ -4,7 +4,7 @@ - Implemented 2026-08-25. Rust now exports and staleness-checks the schema, manifest/vectors, and integrator reference; the TypeScript client ships the - pure `@lightspeed-ai/agent-client/workflow` subpath; Bots and Channels consume + pure `@lightspeed-ai/sdk/workflow` subpath; Bots and Channels consume it and their handwritten emission contracts and workflow-id ports are gone. The client vector suite, both platform unit suites, and the Bots/Channels Temporal integration suites pass after cutover. @@ -31,8 +31,8 @@ resolutions from anyone else (`process_pending_source_resolutions` in transport stays. What is wrong is where the contract lives. The envelope is `engine::emission` -plus `temporal_workflow::types`; the `api` crate does not depend on `engine` -(clients stay on `api` by design) and `engine` has no `schemars`, so none of +plus `temporal_workflow::types`; the `api` crate does not depend on `harness` +(clients stay on `api` by design) and `harness` has no `schemars`, so none of it reaches `crates/api/contract/` or the generated TypeScript client. Every TypeScript receiver therefore hand-mirrors it: @@ -78,10 +78,10 @@ carry it), so receivers stop composing the session workflow id themselves. ### 1. Rust is the source of truth Derive `JsonSchema` on the exported types where they are defined, so the -schema *is* the serde shape and cannot drift. `engine` gains `schemars` +schema *is* the serde shape and cannot drift. `harness` gains `schemars` behind a cargo feature `contract` (a derive, no runtime behaviour; the determinism rule is about side effects, not derives). `temporal-workflow` -enables `engine/contract`, derives on its own contract types, and exposes +enables `harness/contract`, derives on its own contract types, and exposes `workflow_contract::export()` built the way `api::export_schemas()` is: a Draft-07 generator, every type under `definitions`, plus a small constants manifest and a generated reference. Mirror DTOs inside Rust were considered @@ -112,7 +112,7 @@ stale, exactly as `cargo test -p api` does for the API contract. `clients/typescript/scripts/generate.mjs` additionally compiles `workflow.schema.json` into `src/generated/workflow-types.ts`, and the -client ships a `./workflow` subpath (`@lightspeed-ai/agent-client/workflow`): +client ships a `./workflow` subpath (`@lightspeed-ai/sdk/workflow`): - the generated types; - `DELIVER_EMISSION_SIGNAL`, `WORKFLOW_TOOL_RECOVERY_QUERY`, recipe diff --git a/docs/roadmap/archive/p133-retrievable-grant-leases.md b/docs/roadmap/archive/p133-retrievable-grant-leases.md index f75c9849c..30e0406b1 100644 --- a/docs/roadmap/archive/p133-retrievable-grant-leases.md +++ b/docs/roadmap/archive/p133-retrievable-grant-leases.md @@ -118,7 +118,7 @@ Consequences that fall out structurally: principal or `user:` (`engineClientFor(ctx, universe, principal)`); neither leases. The Secrets page shows a badge, never a value. - **Platform workers** identify themselves: the Bots and Channels activity - workers and the platform server send `service_account:lightspeed-bots` / + workers and the platform backend send `service_account:lightspeed-bots` / `-channels` / `-platform` (audit identity, not a credential). In `api-key` deployments the platform mints service keys through `operator/api-keys/create` with a `service_account` principal, which it diff --git a/docs/roadmap/archive/p134-subagents.md b/docs/roadmap/archive/p134-subagents.md index f9138ba9d..8696c5477 100644 --- a/docs/roadmap/archive/p134-subagents.md +++ b/docs/roadmap/archive/p134-subagents.md @@ -389,7 +389,7 @@ Everything fleet, deleted rather than deprecated: | Area | Goes | |---|---| | tools | `crates/tools/src/fleet/` (all seven tools, args, outputs); `FleetToolsetConfig`; `config.fleet` in `resolve_toolset`; the `VfsPolicy::Isolate` workspace derivation | -| server | `temporal-server/src/fleet.rs` except the spawn body that becomes the prepare activity; `AgentApiFleetRuntime`; `start_session_for_fleet_with_profile`, `start_run_for_fleet`, `enqueue_run_for_fleet`, `deliver_message_for_fleet`; the fleet branches and message-dedup path in `worker/session_tools.rs`; fleet wiring in `universe.rs`, `lib.rs`, `main.rs`, `worker/activities/{mod,state}.rs` | +| server | `temporal-runtime/src/fleet.rs` except the spawn body that becomes the prepare activity; `AgentApiFleetRuntime`; `start_session_for_fleet_with_profile`, `start_run_for_fleet`, `enqueue_run_for_fleet`, `deliver_message_for_fleet`; the fleet branches and message-dedup path in `worker/session_tools.rs`; fleet wiring in `universe.rs`, `lib.rs`, `main.rs`, `worker/activities/{mod,state}.rs` | | engine | `FleetFeature`, `FleetProfilesConfig`, `FleetSpawnConfig`, `FleetSpawnBase`; `fleet_policy` on tool-batch requests (renamed `subagents_policy`); `PromiseSource::Run` and its arms in cancellation and source polling (`RunTerminalNotifyIntent` stays — bots and the execution workflow use it) | | api | `FleetFeature` family; `FeaturesConfig.fleet` → `subagents`; `api-projection` fleet mapping; regenerated contract, OpenRPC, TS client, Configurator tools, web reference | | store | `session_links` table, `SessionLinkRecord`, `UpsertSessionLink`, `ListSessionLinks`, `SessionLinkDirection`, the store trait methods and `store-pg` implementations | @@ -434,7 +434,7 @@ the retired `session_links` table is absent. Existing dev databases are reset `CreateSession` with origin and the transactional root reservation, `SessionOrigin` on both views, `session/list` filters, link traits deleted, contract regenerated. -2. **Grant** (½ day): `SubagentsFeature` in `engine` + `api` replacing the +2. **Grant** (½ day): `SubagentsFeature` in `harness` + `api` replacing the fleet family; admission validation of `agents[]`; `subagents_policy` on the batch request; `api-projection`; Configurator/TS/web regeneration; the web config-editor card. diff --git a/docs/roadmap/archive/p135-bot-federation.md b/docs/roadmap/archive/p135-bot-federation.md index e50521a4a..e4035c73a 100644 --- a/docs/roadmap/archive/p135-bot-federation.md +++ b/docs/roadmap/archive/p135-bot-federation.md @@ -140,7 +140,7 @@ bot_emit { kind, summary, data?, to?: botName, sessionKey? } webhook ingest uses: enabled bot → enabled `bot` trigger → `from` → hop bound → sender rate cap → filter → route → coalesce params → `whenBusy` → store-then-wake. That pipeline (`admitBotEvent` and - the breaker check) moves from `platform/server` routes into the bots + the breaker check) moves from `platform/backend` routes into the bots package so ingest, poll, self-emit, and addressed emit share one function; today the self-emit activity duplicates the insert without it. - **Joined.** The tool waits for validation and durable storage only — diff --git a/docs/roadmap/archive/p136-context-catalogs.md b/docs/roadmap/archive/p136-context-catalogs.md index 6b37e4512..b486293ba 100644 --- a/docs/roadmap/archive/p136-context-catalogs.md +++ b/docs/roadmap/archive/p136-context-catalogs.md @@ -4,8 +4,8 @@ - Proposed 2026-08-26, surfaced by the P135 review question "where does a refreshed catalog land in the context, and does it invalidate the prompt - cache?" — it does, from the front. Core tier (`engine`, `llm-runtime`, - `temporal-server` projection, `api` views). Not yet sliced for a sprint; + cache?" — it does, from the front. Core tier (`harness`, `llm-runtime`, + `temporal-runtime` projection, `api` views). Not yet sliced for a sprint; the design is settled enough to build. Implemented the same day; see the entry below. - Extended the same day at Lukas's request: the supersede mechanism is @@ -105,7 +105,7 @@ the message list, before the first user message. `UpsertContext` is a keyed `EntriesApplied`, and the reducer implements a keyed replace as **remove the previous entry wherever it is, then push the new one at the tail with a fresh id** (`apply_entries_applied`, -`crates/engine/src/core/components/context.rs`). Two consequences: +`crates/harness/src/core/components/context.rs`). Two consequences: 1. **The prefix moves.** Removing a message from the front shifts every byte after it. Provider prompt caches are prefix caches (Anthropic at diff --git a/docs/roadmap/archive/p138-model-facing-ids.md b/docs/roadmap/archive/p138-model-facing-ids.md index 610408002..dee9dff1b 100644 --- a/docs/roadmap/archive/p138-model-facing-ids.md +++ b/docs/roadmap/archive/p138-model-facing-ids.md @@ -6,9 +6,9 @@ have to pass around?" Weaker models drop and transpose characters in long ids; a mistyped promise id costs a turn. The facts below were verified in code the same day. -- Core tier: `engine` (`PromiseId`, `IdCursors`, the tool batch request, +- Core tier: `harness` (`PromiseId`, `IdCursors`, the tool batch request, promise effects), `tools` (concurrency, workflow-tool adapter, job - arguments), `temporal-server` (session tool runtime, job and sub-agent + arguments), `temporal-runtime` (session tool runtime, job and sub-agent activities), `temporal-workflow` (reply tokens, the source-resolution emission id), `api` (promise views, key-source input), and both contract exports. Core only: the bot-side ids (`bot_emit`'s return, the digest @@ -239,7 +239,7 @@ copies. Registry and API change, not core; not sliced here. ## Tests -- `engine`: `Promise(Created)` below the base or duplicate is an invariant +- `harness`: `Promise(Created)` below the base or duplicate is an invariant violation; the cursor bumps to the max; a recorded batch with out-of-order numbers reduces identically on replay; continue-as-new keeps the cursor. @@ -248,7 +248,7 @@ copies. Registry and API change, not core; not sliced here. duplicate, and invalid field values; `await` / `cancel` / `detach` accept `promise_` and turn a malformed id into a tool error, never an invariant violation. -- `temporal-server`: parallel calls in one batch get disjoint ids; the +- `temporal-runtime`: parallel calls in one batch get disjoint ids; the sub-agent reply token round-trips; job subscriptions are keyed by job id; `job_read` without `environment_id` reads the active environment. - `temporal-workflow`: two holders resolving `promise_1` through one diff --git a/docs/roadmap/archive/p139-channels-as-bot-triggers.md b/docs/roadmap/archive/p139-channels-as-bot-triggers.md index 51a867d7b..4e178424f 100644 --- a/docs/roadmap/archive/p139-channels-as-bot-triggers.md +++ b/docs/roadmap/archive/p139-channels-as-bot-triggers.md @@ -353,7 +353,7 @@ session's context unbounded today. Lands when someone wants silent rooms. endpoint, history replay. 3. **Conversation workflow.** Rename and cut `channelSessionWorkflowV1`; control plane over `chat` triggers; `emitChatEvent` activity into - `@lightspeed/bots` admission; receipt signal handler with the existing + `@lightspeed-ai/bots` admission; receipt signal handler with the existing fallback; accepted-session set for invocations; `#N` handle map in the carry, integer `replyTo`/`message` in the `message_*` schemas (revision 2), `chat.sent` rows on every delivered send, and the diff --git a/docs/roadmap/archive/p140-bot-environments-and-bot-lifecycle.md b/docs/roadmap/archive/p140-bot-environments-and-bot-lifecycle.md index 76c02ef83..4cdcd1e69 100644 --- a/docs/roadmap/archive/p140-bot-environments-and-bot-lifecycle.md +++ b/docs/roadmap/archive/p140-bot-environments-and-bot-lifecycle.md @@ -79,7 +79,7 @@ environment next to the bot, exec pollers have to be handed an id, the Environments page can display an idle policy but not set one on an existing environment, the editor and CLI give no hint that the policy lives there, and there is no way to retire or delete a bot at all -(`platform/server/src/routes/bots.ts` has create and patch only; +(`platform/backend/src/routes/bots.ts` has create and patch only; `enabled: false` pauses). ## Today @@ -88,7 +88,7 @@ and there is no way to retire or delete a bot at all (sub-agents), `provision { providerId, templateId, retention, idlePolicy?, credentials? }` with `requestId = "session:" + sessionId` and an optional `closeWithSession` trigger on `originSession`. -- The applier (`crates/temporal-server/src/gateway/service/profiles.rs`) +- The applier (`crates/temporal-runtime/src/gateway/service/profiles.rs`) activates an `existing` environment through the same status-aware admission as `session/environments/activate`: `provisioning`/`booting` and powered-down environments are admitted as intent (P125/P126), @@ -113,7 +113,7 @@ and there is no way to retire or delete a bot at all `signalWithStart` (`platform/bots/src/events.ts`). - `session/close { force }` cancels the active run and drops queued runs; `session/delete` on an open session force-closes first, then removes the - record (`crates/temporal-server/src/gateway/service/mod.rs`). + record (`crates/temporal-runtime/src/gateway/service/mod.rs`). ## Design — Part A: a bot's environment is an `existing` environment @@ -373,7 +373,7 @@ with the snapshot-patch trick from P135): `bots.closed_at timestamptz`, ## Runtime and platform changes -- `crates/temporal-server/src/environment_resolver.rs`: `ready` + +- `crates/temporal-runtime/src/environment_resolver.rs`: `ready` + `desiredPower != running` → conditional write back to `running`. - `crates/cli` `profiles check`: `existing` idle-policy / external / closed hints. @@ -384,7 +384,7 @@ with the snapshot-patch trick from P135): `bots.closed_at timestamptz`, activity; poll fire resolves a missing `environmentId` from the bot profile; `bot_trigger_put` and its schema description accept the omission. -- `platform/server`: `bots/:botId/close`, `DELETE bots/:botId`, `409` on +- `platform/backend`: `bots/:botId/close`, `DELETE bots/:botId`, `409` on enabling a closed bot, `410` on webhook ingest and manual events for a closed bot; `signalBotConfig` carries `closed`. - `platform/web`: Environments page idle-policy modal and create-dialog @@ -455,8 +455,8 @@ with the snapshot-patch trick from P135): `bots.closed_at timestamptz`, trigger, row cascade); `PATCH` labels-only on a closed bot; web Lifecycle block with Close/Delete confirms, "Closed" on list/detail, "bot closed" on trigger cards. -- **Verified**: `cargo test -p temporal-server --lib environment_resolver`, - `cargo clippy -p temporal-server -p cli --all-targets`, `npm run +- **Verified**: `cargo test -p temporal-runtime --lib environment_resolver`, + `cargo clippy -p temporal-runtime -p cli --all-targets`, `npm run typecheck/test/build`, `check:identity`, `test:migrations` against a scratch platform database, bots Temporal integration 18/18 including the new close scenario (pending event archived `bot_closed`, forced diff --git a/docs/roadmap/archive/p142-bots-and-channels-core-in-rust.md b/docs/roadmap/archive/p142-bots-and-channels-core-in-rust.md index 5beb61534..ab61cb7c2 100644 --- a/docs/roadmap/archive/p142-bots-and-channels-core-in-rust.md +++ b/docs/roadmap/archive/p142-bots-and-channels-core-in-rust.md @@ -8,9 +8,9 @@ deleted). Implementation log at the end of this document. - Proposed 2026-08-30 from a design conversation with Lukas, after a survey of `platform/bots`, `platform/channels`, `platform/workers`, the - Platform server/db/web glue, and the Rust runtime crates. + Platform backend/db/web glue, and the Rust runtime crates. - Direction from Lukas: move bots and the core of Channels (workflows, - control plane, tables) into `temporal-workflow`, `temporal-server`, + control plane, tables) into `temporal-workflow`, `temporal-runtime`, `store-pg`, and dedicated domain crates; keep the messaging bridges (Telegram, WhatsApp) as TypeScript processes in `platform/`; fold the bot and channel API into the existing core API — no second gateway. @@ -36,7 +36,7 @@ conversation is the receiver of `message_*` workflow tools, every event goes through one admission pipeline — but they run as a second product plane written against the core's public API: -- The Platform server is itself a Temporal client (`bot-common.ts`, +- The Platform backend is itself a Temporal client (`bot-common.ts`, `bot-schedules.ts`): signal-with-start, queries, and Schedule reconciliation at boot happen in route handlers. - Two databases hold one product: `bots`, `bot_triggers`, `bot_events`, @@ -64,7 +64,7 @@ and `WorkerTaskTypes` for the workflow/activity split. ## The shape ```text - lightspeed-server (one node; --roles gateway,sessions,bots,channels) + lightspeed-runtime (one node; --roles gateway,sessions,bots,channels) ┌──────────────────────────────────────────────────────────┐ Platform (TS) │ gateway │ ┌──────────────────┐ │ JSON-RPC: session/* profiles/* … bots/* channels/* │ @@ -111,7 +111,7 @@ Two new domain crates follow the `environments` / `mcp` / `profiles` pattern — records, validation, errors, pure logic, `#[async_trait]` store traits, an in-memory store for tests — with no I/O: -**`crates/bots`** (depends on `api`, `engine` for storage ids, `sha2`, +**`crates/bots`** (depends on `api`, `harness` for storage ids, `sha2`, `cel-interpreter`, `cron`, `hmac`) - Records: `BotRecord`, `BotTriggerRecord` with the five `TriggerSpec` @@ -169,7 +169,7 @@ traits, an in-memory store for tests — with no I/O: `workflows/bot_trigger_fire.rs`, `workflows/channel_conversation.rs`, their activity definitions, and contract-export roots and vectors for everything a connector must derive (§7). -- `temporal-server`: `bots/` module (admission pipeline, schedule +- `temporal-runtime`: `bots/` module (admission pipeline, schedule reconciler, tool executor, session ensure/rotate), `worker/activities/ {bots,channels}.rs`, `gateway/service/{bots_api,channels_api}.rs`, `gateway/hooks.rs`, and the `--task-types` role knob (§6). @@ -333,7 +333,7 @@ JSON-RPC over HTTP: (`self_config`, `emit`) as defense in depth, results and errors as CAS blobs, `reply` promise resolved by signalling the holder session. -The admission pipeline (`temporal-server/src/bots/admission.rs`) is one +The admission pipeline (`temporal-runtime/src/bots/admission.rs`) is one Rust function set used by every path — hook route, manual admit, replay, schedule and poll fires, chat emit, `bot_emit`, receipts: closed-bot guard → `allocate_event_seq` → render → CAS put → insert `ON CONFLICT DO @@ -343,7 +343,7 @@ and rethrow if the wake fails and this call inserted it. Filter misses store nothing. Tool execution and the `bots/*` methods share the same service functions -(`temporal-server/src/bots/`), so a bot editing its own trigger and an +(`temporal-runtime/src/bots/`), so a bot editing its own trigger and an operator editing it through the API go through identical validation. ### 6. Runtime roles @@ -360,11 +360,11 @@ background loops that belong to that subsystem: | `channels` | `lightspeed-channels` | `ChannelConversationWorkflow` | channel activities | ``` -lightspeed-server # all roles, one process (default) -lightspeed-server --roles gateway -lightspeed-server --roles sessions,bots,channels # today's "worker" -lightspeed-server --roles bots --task-types workflows -lightspeed-server --roles bots --task-types activities +lightspeed-runtime # all roles, one process (default) +lightspeed-runtime --roles gateway +lightspeed-runtime --roles sessions,bots,channels # today's "worker" +lightspeed-runtime --roles bots --task-types workflows +lightspeed-runtime --roles bots --task-types activities ``` `--roles` (env `LIGHTSPEED_ROLES`) replaces the `gateway` / `worker` / @@ -395,7 +395,7 @@ runs the environment reconciler *and* the power reaper (today the gateway-only mode skips the reaper — an asymmetry to fix while rewriting the composition). -`./dev.sh full` becomes runtime + envd + Platform server + web + +`./dev.sh full` becomes runtime + envd + Platform backend + web + Configurator + the opt-in connector host: the four `platform-workers` processes disappear. `platform/workers` becomes the connector host. @@ -430,7 +430,7 @@ two dependencies — the core API and Temporal — and reads no database. (heartbeating, cancelled by scope) — unchanged payloads. 4. Health and metrics as today, per account. -The host authenticates the way the Platform server does: it is a +The host authenticates the way the Platform backend does: it is a first-party deployment process, so in `trusted-header` mode it stamps `x-lightspeed-universe` per call and uses the operator scope for discovery; in `single` mode the universe is fixed; in `api-key` mode @@ -499,7 +499,7 @@ and core-Channels variable groups in `docs/variables.md`. one API. P124's non-goal is reversed for this scope only. 2. **Two domain crates**, `bots` and `channels`, hold everything pure; workflows in `temporal-workflow`, activities and service in - `temporal-server` (use subfolders in `crates/temporal-workflow/src/workflows` to segregate the parts), tables in `store-pg`. No new binary, no new + `temporal-runtime` (use subfolders in `crates/temporal-workflow/src/workflows` to segregate the parts), tables in `store-pg`. No new binary, no new gateway. 3. **Roles per subsystem, one process by default**: `--roles gateway | sessions | bots | channels` (all by default), each worker role its @@ -540,7 +540,7 @@ and core-Channels variable groups in `docs/variables.md`. — ported; the rest moves to `platform/connectors`. - `platform/db/src/schema/{bots,channels}.ts`, migrations `0001_channels`, `0002_bots`. -- `platform/server/src/routes/{bot-hooks,bot-common}.ts`, +- `platform/backend/src/routes/{bot-hooks,bot-common}.ts`, `bot-schedules.ts`; the bot logic in `routes/bots.ts` and `routes/channel-accounts.ts` (they become passthroughs). - `platform/workers` roles `bots-*`, `channels-*`; the Channels search @@ -560,7 +560,7 @@ and core-Channels variable groups in `docs/variables.md`. 2. **Bots runtime** — `BotControllerWorkflow`, `BotTriggerFireWorkflow`, admission pipeline, bot activities, tool executor, Schedules reconciler, hook route, `bots/state/read`, `bots/close` / `delete`, - `profiles/put` reconcile signal; `crates/temporal-server/tests/ + `profiles/put` reconcile signal; `crates/temporal-runtime/tests/ bots_live.rs` porting the eighteen integration scenarios (dedupe, budget, descendants, config reconcile, perKey, coalesce, debounce wake, steer/append, sidecar, retention, rotation ×3, close, @@ -577,12 +577,12 @@ and core-Channels variable groups in `docs/variables.md`. grant-leased Telegram tokens and per-account WhatsApp session directories, `channels/inbound/admit` with the decision → reply mapping, one activity worker per `connectorTaskQueue` (derivation - exported from `@lightspeed-ai/agent-client/workflow` and asserted + exported from `@lightspeed-ai/sdk/workflow` and asserted against the contract vector), one health/metrics listener. `platform/channels` and `platform/workers` are deleted; `dev.sh full` starts one `connectors` process behind `LIGHTSPEED_CHANNELS_CONNECTORS`. `platform/bots` survived only - because `platform/server` still imported it (deleted in slice 4). The WhatsApp + because `platform/backend` still imported it (deleted in slice 4). The WhatsApp group-join pairing announcement was dropped: the core has no "is pairing required" query, and the first message in the group yields `pairing_required` anyway. @@ -666,14 +666,14 @@ and core-Channels variable groups in `docs/variables.md`. TypeScript client regenerated; the workflow contract now exports `ConversationStart`, the connector activity payloads, the connector queue derivation, and channel vectors. -- **Runtime roles.** `lightspeed-server [--roles gateway,sessions,bots,channels] [--task-types all|workflows|activities]` +- **Runtime roles.** `lightspeed-runtime [--roles gateway,sessions,bots,channels] [--task-types all|workflows|activities]` replaces the `gateway`/`worker`/`both` subcommands; per-role queues `LIGHTSPEED_TASK_QUEUE` (`lightspeed-sessions`), `LIGHTSPEED_TASK_QUEUE_BOTS`, `LIGHTSPEED_TASK_QUEUE_CHANNELS`; the bot schedule reconciler runs beside the environment reconciler and power reaper. - **Bots runtime.** `BotControllerWorkflow` (lanes as boxed futures polled under the loop, no custom wakers; 32 unit tests) and one - `BotTriggerFireWorkflow`; `temporal-server/src/bots/`: store-then-wake + `BotTriggerFireWorkflow`; `temporal-runtime/src/bots/`: store-then-wake admission with row compensation, Temporal Schedules through the raw workflow service (the typed client cannot carry workflow input), the controller's session activities, the pushed `bot_*` executor, receipts and @@ -687,7 +687,7 @@ and core-Channels variable groups in `docs/variables.md`. activities, and the connector seam: three activities on `lightspeed-connector-{provider}-{digest}` served by the TypeScript connector host in `platform/connectors`. -- **Live proof** (`cargo test -p temporal-server --test bots_live|channels_live -- --ignored --test-threads=1`): +- **Live proof** (`cargo test -p temporal-runtime --test bots_live|channels_live -- --ignored --test-threads=1`): manual event → run → outcome, duplicate admission keeps `#N`; webhook trigger with filter and coalescing into one batch delivery, filtered and probed requests refused; daily budget parking; Temporal Schedule create / @@ -753,8 +753,8 @@ and core-Channels variable groups in `docs/variables.md`. documents carry `data.conversation` / `data.message` (CEL filters written against the TS layout need updating). - **Slice 4, Platform cut-over (2026-08-30).** `platform/bots` is deleted - and the Platform server is no longer a Temporal client - (`@temporalio/client` and `@lightspeed/bots` left its dependencies). + and the Platform backend is no longer a Temporal client + (`@temporalio/client` and `@lightspeed-ai/bots` left its dependencies). `routes/bots.ts` and `routes/channel-accounts.ts` are thin passthroughs on the existing `engineClientFor` / `withGateway` seam at the same URL paths with the core response shapes: reads keep member access, writes @@ -773,7 +773,7 @@ and core-Channels variable groups in `docs/variables.md`. (`LIGHTSPEED_PLATFORM_SCHEMA_REVISION=1`), and the migration gate now asserts the moved tables never reappear (the `lightspeed_channels` role machinery went with them). The web UI and the demo backend read - the generated `@lightspeed-ai/agent-client` types (`platform/web/src/api.ts` + the generated `@lightspeed-ai/sdk` types (`platform/web/src/api.ts` re-exports them; the demo emulates the new wire exactly, hooks at the core-shaped path). Release staging no longer ships `platform/bots/src`. Found while migrating: `BotTriggerView` serialized the poll spec's diff --git a/docs/roadmap/archive/p143-mcp-tool-discovery.md b/docs/roadmap/archive/p143-mcp-tool-discovery.md index ab17ae13e..e7f842741 100644 --- a/docs/roadmap/archive/p143-mcp-tool-discovery.md +++ b/docs/roadmap/archive/p143-mcp-tool-discovery.md @@ -437,7 +437,7 @@ there is no stored inventory. ## Session Contract Refactor -Make the greenfield breaking change in both `api` and `engine`: +Make the greenfield breaking change in both `api` and `harness`: ```rust pub struct McpServerLink { @@ -471,9 +471,9 @@ I/O under P110. ## Runtime Placement Keep protocol types and validation in `crates/mcp`. Put network I/O in a new -non-deterministic control-plane adapter owned by `temporal-server`, alongside +non-deterministic control-plane adapter owned by `temporal-runtime`, alongside the gateway's OAuth metadata client and broker-backed secret resolver. Do not -add network dependencies to `engine` or run discovery in workflow code. +add network dependencies to `harness` or run discovery in workflow code. The adapter should expose a deliberately narrow trait: @@ -563,7 +563,7 @@ returns only one byte-bounded result page at a time. - Add sanitized advertised-tool DTOs, error taxonomy, and bounds to `mcp`. - Implement Streamable HTTP initialization and paginated `tools/list` through - `rmcp` in a narrow `temporal-server` adapter; support no legacy transport. + `rmcp` in a narrow `temporal-runtime` adapter; support no legacy transport. - Resolve optional/required credentials through the P69 broker immediately before I/O. - Add the live-only `mcp/servers/tools/discover` command; add no revision @@ -641,7 +641,7 @@ Required coverage includes: deferred-loading values; - two server ids may reuse an endpoint and compatible credential while carrying different tool/approval policies; -- generated API, Configurator MCP, TypeScript client, Platform server, demo, +- generated API, Configurator MCP, TypeScript client, Platform backend, demo, and web tests remain in sync. The serialized `temporal_live_mcp_and_session_links_materialize` acceptance now diff --git a/docs/roadmap/archive/p143b-rmcp-oauth.md b/docs/roadmap/archive/p143b-rmcp-oauth.md index 7867e5179..c3802b1e9 100644 --- a/docs/roadmap/archive/p143b-rmcp-oauth.md +++ b/docs/roadmap/archive/p143b-rmcp-oauth.md @@ -35,7 +35,7 @@ The implementation landed as the greenfield breaking refactor described here: - MCP discovery maps SDK-parsed `invalid_token` and `insufficient_scope` challenges to `grantNeedsReauth` and `additionalConsentRequired`; suggested scopes are diagnostics and never mutate authored consent. -- The generated API/TypeScript contracts and the Platform server editor expose +- The generated API/TypeScript contracts and the Platform backend editor expose current advertised scopes and typed additional-consent diagnostics. Manual preregistration remains available through the API and CLI. @@ -44,9 +44,9 @@ Verification completed locally: - `cargo test -p auth` (85 passed); - `cargo test -p api` (82 passed, including generated-contract freshness); - `cargo test -p store-pg` (unit suite passed; database tests remain opt-in); -- `cargo test -p temporal-server --lib` (249 passed, one unrelated ffmpeg +- `cargo test -p temporal-runtime --lib` (249 passed, one unrelated ffmpeg smoke test ignored), plus the scope-upgrade transport fixture; -- `cargo test -p temporal-server --test mcp_oauth_live -- --ignored +- `cargo test -p temporal-runtime --test mcp_oauth_live -- --ignored --test-threads=1` (database-backed OAuth/MCP round trip passed); - `cargo check --workspace --tests`; - TypeScript generation, typechecking, 206 tests, and live/demo production @@ -155,7 +155,7 @@ component and adapt it to `rmcp`'s OAuth HTTP-client seam: later for P145 without weakening the public control-plane default. Both P143 tool discovery and P143b OAuth discovery should use this component. -It remains outside `engine`, workflows, and the provider adapters. +It remains outside `harness`, workflows, and the provider adapters. ### Discovery and client registration diff --git a/docs/roadmap/archive/p144-mcp-approvals.md b/docs/roadmap/archive/p144-mcp-approvals.md index 5d3d5ae90..55e469f17 100644 --- a/docs/roadmap/archive/p144-mcp-approvals.md +++ b/docs/roadmap/archive/p144-mcp-approvals.md @@ -349,7 +349,7 @@ auto-approve under any name. - `ApprovalId` counter, generic request/decision/cancellation events, the `McpToolCall` subject and MCP continuation variants, reducer state, single-funnel parked-run behavior, and cancel-terminates-pending. -- Remove `providerDefault` across `mcp`, `engine`, `api`, generated clients, +- Remove `providerDefault` across `mcp`, `harness`, `api`, generated clients, the Platform editor, CLI, and demo fixtures; the OpenAI lowering emits `require_approval` explicitly for both remaining values. - OpenAI Responses parsing of `mcp_approval_request` into facts alongside the diff --git a/docs/roadmap/archive/p145-native-mcp-execution.md b/docs/roadmap/archive/p145-native-mcp-execution.md index e280c0c7b..b4a6b8b6b 100644 --- a/docs/roadmap/archive/p145-native-mcp-execution.md +++ b/docs/roadmap/archive/p145-native-mcp-execution.md @@ -28,7 +28,7 @@ dispatch-time P144 approvals, CAS-backed rich-result placeholders, the deployment plus record private-egress gate, Platform/CLI/generated clients, an ignored Temporal live acceptance against the Configurator MCP, and a - standalone `temporal-server/tests/mcp_live.rs` matrix over local Stateless + standalone `temporal-runtime/tests/mcp_live.rs` matrix over local Stateless Streamable HTTP servers. ## Why @@ -277,7 +277,7 @@ below has a TTL rather than none). The injected tools appear identically in the send request and the redacted persisted blob; there is nothing secret in them. -The `temporal-server` implementation adapts the P143 transport — the same +The `temporal-runtime` implementation adapts the P143 transport — the same bounded `rmcp` Streamable HTTP client, SSRF policy, and `McpToolDiscoveryLimits` (which already bound schema bytes/depth for exactly this moment) — plus: @@ -413,7 +413,7 @@ hosting. Sessions are per-activity; Streamable HTTP only. - `McpInventoryResolver` in `llm-runtime`, lowering in all three adapters (sorted, canonical, in-place expansion), redacted-blob parity, typed injection failures, aggregate bounds. -- `temporal-server` resolver over the shared transport with broker + TTL +- `temporal-runtime` resolver over the shared transport with broker + TTL single-flight cache. ### Slice 3 — Call execution @@ -440,7 +440,7 @@ hosting. Sessions are per-activity; Streamable HTTP only. ### Slice 6 — Live acceptance -- **Standalone native matrix**: `temporal-server/tests/mcp_live.rs` runs +- **Standalone native matrix**: `temporal-runtime/tests/mcp_live.rs` runs through the real registry/API, Postgres, Temporal worker, approval continuation, `rmcp` client, and local Stateless Streamable HTTP servers. It covers a small Selected/injected server; a paginated 45-tool All/search diff --git a/docs/roadmap/archive/p147-session-checkpoints-and-bounded-reads.md b/docs/roadmap/archive/p147-session-checkpoints-and-bounded-reads.md index d07a486ad..bcdffd05b 100644 --- a/docs/roadmap/archive/p147-session-checkpoints-and-bounded-reads.md +++ b/docs/roadmap/archive/p147-session-checkpoints-and-bounded-reads.md @@ -80,7 +80,7 @@ Several amplifiers multiply that cost: replays at a rate proportional to run activity, which is worse than a fixed-interval poll. The consumer never reads `run.entries`; a summary view would satisfy it. -- The Platform server instructions editor fetches an entire `SessionView` +- The Platform backend instructions editor fetches an entire `SessionView` only to read `activeContext.entries`. - The Configurator MCP wrapper emits every successful result twice: once JSON-stringified into `content`, once as `structuredContent`. diff --git a/docs/roadmap/archive/p148-key-based-outbound-environment-registration.md b/docs/roadmap/archive/p148-key-based-outbound-environment-registration.md index d292b8823..05e75fec3 100644 --- a/docs/roadmap/archive/p148-key-based-outbound-environment-registration.md +++ b/docs/roadmap/archive/p148-key-based-outbound-environment-registration.md @@ -9,7 +9,7 @@ API; the outbound transport; lifecycle, model-tool group, and CLI; the Platform key management and demo. Verified by the unit suites of every touched crate and by the live suite - `crates/temporal-server/tests/environment_registration_live.rs`, which + `crates/temporal-runtime/tests/environment_registration_live.rs`, which runs an in-process `envd` against the real gateway, Postgres, and Temporal: first registration, two concurrent reverse-dialed routes, offline and identity-only reconnect, a second identity under one key, refusal of a new diff --git a/docs/roadmap/archive/p151-exec-leftover-processes.md b/docs/roadmap/archive/p151-exec-leftover-processes.md index c39e1e576..422777212 100644 --- a/docs/roadmap/archive/p151-exec-leftover-processes.md +++ b/docs/roadmap/archive/p151-exec-leftover-processes.md @@ -167,7 +167,7 @@ The polling has a second cause: the handle path does not work end to end. calls are unreachable. - The read cursor does not survive a tool batch. The hosted worker opens a fresh data-plane connection per tool activity - (`crates/temporal-server/src/worker/session_tools.rs`, + (`crates/temporal-runtime/src/worker/session_tools.rs`, `runtime_environment_for_resource`) and closes it after the batch. The `RemoteProcessExecutor` built from it keeps the per-handle `next_seq` in memory, so a handle used in a later batch reads with `after_seq: None` and @@ -275,7 +275,7 @@ The evaluator cannot account for tool output from the event log: `toolCallCompleted` carries a status and effects but no output size or truncation flag. `runFailed` carries a free-text message, although the engine already classifies the failure: `RunFailure.kind` in -`crates/engine/src/core/components/run.rs` is one of `model_failure`, +`crates/harness/src/core/components/run.rs` is one of `model_failure`, `tool_failure`, `context_failure`, `limit_exceeded`, `cancelled`, `internal`, and the API event in `crates/api/src/sessions.rs` drops it. diff --git a/docs/roadmap/archive/p159-builtin-tool-registry-and-late-resolution.md b/docs/roadmap/archive/p159-builtin-tool-registry-and-late-resolution.md index ac281a363..feafeaf7c 100644 --- a/docs/roadmap/archive/p159-builtin-tool-registry-and-late-resolution.md +++ b/docs/roadmap/archive/p159-builtin-tool-registry-and-late-resolution.md @@ -113,7 +113,7 @@ chosen from the effective turn model, including a run model override. The engine owns the small protocol types, or they live in a dependency-light protocol module. The `tools` crate owns the catalog of implementations, schema -builders, and codecs. `engine` must not depend on `tools`, resolve a built-in +builders, and codecs. `harness` must not depend on `tools`, resolve a built-in schema, or acquire one reducer branch per built-in implementation. ## Decision 2: Definition Source and Execution Are Separate @@ -349,7 +349,7 @@ not a promise that stochastic scores will be numerically identical. ### Slice 2 — Internal registry and definition sources -- Replace final-name keys and routing references in `engine` with internal ids; +- Replace final-name keys and routing references in `harness` with internal ids; adapt tool choice, events, call facts, policy lookup, and workflow definitions. - Split built-in registration from rendering in `tools::toolset` and all code-owned definition producers. Keep externally authored schema refs. @@ -398,8 +398,8 @@ not a promise that stochastic scores will be numerically identical. preserve existing approval, promise, cancellation, and completion behavior. - Transcript replay preserves original exposed names, raw arguments, call ids, result pairing, and provider-native blocks after internal identity changes. -- Generated contracts and consumers are current. Scope Rust checks to `engine`, - `tools`, `llm-runtime`, `temporal-workflow`, `temporal-server`, `api`, +- Generated contracts and consumers are current. Scope Rust checks to `harness`, + `tools`, `llm-runtime`, `temporal-workflow`, `temporal-runtime`, `api`, `api-projection`, and `eval`, then run the TypeScript checks for changed clients. - Once the developer confirms the environment and credentials are safe, run the relevant ignored integration suites with their required serialization and a @@ -427,7 +427,7 @@ not a promise that stochastic scores will be numerically identical. workspace, environment, one-shot, explicit canonical, web, and workflow configurations. Their regression test renders with an empty blob store. - Verification passed: `cargo check --workspace --all-targets`; unit suites for - `engine`, `tools`, `llm-runtime`, `temporal-server`, `temporal-workflow`, `api`, + `harness`, `tools`, `llm-runtime`, `temporal-runtime`, `temporal-workflow`, `api`, `api-projection`, `test-support`, `bots`, and `channels`; and the complete provider-request fixture comparison. Coverage includes engine event replay from a checkpoint, run model overrides, unknown aliases, collisions, diff --git a/docs/roadmap/archive/p61-crate-layout-and-architecture.md b/docs/roadmap/archive/p61-crate-layout-and-architecture.md index ad1322779..66d3e7b27 100644 --- a/docs/roadmap/archive/p61-crate-layout-and-architecture.md +++ b/docs/roadmap/archive/p61-crate-layout-and-architecture.md @@ -12,7 +12,7 @@ been updated to the new names. - The prototype Temporal package was split into `workflow`, `worker`, and `gateway`, then folded into the current `temporal-workflow` plus - `temporal-server` shape: `temporal-server` owns worker and gateway modules + `temporal-runtime` shape: `temporal-runtime` owns worker and gateway modules plus a `server` binary with `worker`, `gateway`, and combined modes. - Public deployable names, server metadata, task queue defaults, and local dev env vars have moved off the Claw codename. @@ -29,7 +29,7 @@ - Workflow admission now wraps a single encoded CoreAgent command. Gateway owns `run/start` input CAS writes and `CoreAgentCommand::RequestRun` construction; the old workflow-local text-run admission variant has been removed. -- The CLI no longer depends on `engine`; public session id validation now lives +- The CLI no longer depends on `harness`; public session id validation now lives at the `api` boundary. **Decision, 2026-05-30** @@ -50,9 +50,9 @@ Restructure the workspace so the crate layout matches the product runtime: ```text client -> api - -> temporal-server gateway module + -> temporal-runtime gateway module -> temporal-workflow - -> temporal-server worker activities + -> temporal-runtime worker activities -> engine -> store-pg / CAS ``` @@ -65,9 +65,9 @@ execution should no longer be maintained as a parallel production runtime. ```text crates/api/ client protocol DTOs, method constants, JSON-RPC envelopes/errors crates/api-projection/ engine log/state -> api views -crates/engine/ deterministic reducer, event log domain, drive machine +crates/harness/ deterministic reducer, event log domain, drive machine crates/temporal-workflow/ Temporal workflow, signals, queries, activity DTOs -crates/temporal-server/ hosted worker, HTTP/JSON-RPC gateway, and combined binary +crates/temporal-runtime/ hosted worker, HTTP/JSON-RPC gateway, and combined binary crates/tools/ host/tool package crates/llm-clients/ provider-native OpenAI/Anthropic clients crates/llm-runtime/ product LLM adapters from engine requests to llm-clients @@ -86,9 +86,9 @@ It should not expose a second supported `AgentApiService` implementation. ```text crates/agent-api/ -> crates/api/ crates/agent-projection/ -> crates/api-projection/ -crates/agent-core/ -> crates/engine/ +crates/agent-core/ -> crates/harness/ agents/claw/ -> split across workflow, worker, and gateway - -> current shape is temporal-workflow plus temporal-server modules + -> current shape is temporal-workflow plus temporal-runtime modules crates/agent-tools/ -> crates/tools/ crates/agent-eval/ -> crates/eval/ crates/agent-local/ -> remove or repurpose as crates/test-support/ @@ -109,7 +109,7 @@ Own the stable client boundary: - JSON-RPC request/response/notification envelopes - API error kinds and transport-neutral service traits -`api` must not depend on `engine`, Temporal, stores, provider clients, tools, or +`api` must not depend on `harness`, Temporal, stores, provider clients, tools, or gateway code. ### `api-projection` @@ -119,7 +119,7 @@ Project committed engine state and log entries into `api` views. It may depend on: - `api` -- `engine` +- `harness` - blob-store read traits needed to materialize user-visible text It must not admit commands, append events, execute tools, call LLM providers, or @@ -128,7 +128,7 @@ talk to Temporal. If the gateway becomes the only user of this crate, we can later fold it into `gateway`, but projection logic should not move into `api`. -### `engine` +### `harness` Own the central deterministic machinery: @@ -139,11 +139,11 @@ Own the central deterministic machinery: - tool request/result records required by the reducer - substrate-neutral drive actions -`engine` must stay deterministic. It must not perform provider calls, shell +`harness` must stay deterministic. It must not perform provider calls, shell commands, filesystem operations, network I/O, Temporal activities, or database I/O. -The rename from `agent-core` to `engine` is intentional. The crate is the +The rename from `agent-core` to `harness` is intentional. The crate is the central product engine, not a generic external SDK core. ### `temporal-workflow` @@ -154,13 +154,13 @@ Own Temporal workflow code and workflow-facing types: - signals and queries - workflow args - activity request/response DTOs -- Temporal helper types that must be shared by temporal-server gateway and +- Temporal helper types that must be shared by temporal-runtime gateway and worker modules `temporal-workflow` should contain orchestration logic only. Activity -implementations and process wiring belong in `temporal-server`. +implementations and process wiring belong in `temporal-runtime`. -### `temporal-server` +### `temporal-runtime` Own hosted runtime process concerns: @@ -176,7 +176,7 @@ Own hosted runtime process concerns: - future auth, tenancy, rate limits, and streaming transports The gateway and worker roles remain separate modules and runtime modes inside -`temporal-server`. Split deployment uses the `server gateway` and +`temporal-runtime`. Split deployment uses the `server gateway` and `server worker` subcommands; local and small deployments can use the combined mode. @@ -189,7 +189,7 @@ Own host/tool packages used by the product: - tool catalogs/profiles - tool runtime helpers -It may depend on `engine` for tool request/result types, but it should not +It may depend on `harness` for tool request/result types, but it should not depend on `gateway` or `temporal-workflow`. ### `llm-clients` @@ -208,7 +208,7 @@ crate while it has real tests and reuse. It should not grow into an SDK layer. Become API-first. -The normal CLI path should talk to the temporal-server gateway. Local mode +The normal CLI path should talk to the temporal-runtime gateway. Local mode should not require a separate production runtime; local development should run the local Temporal stack and the `server` binary in combined mode, or split `server worker` and `server gateway` processes when needed. A fast in-process @@ -337,7 +337,7 @@ Move in coarse, breaking slices: 1. Done. Rename `agent-api` to `api` and update imports. 2. Done. Rename `agent-projection` to `api-projection` and update imports. -3. Done. Rename `agent-core` to `engine` and update imports. +3. Done. Rename `agent-core` to `harness` and update imports. 4. Done. Split `agents/claw` into hosted workflow/runtime crates. 5. Done. Move activity implementations and worker binary into hosted runtime code. diff --git a/docs/roadmap/archive/p62-cas-vfs.md b/docs/roadmap/archive/p62-cas-vfs.md index 94b7392b6..da04a4531 100644 --- a/docs/roadmap/archive/p62-cas-vfs.md +++ b/docs/roadmap/archive/p62-cas-vfs.md @@ -4,7 +4,7 @@ - Complete for the accepted P62 scope. - Implemented: G1-G2.5, first-cut G3, first-cut G4, and G7 across `crates/vfs`, `crates/tools`, `crates/store-fs`, `crates/store-pg`, - `crates/api`, `crates/temporal-server`, and `crates/cli`. + `crates/api`, `crates/temporal-runtime`, and `crates/cli`. - Out of scope for P62 completion: G5 and the host-target portion of G6, deferred until real VM host targets exist. - Out of scope for P62 completion: G3 workspace quotas and mount policy limits, @@ -62,7 +62,7 @@ The missing abstraction is a stable, content-addressed filesystem tree. ## Non-Goals - Do not build a full POSIX filesystem in the first cut. -- Do not put VFS scanning, materialization, or path I/O in `engine`. +- Do not put VFS scanning, materialization, or path I/O in `harness`. - Do not require every VFS snapshot to be materialized into a Unix directory. - Do not make process execution work against CAS by pretending a process can see virtual paths. @@ -75,7 +75,7 @@ The missing abstraction is a stable, content-addressed filesystem tree. Build VFS as a runtime/storage concern, not as a reducer concern. -`engine` may store and replay `BlobRef`s that point at VFS manifests, and it +`harness` may store and replay `BlobRef`s that point at VFS manifests, and it may record context items whose payload is a VFS snapshot ref. It should not parse manifests, list directories, enforce mount policy, or perform I/O. @@ -721,7 +721,7 @@ later. Implementation note: expose commit refs as structured, non-model-visible tool result metadata. Prefer a generic tool-effect contract over embedding VFS -knowledge in `engine`; for VFS commits, carry the workspace id, new snapshot +knowledge in `harness`; for VFS commits, carry the workspace id, new snapshot manifest ref, and new revision inline. Do not write a separate effect blob just to link this metadata; use refs only when the effect naturally points at an existing CAS object or the metadata is too large for the event/result shape. diff --git a/docs/roadmap/archive/p63-skills.md b/docs/roadmap/archive/p63-skills.md index 835f32fcb..a81465588 100644 --- a/docs/roadmap/archive/p63-skills.md +++ b/docs/roadmap/archive/p63-skills.md @@ -5,7 +5,7 @@ - Accepted direction; remaining broader target-scoped work is deferred to follow-up roadmap items rather than blocking P63. - Depends on P62 for CAS-backed skill resource trees -- First-cut `engine` skill model types are implemented: +- First-cut `harness` skill model types are implemented: `SkillState`, skill ids, skill catalog/activation context item kinds, and active run/session-scoped activation records. - First-cut engine command/event/reducer wiring is implemented for setting the @@ -105,7 +105,7 @@ over CAS and host targets, not as engine-local process state. ## Non-Goals -- Do not execute skill scripts inside `engine`. +- Do not execute skill scripts inside `harness`. - Do not scan local worker filesystems for project skills in hosted mode. - Do not let a skill grant itself tools or permissions. - Do not require a Unix environment for instruction-only skills. @@ -856,7 +856,7 @@ provider request blob is the source of truth for the exact final text. ### Catalog Lifecycle And Context Injection -Skill headers are read during runtime catalog discovery, not inside `engine`. +Skill headers are read during runtime catalog discovery, not inside `harness`. Discovery reads each candidate `SKILL.md` enough to parse YAML frontmatter (`name`, `description`, and optional short description) and reads optional @@ -1159,7 +1159,7 @@ Mutating tools must still fail on read-only skill mounts. ## Discovery -Discovery is a runtime operation. It should never run in `engine`. +Discovery is a runtime operation. It should never run in `harness`. Inputs: @@ -1765,7 +1765,7 @@ Essential. ### G1: Skill Model And Parser -- Add skill metadata structs outside `engine`. +- Add skill metadata structs outside `harness`. - Use discriminated location/source structs rather than many optional fields. - Parse `SKILL.md` YAML frontmatter. - Parse optional `agents/lightspeed.yaml`. diff --git a/docs/roadmap/archive/p64-provider-native-compaction.md b/docs/roadmap/archive/p64-provider-native-compaction.md index 21c119f54..29e193d2b 100644 --- a/docs/roadmap/archive/p64-provider-native-compaction.md +++ b/docs/roadmap/archive/p64-provider-native-compaction.md @@ -96,7 +96,7 @@ fallback only when there is a concrete use case. - Do not implement compaction by default as a text-summary turn. - Do not ask the model to reinterpret provider-native opaque compaction items. -- Do not make `engine` call OpenAI, Anthropic, tokenizers, or any other +- Do not make `harness` call OpenAI, Anthropic, tokenizers, or any other provider service. - Do not put provider-specific JSON parsing into reducer logic beyond compact metadata required for deterministic branching. @@ -111,7 +111,7 @@ fallback only when there is a concrete use case. Compaction is a context-window operation, not a generic agent subroutine. -`engine` should own deterministic facts: +`harness` should own deterministic facts: - the active compaction policy, - whether a provider request is allowed or expected to trigger native diff --git a/docs/roadmap/archive/p65-prompt-management.md b/docs/roadmap/archive/p65-prompt-management.md index 2212e95fe..2c5b9a03f 100644 --- a/docs/roadmap/archive/p65-prompt-management.md +++ b/docs/roadmap/archive/p65-prompt-management.md @@ -39,9 +39,9 @@ Lightspeed's live instructions path is context-entry based: - `temporal-workflow` opens a session and upserts default instructions as `instructions.000.default`. -- `engine` accepts external instruction context edits only under +- `harness` accepts external instruction context edits only under `instructions.*` keys. -- `engine` plans instruction entries first, sorted by key. +- `harness` plans instruction entries first, sorted by key. - `llm-runtime` materializes OpenAI Responses instruction entries into the provider top-level `instructions` field by concatenating their text. - Skills use a different lane: `SkillCatalog` and `SkillActivation` context @@ -95,7 +95,7 @@ or deleted entries under the managed prefix in one deterministic context event. ## Non-Goals - Do not put VFS reads, host filesystem reads, file watches, or prompt assembly - in `engine`. + in `harness`. - Do not reintroduce `ContextConfig.instructions_ref`. - Do not add generic developer-message prompt files in G1. - Do not force heartbeat, bootstrap, or memory content into permanent session @@ -387,7 +387,7 @@ which provider paths actually receive instruction entries. ### G4: Gateway Pre-Run Refresh -- Add idle pre-run refresh helper in `temporal-server`. +- Add idle pre-run refresh helper in `temporal-runtime`. - Refresh prompts and skill catalog before `run/start` when idle. - Leave active/queued sessions unchanged in G1. - Add gateway tests for changed prompt files affecting the next run. diff --git a/docs/roadmap/archive/p66-minimal-web-access.md b/docs/roadmap/archive/p66-minimal-web-access.md index 9a61dd9a6..3e8a6beac 100644 --- a/docs/roadmap/archive/p66-minimal-web-access.md +++ b/docs/roadmap/archive/p66-minimal-web-access.md @@ -83,7 +83,7 @@ https://developers.openai.com/api/docs/guides/tools-web-search credentials, or internal-network access. - Do not implement browser automation or page interaction. - Do not make OpenAI Chat Completions search models part of the first cut. -- Do not make `engine` perform provider calls, network I/O, DNS resolution, or +- Do not make `harness` perform provider calls, network I/O, DNS resolution, or page extraction. - Do not parse web-search result content in reducers for branching decisions. @@ -179,7 +179,7 @@ disables the provider-native search tool for a session. ### G1 Implementation Shape -Keep the provider-native tool builder outside `engine`. +Keep the provider-native tool builder outside `harness`. Candidate crate shape: diff --git a/docs/roadmap/archive/p67-direct-remote-mcp.md b/docs/roadmap/archive/p67-direct-remote-mcp.md index ccb5dba68..7cf2cec3b 100644 --- a/docs/roadmap/archive/p67-direct-remote-mcp.md +++ b/docs/roadmap/archive/p67-direct-remote-mcp.md @@ -65,7 +65,7 @@ blocks are **context observations**. Do not model provider-discovered MCP tools as Lightspeed `ToolSpec`s in the first cut. Use a `ToolKind::RemoteMcp` variant in the active session tool map, not a -standalone MCP subsystem in `engine`: +standalone MCP subsystem in `harness`: ```rust pub enum ToolKind { @@ -94,14 +94,14 @@ P69. - Do not put bearer tokens, OAuth access tokens, cookies, or API keys in engine events, CAS blobs, planned request records, or stored provider request blobs. -- Do not make `engine` perform MCP list-tools calls, MCP tool calls, HTTP +- Do not make `harness` perform MCP list-tools calls, MCP tool calls, HTTP transport, OAuth refresh, DNS resolution, or connectivity checks. - Do not parse MCP tool results in reducers for branching decisions unless a later milestone introduces a concrete deterministic fact. ## Core Model -`engine` has a declarative, non-secret MCP server spec: +`harness` has a declarative, non-secret MCP server spec: ```rust pub struct RemoteMcpToolSpec { @@ -160,7 +160,7 @@ emit `ToolEvent::CallStarted` for direct MCP. The turn planner reads `RemoteMcp` specs from the same active tool map as function and provider-native tools. -`engine` should preserve provider compatibility without knowing provider wire +`harness` should preserve provider compatibility without knowing provider wire details. A `RemoteMcp` spec is compatible with provider API kinds that have a runtime lowering implementation: @@ -249,7 +249,7 @@ for example: ``` Anthropic MCP may require a provider beta header. That belongs in provider -client/runtime configuration, not in `engine`. +client/runtime configuration, not in `harness`. ## Secret Injection And Redaction @@ -275,7 +275,7 @@ required for that spec and resolution either succeeds or fails the generation with a typed error before provider I/O. Optional auth is expressed by `auth_ref: None`, decided at link/config time. `ResolvedSecretValue` is a wrapper whose `Debug` output is redacted. `llm-runtime` owns this trait and -stays free of auth-store dependencies; `temporal-server` adapts the P69 broker +stays free of auth-store dependencies; `temporal-runtime` adapts the P69 broker to it and dispatches on `SecretRef.namespace` (`auth_grant` -> broker, `env` -> environment lookup for development). @@ -387,7 +387,7 @@ It is an observation of what the server returned for a given call. Suggested first-cut changes: ```text -crates/engine/src/core/components/tooling.rs +crates/harness/src/core/components/tooling.rs RemoteMcpToolSpec RemoteMcpApprovalPolicy SecretRef diff --git a/docs/roadmap/archive/p68-remote-mcp-registry-linking.md b/docs/roadmap/archive/p68-remote-mcp-registry-linking.md index e2b5c58a4..f3fdc0f6f 100644 --- a/docs/roadmap/archive/p68-remote-mcp-registry-linking.md +++ b/docs/roadmap/archive/p68-remote-mcp-registry-linking.md @@ -84,7 +84,7 @@ lightspeed mcp link --session session_1 crm --auth-grant authgrant_123 The engine remains deterministic. It records only the sanitized MCP server spec and an optional auth reference in the event-sourced tool registry. Server catalog edits, metadata discovery, OAuth, token refresh, secret storage, and -connectivity checks are outside `engine`. +connectivity checks are outside `harness`. ## Relationship To P67 And P69 @@ -145,7 +145,7 @@ link either omits auth for public servers or names the auth handle to use. - Do not implement OAuth flows in P68. - Do not implement encrypted secret storage in P68. - Do not implement token refresh or a runtime token broker in P68. -- Do not make `engine` perform MCP HTTP discovery, tool listing, OAuth, token +- Do not make `harness` perform MCP HTTP discovery, tool listing, OAuth, token lookup, or secret resolution. - Do not implement a Lightspeed-hosted MCP bridge/client runtime. - Do not implement private/on-prem tunnels. @@ -348,7 +348,7 @@ crates/api/src/mcp.rs public request/response DTOs for server registry and session linking auth policy and auth handle refs, never plaintext tokens -crates/temporal-server/src/mcp/ +crates/temporal-runtime/src/mcp/ JSON-RPC handlers for catalog and linking operations optional non-secret metadata discovery @@ -431,11 +431,11 @@ Acceptance criteria: - discovered non-secret auth hints populate `McpServerAuthPolicy`; - failures produce explicit server status without blocking manual no-auth registration; -- metadata discovery runs outside `engine`. +- metadata discovery runs outside `harness`. ## Future Work -- MCP server health checks and preflight tool listing outside `engine`. +- MCP server health checks and preflight tool listing outside `harness`. - Hosted UI for managing MCP servers and session links. - MCP-specific convenience wrappers over P69 auth login/status/revoke commands. - Approval UI for provider-hosted MCP calls where provider APIs surface diff --git a/docs/roadmap/archive/p69-generic-auth-token-broker.md b/docs/roadmap/archive/p69-generic-auth-token-broker.md index adcc3ea84..9ee67e99d 100644 --- a/docs/roadmap/archive/p69-generic-auth-token-broker.md +++ b/docs/roadmap/archive/p69-generic-auth-token-broker.md @@ -126,7 +126,7 @@ Placement rules: (`engine::LlmGenerationRequest` with `SecretRef`s); the activity body resolves refs immediately before the provider call; - `llm-runtime` owns a narrow `SecretResolver` trait and stays free of auth - and store dependencies. `temporal-server` adapts the broker to that trait + and store dependencies. `temporal-runtime` adapts the broker to that trait and dispatches on `SecretRef.namespace` (`auth_grant` -> broker, `env` -> env resolver for development). @@ -196,7 +196,7 @@ SecretRef { } ``` -`engine` never resolves that reference. Runtime adapters and gateways ask P69's +`harness` never resolves that reference. Runtime adapters and gateways ask P69's token broker for a current token. ## Provider Kinds @@ -631,7 +631,7 @@ crates/api/src/lib.rs public auth grant DTOs and methods secret refs and statuses, never durable plaintext tokens -crates/temporal-server/src/gateway + worker +crates/temporal-runtime/src/gateway + worker auth/grants JSON-RPC handlers broker -> llm-runtime SecretResolver adapter in the worker later: callback handling, refresh, lease orchestration @@ -646,7 +646,7 @@ crates/llm-runtime/src/secrets.rs The narrow shared crate exists from the start (`auth`, mirroring the `mcp` precedent) rather than waiting for shared code to grow. Dependency direction is deliberate: `llm-runtime` defines its own resolver -boundary and never depends on `auth` or `store-pg`; `temporal-server` +boundary and never depends on `auth` or `store-pg`; `temporal-runtime` adapts the broker to that boundary. Keep provider drivers behind traits so `oauth2`, GitHub client helpers, or MCP SDK helpers can be swapped without schema churn. @@ -908,7 +908,7 @@ typed failure before provider I/O. Adapter registration no longer requires env keys at startup; a deployment can run on stored keys alone. Boundary shape mirrors `SecretResolver`: `llm-runtime` owns a narrow -`ProviderKeyResolver` trait (no auth/store dependencies); `temporal-server` +`ProviderKeyResolver` trait (no auth/store dependencies); `temporal-runtime` adapts the universe-bound provider/secret stores to it. Resolution does not go through `AuthTokenBroker` — that boundary is grant-keyed and there is no grant; it is a provider-row read plus secret decrypt behind the trait. diff --git a/docs/roadmap/archive/p70-external-integration-surface.md b/docs/roadmap/archive/p70-external-integration-surface.md index 5c1f9318b..fc6f5567e 100644 --- a/docs/roadmap/archive/p70-external-integration-surface.md +++ b/docs/roadmap/archive/p70-external-integration-surface.md @@ -64,7 +64,7 @@ Consequences worth stating as product contract: No wait/long-poll parameter, no SSE/WebSocket. - `RunStartParams` has no client-supplied idempotency key. The engine already threads `Option` through `CoreAgentCommand::RequestRun` into - `RunEvent::Accepted` (`crates/engine/src/core/admit.rs`), but the gateway + `RunEvent::Accepted` (`crates/harness/src/core/admit.rs`), but the gateway never sets it and nothing deduplicates on it. - The gateway has no per-request auth. For this deployment the network boundary (Tailscale ACLs) is the access control; see Non-Goals. @@ -294,7 +294,7 @@ work: Python client, opt-in gateway smoke tests, and CI drift checks. Messaging bridge overlay implemented 2026-06-11: `interop/messaging/` contains a private Node package for Telegram and WhatsApp. It depends on -`@lightspeed-ai/agent-client` via `file:../ts-client`, maps each chat/thread to a +`@lightspeed-ai/sdk` via `file:../ts-client`, maps each chat/thread to a stable Lightspeed session, uses stable submission ids for channel message retries, long-polls run completion through the JSON-RPC API, and keeps channel state/dedupe in a local JSON store. This does not change the gateway contract; @@ -326,7 +326,7 @@ selecting a gateway base URL. universe's sessions against the wrong store; deriving the queue from the universe makes that isolation impossible to misconfigure silently. Gateway and worker derive the same default from the shared config path. - Implemented 2026-06-11 (`task_queue_from_env` in `temporal-server`). + Implemented 2026-06-11 (`task_queue_from_env` in `temporal-runtime`). ## Non-Goals diff --git a/docs/roadmap/archive/p71-messaging-channel-gateway.md b/docs/roadmap/archive/p71-messaging-channel-gateway.md index 7f238a86c..58d6f64f5 100644 --- a/docs/roadmap/archive/p71-messaging-channel-gateway.md +++ b/docs/roadmap/archive/p71-messaging-channel-gateway.md @@ -349,14 +349,14 @@ Acceptance criteria: - [x] duplicate append with the same idempotency key is a no-op. Implemented 2026-06-12: the entry key is the idempotency handle (no separate -submission id). `crates/engine` now admits `Message { role: User }` entries +submission id). `crates/harness` now admits `Message { role: User }` entries through external context edits on non-reserved keys and skips identical upserts as no-ops (`admit.rs`, `context.rs`); assistant-role edits remain rejected. The gateway adds `context/append` (`crates/api` method + -`temporal-server` handler with CAS materialization, unchanged-key pre-check, +`temporal-runtime` handler with CAS materialization, unchanged-key pre-check, and `wait_for_context_entries_applied`). Contract artifacts and the TS client are regenerated. End-to-end coverage in -`crates/temporal-server/tests/sessions_live.rs` +`crates/temporal-runtime/tests/sessions_live.rs` (`temporal_live_context_append_is_idempotent_and_projected`); the bridge batches room events per chat (flush every 30s / 20 events, budget 50 with drop reporting) and drains the buffer before an activating turn. diff --git a/docs/roadmap/archive/p72-audio-transcription-preprocessing.md b/docs/roadmap/archive/p72-audio-transcription-preprocessing.md index 1b33961da..f084fd12b 100644 --- a/docs/roadmap/archive/p72-audio-transcription-preprocessing.md +++ b/docs/roadmap/archive/p72-audio-transcription-preprocessing.md @@ -275,7 +275,7 @@ Completed 2026-06-16: Partial 2026-06-16: -- Added `crates/temporal-server/tests/preprocess_live.rs`, an ignored live +- Added `crates/temporal-runtime/tests/preprocess_live.rs`, an ignored live Temporal/Postgres admission test that submits `audio/ogg` through `run/start`, injects a deterministic fake transcriber, and verifies the admitted run input contains transcript text instead of the raw audio preview. diff --git a/docs/roadmap/archive/p74-planned-request-event-bloat.md b/docs/roadmap/archive/p74-planned-request-event-bloat.md index 57d47338f..3407b31dd 100644 --- a/docs/roadmap/archive/p74-planned-request-event-bloat.md +++ b/docs/roadmap/archive/p74-planned-request-event-bloat.md @@ -37,14 +37,14 @@ Every `lightspeed.core.turn.planned` event embeds a full `LlmRequest`: ```rust -// crates/engine/src/core/components/turn.rs +// crates/harness/src/core/components/turn.rs Planned { turn_id: TurnId, run_id: RunId, request: LlmRequest, }, -// crates/engine/src/core/components/llm.rs +// crates/harness/src/core/components/llm.rs pub struct LlmRequest { pub model: ModelSelection, pub request_fingerprint: String, diff --git a/docs/roadmap/archive/p76-environment-runtime-projection.md b/docs/roadmap/archive/p76-environment-runtime-projection.md index 8aaa31161..47560f59a 100644 --- a/docs/roadmap/archive/p76-environment-runtime-projection.md +++ b/docs/roadmap/archive/p76-environment-runtime-projection.md @@ -26,7 +26,7 @@ file tools on `fs:session` from process tools requiring an active `env` target. - Regenerated API contract artifacts and TypeScript generated types. - Verified with: - `cargo test -p engine -p api -p api-projection -p tools -p llm-runtime -p temporal-workflow -p temporal-server -p test-support --tests` + `cargo test -p harness -p api -p api-projection -p tools -p llm-runtime -p temporal-workflow -p temporal-runtime -p test-support --tests` - Verified TypeScript client with: `npm run typecheck && npm run test && npm run build` in `clients/typescript`. diff --git a/docs/roadmap/archive/p77-session-environment-manager.md b/docs/roadmap/archive/p77-session-environment-manager.md index 478b46c5c..917b09c50 100644 --- a/docs/roadmap/archive/p77-session-environment-manager.md +++ b/docs/roadmap/archive/p77-session-environment-manager.md @@ -10,7 +10,7 @@ **Progress** - Added a shared environment projection planner in `tools::environment::projection`. -- Added `temporal_server::environment::SessionEnvironmentManager` as the hosted +- Added `temporal_runtime::environment::SessionEnvironmentManager` as the hosted owner for session environment projection refreshes. - Replaced duplicated projection command construction in the gateway, Temporal worker skill-refresh activity, and in-process test runner. @@ -18,9 +18,9 @@ ownership boundary; it does not add a sandbox provider or local process executor. - Verified with: - `cargo test -p tools -p temporal-server -p test-support --tests` + `cargo test -p tools -p temporal-runtime -p test-support --tests` - After the final cleanup, verified the manager compile path with: - `cargo test -p temporal-server environment::tests::manager_projects_active_environment_from_default_env_target --lib` + `cargo test -p temporal-runtime environment::tests::manager_projects_active_environment_from_default_env_target --lib` ## Goal @@ -52,7 +52,7 @@ Use two layers: - `tools::environment::projection` owns pure snapshot planning and CAS-backed command preparation. -- `temporal-server::environment::SessionEnvironmentManager` owns hosted runtime +- `temporal-runtime::environment::SessionEnvironmentManager` owns hosted runtime inputs: VFS mounts now, environment records and active selection next. The deterministic engine still only sees ordinary context upsert/remove @@ -82,7 +82,7 @@ The planner: ### G2: Hosted Manager Boundary -Add `SessionEnvironmentManager` in `temporal-server`. +Add `SessionEnvironmentManager` in `temporal-runtime`. The manager currently owns: @@ -107,7 +107,7 @@ Route the existing refresh paths through the shared planner/manager: The gateway remains responsible for submitting commands and waiting for context entries to apply. The worker remains responsible for composing environment projection refresh with skill-catalog refresh. Test-support calls the pure -planner directly to avoid a dependency cycle on `temporal-server`. +planner directly to avoid a dependency cycle on `temporal-runtime`. ## Non-Goals @@ -125,4 +125,4 @@ planner directly to avoid a dependency cycle on `temporal-server`. - The in-process runner uses the same pure planner as hosted code. - Existing P76 behavior is preserved for VFS-only sessions: publish VFS catalog, publish empty environment catalog, and clear active environment. -- Focused tools, temporal-server, and test-support tests pass. +- Focused tools, temporal-runtime, and test-support tests pass. diff --git a/docs/roadmap/archive/p78-active-environment-runtime-wiring.md b/docs/roadmap/archive/p78-active-environment-runtime-wiring.md index c56dd658c..b06b32621 100644 --- a/docs/roadmap/archive/p78-active-environment-runtime-wiring.md +++ b/docs/roadmap/archive/p78-active-environment-runtime-wiring.md @@ -21,7 +21,7 @@ - Added a fake-process environment test proving a single runtime can read VFS files through `fs:session` and execute a command through `env:test`. - Verified with: - `cargo test -p temporal-server -p tools -p llm-runtime --tests` + `cargo test -p temporal-runtime -p tools -p llm-runtime --tests` ## Goal @@ -99,4 +99,4 @@ The test proves: - Active environment projection is non-empty when the default env target points at a registered environment. - A fake process environment test covers file-tool plus process-tool routing. -- Focused tools, LLM-rendering, and temporal-server tests pass. +- Focused tools, LLM-rendering, and temporal-runtime tests pass. diff --git a/docs/roadmap/archive/p79-session-environment-api.md b/docs/roadmap/archive/p79-session-environment-api.md index 80052b7cd..700d16293 100644 --- a/docs/roadmap/archive/p79-session-environment-api.md +++ b/docs/roadmap/archive/p79-session-environment-api.md @@ -23,7 +23,7 @@ API activation and model-visible context share the same registry. - Regenerated committed API contract artifacts under `crates/api/contract/`. - Verified with: - `cargo test -p api -p temporal-server --tests` + `cargo test -p api -p temporal-runtime --tests` - Also checked adjacent environment/runtime crates with: `cargo test -p tools -p llm-runtime -p api-projection -p test-support --tests` diff --git a/docs/roadmap/archive/p80-environment-provider-registry.md b/docs/roadmap/archive/p80-environment-provider-registry.md index cdf48b440..8bb08e725 100644 --- a/docs/roadmap/archive/p80-environment-provider-registry.md +++ b/docs/roadmap/archive/p80-environment-provider-registry.md @@ -53,7 +53,7 @@ capacity is bound to a session environment. ## Process Boundary -Keep the registry in `temporal-server` first. +Keep the registry in `temporal-runtime` first. This is a separate API boundary, not necessarily a separate service boundary. Splitting into a standalone provider-registry service is a deployment decision @@ -489,7 +489,7 @@ session environment. Implemented as ignored live test `temporal_live_fake_provider_create_attach_and_process_tool` in -`crates/temporal-server/tests/environment_provider_live.rs`. It starts an +`crates/temporal-runtime/tests/environment_provider_live.rs`. It starts an in-process WebSocket fake provider, registers it through the gateway, exercises heartbeat/listTargets, bridge-style attach, sandbox-style create, process tool execution through the environment data plane, and close/detach semantics. diff --git a/docs/roadmap/archive/p81-guest-os-bridge-runner.md b/docs/roadmap/archive/p81-guest-os-bridge-runner.md index 116d47544..bc95a0c8a 100644 --- a/docs/roadmap/archive/p81-guest-os-bridge-runner.md +++ b/docs/roadmap/archive/p81-guest-os-bridge-runner.md @@ -88,7 +88,7 @@ crates/host-bridge/ Working binary name: `host-bridge`. The runner may depend on `api`, `environment-protocol`, and small transport helpers. It -must not depend on `cli`, `temporal-server`, `store-pg`, `engine`, or any +must not depend on `cli`, `temporal-runtime`, `store-pg`, `harness`, or any workflow/runtime crate. The dependency direction should be: ```text @@ -99,7 +99,7 @@ host-bridge -> transport/json-rpc helper code If the existing JSON-RPC/WebSocket mechanics are too client-oriented, extract a small shared helper crate instead of making the runner depend on -`temporal-server`. +`temporal-runtime`. ## Runner Model @@ -392,7 +392,7 @@ fake provider only simulated. ## Done When -- A standalone `host-bridge` binary can run outside `temporal-server` and +- A standalone `host-bridge` binary can run outside `temporal-runtime` and outside the Lightspeed CLI. - The runner registers and heartbeats as a bridge provider. - The gateway can attach its `local` target to a session and activate it. diff --git a/docs/roadmap/archive/p83-fleet-subagent-control-plane.md b/docs/roadmap/archive/p83-fleet-subagent-control-plane.md index 14dc0b453..a43ffd719 100644 --- a/docs/roadmap/archive/p83-fleet-subagent-control-plane.md +++ b/docs/roadmap/archive/p83-fleet-subagent-control-plane.md @@ -106,9 +106,9 @@ parent model tool call ``` Starting another top-level workflow is a side effect. It belongs in an activity -or runtime service, not in `engine` and not in pure workflow reducer code. +or runtime service, not in `harness` and not in pure workflow reducer code. -The first hosted implementation should live in `temporal-server`. No new registry +The first hosted implementation should live in `temporal-runtime`. No new registry crate is introduced for v1; revisit one only if `agent_id` ever diverges from `session_id`. @@ -424,12 +424,12 @@ workflows by default. - Toolset exposure is wired through `crates/tools/src/toolset.rs` with a `FleetToolsetConfig`. The gateway's session-toolset assembly enables it from the per-session config gate. -- Hosted execution lives in `temporal-server`, for example - `crates/temporal-server/src/fleet.rs` plus worker wiring. `FleetService` owns +- Hosted execution lives in `temporal-runtime`, for example + `crates/temporal-runtime/src/fleet.rs` plus worker wiring. `FleetService` owns the runtime behavior: source resolution, deterministic child id derivation, P82 clone/fork calls, VFS policy application, link upsert, workflow start, and child run admission. -- `SessionTools` in `crates/temporal-server/src/worker/session_tools.rs` routes +- `SessionTools` in `crates/temporal-runtime/src/worker/session_tools.rs` routes `agent_*` calls to the Fleet executor directly, similar to the existing messaging fast path. The generic `InlineToolRuntime` currently executes only builtins/web-fetch style bindings, so exposing Fleet specs in the toolset is @@ -523,7 +523,7 @@ setup pass and reuse the deterministic child run submission id. `call_id`. - Ensure Fleet tool execution uses the same blob/result shape as other tools and returns compact model-visible handles/status. -- Keep all Fleet side effects out of `engine` and deterministic workflow reducer +- Keep all Fleet side effects out of `harness` and deterministic workflow reducer code. Implementation note: hosted workers inject a Fleet executor into `SessionTools` @@ -629,4 +629,4 @@ workflow plus initial and follow-up child runs complete. - The parent can cancel a child's active run or close the child session. - The model-visible tool surface stays small (4 tools) and does not expose the full session API. -- No Fleet side effects are performed inside `engine`. +- No Fleet side effects are performed inside `harness`. diff --git a/docs/roadmap/archive/p84-fleet-wait-and-callbacks.md b/docs/roadmap/archive/p84-fleet-wait-and-callbacks.md index 0eefd5ad6..cb76af448 100644 --- a/docs/roadmap/archive/p84-fleet-wait-and-callbacks.md +++ b/docs/roadmap/archive/p84-fleet-wait-and-callbacks.md @@ -41,7 +41,7 @@ Give a supervisor agent two missing capabilities: Both must slot cleanly into the Temporal runtime, support **hours-to-days** waits cheaply, and keep wall-clock / side-effect logic out of the deterministic -`engine` core. +`harness` core. ## Temporal Primitives We Rely On (Confirmed) @@ -123,7 +123,7 @@ timeout_ms? int (default: none) - `mode = any` — `select`: resolve when the **first** named run is terminal (the result reports which). - Each run resolves on `Completed`, `Failed`, or `Cancelled` - (`crates/engine/src/core/components/run.rs:88`), observed from the target itself + (`crates/harness/src/core/components/run.rs:88`), observed from the target itself (see Runtime Shape) — so it works even if a child never calls `agent_send` or crashes mid-task and is retried. - `timeout_ms` is **optional** with **no default**: absent, the wait is indefinite @@ -298,7 +298,7 @@ it is produced later, when the joined runs reach terminal. The engine gains a user and nothing in the engine knows about Fleet. This must fit the engine's existing batch contract precisely -(`crates/engine/src/core/`): +(`crates/harness/src/core/`): - A run has **one `active_tool_batch_id` at a time** (`run.rs:70`), and a batch completes **all-or-nothing**: `validate_tool_batch_result` (`drive.rs:579`) @@ -472,7 +472,7 @@ is not an activity, it is the target workflow's own durable terminal handler. `agent_task` (parent -> child) and a child -> parent callback are **the same runtime primitive**: admit a `RequestRun` on another session via -`signal_submit_admission` (`crates/temporal-server/src/gateway/service/workflow.rs:28`). +`signal_submit_admission` (`crates/temporal-runtime/src/gateway/service/workflow.rs:28`). There is no second transport. Two direction-locked tools (`agent_task` down, `agent_notify` up) bake a **tree** @@ -758,7 +758,7 @@ address-an-existing-agent surface. P84 standardizes the whole Fleet surface on This is a **wire-contract change**: it touches the strict JSON schemas, the committed contract artifacts under `crates/api/contract/`, the hosted Fleet executor -in `crates/temporal-server/src/fleet.rs`, and the deterministic Fleet tests that +in `crates/temporal-runtime/src/fleet.rs`, and the deterministic Fleet tests that assert field names. Regenerate artifacts via `cargo run -p api --bin export-schema` and update P83's tool-contract prose. Bundled into P84's S1 so the rename and the new tools land in one contract revision. @@ -770,7 +770,7 @@ rename and the new tools land in one contract revision. (`waits: [{target_session_id, run_id}]`, `mode: all|any`, optional `timeout_ms`); add the optional `report_back` directive to `agent_spawn`. Strict schemas; tool names; `ToolSpecBundle` entries. No Postgres/Temporal deps here. -- `crates/engine/src/core/`: +- `crates/harness/src/core/`: - Add the **generic deferred-tool-batch** primitive that fits the existing batch contract: a single-call batch may return `ToolBatchOutcome::Deferred { batch_id, resume_directive }` (opaque runtime blob @@ -802,7 +802,7 @@ rename and the new tools land in one contract revision. unsubscribe open handles best-effort. - **Continue-as-new guard**: extend `can_continue_as_new_at_idle` (`:724`) to be false while any `RunSubscription` or active wait exists. -- `crates/temporal-server/src/`: +- `crates/temporal-runtime/src/`: - `fleet.rs`: `agent_send` resolution (`parent` via link / `session` by id), `session_link` edge check (else `not_reachable`), envelope-encode `payload`, admit recipient run with derived `submission_id`; diff --git a/docs/roadmap/archive/p85-agent-profiles.md b/docs/roadmap/archive/p85-agent-profiles.md index 857f9fd97..a52dd49c2 100644 --- a/docs/roadmap/archive/p85-agent-profiles.md +++ b/docs/roadmap/archive/p85-agent-profiles.md @@ -46,7 +46,7 @@ P85 is implemented end-to-end with these concrete pieces: - **Postgres registry** in `crates/store-pg/`: migration `006_agent_profiles.sql` and `PgStore`'s `ProfileStore` implementation with optimistic revision checks and document JSONB storage. -- **Hosted runtime applier** in `temporal-server`: resolves named or inline +- **Hosted runtime applier** in `temporal-runtime`: resolves named or inline `ProfileSource`, merges profile config into `session/start` with explicit start config winning at the top level, and applies existing-session profiles in order: config, instructions, mounts, MCP, environments. Apply is convergent: @@ -75,15 +75,15 @@ cargo test -p api cargo test -p tools cargo test -p cli --tests cargo test -p store-pg --lib -cargo test -p temporal-server +cargo test -p temporal-runtime npm --prefix clients/typescript run test npm --prefix clients/typescript run typecheck npm --prefix interop/messaging run test:bridge npm --prefix interop/messaging run typecheck:bridge npm --prefix interop/messaging run build:bridge -source scripts/dev/env.sh && cargo test -p temporal-server --test profiles_live temporal_live_profiles_create_start_and_apply_idempotently -- --ignored --exact --nocapture -source scripts/dev/env.sh && cargo test -p temporal-server --test subagents_live temporal_live_fleet_executor_spawns_profile_child -- --ignored --exact --nocapture -source scripts/dev/env.sh && cargo test -p temporal-server --test environment_provider_live temporal_live_profile_attaches_host_environment -- --ignored --exact --nocapture +source scripts/dev/env.sh && cargo test -p temporal-runtime --test profiles_live temporal_live_profiles_create_start_and_apply_idempotently -- --ignored --exact --nocapture +source scripts/dev/env.sh && cargo test -p temporal-runtime --test subagents_live temporal_live_fleet_executor_spawns_profile_child -- --ignored --exact --nocapture +source scripts/dev/env.sh && cargo test -p temporal-runtime --test environment_provider_live temporal_live_profile_attaches_host_environment -- --ignored --exact --nocapture ``` ## Goal @@ -155,7 +155,7 @@ boundary rather than in a separate crate: 3. **`crates/store-pg/src/profile.rs`** + migration `006_agent_profiles.sql` — the Postgres-backed `ProfileStore`. A profile catalog table, exactly like the MCP server catalog (`003_mcp.sql`) and environment registry (`006_*`). -4. **profile applier** in the hosted runtime (`temporal-server`) — resolves a +4. **profile applier** in the hosted runtime (`temporal-runtime`) — resolves a profile reference to a concrete `AgentProfile`, then applies it against a target session through the internal `AgentApiService` and resource stores (the same calls the bridge makes today, now in Rust). @@ -423,13 +423,13 @@ bridge starts the session with `tools.messaging = true`. ## Crash / Idempotency / Determinism - The registry is plain CRUD storage; no determinism concern (it is read by the - applier, never by `engine`). + applier, never by `harness`). - **Apply is idempotent and convergent**: keyed per mount/link/environment so a retry (tool-activity retry on `agent_spawn`, bridge retry, gateway restart mid-apply) re-issues only missing steps. This is the same property the bridge's old `startedSessions` set approximated, made real. - For `agent_spawn`, application happens in the **Fleet tool activity / hosted - runtime** (outside `engine`), exactly where P83 already does clone/fork/link + runtime** (outside `harness`), exactly where P83 already does clone/fork/link side effects. The engine learns nothing about profiles. The spawned child run's `submission_id` is still derived from the parent tool identity (P83), so spawn retries do not double-provision or double-admit. @@ -453,7 +453,7 @@ bridge starts the session with `tools.messaging = true`. Postgres `ProfileStore` impl and an `agent_profiles` catalog table (id, display_name, description, revision, document JSONB, timestamps). (Pattern: `mcp.rs` / `003_mcp.sql`.) -- `crates/temporal-server/`: +- `crates/temporal-runtime/`: - **Profile applier**: resolve a `ProfileSource` (registry lookup for `named`, verbatim for `inline`; no merging), then apply to a session via internal `AgentApiService` + VFS/MCP/environment stores in the canonical order, @@ -588,7 +588,7 @@ bridge starts the session with `tools.messaging = true`. - The **messaging bridge provisions through native profiles** (named id shorthand or inline `ProfileSource`). Legacy recipe JSON is rejected instead of converted; the bridge's manual mount/link/attach provisioning loop is gone. -- No profile logic lives in `engine`; the applier runs in the hosted runtime +- No profile logic lives in `harness`; the applier runs in the hosted runtime exactly where P83 performs clone/fork/link side effects. - Fleet children provisioned from a profile record the requested `ProfileSource` in spawn-link metadata so `agent_read` can explain profile-based child @@ -709,7 +709,7 @@ tables and indexes). Only the API exposure layer is missing. Implemented following the existing `environmentProviders/register` pattern: new method constants + params/response DTOs in `crates/api/`, two `api_methods!` -entries, two gateway handler wrappers in `temporal-server` that call the +entries, two gateway handler wrappers in `temporal-runtime` that call the existing store methods and reuse the existing `environment_provider_view` / `environment_target_summary_view` mappers. Contract artifacts and the generated TS client were regenerated. No store, schema, or migration changes. diff --git a/docs/roadmap/archive/p86-durable-environment-jobs.md b/docs/roadmap/archive/p86-durable-environment-jobs.md index 5faa8a6aa..8d8c3c57d 100644 --- a/docs/roadmap/archive/p86-durable-environment-jobs.md +++ b/docs/roadmap/archive/p86-durable-environment-jobs.md @@ -745,7 +745,7 @@ Reasoning: - a separate poller workflow would still have to signal the session workflow to resume the batch, adding lifecycle, cancellation, idempotency, and ownership surfaces without removing the need for session-side wait state; -- the specific job logic can be kept out of `engine` and isolated in the +- the specific job logic can be kept out of `harness` and isolated in the Temporal runtime as a directive handler, beside the existing Fleet wait handler. @@ -759,7 +759,7 @@ ActiveDeferredWait environment_job_wait(...) new P86 shape ``` -The deterministic `engine` still only sees a parked tool batch and a later +The deterministic `harness` still only sees a parked tool batch and a later `ResumeToolBatch`. ### Active Job Wait Record @@ -982,7 +982,7 @@ Job handle records must still avoid accidental leakage: - Add toolset config gate for environment jobs. - Start defaults through the active `env` target but supports explicit `env_id`; read/wait/cancel use job handles with optional `env_id` defaulting. -- Add tool executor logic in `temporal-server` that can return deferred outcomes +- Add tool executor logic in `temporal-runtime` that can return deferred outcomes for lone `job_wait` batches. ### G5. Workflow Wait Integration diff --git a/docs/roadmap/archive/p87-environment-credential-injection.md b/docs/roadmap/archive/p87-environment-credential-injection.md index 32257a339..42903d91a 100644 --- a/docs/roadmap/archive/p87-environment-credential-injection.md +++ b/docs/roadmap/archive/p87-environment-credential-injection.md @@ -260,7 +260,7 @@ failing is clearer than silently shadowing caller input. ## Environment Protocol And Bridge `run_process` and `job_submit` have an internal resolved-secret-env path -between `temporal-server` and the active `JobExecutor`/`ProcessExecutor`. This +between `temporal-runtime` and the active `JobExecutor`/`ProcessExecutor`. This path is not exposed in model-visible or public API DTOs. The environment data-plane request can carry: @@ -347,7 +347,7 @@ records, not in the environment binding row. - [x] Load credential bindings when constructing runtime environments or immediately before process/job spawn. -- [x] Resolve bindings in `temporal-server` runtime code, outside workflow replay. +- [x] Resolve bindings in `temporal-runtime` runtime code, outside workflow replay. - [x] Merge resolved credential env into environment process/job starts. - [x] Reject caller `env` entries that collide with bound credential env names. @@ -362,7 +362,7 @@ records, not in the environment binding row. - [x] Store tests for credential binding behavior. - [x] API tests for bind/list/unbind JSON-RPC routing. -- [x] Runtime wiring covered by temporal-server and tools tests. +- [x] Runtime wiring covered by temporal-runtime and tools tests. - [x] Bridge tests that process/job starts receive hidden env vars and redacted output does not persist resolved values. - [ ] Runtime tests that `run_process` and `job_submit` receive bound env vars diff --git a/docs/roadmap/archive/p88-media-aware-context-append-and-activation.md b/docs/roadmap/archive/p88-media-aware-context-append-and-activation.md index ac896c801..a07e813dd 100644 --- a/docs/roadmap/archive/p88-media-aware-context-append-and-activation.md +++ b/docs/roadmap/archive/p88-media-aware-context-append-and-activation.md @@ -104,7 +104,7 @@ concepts. and documents become model-visible media/document context exactly as `run/start` admits them today. - No channel-specific methods or server-side channel policy. -- No provider calls or filesystem/network side effects inside `engine`. +- No provider calls or filesystem/network side effects inside `harness`. ## API Shape @@ -322,7 +322,7 @@ Workflow-owned preprocessing is still required: - provider calls, transcoding, and blob reads/writes stay in worker activities; - workflow history records the activity outcome; -- `engine` only admits deterministic `CoreAgentCommand` values; +- `harness` only admits deterministic `CoreAgentCommand` values; - typed admission/preprocessing failures remain machine-readable. Because append preprocessing can rewrite entries, gateway waiting and diff --git a/docs/roadmap/archive/p89-room-context-retention.md b/docs/roadmap/archive/p89-room-context-retention.md index 799bb72f0..31d99f127 100644 --- a/docs/roadmap/archive/p89-room-context-retention.md +++ b/docs/roadmap/archive/p89-room-context-retention.md @@ -134,7 +134,7 @@ Replace the pruned backlog span with meaning instead of dropping it (consumed history already gets this from normal compaction): - before pruning, generate a summary of the outgoing span (worker activity or - a dedicated run, never inside `engine`); + a dedicated run, never inside `harness`); - the prune commits one updated `channel.room..summary` entry alongside the batch removal; - summary updates fold the previous summary with the newly pruned span so the @@ -165,7 +165,7 @@ never block ingestion on the summarizer. ## Non-Goals -- No engine-side channel awareness. `engine` keeps generic keyed context; all +- No engine-side channel awareness. `harness` keeps generic keyed context; all room semantics stay in bridge policy. - No per-message TTL scheduling; retention triggers on append, not timers. - No cross-room/global summarization in this item. diff --git a/docs/roadmap/archive/p90-multi-tenancy.md b/docs/roadmap/archive/p90-multi-tenancy.md index 90fa6bc03..c4c3d6574 100644 --- a/docs/roadmap/archive/p90-multi-tenancy.md +++ b/docs/roadmap/archive/p90-multi-tenancy.md @@ -145,7 +145,7 @@ What is single-tenant is everything above the rows: - `PgStore` binds one `universe_id` at construction (`crates/store-pg/src/lib.rs`), read once from `LIGHTSPEED_PG_UNIVERSE_ID` - (`crates/temporal-server/src/config.rs`). Every runtime singleton built from + (`crates/temporal-runtime/src/config.rs`). Every runtime singleton built from it — `GatewayAgentApi`, `ActivityState` (LLM runtime, tool registry, token broker) — serves exactly one universe per process. - The Temporal task queue is derived from that one universe diff --git a/docs/roadmap/archive/p91-core-agent-structure-cleanup.md b/docs/roadmap/archive/p91-core-agent-structure-cleanup.md index ce1b3b601..bcb418869 100644 --- a/docs/roadmap/archive/p91-core-agent-structure-cleanup.md +++ b/docs/roadmap/archive/p91-core-agent-structure-cleanup.md @@ -28,7 +28,7 @@ files, `decode_dynamic_entry` → `decode_stored_entry`, and related test names and comments renamed. Stored bytes unchanged. - Engine-focused refactor with downstream fixups in `temporal-workflow`, - `temporal-server`, `api-projection`, `test-support`, `store-fs`, `store-pg`, + `temporal-runtime`, `api-projection`, `test-support`, `store-fs`, `store-pg`, and `eval`. - Supersedes the SDK-era "open kernel" posture from P54 (composable agent kernel). Lightspeed is a product; CoreAgent is the only agent domain, now and @@ -51,7 +51,7 @@ Commit the engine to a fixed event vocabulary and a closed core FSM: ## Inventory -Every open abstraction in `engine` was traced to its consumers across the +Every open abstraction in `harness` was traced to its consumers across the workspace (2026-07-03, branch `multi-tenant`): | # | Structure | Location | Consumers found | Action | @@ -134,7 +134,7 @@ slices 2 and 3 each change exactly one persisted shape. 9. `CoreAgentDrive`: drop the `codec` / `admit` / `apply` / `planner` fields (all stateless); call the functions. 10. Fix downstream imports and call sites: `temporal-workflow` (`rehydrate`, - `workflow/{mod,drive,admissions}`, `types`, tests), `temporal-server` + `workflow/{mod,drive,admissions}`, `types`, tests), `temporal-runtime` (gateway service, fleet, activity tests, `fake_loop`), `api-projection`, `test-support`. Prune `lib.rs` / `session/mod.rs` / `core/mod.rs` re-exports; update the P54-era module docs. @@ -147,7 +147,7 @@ slices 2 and 3 each change exactly one persisted shape. `.event`. 3. Stored envelope payloads lose one nesting level: `{"kind":{"lifecycle":"closed"}}` → `{"lifecycle":"closed"}`. Regenerate the - engine fixtures under `crates/engine/fixtures/`. + engine fixtures under `crates/harness/fixtures/`. ### Slice 3 — Drop `AgentHandle` (schema change) @@ -160,7 +160,7 @@ slices 2 and 3 each change exactly one persisted shape. local stacks via `scripts/dev/` helpers. 3. `store-fs`: drop the field from the session record JSON. 4. Delete the `AgentHandle` string id from `session/ids.rs`. -5. Fix constructors across `temporal-server` (activities, fleet), +5. Fix constructors across `temporal-runtime` (activities, fleet), `test-support`, `eval`, `store-*` tests, and `llm-runtime` live tests. ### Slice 4 — Rename the envelope types (mechanical) @@ -178,5 +178,5 @@ slices 2 and 3 each change exactly one persisted shape. - `cargo build` + full `cargo test` workspace-wide after every slice. - `api` wire types are untouched (the cleanup is engine/storage-internal), so no `crates/api/contract` regeneration is expected; `cargo test -p api` confirms. -- Slice 2: fixture round-trip tests in `engine` prove the new payload shape. +- Slice 2: fixture round-trip tests in `harness` prove the new payload shape. - Slice 3: `store-pg` live tests against a reset local stack. diff --git a/docs/roadmap/archive/p95-config-redesign.md b/docs/roadmap/archive/p95-config-redesign.md index 5a3e5166b..bc92219b2 100644 --- a/docs/roadmap/archive/p95-config-redesign.md +++ b/docs/roadmap/archive/p95-config-redesign.md @@ -162,7 +162,7 @@ ### Session config and its patch machinery - Engine `SessionConfig { model, run, turn, context, tools, fleet }` — - `crates/engine/src/core/components/config.rs:10-20`. Stored fully inside + `crates/harness/src/core/components/config.rs:10-20`. Stored fully inside `ConfigChanged { config, revision }` lifecycle events (`core/components/lifecycle.rs:11-14`); `config_revision` starts at 0 and is bumped with `checked_add(1)` at admission (`core/admit.rs:38-83`). @@ -173,7 +173,7 @@ `FieldPatch = Set(T) | Clear` (`sessions.rs:199-214`). The engine mirrors the whole patch tree (`SessionConfigPatch`, `OptionalConfigPatch`, `config.rs:46-252`), and the gateway translates between the two - (`temporal-server/src/gateway/service/api_config.rs`). + (`temporal-runtime/src/gateway/service/api_config.rs`). - Defaults are applied in three places: `default_session_config` seeds the base at open (`temporal-workflow/src/config.rs:35-48`, `DEFAULT_MODEL`), narrow serde defaults on sub-structs, and lazy `effective_*` helpers at projection @@ -584,9 +584,9 @@ the wire surface over. No shims. (`model`/`generation`/`limits`/`context`/`features`), delete engine patch types (`SessionConfigPatch`, `OptionalConfigPatch`, all `apply_to`), `PatchSessionConfig` → `ReplaceSessionConfig`, version pinning + validation - updates (`engine/src/core/components/{config,command,lifecycle}.rs`, + updates (`harness/src/core/components/{config,command,lifecycle}.rs`, `core/admit.rs`); regenerate engine fixtures. Downstream crates may not - compile during this slice — `cargo test -p engine` is the green bar. + compile during this slice — `cargo test -p harness` is the green bar. 2. **Workspace alignment + API cutover** — fix everything against the new structures in one pass: `default_session_config` (`temporal-workflow/src/config.rs`); gateway translation + feature→toolset diff --git a/docs/roadmap/archive/p97-model-discovery.md b/docs/roadmap/archive/p97-model-discovery.md index f0c2fce10..0e6a08d18 100644 --- a/docs/roadmap/archive/p97-model-discovery.md +++ b/docs/roadmap/archive/p97-model-discovery.md @@ -189,7 +189,7 @@ the Anthropic request-lowering/admission vocabulary agree. It must not relabel capabilities, and no credentials in the serialized response. Regenerate `crates/api/contract/` with `cargo run -p api --bin export-schema`, then run `cargo test -p api`, `cargo test -p llm-clients`, and - `cargo test -p temporal-server`. + `cargo test -p temporal-runtime`. ## Explicit non-goals diff --git a/docs/roadmap/archive/p98-context-revisions-and-instruction-reconciliation.md b/docs/roadmap/archive/p98-context-revisions-and-instruction-reconciliation.md index a5370035f..de9f4688f 100644 --- a/docs/roadmap/archive/p98-context-revisions-and-instruction-reconciliation.md +++ b/docs/roadmap/archive/p98-context-revisions-and-instruction-reconciliation.md @@ -279,7 +279,7 @@ correlation model. ## Implementation 1. **Completed.** Add optional expected revisions and a shared validator to the - three direct context commands in `engine`. Add structured revision-conflict + three direct context commands in `harness`. Add structured revision-conflict rejection details and admission tests. 2. **Completed.** Update command constructors with `expected_revision: None`, and preserve the supplied value through workflow input preprocessing. diff --git a/docs/roadmap/later/pNNN-environment-browser-ide.md b/docs/roadmap/later/pNNN-environment-browser-ide.md index 4b3e02b23..1ef9ca4c2 100644 --- a/docs/roadmap/later/pNNN-environment-browser-ide.md +++ b/docs/roadmap/later/pNNN-environment-browser-ide.md @@ -100,7 +100,7 @@ Verified against the repository when this proposal was written: already provides filesystem operations, search, process execution, and PTYs. A full code-server integration uses its own backend for IDE operations; these existing methods continue serving agent tools. -- The [environment gateway](../../../crates/temporal-server/src/environments/gateway.rs) +- The [environment gateway](../../../crates/temporal-runtime/src/environments/gateway.rs) routes by universe, environment, and incarnation. Registered daemons can serve envd traffic through reverse-dialed data sockets. Those sockets carry the envd protocol today, not arbitrary application HTTP or TCP traffic. diff --git a/docs/roadmap/later/pNNN-local-runtime-without-temporal.md b/docs/roadmap/later/pNNN-local-runtime-without-temporal.md index 1b553cf7e..1d0781c9b 100644 --- a/docs/roadmap/later/pNNN-local-runtime-without-temporal.md +++ b/docs/roadmap/later/pNNN-local-runtime-without-temporal.md @@ -83,7 +83,7 @@ what makes a second runtime plausible. | Piece | State today | Reusable as-is for local? | | --- | --- | --- | -| `engine` (30k lines) incl. `CoreAgentDrive` | Deterministic, zero Temporal dependency. Emits `AppendEvents`, `GenerateLlm`, `CompactContext`, `InvokeTools`, `Idle`, `Closed`. | Yes | +| `harness` (30k lines) incl. `CoreAgentDrive` | Deterministic, zero Temporal dependency. Emits `AppendEvents`, `GenerateLlm`, `CompactContext`, `InvokeTools`, `Idle`, `Closed`. | Yes | | `SessionRunner` in `test-support` (2.5k lines) | Substrate-neutral loop: `drive_until_quiescent` fulfils LLM, compaction and tool actions in-process. Used by `eval` and replay tests. | Yes, after promoting it out of test-support | | `llm-runtime` + `llm-clients` (31k lines) | `impl CoreAgentLlm for LlmRuntime`; Anthropic, OpenAI Responses, Completions. | Yes | | `tools` (27k lines) | `InlineToolRuntime`, local and scoped filesystem tools, VFS, skills. | Mostly. The local process executor is a one-line placeholder, so there is no in-process shell tool. | @@ -108,7 +108,7 @@ abstraction between it and the SDK. | Option | What it means | Hosted runtime | Local install | Rough effort | Main risk | | --- | --- | --- | --- | --- | --- | -| **A. Bundle the current stack** | A launcher starts the Temporal dev server (SQLite-backed), an embedded or managed Postgres, envd and `lightspeed-server` as subprocesses behind one command. | Unchanged | One command, but Go + Postgres binaries, several processes, and slow startup | 2–4 weeks | Feels like a server install, not a CLI tool, so it may not fix adoption | +| **A. Bundle the current stack** | A launcher starts the Temporal dev server (SQLite-backed), an embedded or managed Postgres, envd and `lightspeed-runtime` as subprocesses behind one command. | Unchanged | One command, but Go + Postgres binaries, several processes, and slow startup | 2–4 weeks | Feels like a server install, not a CLI tool, so it may not fix adoption | | **B. Two runtimes** | Keep the Temporal runtime. Build a separate local runtime around `SessionRunner`, SQLite and the filesystem CAS that serves the same public API. | Unchanged | Single binary, no services | 2–3 months for interactive sessions | Orchestration semantics (admission, steering, cancel, promises, sub-agents) are re-implemented and drift from the hosted behaviour | | **C. One orchestration core, two substrates** | Do for the session workflow what the engine did for the agent loop: move admission racing, preparation, promise polling, emission delivery and the watchdog into a sans-IO orchestrator. Temporal and a local tokio/SQLite substrate each interpret it. | Temporal stays, behind a thinner shell | Single binary, no services | 3–5 months, mostly refactoring the hosted path first | A large refactor of working, live-validated code; Temporal's determinism rules (e.g. no custom wakers) constrain the shared design | | **D. Drop Temporal everywhere** | Option C, plus a Postgres-backed durable substrate (inbox, outbox, timers, leases) replaces Temporal in hosted too. | Postgres-only; we own scheduling, leases and failover | Same binary with SQLite | 6+ months | We take on the distributed-systems work Temporal does today: worker leases, failover, timer sweeps, at-least-once delivery, schedules | @@ -187,10 +187,10 @@ The orchestration gets its own crate rather than living in the engine: | Crate | Role | | --- | --- | -| `harness` (renamed from `engine`) | Lightspeed's native agent loop: events, session state, context, tool planning, `CoreAgentDrive`. Deterministic and event-sourced. | +| `harness` (renamed from `harness`) | Lightspeed's native agent loop: events, session state, context, tool planning, `CoreAgentDrive`. Deterministic and event-sourced. | | `sessions` (new) | Sans-IO session orchestration: admission inbox, run slot, preparation steps, promise sources, emission outbox, workflow-start dedupe, wake computation, cancel watchdog. Depends on `harness`. | | `temporal-workflow` | Thin interpreters that run `sessions`, `bots` and `channels` state machines on Temporal. | -| `temporal-runtime` (renamed from `temporal-server`) | Activities, roles and Temporal wiring. | +| `temporal-runtime` (renamed from `temporal-runtime`) | Activities, roles and Temporal wiring. | | `local-runtime` (later) | Tokio interpreter of `sessions` over SQLite, filesystem CAS and embedded envd. | Why `sessions` is separate from `harness`: @@ -276,7 +276,7 @@ notes where Option B differs. | --- | --- | --- | --- | --- | --- | | 1 | Local backend behind the public API | `AgentApiService` trait (about 119 methods, many with "unavailable" defaults) and a generic `dispatch_json_rpc` in `crates/api` | `LocalAgentApi` implementing the session, run, context, events, VFS and models subset. The CLI calls it in-process; `lightspeed serve` exposes it to the web UI. | 3–4 | Same | | 2 | Session orchestrator | `CoreAgentDrive`; `SessionRunner` (synchronous drive-until-quiescent); the Temporal session workflow | Admissions handled while a model or tool call runs (steer, cancel, approvals), awaits and timers, promises, queued runs, sub-agents spawned in-process | 8–12, which includes reshaping the hosted workflow | 5–7 on its own, then every later feature built twice | -| 3 | SQLite store | Store traits in `engine`, `vfs`, `environments`, `auth`, `mcp`, `profiles`; `store-pg` as the reference | A `store-sqlite` crate with one-file migrations. jsonb containment becomes `json_each` or filtering in the app; `text[]` becomes JSON; advisory locks become a single-writer process lock. | 3–5 | Same | +| 3 | SQLite store | Store traits in `harness`, `vfs`, `environments`, `auth`, `mcp`, `profiles`; `store-pg` as the reference | A `store-sqlite` crate with one-file migrations. jsonb containment becomes `json_each` or filtering in the app; `text[]` becomes JSON; advisory locks become a single-writer process lock. | 3–5 | Same | | 4 | Filesystem CAS + collection | `FsBlobStore` (sha256 layout) | Wire it in; reference roots and sweeps without Postgres | 1 | Same | | 5 | Local shell and process tools | envd (12k lines) runs on laptops today; the in-process `ProcessExecutor` is a placeholder | Embed envd as a library over an in-memory transport, or spawn it as a sidecar. Default the active environment to the working directory. | 2–3 | Same | | 6 | Permission model for a user's own machine | MCP approvals (`AwaitingApproval`, parked runs) | Approvals for shell and writes outside the workspace, with allow rules per session and per directory. Codex and Claude Code users expect this. | 2–3 | Same | @@ -350,7 +350,7 @@ weeks for two engineers. | Phase | Duration | Work | Gate after | | --- | --- | --- | --- | | 0 · Spike | 2–4 weeks, in parallel with phase 1 | CLI over `SessionRunner`; in-memory or SQLite store; embedded envd; try with design partners | **Go / no-go on local:** spike used on real tasks | -| 1 · Extract `sessions` | 5–7 weeks | Port one slice both ways and pick sync core or async host trait; sans-IO orchestrator; thin Temporal interpreter; `SessionControl` trait; neutral activity errors; `engine` → `harness` and `temporal-server` → `temporal-runtime` renames | **Hosted unchanged:** live Temporal suites green on the thin interpreter | +| 1 · Extract `sessions` | 5–7 weeks | Port one slice both ways and pick sync core or async host trait; sans-IO orchestrator; thin Temporal interpreter; `SessionControl` trait; neutral activity errors; `harness` → `harness` and `temporal-runtime` → `temporal-runtime` renames | **Hosted unchanged:** live Temporal suites green on the thin interpreter | | 2 · Local substrate | 5–7 weeks | SQLite store; tokio interpreter of `sessions`; shell approvals; one-binary packaging | **Parity:** conformance suite green on both substrates | | 3 · Beta and bridge | 2–3 weeks | Public local release; push session to hosted; docs and onboarding | Then revisit Option D | diff --git a/docs/roadmap/later/pNNN-reentrant-run-start-deadlock.md b/docs/roadmap/later/pNNN-reentrant-run-start-deadlock.md index 5156042f9..faec78b79 100644 --- a/docs/roadmap/later/pNNN-reentrant-run-start-deadlock.md +++ b/docs/roadmap/later/pNNN-reentrant-run-start-deadlock.md @@ -53,14 +53,14 @@ on the reentrant request. Relevant code: -- `crates/temporal-server/src/gateway/service/mod.rs`: +- `crates/temporal-runtime/src/gateway/service/mod.rs`: `start_run_internal` signals `RequestRun` and waits for `wait_for_run_accepted`. -- `crates/temporal-server/src/gateway/service/workflow.rs`: +- `crates/temporal-runtime/src/gateway/service/workflow.rs`: `wait_for_run_accepted` only returns matching active or completed runs. - `platform/configurator-mcp/src/config.ts`: Configurator upstream calls time out after 60 seconds by default. -- `crates/temporal-server/src/gateway/service/mod.rs`: gateway operations time +- `crates/temporal-runtime/src/gateway/service/mod.rs`: gateway operations time out after 90 seconds by default. The Configurator timeout broke the synchronous wait seen by the provider, but diff --git a/docs/roadmap/p165-documentation.md b/docs/roadmap/p165-documentation.md index f15086c3f..1c60ee653 100644 --- a/docs/roadmap/p165-documentation.md +++ b/docs/roadmap/p165-documentation.md @@ -153,7 +153,7 @@ supported behavior. | Environments | [Environment guide](../documentation/environments/overview.md), [Incus provider guide](../../crates/environment-provider-incus/README.md), [outbound daemon registration](archive/p148-key-based-outbound-environment-registration.md), [profile provisioning](archive/p125-profile-provisioned-environments.md), and [environment API types](../../crates/api/src/environments.rs). | | Deployment and operation | [Build and release](../releasing.md), [release manifest schema](../../release/release-manifest.schema.json), [environment variables](../documentation/reference/environment-variables.md), [tenant isolation](../documentation/deployment/multi-tenancy.md), [Platform guide](../../platform/README.md), and [runtime role instructions](../../scripts/dev/README.md#manual-runtime-roles). | | Integration and extension | [TypeScript client guide](../../clients/typescript/README.md), [Configurator MCP guide](../../platform/configurator-mcp/README.md), [workflow contract](../../crates/temporal-workflow/contract/workflow-contract.md), [environment protocol](../../crates/environment-protocol/src/lib.rs), [tool packages](../../crates/tools/src/lib.rs), and [LLM clients](../../crates/llm-clients/README.md). | -| How it works | [Architecture walkthrough](../documentation/how-it-works/architecture.md), [engine guide](../../crates/engine/README.md), [environment guide](../documentation/environments/overview.md), and the bot/channel/delegation designs above. | +| How it works | [Architecture walkthrough](../documentation/how-it-works/architecture.md), [engine guide](../../crates/harness/README.md), [environment guide](../documentation/environments/overview.md), and the bot/channel/delegation designs above. | | Development and reference | [Repository contribution guidance](../../AGENTS.md), [contribution policy](../../CONTRIBUTING.md), [development guide](../../scripts/dev/README.md), [evaluation harness](../../crates/eval/README.md), [API exporter](../../crates/api/src/bin/export-schema.rs), [workflow exporter](../../crates/temporal-workflow/src/bin/export-workflow-contract.rs), and [profile configuration reference generator](../../platform/scripts/generate-config-reference.mjs). | ## Implementation progress diff --git a/docs/roadmap/p172-workflow-owned-toolset-reconciliation.md b/docs/roadmap/p172-workflow-owned-toolset-reconciliation.md index 13f011201..fd665dfaf 100644 --- a/docs/roadmap/p172-workflow-owned-toolset-reconciliation.md +++ b/docs/roadmap/p172-workflow-owned-toolset-reconciliation.md @@ -228,7 +228,7 @@ workflow execution. Total: 105 passing live tests (68 runtime, 37 storage). ### Earlier validation and deployment requirements - Shared environment discovery: 331 server unit tests passed (one ignored), - along with `cargo check -p temporal-server --all-targets`. + along with `cargo check -p temporal-runtime --all-targets`. Regression coverage verifies one connection/initialization/directory check for two scans, fresh edits, disabled and controller-owned sources, unchanged skill observations, independent failure publication, and reconnection after a scan @@ -257,7 +257,7 @@ readiness and operation receipts, and steering always names its target run. - Compatibility cleanup validation passed: 222 engine and 133 workflow unit tests, plus `cargo check --workspace --all-targets`. The workflow contract exporter produced no artifact changes. Live histories were not replayed. -- Rust tests passed for `engine`, `temporal-workflow`, `temporal-server`, +- Rust tests passed for `harness`, `temporal-workflow`, `temporal-runtime`, `profiles`, `environments`, `store-pg`, and `api`, including engine replay and committed contract checks. Final workflow/runtime unit reruns passed. - `cargo check --workspace --all-targets` passed. Live suites, including the diff --git a/docs/roadmap/p173-session-config-attachments.md b/docs/roadmap/p173-session-config-attachments.md index cddc55671..4809c66d8 100644 --- a/docs/roadmap/p173-session-config-attachments.md +++ b/docs/roadmap/p173-session-config-attachments.md @@ -283,7 +283,7 @@ Never re-propose without new evidence: ## Implementation - [x] Consolidate hosted environment lifecycle, gateway, resolver, runtime, and - source discovery modules under `crates/temporal-server/src/environments/`. + source discovery modules under `crates/temporal-runtime/src/environments/`. - [x] Engine config types and validation: attachment lists, ladders, uniqueness, one `default`, one `inherit` (profiles only), snapshot links read-only. @@ -370,10 +370,10 @@ Never re-propose without new evidence: native injection, and native search; invalid environment IDs returning errors; skipping unused default validation; and catalog invalidation, stale-publication rejection, and replay across selection changes. -- Contracts regenerated; engine, tools, temporal-workflow, temporal-server, +- Contracts regenerated; engine, tools, temporal-workflow, temporal-runtime, profiles, api, and platform checks green. -Review fixes passed 933 unit tests across engine, temporal-server, +Review fixes passed 933 unit tests across engine, temporal-runtime, temporal-workflow, and tools (one ignored), plus `cargo check --workspace --all-targets`. diff --git a/docs/roadmap/p174-gateway-session-lifecycle.md b/docs/roadmap/p174-gateway-session-lifecycle.md index c6a441941..c721e1d8a 100644 --- a/docs/roadmap/p174-gateway-session-lifecycle.md +++ b/docs/roadmap/p174-gateway-session-lifecycle.md @@ -52,12 +52,12 @@ missing loads, describes, retry signals, and status queries. They cover: The existing fingerprint-matching test moved beside its implementation. -- `cargo check -p temporal-server --lib` passed. -- `cargo test -p temporal-server --lib gateway::service::`: 128 tests passed. -- `cargo test -p temporal-server --lib`: 344 tests passed; one existing test +- `cargo check -p temporal-runtime --lib` passed. +- `cargo test -p temporal-runtime --lib gateway::service::`: 128 tests passed. +- `cargo test -p temporal-runtime --lib`: 344 tests passed; one existing test remained ignored. - The eight lifecycle tests passed again after a test-fixture lint cleanup. -- `cargo clippy -p temporal-server --lib --tests --no-deps` completed with four +- `cargo clippy -p temporal-runtime --lib --tests --no-deps` completed with four pre-existing diagnostics and no new warnings. Moving the lifecycle methods removed the previous test-module-ordering warning in `workflow.rs`. - Changed-file formatting and `git diff --check` passed. diff --git a/docs/roadmap/p175-rust-maintenance.md b/docs/roadmap/p175-rust-maintenance.md index a4619b46d..3ad202d17 100644 --- a/docs/roadmap/p175-rust-maintenance.md +++ b/docs/roadmap/p175-rust-maintenance.md @@ -60,15 +60,15 @@ restructuring. Validation on 2026-09-13: -- `cargo test -p engine --features contract`: 225 tests passed, including ID +- `cargo test -p harness --features contract`: 225 tests passed, including ID validation/serialization and replay coverage with schema derives enabled. -- `cargo test -p temporal-server --lib worker::`: 97 tests passed; one existing +- `cargo test -p temporal-runtime --lib worker::`: 97 tests passed; one existing test remained ignored. No live or credentialed suites ran. - `cargo test -p api --test schema_artifacts -p temporal-workflow --test workflow_contract`: all ten tests passed, including the committed-artifact staleness gates. - Formatting checks for changed Rust files and `git diff --check` passed. -- Strict Clippy (`--lib --tests --features engine/contract --no-deps -- -D warnings` - for `engine` and `temporal-server`) found five pre-existing diagnostics in +- Strict Clippy (`--lib --tests --features harness/contract --no-deps -- -D warnings` + for `harness` and `temporal-runtime`) found five pre-existing diagnostics in untouched code: a blank line after a doc comment, two collapsible conditionals, and two test-module ordering warnings. These are outside this refactor. The same command without `-D warnings` completed with only those diagnostics. @@ -91,9 +91,9 @@ Validation on 2026-09-13: - `cargo test -p llm-clients --lib --test openai_endpoint_override`: 42 unit tests and six local HTTP/endpoint tests passed. -- `cargo test -p temporal-server --lib worker::mcp::`: all 15 MCP tests passed. +- `cargo test -p temporal-runtime --lib worker::mcp::`: all 15 MCP tests passed. - `cargo clippy -p llm-clients --all-targets --no-deps -- -D warnings` passed. -- `cargo clippy -p temporal-server --lib --tests --no-deps` completed with only +- `cargo clippy -p temporal-runtime --lib --tests --no-deps` completed with only the same five pre-existing diagnostics recorded above. - Formatting checks for changed Rust files and `git diff --check` passed. No live or credentialed suites ran. @@ -110,9 +110,9 @@ Completed 2026-09-13: promise handling, and each command's leading event and retry checks. - Add a regression for mixed pending, missing, and terminal promises with completion-key order different from promise-ID order. -- `cargo test -p engine --features contract`: 226 tests passed, including +- `cargo test -p harness --features contract`: 226 tests passed, including existing replay and workflow-tool failure/idempotency coverage. -- `cargo clippy -p engine --all-targets --features contract --no-deps -- -D warnings` +- `cargo clippy -p harness --all-targets --features contract --no-deps -- -D warnings` passed, as did changed-file formatting and `git diff --check`. ## Gateway session lifecycle cleanup @@ -123,3 +123,207 @@ state loads, shared retry completion, retained declaration admission, and shared workspace validation. Seven new offline tests exercise recovery and readiness; the complete server library suite passed with 344 tests and one existing ignored test. Live suites were not run. + +## Harness and runtime naming + +Implemented 2026-10-03: + +- [x] Rename the deterministic agent crate to `harness` and the hosted + composition crate to `temporal-runtime`, preserving their existing boundaries. +- [x] Rename the executable to `lightspeed-runtime` and align local launchers, + CI, container entrypoints, release archives, and manifest artifact names. +- [x] Update source references and documentation, regenerating contract and + consumer documentation from the authored sources. + +Validation: + +- `cargo test --workspace --locked`: 2116 tests passed; 237 ignored. + No live or credentialed tests ran. +- `cargo clippy --workspace --all-targets --locked -- -D warnings` passed. +- `npm run check:dev`, `npm run test:build`, `npm run typecheck`, + `npm run check:docs`, and `npm run build:docs` passed. +- `cargo build -p temporal-runtime --bin lightspeed-runtime --locked` passed. +- Release metadata and shell syntax checks, Rust formatting, and + `git diff --check` passed. The renamed executable reports + `lightspeed-runtime` in its version and help output. +- Regenerated API and workflow schemas retain the same structure outside + descriptions; the Cargo lockfile changes only package and dependency names. + +## JavaScript package and backend naming + +Implemented 2026-10-03: + +- [x] Standardize JavaScript workspace packages on `@lightspeed-ai`, name the + public SDK `@lightspeed-ai/sdk`, and retain private publication settings + on internal packages. +- [x] Rename the Platform backend package and directory to + `@lightspeed-ai/platform-backend` and `platform/backend`. +- [x] Align imports, generated policy imports, workspace commands, npm + lockfiles, local startup, release staging/publication, and documentation. + +Validation: + +- `npm test`: 1,170 workspace tests passed. +- `npm run build`, `npm run typecheck`, `npm run check:dev`, + `npm run check:identity`, `npm run test:build`, and `npm run check:docs` + passed. The build includes the public client, Configurator, live web UI, + and demo UI. +- Generated client/schema, Configurator, policy, and profile-reference files + regenerate without further changes. +- Built a staged `@lightspeed-ai/sdk` tarball, installed it into the + staged Configurator with its standalone lockfile, and verified imports. + Staged both runtime bundles and verified backend and connector imports + from their extracted artifacts. No packages were published. +- Registry dependency versions and integrity hashes remain unchanged; + internal packages retain `private: true`. Obsolete workspace lock entries + were removed. Shell syntax and `git diff --check` passed. + +SDK name finalized on 2026-10-03: the public package is `@lightspeed-ai/sdk`, +including its `/workflow` and schema exports. Installation examples, imports, +workspace commands, publication metadata, and the bundled `sdk.tgz` agree. +`npm run check`, `npm run check:docs`, and `npm run test:build` passed. +Staged SDK, Configurator, backend, and connector packaging/import checks passed; +no package was published. Dependency versions remain unchanged. + +## Coordinated JavaScript dependency update + +Implemented 2026-10-03: + +- [x] Update Node to 24.21.0 across CI and all four container images, including + verified image digests, and require that version for repository development. +- [x] Align shared dependencies across workspaces and refresh the root, SDK, + and Configurator lockfiles. Major toolchain updates include TypeScript 6.0.3, + Vite 8.3.2, Vitest 5.0.3, jsdom 30.1.1, and React's Vite plugin 6.1.1. + React/React DOM are 19.3.0; Temporal packages are uniformly 1.24.0; + MCP client/server are 2.3.0 with their compatible Node adapter 2.1.1. +- [x] Declare Better Auth explicitly for database auth code generation, + remove TypeScript's deprecated `baseUrl`, and adapt test mock types and + browser/Markdown assertions to the upgraded libraries. +- [x] Retain TypeScript 6 while `@astrojs/check` supports only 5/6, Mermaid 11 + while `astro-mermaid` supports only 10/11, and Node type declarations on 24 + to match the runtime. Retain stable Drizzle releases and the existing + Baileys release-candidate track. + +Security review after the update: + +- Root audit findings decreased from 28 to 17 package entries (13 high, + four moderate), arising from three underlying advisories. SDK and + Configurator standalone audits are clean, including development dependencies; + the connectors' production audit is also clean. +- The remaining high findings are + [braces in shadcn tooling](https://github.com/advisories/GHSA-vfj7-8cjw-p6xm) + and [http-cache-semantics in Astro](https://github.com/advisories/GHSA-ch52-4w7c-c8xp). + Neither advisory currently has a patched release. The documentation site + and web UI are built as static assets. +- The four moderate findings are the deprecated esbuild-kit chain in stable + Drizzle Kit, ending in [esbuild's development-server advisory](https://github.com/advisories/GHSA-67mh-4wv8-2f99). + Better Auth's optional peer also brings this chain into the backend's + production dependency graph; the application does not run an esbuild server. + No forced downgrades or unverified dependency overrides were applied. + +Validation on Node 24.21.0 and npm 11.19.0: + +- Clean `npm ci`, `npm run check`, `npm test` (1,170 workspace tests), + `npm run test:build` (16 checks), and `npm run check:docs` passed. + Generated contracts and consumer files remain unchanged. +- The SDK tarball builds from its standalone lockfile; the staged Configurator + installs and imports it. Both runtime bundles stage and import successfully. + Temporal's native core initializes and shuts down without a server. +- Workspace dependency ranges agree, all three lockfiles match their manifests, + and `git diff --check` passes. No package was published. +- Live Temporal, SSO, and PostgreSQL migration suites were not run; offline + backend/auth tests passed, including their PGlite coverage. Container images + were not rebuilt locally. + +## Coordinated Rust dependency update + +- [x] Review direct Cargo dependencies against stable registry releases and + refresh the workspace lockfile. Major updates include Temporal SDK 1.0.0 + with its matching core 0.9.0, SQLx 0.9.0, Axum 0.8.9, Reqwest 0.13.5, + RMCP 3.5.0, Ratatui 0.30.2, and the RustCrypto libraries. +- [x] Align rustup, CI, and the pinned release build image on Rust 1.99.0. +- [x] Adapt workflow registration, signal-with-start, asynchronous heartbeats, + cancellation, retry policies, and typed failures. Workflow names and wire + payloads remain stable. Detached cancellation tokens preserve the existing + control loops and allow cleanup after workflow cancellation. +- [x] Simplify deployment to role selection: each worker role runs its workflows + and activities together through the standard SDK runtime and worker constructor. + Remove the task-type flag/environment variable, custom core-worker construction, + experimental SDK feature, and direct core dependencies. Separate workflow-only + plugin and activity-only connector fixtures use their normal registrations. +- [x] Review SQLx's explicit assertions for dynamically constructed SQL: + identifiers and fragments come from internal schema definitions, while + request values remain bound parameters. Test schemas use generated UUIDs. +- [x] Adapt cryptographic random generation and digest APIs, and add an + independent AES-256-GCM fixture that verifies persisted secret ciphertext, + authenticated metadata, tamper rejection, and nonce freshness. +- [x] Retain `sse-stream` 0.2.6 because RMCP's transport trait exposes 0.2 + types. `serde_yaml` remains at its final 0.9 release; replacing that + deprecated parser is separate from updating existing package versions. + +Initial dependency-upgrade validation completed on 2026-10-03: + +- Full `cargo clean` removed 119.4 GiB before the fresh build and tests. +- `cargo clippy --workspace --all-targets --locked -- -D warnings` passed. +- `cargo test --workspace --locked` passed: 2,119 tests, with 237 live or + external tests ignored by the default run. Generated contracts remain unchanged. +- Selected live tests passed, serialized against local PostgreSQL, MinIO, and + Temporal: 46 storage tests and nine workflow/MCP tests covering continuation, + checkpoints, cancellation, workflow tools, schedules, and channel replies. +- Ten paid live tests passed against OpenAI, Anthropic, and DeepSeek: streaming, + endpoint/auth overrides, hosted tool round trips, compaction and continuation, + and recovery after a provider rejection. +- RustSec audit findings decreased from 13 vulnerabilities, nine maintenance/ + soundness warnings, and two yanked versions to zero vulnerabilities or warnings. +- Formatting, release metadata verification, documentation checks, and + `git diff --check` passed. Linux release containers were not rebuilt locally. + +Worker simplification follow-up on 2026-10-03: role selection remains the +scaling boundary; independent workflow/activity deployment has been removed. +Deployment and environment-reference documentation now match. + +- A second `cargo clean` removed 52.1 GiB before rebuilding. +- `cargo test -p temporal-runtime -p temporal-workflow --locked` passed: + 523 tests, with 79 external tests ignored by the default run. The CLI test + checks role selection and rejects the removed task-type flag. +- Ten serialized live tests passed: session execution and continuation, + cancellation, workflow-tool plugins, bot schedules, channel replies, and + three paid hosted tool round trips using OpenAI and Anthropic. These exercise + combined workers, workflow-only plugins, and activity-only connectors through + the standard SDK constructor. +- The exact workspace Clippy gate, formatting, documentation checks, and + `git diff --check` passed. The resolved SDK features exclude `experimental`. + +## CI/CD preflight + +Checked on 2026-10-03 without building container images. Two release defects +were found and fixed: + +- Cached Rust builds could retain an earlier commit SHA because the build + script watched only `.git/HEAD`. It now watches Git's resolved HEAD, current + branch, and packed-reference paths. A regression test builds a fixture across + commits, packed refs, detached HEAD, and a linked worktree. +- Configurator staging replaced the SDK lock entry without its production + dependency graph. The isolated SDK workflow import then failed on missing + `@noble/hashes`. Staging now nests the SDK's locked production dependencies + under the packed SDK, preserving Configurator's own resolutions. An offline + installation test covers direct and transitive dependencies and excludes + development dependencies. + +Validation: + +- `cargo test --workspace --locked` passed 2,118 tests; the new build-identity + regression passed separately. The final strict workspace Clippy gate passed. +- Clean `npm ci`, the complete `npm run check:ci`, and documentation checks + passed. An initial PGlite setup timed out during concurrent Rust compilation; + the unchanged consumer gate passed on rerun. All 17 CI/release-script tests + passed after the packaging fix. +- Rust's live migration-ledger test and the Platform migration gate passed. +- All four native binaries built and reported the current commit SHA. The + staged SDK tarball, Configurator, backend and connector bundles imported + successfully; the packaged JavaScript Temporal native core initialized and + shut down successfully. +- Release metadata, generated-file freshness, shell syntax, workflow lint, + rename references, and CI change classification passed. Pinned container + base digests and their Linux/amd64 manifests were verified remotely. +- Linux GNU/musl compilation and container image smoke tests remain for CI/CD. diff --git a/docs/roadmap/p179-core-universes-keys-and-actors.md b/docs/roadmap/p179-core-universes-keys-and-actors.md index c08a45aa0..c94f0320d 100644 --- a/docs/roadmap/p179-core-universes-keys-and-actors.md +++ b/docs/roadmap/p179-core-universes-keys-and-actors.md @@ -389,9 +389,9 @@ and UI tests, generated-client checks, and production/demo builds pass. - [API keys](../../crates/store-pg/src/api_keys.rs), [session store](../../crates/store-pg/src/session.rs). -- [Gateway authentication](../../crates/temporal-server/src/gateway/authentication.rs), - [request context](../../crates/temporal-server/src/gateway/request_context.rs), - [shared-service authorization](../../crates/temporal-server/src/gateway/service/authorization.rs), - [controller rules](../../crates/temporal-server/src/gateway/service/controller.rs). +- [Gateway authentication](../../crates/temporal-runtime/src/gateway/authentication.rs), + [request context](../../crates/temporal-runtime/src/gateway/request_context.rs), + [shared-service authorization](../../crates/temporal-runtime/src/gateway/service/authorization.rs), + [controller rules](../../crates/temporal-runtime/src/gateway/service/controller.rs). - [Method manifest](../../crates/api/src/rpc.rs), [access vocabulary and method classification](../../crates/api/src/access.rs). diff --git a/docs/roadmap/p180-platform-organizations-roles-and-unshared-work.md b/docs/roadmap/p180-platform-organizations-roles-and-unshared-work.md index be0a878e5..bdb1cd943 100644 --- a/docs/roadmap/p180-platform-organizations-roles-and-unshared-work.md +++ b/docs/roadmap/p180-platform-organizations-roles-and-unshared-work.md @@ -75,7 +75,7 @@ For every forwarded request, in order: `not_found` for the universe. 2. **Method.** The member's role meets the method's minimum role. The table is generated from the manifest's `role` metadata into - `platform/server/src/routes/method-roles.ts`; a test asserts every + `platform/backend/src/routes/method-roles.ts`; a test asserts every manifest method has an entry, so a new core method fails the Platform build until it is classified. Otherwise `forbidden`. 3. **Target.** When the manifest names a `target` for the method and the @@ -231,7 +231,7 @@ greenfield rule: Notes on steps 1 and 2 as built: -- The gate is the member client (`platform/server/src/runtime-client.ts`): +- The gate is the member client (`platform/backend/src/runtime-client.ts`): every core call a route makes for a member passes the role and target checks, so a new route cannot forget them. Deployment methods use a separate client and are never called on a member's behalf. @@ -311,11 +311,11 @@ written; the live core suites cover the core half. ## Current seams -- [Better Auth setup](../../platform/server/src/auth.ts), - [gateway proxy](../../platform/server/src/routes/gateway.ts), - [universes routes](../../platform/server/src/routes/universes.ts), - [runtime client](../../platform/server/src/runtime-client.ts), - [bootstrap](../../platform/server/src/bootstrap.ts). +- [Better Auth setup](../../platform/backend/src/auth.ts), + [gateway proxy](../../platform/backend/src/routes/gateway.ts), + [universes routes](../../platform/backend/src/routes/universes.ts), + [runtime client](../../platform/backend/src/runtime-client.ts), + [bootstrap](../../platform/backend/src/bootstrap.ts). - [Platform schema](../../platform/db/src/schema/auth.ts), [Members page](../../platform/web/src/pages/MembersPage.tsx), - [Configurator installer](../../platform/server/src/routes/setups.ts). + [Configurator installer](../../platform/backend/src/routes/setups.ts). diff --git a/docs/roadmap/p181-single-sign-on-and-directory-membership.md b/docs/roadmap/p181-single-sign-on-and-directory-membership.md index 35100ddc2..b9a3a1b08 100644 --- a/docs/roadmap/p181-single-sign-on-and-directory-membership.md +++ b/docs/roadmap/p181-single-sign-on-and-directory-membership.md @@ -209,7 +209,7 @@ user-authorized MCP access are deferred. ## Configuration -Implemented settings; the [environment reference](../documentation/reference/environment-variables.md#platform-server) gives defaults and validation: +Implemented settings; the [environment reference](../documentation/reference/environment-variables.md#platform-backend) gives defaults and validation: ```text LIGHTSPEED_PLATFORM_OIDC_ISSUER @@ -324,9 +324,9 @@ that provider's behavior. ## Current seams -- [Better Auth setup](../../platform/server/src/auth.ts), - [Platform settings](../../platform/server/src/env.ts), - [universes routes](../../platform/server/src/routes/universes.ts), - [bootstrap](../../platform/server/src/bootstrap.ts). +- [Better Auth setup](../../platform/backend/src/auth.ts), + [Platform settings](../../platform/backend/src/env.ts), + [universes routes](../../platform/backend/src/routes/universes.ts), + [bootstrap](../../platform/backend/src/bootstrap.ts). - [Platform schema](../../platform/db/src/schema/auth.ts), [Members page](../../platform/web/src/pages/MembersPage.tsx). diff --git a/docs/roadmap/p182-deprovisioning-and-directory-updates.md b/docs/roadmap/p182-deprovisioning-and-directory-updates.md index a97966a86..a462fde1c 100644 --- a/docs/roadmap/p182-deprovisioning-and-directory-updates.md +++ b/docs/roadmap/p182-deprovisioning-and-directory-updates.md @@ -219,7 +219,7 @@ acceptance step; no automatic deactivation or core-key cascade was added. ## Current seams -- [Better Auth setup](../../platform/server/src/auth.ts), +- [Better Auth setup](../../platform/backend/src/auth.ts), [Platform schema](../../platform/db/src/schema/auth.ts), - [universes routes](../../platform/server/src/routes/universes.ts), + [universes routes](../../platform/backend/src/routes/universes.ts), [Members page](../../platform/web/src/pages/MembersPage.tsx). diff --git a/docs/roadmap/p184-universe-model-defaults-and-transcription.md b/docs/roadmap/p184-universe-model-defaults-and-transcription.md index 846509f1c..25ff6b493 100644 --- a/docs/roadmap/p184-universe-model-defaults-and-transcription.md +++ b/docs/roadmap/p184-universe-model-defaults-and-transcription.md @@ -23,7 +23,7 @@ can add a slot, adapter, and operation without extending session orchestration. ## Baseline before implementation -- `temporal-server/src/config.rs` resolves an omitted session model from +- `temporal-runtime/src/config.rs` resolves an omitted session model from `LIGHTSPEED_CHAT_PROVIDER` and `LIGHTSPEED_CHAT_MODEL`, with built-in defaults of `openai` and `gpt-5.5`. The API kind is fixed to OpenAI Responses. - Session creation, configuration replacement, and profile application use @@ -364,7 +364,7 @@ writing. A conflict is reported without automatically retrying over a newer choice. `--json` returns the defaults record for each command. Before starting an upgraded runtime, apply schema revision 10 with -`cargo run -p temporal-server -- migrate`. Remove `LIGHTSPEED_CHAT_PROVIDER` +`cargo run -p temporal-runtime -- migrate`. Remove `LIGHTSPEED_CHAT_PROVIDER` and `LIGHTSPEED_CHAT_MODEL`; their presence now produces an actionable startup error. Select each universe explicitly in the CLI and set its intended route. Existing sessions remain usable with their stored models, and explicit-model @@ -520,7 +520,7 @@ maps supported file-transcription families to the audio protocol, bypasses the agent-only age filter for those routes, and keeps them out of agent pickers. Custom providers continue to use their declared API kinds and manual choices. -Validation passed: 572 web tests, 162 Platform server tests, 13 Rust model +Validation passed: 572 web tests, 162 Platform backend tests, 13 Rust model discovery tests, eight API contract tests, TypeScript checks, and production and demo builds. Browser checks covered speech suggestions, editable transcript preview, clearing the default, and mobile layout. A real Chromium recorder diff --git a/docs/roadmap/p185-external-harness-sessions.md b/docs/roadmap/p185-external-harness-sessions.md index 0670708b3..7f6dc38a8 100644 --- a/docs/roadmap/p185-external-harness-sessions.md +++ b/docs/roadmap/p185-external-harness-sessions.md @@ -84,10 +84,10 @@ universal definition of run completion. ## Current repository boundary -- [StoredEvent](../../crates/engine/src/session/stored.rs) already has a generic +- [StoredEvent](../../crates/harness/src/session/stored.rs) already has a generic `kind`, `version`, and `payload` envelope. The session store supports ordered appends with an expected head and retains referenced content. -- [Session storage projections](../../crates/engine/src/storage/session.rs) +- [Session storage projections](../../crates/harness/src/storage/session.rs) recognize native core lifecycle and run events. Generic storage does not yet make sessions independent of the engine. - [API projections](../../crates/api-projection/src/lib.rs) consume native core @@ -201,9 +201,9 @@ modules within the crates that already own each boundary: | `environment-protocol` | Harness capability, request/response types, observation envelopes, and typed errors | | `environment-client` | Typed calls over existing connections and an executable validation example | | `environment-daemon` | Harness supervisor, ACP driver, local journal, and process cleanup | -| `engine` | Shared deterministic session/log types in existing session/storage modules, separate from the native core reducer | +| `harness` | Shared deterministic session/log types in existing session/storage modules, separate from the native core reducer | | `temporal-workflow` | External-session state machine and workflow, added after bridge validation | -| `temporal-server` | Runtime activities, admission, and backend dispatch, added after bridge validation | +| `temporal-runtime` | Runtime activities, admission, and backend dispatch, added after bridge validation | | `store-pg` / `store-fs` | Existing session-log persistence and backend-aware projections | | `api` / `api-projection` | Public session capabilities and views for both backends | @@ -284,10 +284,10 @@ become a feature-specific branch in the stable native session worker. Separate shared session identity, lifecycle, storage contracts, and public facts from native core execution within the existing session/storage modules -in `engine`. Do not create a new session-domain crate. The external workflow +in `harness`. Do not create a new session-domain crate. The external workflow may reuse those deterministic types without driving the native core reducer or requiring a populated `CoreAgentState`; it has its own reducer and -checkpoint format. envd remains independent of `engine` and session storage. +checkpoint format. envd remains independent of `harness` and session storage. Retain one ordered session log with backend-aware event families: diff --git a/docs/roadmap/p187-compaction-defaults-and-context-limit-recovery.md b/docs/roadmap/p187-compaction-defaults-and-context-limit-recovery.md index 6b4cac31a..64369057f 100644 --- a/docs/roadmap/p187-compaction-defaults-and-context-limit-recovery.md +++ b/docs/roadmap/p187-compaction-defaults-and-context-limit-recovery.md @@ -505,7 +505,7 @@ serialized hosted standalone-compaction and continuation tests. Completed checks on 2026-10-01: -- Cross-crate engine, runtime, provider client, API projection, workflow, and +- Cross-crate harness, runtime, provider client, API projection, workflow, and in-process runner tests, including replay, protected tool exchanges, unknown capacity recovery, partial-output discard, cancellation, manual queueing, exact full native windows, same-route fallback, and capability selection. diff --git a/docs/roadmap/p188-stable-context-catalogs.md b/docs/roadmap/p188-stable-context-catalogs.md index 1db0599db..8dad03600 100644 --- a/docs/roadmap/p188-stable-context-catalogs.md +++ b/docs/roadmap/p188-stable-context-catalogs.md @@ -81,7 +81,7 @@ machine; presentation can fall back to full IDs for colliding attachments. Validation: -- Library suites for engine, tools, temporal-workflow, temporal-server, +- Library suites for engine, tools, temporal-workflow, temporal-runtime, llm-runtime, and test-support: 1,190 passed; the existing external ffmpeg smoke test remains ignored. - Discovery regression exercises local mock transport timeouts, incomplete diff --git a/docs/site/README.md b/docs/site/README.md index d75af2d9e..919422ed2 100644 --- a/docs/site/README.md +++ b/docs/site/README.md @@ -19,7 +19,7 @@ original manual and included references; edits update the preview. Ctrl-C or For a standalone preview alongside another launcher profile, `npm run dev:docs` still invokes Astro directly. Astro can run that server in the background when -it detects an agent; `npm exec --workspace @lightspeed/docs -- astro dev stop` +it detects an agent; `npm exec --workspace @lightspeed-ai/docs -- astro dev stop` stops it. Search is indexed during the production build, so use `preview:docs` when checking search behavior. @@ -70,7 +70,7 @@ credentials. For a loopback-only demo server, use: ```bash -npm run dev:demo --workspace @lightspeed/platform-web -- --host 127.0.0.1 +npm run dev:demo --workspace @lightspeed-ai/platform-web -- --host 127.0.0.1 ``` | Image | Demo view and state | diff --git a/docs/site/package.json b/docs/site/package.json index 7acfe90ea..da09c6306 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -1,5 +1,5 @@ { - "name": "@lightspeed/docs", + "name": "@lightspeed-ai/docs", "private": true, "type": "module", "scripts": { @@ -10,23 +10,23 @@ "check": "npm run test && astro check && npm run build" }, "dependencies": { - "@astrojs/markdown-remark": "7.3.0", - "@astrojs/starlight": "0.42.0", - "astro": "7.3.1", + "@astrojs/markdown-remark": "7.3.1", + "@astrojs/starlight": "0.42.5", + "astro": "7.3.5", "astro-mermaid": "2.1.0", "cookie": "2.0.1", "mdast-util-to-string": "^4.0.0", - "mermaid": "^11.12.0", + "mermaid": "^11.17.2", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.5", - "unist-util-visit": "^5.0.0" + "unist-util-visit": "^5.1.0" }, "devDependencies": { - "@astrojs/check": "^0.9.9", - "cheerio": "^1.1.2", - "typescript": "^5.8.3" + "@astrojs/check": "^0.9.10", + "cheerio": "^1.2.0", + "typescript": "^6.0.3" }, "engines": { "node": ">=24" diff --git a/package-lock.json b/package-lock.json index 8391e2740..9ad73bef8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,97 +12,77 @@ "platform/configurator-mcp", "platform/connectors", "platform/db", - "platform/server", + "platform/backend", "platform/shared", "platform/web" ], "devDependencies": { - "@types/node": "^24.0.0", - "tsx": "^4.20.0", - "typescript": "^5.8.3" + "@types/node": "^24.19.1", + "tsx": "^4.23.15", + "typescript": "^6.0.3" }, "engines": { - "node": ">=24" + "node": ">=24.21.0" } }, "clients/typescript": { - "name": "@lightspeed-ai/agent-client", + "name": "@lightspeed-ai/sdk", "version": "0.0.0", "dependencies": { - "@noble/hashes": "2.2.0" + "@noble/hashes": "2.4.0" }, "devDependencies": { - "@types/node": "^24.0.0", - "json-schema-to-typescript": "^15.0.4", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "@types/node": "^24.19.1", + "json-schema-to-typescript": "^16.0.0", + "typescript": "^6.0.3", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" } }, "docs/site": { - "name": "@lightspeed/docs", + "name": "@lightspeed-ai/docs", "dependencies": { - "@astrojs/markdown-remark": "7.3.0", - "@astrojs/starlight": "0.42.0", - "astro": "7.3.1", + "@astrojs/markdown-remark": "7.3.1", + "@astrojs/starlight": "0.42.5", + "astro": "7.3.5", "astro-mermaid": "2.1.0", "cookie": "2.0.1", "mdast-util-to-string": "^4.0.0", - "mermaid": "^11.12.0", + "mermaid": "^11.17.2", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.5", - "unist-util-visit": "^5.0.0" + "unist-util-visit": "^5.1.0" }, "devDependencies": { - "@astrojs/check": "^0.9.9", - "cheerio": "^1.1.2", - "typescript": "^5.8.3" + "@astrojs/check": "^0.9.10", + "cheerio": "^1.2.0", + "typescript": "^6.0.3" }, "engines": { "node": ">=24" } }, - "docs/site/node_modules/cookie": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", - "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", - "license": "MIT", - "engines": { - "node": ">=22" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/@antfu/install-pkg": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.0.1.tgz", - "integrity": "sha512-iCKVQcIC0e3oDxEfs3SHQGW+ovhBMZmS1TE+bTk50rVyMCBmCfClv7Qi3HQKlumYwvjb/iIMeWCW2i67q6kFfQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.1.0.tgz", + "integrity": "sha512-sdg9NxU3zR4Mnawfbc/x6GB5Wf17WYud5qOuEuxXjaKpYpMkISSJEjItGebXJ2bQ4DIcly4NYH23mtkGJjvKUw==", "license": "MIT", "dependencies": { - "package-manager-detector": "^1.7.0", - "tinyexec": "^1.2.4" + "package-manager-detector": "^1.8.0", + "tinyexec": "^1.3.1" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@antfu/install-pkg/node_modules/tinyexec": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", - "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/@apidevtools/json-schema-ref-parser": { "version": "11.9.3", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.3.tgz", + "integrity": "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -118,196 +98,112 @@ } }, "node_modules/@asamuzakjp/css-color": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@csstools/css-calc": "^2.1.3", - "@csstools/css-color-parser": "^3.0.9", - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "lru-cache": "^10.4.3" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@astrojs/check": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.10.tgz", - "integrity": "sha512-zgx/UQMozdjOa3bOxjgeCFdtpE3c9rRX6xHwa+2QXvy8z8Akifu2AtubHyv/zzC2znO8dl8fFWL4K+Ba9kS8HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@astrojs/language-server": "^2.16.7", - "chokidar": "^4.0.3", - "kleur": "^4.1.5", - "yargs": "^18.0.0" - }, - "bin": { - "astro-check": "bin/astro-check.js" - }, - "peerDependencies": { - "typescript": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/@astrojs/check/node_modules/ansi-regex": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", - "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@astrojs/check/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@astrojs/check/node_modules/cliui": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@astrojs/check/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-7.1.3.tgz", + "integrity": "sha512-1t1U8Cm3RBl9vh3RAZhjkPaduzLSvQJRToRrxpGR/eDRW99mOREleuu+mWfiFa795bUzjwht7NgphCKTs2ianQ==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.2.2" + "@csstools/css-calc": "^3.4.2", + "@csstools/css-color-parser": "^4.2.5", + "@csstools/css-parser-algorithms": "^4.0.2", + "@csstools/css-tokenizer": "^4.0.2", + "lru-cache": "^11.5.3" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/@astrojs/check/node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "node_modules/@asamuzakjp/dom-selector": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-9.2.4.tgz", + "integrity": "sha512-YnVzxDxLaqL0t7Q4wfcgHZjg55Wm6y5EaO7Bhu3q9J7wq/8iw3PhsnWiOQhYekx4VexnbkgWpTT6n+QIV7kczw==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "bidi-js": "^1.1.0", + "css-tree": "^3.2.1", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.5.3" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/@astrojs/check/node_modules/yargs": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", - "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==", + "node_modules/@astrojs/astro2tsx": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@astrojs/astro2tsx/-/astro2tsx-0.1.2.tgz", + "integrity": "sha512-Uj/M9zbrhu5cIZEvWAGTbQJRKSxXWJ/E59BZwt7F+chrKhbfttW+9rkS/l+1QxoJP1KU3UnpM62M7yszfAI0WA==", "dev": true, "license": "MIT", "dependencies": { - "cliui": "^9.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "string-width": "^8.2.1", - "y18n": "^5.0.5", - "yargs-parser": "^22.0.0" + "@emnapi/core": "1.11.3", + "@napi-rs/wasm-runtime": "1.2.4" }, "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, - "node_modules/@astrojs/check/node_modules/yargs-parser": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@astrojs/check/node_modules/yargs/node_modules/string-width": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", - "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "node_modules/@astrojs/check": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.10.tgz", + "integrity": "sha512-zgx/UQMozdjOa3bOxjgeCFdtpE3c9rRX6xHwa+2QXvy8z8Akifu2AtubHyv/zzC2znO8dl8fFWL4K+Ba9kS8HQ==", "dev": true, "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.5.0", - "strip-ansi": "^7.1.2" + "@astrojs/language-server": "^2.16.7", + "chokidar": "^4.0.3", + "kleur": "^4.1.5", + "yargs": "^18.0.0" }, - "engines": { - "node": ">=20" + "bin": { + "astro-check": "bin/astro-check.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "typescript": "^5.0.0 || ^6.0.0" } }, - "node_modules/@astrojs/compiler": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", - "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", - "dev": true, - "license": "MIT" - }, "node_modules/@astrojs/compiler-binding": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding/-/compiler-binding-0.4.0.tgz", - "integrity": "sha512-x2RjDUuWfwLNtc3mjAdSRInwqh/rqbLar9cm/5FOMbHvmYZB7yfKewzSclAxWjIZsypJDXv1lhaP2WG+P8TK3g==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding/-/compiler-binding-0.5.1.tgz", + "integrity": "sha512-oczyolLUl9mNrtuBuNjuvn5thpHrFLXAHAWGTRg0JDHQ8cGVsVeFekOu2uSoQGgainJIi+A3/9m0DyYwz3Nlnw==", "license": "MIT", "engines": { "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@astrojs/compiler-binding-darwin-arm64": "0.4.0", - "@astrojs/compiler-binding-darwin-x64": "0.4.0", - "@astrojs/compiler-binding-linux-arm64-gnu": "0.4.0", - "@astrojs/compiler-binding-linux-arm64-musl": "0.4.0", - "@astrojs/compiler-binding-linux-x64-gnu": "0.4.0", - "@astrojs/compiler-binding-linux-x64-musl": "0.4.0", - "@astrojs/compiler-binding-wasm32-wasi": "0.4.0", - "@astrojs/compiler-binding-win32-arm64-msvc": "0.4.0", - "@astrojs/compiler-binding-win32-x64-msvc": "0.4.0" + "@astrojs/compiler-binding-android-arm64": "0.5.1", + "@astrojs/compiler-binding-darwin-arm64": "0.5.1", + "@astrojs/compiler-binding-darwin-x64": "0.5.1", + "@astrojs/compiler-binding-linux-arm64-gnu": "0.5.1", + "@astrojs/compiler-binding-linux-arm64-musl": "0.5.1", + "@astrojs/compiler-binding-linux-x64-gnu": "0.5.1", + "@astrojs/compiler-binding-linux-x64-musl": "0.5.1", + "@astrojs/compiler-binding-wasm32-wasi": "0.5.1", + "@astrojs/compiler-binding-win32-arm64-msvc": "0.5.1", + "@astrojs/compiler-binding-win32-x64-msvc": "0.5.1" + } + }, + "node_modules/@astrojs/compiler-binding-android-arm64": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-android-arm64/-/compiler-binding-android-arm64-0.5.1.tgz", + "integrity": "sha512-nMb2nMIJtcWLNH+fV75Enmi+jp4tIOYOfsv4XtpgdOWkqc9P4uSSdK5u1xb340AzrXo5V18SxLl/nc3vcqtamQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@astrojs/compiler-binding-darwin-arm64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-arm64/-/compiler-binding-darwin-arm64-0.4.0.tgz", - "integrity": "sha512-ZVUwHundaQyFNjE6uoa0usaC0WOCitDCLS/4mdb4rOiJXwVUuKJBMxI5WMzXLWmamsXtK/Z//ifLXvV5Yeh4Hw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-arm64/-/compiler-binding-darwin-arm64-0.5.1.tgz", + "integrity": "sha512-5k4+nZ/WRt+dcVow4z7rBuI7iv9A58h/uQ91YJe1PrTivbcCkq3u2Ynx/AZJwII4CsZawBCeGpojkFjutZBhBQ==", "cpu": [ "arm64" ], @@ -321,9 +217,9 @@ } }, "node_modules/@astrojs/compiler-binding-darwin-x64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-x64/-/compiler-binding-darwin-x64-0.4.0.tgz", - "integrity": "sha512-FI6G8AY8u6fR1SI/QRR5yGMwtvZwP34CDmZpZ5HwJGa50UM1VISTLhqkhV4a476pmgd25X1Aur2dqw6hUnrlKA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-x64/-/compiler-binding-darwin-x64-0.5.1.tgz", + "integrity": "sha512-0Buw+YST9Ff2EqQyhRMQujuFq/dijLw3zXWhsvI0dJ2pGrT38iVoxTEca2eBX/PfhlwkVWSRJEKO5gMqKHyeHg==", "cpu": [ "x64" ], @@ -337,9 +233,9 @@ } }, "node_modules/@astrojs/compiler-binding-linux-arm64-gnu": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-gnu/-/compiler-binding-linux-arm64-gnu-0.4.0.tgz", - "integrity": "sha512-lB9gLFJK7m82EnjaU8nlRBEfcwGNeHidW3sSjODTUjMNaoewVuUz9fwwdY5M4jiSXIqWLH3yl6TX8FTDKA74Sw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-gnu/-/compiler-binding-linux-arm64-gnu-0.5.1.tgz", + "integrity": "sha512-x5LRpyCoMKuu3INr18cn42YhwSOaRpp9b5Ny3eJJ/sWVeejC16Zeshu1JlvlSmEZACLeWxU5JM0RX6T6nI+YyA==", "cpu": [ "arm64" ], @@ -353,9 +249,9 @@ } }, "node_modules/@astrojs/compiler-binding-linux-arm64-musl": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-musl/-/compiler-binding-linux-arm64-musl-0.4.0.tgz", - "integrity": "sha512-HPbvWqbxFxyaoQJhLxCaSjtYBx9KBo7JGVzEFZCmMl968a2PsSH0UfiODYgYPXofTOIsIH2aoCcrHXML0IA3ig==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-musl/-/compiler-binding-linux-arm64-musl-0.5.1.tgz", + "integrity": "sha512-mL7tQEuDk3rGfaKmrO63nw6WBy1TPVioQGmVyjcAr+C+a/k3SVMYBytNSMqH9mZPT/Swj30JaZ2N842Z1NnOEQ==", "cpu": [ "arm64" ], @@ -369,9 +265,9 @@ } }, "node_modules/@astrojs/compiler-binding-linux-x64-gnu": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-gnu/-/compiler-binding-linux-x64-gnu-0.4.0.tgz", - "integrity": "sha512-tQKolMxoJ/+0AmLWm1PmJ/i+z3i10ZU1bNuVjEDulCf48azEMtUNjTZgHJ5MPtpYRNc7dlETr8QujUfduzoC7Q==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-gnu/-/compiler-binding-linux-x64-gnu-0.5.1.tgz", + "integrity": "sha512-uLGc9jtxwiDe4cQyhNPQim4ECiB/YzbWlXssfLAv8r374kArfTwBHjwR2+j+XVyF71yCx5mF9YNRclRqdNBgeg==", "cpu": [ "x64" ], @@ -385,9 +281,9 @@ } }, "node_modules/@astrojs/compiler-binding-linux-x64-musl": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-musl/-/compiler-binding-linux-x64-musl-0.4.0.tgz", - "integrity": "sha512-5v5YymudsxMHp3NBLCS8BUlu5CRqeLtWD9cKS/4nIhIEHCbpz9okmVV6I0HWqmBAPhWYcDa3vw/vltYPrOQCTA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-musl/-/compiler-binding-linux-x64-musl-0.5.1.tgz", + "integrity": "sha512-G0cywinaQUc8v1MrytvYKUX7svTDMmYtOCZfxjwKPbJi59zIqM+Ll0rWgO0GQWLZH3XoPYo19ZwlP3Xt9ep9YA==", "cpu": [ "x64" ], @@ -401,25 +297,27 @@ } }, "node_modules/@astrojs/compiler-binding-wasm32-wasi": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-wasm32-wasi/-/compiler-binding-wasm32-wasi-0.4.0.tgz", - "integrity": "sha512-m/phuH3x3PREvv1OnkM44NoPh4MatUadix1fB1u5SvMLCyDTUZykDJbKnWf1cjnYmHdlB8HcjTjl6JrCqAIXcw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-wasm32-wasi/-/compiler-binding-wasm32-wasi-0.5.1.tgz", + "integrity": "sha512-yMhLL8asmLydoAdnEZxAw6eLfNDs3YJl6jqn0pjPt6zrb2U5qIDLnii4/twThpIFODKkQ6YDpBRTOz/vSfZCxw==", "cpu": [ "wasm32" ], "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^1.2.2" + "@emnapi/core": "1.11.3", + "@emnapi/runtime": "1.11.3", + "@napi-rs/wasm-runtime": "^1.2.4" }, "engines": { - "node": ">=14.0.0" + "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@astrojs/compiler-binding-win32-arm64-msvc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-arm64-msvc/-/compiler-binding-win32-arm64-msvc-0.4.0.tgz", - "integrity": "sha512-B9zYf3okEY83kM8gydlpH2BHP00w4ifxPqlYlWrgTwuD6wnkrJDCwBlgy1q31cERjCJRXN1lrE2VmkLvFjv/6g==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-arm64-msvc/-/compiler-binding-win32-arm64-msvc-0.5.1.tgz", + "integrity": "sha512-aClIG6poFt3Wf/bZykrEAX2nAnKvBHW6RXiKUa69QjBtWH0/FOlOAjnFcxRNlhej2AMWNYFx0o+LGjwMcH8P7Q==", "cpu": [ "arm64" ], @@ -433,9 +331,9 @@ } }, "node_modules/@astrojs/compiler-binding-win32-x64-msvc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-x64-msvc/-/compiler-binding-win32-x64-msvc-0.4.0.tgz", - "integrity": "sha512-zB0Nrv0dGc0zZWPGDRmmETTPhDRqyZjAjk+gWMlVrJX5U89obpB3VUUE1ZiHxOCN5LQojeLK6O8L/dnoHolvNQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-x64-msvc/-/compiler-binding-win32-x64-msvc-0.5.1.tgz", + "integrity": "sha512-/E6uBCagY70YpWqssBC+/FuniNSloeQPRgj7l3LDWiqjxIyTLnIgX1sTt18FU7jrigetpSnC9cHAM6b6IxSgPw==", "cpu": [ "x64" ], @@ -449,12 +347,12 @@ } }, "node_modules/@astrojs/compiler-rs": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler-rs/-/compiler-rs-0.4.0.tgz", - "integrity": "sha512-koVikeon1kreEy+/JzLQRy3vzHHQVOjycs4degg4vFufKApZOwMZvSSAEztYNhmcQVfNVsVZZI4cEge3cexAbQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-rs/-/compiler-rs-0.5.1.tgz", + "integrity": "sha512-1k1acnX7DepIiea9U9/Y+d1hdAFfylu1ZQQkkYgRSwBOBAsXInolyZuh/2tax+83vu/A+hOYP6P3+265RvMTvw==", "license": "MIT", "dependencies": { - "@astrojs/compiler-binding": "0.4.0" + "@astrojs/compiler-binding": "0.5.1" }, "engines": { "node": ">=22.12.0" @@ -477,21 +375,20 @@ } }, "node_modules/@astrojs/language-server": { - "version": "2.16.16", - "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.16.tgz", - "integrity": "sha512-KuS17AOOqH/M5mHXPmKvtp8L+NNteARC7Xjf395+9R9dtJOBndqdStwU4V+OKzYZpgZ+hliV13knzx/oMtFl7Q==", + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.17.1.tgz", + "integrity": "sha512-gG7bvMVNIXgoSe1pM9dI1HsSDLU1EIc/dSAYQ0DuReLyLkOBjsiqvaRYgQltWaldLxh0bNEqjgreLfjd9OnUxQ==", "dev": true, "license": "MIT", "dependencies": { - "@astrojs/compiler": "^2.13.1", + "@astrojs/astro2tsx": "^0.1.0", "@astrojs/yaml2ts": "^0.2.4", - "@jridgewell/sourcemap-codec": "^1.5.5", "@volar/kit": "~2.4.28", "@volar/language-core": "~2.4.28", "@volar/language-server": "~2.4.28", "@volar/language-service": "~2.4.28", "muggle-string": "^0.4.1", - "tinyglobby": "^0.2.16", + "tinyglobby": "^0.2.17", "volar-service-css": "0.0.71", "volar-service-emmet": "0.0.71", "volar-service-html": "0.0.71", @@ -500,7 +397,7 @@ "volar-service-typescript-twoslash-queries": "0.0.71", "volar-service-yaml": "0.0.71", "vscode-html-languageservice": "^5.6.2", - "vscode-uri": "^3.1.0" + "vscode-uri": "^3.2.0" }, "bin": { "astro-ls": "bin/nodeServer.js" @@ -519,9 +416,9 @@ } }, "node_modules/@astrojs/markdown-remark": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-7.3.0.tgz", - "integrity": "sha512-mRwn2W2PKkOj8XEAiD3b9RIF4qq6FKB6U4c98GxFLkEJH7uA6ZZv8TiqVjJSPMANLb1NtwBTgkY+KO4mTXnT/Q==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-7.3.1.tgz", + "integrity": "sha512-QCjsjZQl0+Cgb91+T3Ip9hyUe1r5aLm4udi584rML9YO3syupbAYE+jWpAxYg+z4lFLNUugPrylFxZ+8qFTClg==", "license": "MIT", "peer": true, "dependencies": { @@ -550,9 +447,9 @@ } }, "node_modules/@astrojs/markdown-satteri": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-satteri/-/markdown-satteri-0.4.0.tgz", - "integrity": "sha512-wykOOW9KsUVcZweOpY/CeXpdKcCKZy6fQbdcteWFuI75+sQCiqxYM7VKsGa5b+aGl3cYQscFY37rsbbyal5MRw==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-satteri/-/markdown-satteri-0.4.2.tgz", + "integrity": "sha512-g4QehXnB/MzxQWnSf17NciFInMqEJy9948p8cc7zGg/r7995m0Ln5PMr3Xlnj24iey1LchaoZ3SzTOa3D4P/3w==", "license": "MIT", "dependencies": { "@astrojs/internal-helpers": "0.11.0", @@ -562,13 +459,13 @@ } }, "node_modules/@astrojs/mdx": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-8.0.0.tgz", - "integrity": "sha512-4I/z+VgUO0B9I/+yhzIEpLyBYQZNJsInmrtqClP4lqX9yvUpbuV72zfRTZ8VqJLKABETUE5CYOl+23va8nqxZg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-8.0.2.tgz", + "integrity": "sha512-WedIVP2Bu8fXSzxb3ZYZ8xDrWWjf2SRKCneh52Llhoa+O3lcpHPhoZVP3FerlivUaH/0LJz2yVaCNvMdg0u8Bw==", "license": "MIT", "dependencies": { "@astrojs/internal-helpers": "0.11.0", - "@astrojs/markdown-satteri": "0.4.0", + "@astrojs/markdown-satteri": "0.4.2", "es-module-lexer": "^2.0.0" }, "engines": { @@ -577,7 +474,7 @@ "peerDependencies": { "@astrojs/markdown-remark": "^7.3.0", "@astrojs/markdown-satteri": "^0.4.0", - "astro": "^7.2.6" + "astro": "^7.2.10" }, "peerDependenciesMeta": { "@astrojs/markdown-remark": { @@ -585,12 +482,6 @@ } } }, - "node_modules/@astrojs/mdx/node_modules/es-module-lexer": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", - "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", - "license": "MIT" - }, "node_modules/@astrojs/prism": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-4.0.2.tgz", @@ -614,9 +505,9 @@ } }, "node_modules/@astrojs/starlight": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.42.0.tgz", - "integrity": "sha512-EVsGnyGJ6rRNwGRZFYmGABo0qTQ55F7OSmfSL0VK+5lsqD+u6GWcB8tFqXETcUvP8kyn90W+QBLSL2aer9jNJQ==", + "version": "0.42.5", + "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.42.5.tgz", + "integrity": "sha512-S6hjUexk9rrKtjJF3WR8T9dM1woNR7X2XU8e3wj4OpRT4X15AXk/mzPjWe/Qd5+P8whHj2+ves+k06qirBzimg==", "license": "MIT", "dependencies": { "@astrojs/markdown-satteri": "^0.4.0", @@ -658,15 +549,6 @@ } } }, - "node_modules/@astrojs/starlight/node_modules/magic-string": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", - "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, "node_modules/@astrojs/telemetry": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.3.tgz", @@ -682,21 +564,6 @@ "node": "18.20.8 || ^20.3.0 || >=22.0.0" } }, - "node_modules/@astrojs/telemetry/node_modules/is-docker": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-4.0.0.tgz", - "integrity": "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@astrojs/yaml2ts": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.4.tgz", @@ -709,6 +576,8 @@ }, "node_modules/@babel/code-frame": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", @@ -721,6 +590,8 @@ }, "node_modules/@babel/compat-data": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -728,6 +599,8 @@ }, "node_modules/@babel/core": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "license": "MIT", "peer": true, "dependencies": { @@ -757,6 +630,8 @@ }, "node_modules/@babel/generator": { "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.8", @@ -771,6 +646,8 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", "license": "MIT", "dependencies": { "@babel/types": "^7.29.7" @@ -781,6 +658,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.29.7", @@ -793,8 +672,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", @@ -814,6 +704,8 @@ }, "node_modules/@babel/helper-globals": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -821,6 +713,8 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.29.7", @@ -832,6 +726,8 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.29.7", @@ -843,6 +739,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.29.7", @@ -858,6 +756,8 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", "license": "MIT", "dependencies": { "@babel/types": "^7.29.7" @@ -868,6 +768,8 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -875,6 +777,8 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.29.7", @@ -890,6 +794,8 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.29.7", @@ -901,6 +807,8 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -908,6 +816,8 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -915,6 +825,8 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -922,6 +834,8 @@ }, "node_modules/@babel/helpers": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "license": "MIT", "dependencies": { "@babel/template": "^7.29.7", @@ -932,7 +846,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.8", + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", "license": "MIT", "dependencies": { "@babel/types": "^7.29.8" @@ -946,6 +862,8 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" @@ -959,6 +877,8 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" @@ -972,6 +892,8 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz", + "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.29.7", @@ -984,36 +906,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.29.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.29.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.29.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.29.7", + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.9.tgz", + "integrity": "sha512-FFwIwzU+7SCOuxxV4YtJql6T9981ZVTm+FHO5GhVsRqCTdy0WwrEZh3l42ARpXruJUDGOptdduHW6Zr7pNPLNg==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", @@ -1031,6 +927,8 @@ }, "node_modules/@babel/preset-typescript": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz", + "integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", @@ -1048,6 +946,8 @@ }, "node_modules/@babel/runtime": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -1055,6 +955,8 @@ }, "node_modules/@babel/template": { "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", @@ -1067,6 +969,8 @@ }, "node_modules/@babel/traverse": { "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", @@ -1083,6 +987,8 @@ }, "node_modules/@babel/types": { "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.29.7", @@ -1093,11 +999,13 @@ } }, "node_modules/@base-ui/react": { - "version": "1.7.0", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@base-ui/react/-/react-1.8.0.tgz", + "integrity": "sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.29.2", - "@base-ui/utils": "0.3.2", + "@babel/runtime": "^7.29.7", + "@base-ui/utils": "0.4.0", "@floating-ui/react-dom": "^2.1.9", "@floating-ui/utils": "^0.2.12", "use-sync-external-store": "^1.6.0" @@ -1129,10 +1037,12 @@ } }, "node_modules/@base-ui/utils": { - "version": "0.3.2", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@base-ui/utils/-/utils-0.4.0.tgz", + "integrity": "sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.29.2", + "@babel/runtime": "^7.29.7", "@floating-ui/utils": "^0.2.12", "reselect": "^5.2.0", "use-sync-external-store": "^1.6.0" @@ -1149,9 +1059,9 @@ } }, "node_modules/@better-auth/core": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@better-auth/core/-/core-1.7.6.tgz", - "integrity": "sha512-yBDDO0J4VCHT1qEZtzj6aMexX4etyLesitoxehcWHzPrzYqrFHwe/hgskye+imlGhQVOysuljMg8M8BA6GrtIg==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@better-auth/core/-/core-1.7.7.tgz", + "integrity": "sha512-srgFzHEjB2WWlokFz1i4BfG41sNhsA105Pukgqu6RrEh5A+LSkzf1mCHydVipkjt9l5qswtBMi7IL6ouHbZL4Q==", "license": "MIT", "peer": true, "dependencies": { @@ -1175,12 +1085,12 @@ } }, "node_modules/@better-auth/drizzle-adapter": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@better-auth/drizzle-adapter/-/drizzle-adapter-1.7.6.tgz", - "integrity": "sha512-ENlhwC7kkTjquuiel3Efggik0hC4vtD7ppJ8FhsiHhRJA8K6RT4hbhzkfm6keNvjdnAeWwCejm7FmMO4GoSGpA==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@better-auth/drizzle-adapter/-/drizzle-adapter-1.7.7.tgz", + "integrity": "sha512-qon0U94PR5FQysuyGoAlGVQpIIiNg5dtDpwjE63sN/HjoRWZadZzHPcS9mn7JsJyQZK6iTNhd7LD0AaXt2f78w==", "license": "MIT", "peerDependencies": { - "@better-auth/core": "^1.7.6", + "@better-auth/core": "^1.7.7", "@better-auth/utils": "0.4.2", "drizzle-orm": "^0.45.2 || >=1.0.0-rc.1 <2.0.0" }, @@ -1191,12 +1101,12 @@ } }, "node_modules/@better-auth/kysely-adapter": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@better-auth/kysely-adapter/-/kysely-adapter-1.7.6.tgz", - "integrity": "sha512-BV+DX2/z/6ozNC9DYSge78wjLerq6Bxd/lSPjzzuq9eEutkQDAJTuiaETzgGYqNV5LlEWi8TZFAQTEq/wavOEQ==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@better-auth/kysely-adapter/-/kysely-adapter-1.7.7.tgz", + "integrity": "sha512-9FONOCgOcrQI9wJ5v1oDGIg9sT7pa9RjZZQ4fsCTudo8R87SrIGNUvUxDFTJhZvUblvFfGaIBR9Vb8LA+8bqLQ==", "license": "MIT", "peerDependencies": { - "@better-auth/core": "^1.7.6", + "@better-auth/core": "^1.7.7", "@better-auth/utils": "0.4.2", "kysely": "^0.28.17 || ^0.29.0" }, @@ -1207,22 +1117,22 @@ } }, "node_modules/@better-auth/memory-adapter": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@better-auth/memory-adapter/-/memory-adapter-1.7.6.tgz", - "integrity": "sha512-ng1xv8k2JsEIjnqzJzdoVOQrnoCLRuk4EiQL9yYAThyg6zYzV00LynlhH+O9OMUZ+yGVpGqGZmr5xcTiUSV2uA==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@better-auth/memory-adapter/-/memory-adapter-1.7.7.tgz", + "integrity": "sha512-FqKFEe+b5tXXV0gRbyirca+qXgMpLOeJ8Wk19yykb/scQKy0WJ4k22WzEV3TTPctQV9DZhwCXPlDtQhnlOv5Gg==", "license": "MIT", "peerDependencies": { - "@better-auth/core": "^1.7.6", + "@better-auth/core": "^1.7.7", "@better-auth/utils": "0.4.2" } }, "node_modules/@better-auth/mongo-adapter": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@better-auth/mongo-adapter/-/mongo-adapter-1.7.6.tgz", - "integrity": "sha512-GvBwZli8i4XINMAj9tlW7eV9E8Dr+JWqavXjUs2o81GZt/Vh8wiX+31KK1jQ4iOuejfjpLoXcoFtlIPgf/pVog==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@better-auth/mongo-adapter/-/mongo-adapter-1.7.7.tgz", + "integrity": "sha512-ZnVDuRrXqbf0oHphrEN27oTImNH5NTO26dtWatq5cXyYAsH7goof9QIoTOmxTbBxUQahKBw9T6+9h6n+RtOE+g==", "license": "MIT", "peerDependencies": { - "@better-auth/core": "^1.7.6", + "@better-auth/core": "^1.7.7", "@better-auth/utils": "0.4.2", "mongodb": "^6.0.0 || ^7.0.0" }, @@ -1233,12 +1143,12 @@ } }, "node_modules/@better-auth/prisma-adapter": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@better-auth/prisma-adapter/-/prisma-adapter-1.7.6.tgz", - "integrity": "sha512-31rz2OXIx2Q1L4Jhd5F71dafIWqder/Bo6vJ+eCgO5iZ0gvnv7fUmM95DvbVUoPC69XYpcIM/6PJmQ3M6RydWg==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@better-auth/prisma-adapter/-/prisma-adapter-1.7.7.tgz", + "integrity": "sha512-4YcnrcVdvWiAZw0sZl63tWUClPXg5r3QsLn7C2sG7kKEBY06zOng0ibecyxRBixKq1zE1ceHuEUqez5Rhi+nQA==", "license": "MIT", "peerDependencies": { - "@better-auth/core": "^1.7.6", + "@better-auth/core": "^1.7.7", "@better-auth/utils": "0.4.2", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" @@ -1253,18 +1163,20 @@ } }, "node_modules/@better-auth/telemetry": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@better-auth/telemetry/-/telemetry-1.7.6.tgz", - "integrity": "sha512-xgRwPja2wTJtcu+OQZR2IiNpAmviddnW3n5Do5umXRugJFW3v9KlSmYjYm580mVsPnU4upvZkvSRl9v8DgSDtA==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@better-auth/telemetry/-/telemetry-1.7.7.tgz", + "integrity": "sha512-PaRA6i+kAioVYmza2gHPcdrxP0hAotph4KV9hft2GeNJq+AZXDiBu3FuLM9HxvcmiZeUT74Vufqd9ypmB8veTA==", "license": "MIT", "peerDependencies": { - "@better-auth/core": "^1.7.6", + "@better-auth/core": "^1.7.7", "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.2" } }, "node_modules/@better-auth/utils": { "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@better-auth/utils/-/utils-0.4.2.tgz", + "integrity": "sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==", "license": "MIT", "peer": true, "dependencies": { @@ -1280,6 +1192,8 @@ }, "node_modules/@borewit/text-codec": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", + "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==", "license": "MIT", "funding": { "type": "github", @@ -1292,12 +1206,25 @@ "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", "license": "MIT" }, - "node_modules/@bruits/satteri-darwin-arm64": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@bruits/satteri-darwin-arm64/-/satteri-darwin-arm64-0.10.5.tgz", - "integrity": "sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA==", - "cpu": [ - "arm64" + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@bruits/satteri-darwin-arm64": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-darwin-arm64/-/satteri-darwin-arm64-0.10.5.tgz", + "integrity": "sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA==", + "cpu": [ + "arm64" ], "license": "MIT", "optional": true, @@ -1447,6 +1374,8 @@ }, "node_modules/@cacheable/memory": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", "license": "MIT", "dependencies": { "@cacheable/utils": "^2.5.0", @@ -1457,6 +1386,8 @@ }, "node_modules/@cacheable/node-cache": { "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@cacheable/node-cache/-/node-cache-1.7.6.tgz", + "integrity": "sha512-6Omk2SgNnjtxB5f/E6bTIWIt5xhdpx39fGNRQgU9lojvRxU68v+qY+SXXLsp3ZGukqoPjsK21wZ6XABFr/Ge3A==", "license": "MIT", "dependencies": { "cacheable": "^2.3.1", @@ -1469,6 +1400,8 @@ }, "node_modules/@cacheable/utils": { "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", "license": "MIT", "dependencies": { "hashery": "^1.5.1", @@ -1494,9 +1427,9 @@ "license": "Apache-2.0" }, "node_modules/@clack/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.0.tgz", - "integrity": "sha512-zNikCcd8BbcEvzzG1sbXFrRHFk5kHPrpwZwksPvf9qyQO1Teb7JaXaOAxXZei9nZLDW0gaZawiuTCji88bTBhw==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.1.tgz", + "integrity": "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==", "license": "MIT", "dependencies": { "fast-wrap-ansi": "^0.2.0", @@ -1507,12 +1440,12 @@ } }, "node_modules/@clack/prompts": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.0.tgz", - "integrity": "sha512-PXzLZ8N34rxmuo4dJg3xtOXhcBse94qGjDqsteoEYrFrrZ5FSjIGwMAuOcv64ln8rHVBBD06XeVGr+/JX+plcA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.1.tgz", + "integrity": "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==", "license": "MIT", "dependencies": { - "@clack/core": "1.5.0", + "@clack/core": "1.5.1", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" @@ -1522,9 +1455,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.2.tgz", + "integrity": "sha512-grhRy3OKmniaAEKXMjua5z/EODX0MSqBGjunw8+j/3HQjOnahs2AGhvEOIYVUWcU6ScApbhLhVrQTX8XqrMrow==", "dev": true, "funding": [ { @@ -1538,13 +1471,13 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.4.3.tgz", + "integrity": "sha512-iex20d8CHVkyvg6B7UKV7uHnI2Bqo9g+EFfT9E0y+GvTvhZ/DwONJ+9aKb1dlqm0ZiGsL5RXjp0fCoJYnkeDjA==", "dev": true, "funding": [ { @@ -1558,17 +1491,17 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.2", + "@csstools/css-tokenizer": "^4.0.2" } }, "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.2.6.tgz", + "integrity": "sha512-iiPQ3iRWwnJkeEn6RIu6SJPr7hYrLz6XZ9s/QZl+2/LI5KQVjpl2fdmDSZKuD4xP6GMmMPgHFFXg6k1Wkz0Trg==", "dev": true, "funding": [ { @@ -1582,21 +1515,21 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" + "@csstools/color-helpers": "^6.1.2", + "@csstools/css-calc": "^3.4.3" }, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.2", + "@csstools/css-tokenizer": "^4.0.2" } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.2.tgz", + "integrity": "sha512-40cSKyMvK+tq4qz6Awrlye2WGuOKt3FwPgtGg6KTfbHOWNw+Rk1rzbAtZnZ6IBhsY491HLRnDXwoyBAijmmILA==", "dev": true, "funding": [ { @@ -1611,16 +1544,41 @@ "license": "MIT", "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-tokenizer": "^4.0.2" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.15.tgz", + "integrity": "sha512-J0u7HkVl2nzSlhsiTOp4AmwcUQ3D+mGEEKfBy/7To5/y7F2OHwyLrXfrhR0SMgr4p5Lo+eaMVSeai24zUcBIxA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } } }, "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.2.tgz", + "integrity": "sha512-OoKoR0f76dCY666JlcbhmVTs2drYj1GUXZTYTcbUgJjh9Nv41aFfZ21bPQTERm5+L5cBDo466NltB2lplS5GBw==", "dev": true, "funding": [ { @@ -1635,13 +1593,13 @@ "license": "MIT", "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@ctrl/tinycolor": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", - "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.1.tgz", + "integrity": "sha512-Vh5uy9Y1JBMId6J1f68TMXnZrTCvNdo9Fu2k0d1YnJngR+sM5kWTKl441c/3TFs+cG0NWOjRWgQ/iaWhbYx+7A==", "license": "MIT", "engines": { "node": ">=14" @@ -1649,6 +1607,8 @@ }, "node_modules/@dotenvx/dotenvx": { "version": "1.75.1", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.75.1.tgz", + "integrity": "sha512-/BITOC9dmS/edY2zQwZNicQ059O6RKabtQfyEafV0nGtfYRNHYy1DIPiYVcov40+tob9hfmBnbR963dS+EQ1DQ==", "license": "BSD-3-Clause", "dependencies": { "@dotenvx/primitives": "^0.8.0", @@ -1677,6 +1637,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/commander": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "license": "MIT", "engines": { "node": ">=16" @@ -1684,6 +1646,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/define-lazy-prop": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "license": "MIT", "engines": { "node": ">=8" @@ -1691,6 +1655,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/execa": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -1712,6 +1678,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/get-stream": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "license": "MIT", "engines": { "node": ">=10" @@ -1722,6 +1690,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/human-signals": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -1729,6 +1699,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/is-docker": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "license": "MIT", "bin": { "is-docker": "cli.js" @@ -1742,6 +1714,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/is-stream": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" @@ -1752,6 +1726,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/is-wsl": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "license": "MIT", "dependencies": { "is-docker": "^2.0.0" @@ -1762,6 +1738,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/isexe": { "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", "license": "BlueOak-1.0.0", "engines": { "node": ">=18" @@ -1769,6 +1747,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/npm-run-path": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -1779,6 +1759,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/open": { "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", @@ -1794,10 +1776,14 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/signal-exit": { "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, "node_modules/@dotenvx/dotenvx/node_modules/strip-final-newline": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "license": "MIT", "engines": { "node": ">=6" @@ -1805,6 +1791,8 @@ }, "node_modules/@dotenvx/dotenvx/node_modules/which": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "license": "ISC", "dependencies": { "isexe": "^3.1.1" @@ -1818,10 +1806,14 @@ }, "node_modules/@dotenvx/primitives": { "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@dotenvx/primitives/-/primitives-0.8.0.tgz", + "integrity": "sha512-VYJy0uhFm9zTJ1TxBaW/pA8bjbOM/OttaNMwZ1RHG4JKyRG7DhSdiqD1ipQoAyoD22olUtxbP78W9xY3Wd11bg==", "license": "BSD-3-Clause" }, "node_modules/@drizzle-team/brocli": { "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz", + "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==", "devOptional": true, "license": "Apache-2.0" }, @@ -1894,8 +1886,44 @@ "dev": true, "license": "MIT" }, + "node_modules/@emnapi/core": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz", + "integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==", + "devOptional": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "devOptional": true, + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", + "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild-kit/core-utils": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz", + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", + "deprecated": "Merged into tsx: https://tsx.hirok.io", "devOptional": true, "license": "MIT", "dependencies": { @@ -1953,6 +1981,8 @@ }, "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "cpu": [ "arm64" ], @@ -2255,6 +2285,8 @@ }, "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "devOptional": true, "hasInstallScript": true, "license": "MIT", @@ -2291,6 +2323,9 @@ }, "node_modules/@esbuild-kit/esm-loader": { "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", + "deprecated": "Merged into tsx: https://tsx.hirok.io", "devOptional": true, "license": "MIT", "dependencies": { @@ -2298,6 +2333,19 @@ "get-tsconfig": "^4.7.0" } }, + "node_modules/@esbuild-kit/esm-loader/node_modules/get-tsconfig": { + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.3.tgz", + "integrity": "sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", @@ -2364,6 +2412,8 @@ }, "node_modules/@esbuild/darwin-arm64": { "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", "cpu": [ "arm64" ], @@ -2712,6 +2762,24 @@ "node": ">=18" } }, + "node_modules/@exodus/bytes": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.16.0.tgz", + "integrity": "sha512-IcpW84uEn3N7ETtNZMlxKhfl6Pec8rUNGOTBtWbK1FKhJxIFAptZyVrvVRVBimAJxJCgc3PxepxkdWWG4DVzfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, "node_modules/@expressive-code/core": { "version": "0.44.2", "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.44.2.tgz", @@ -2759,6 +2827,8 @@ }, "node_modules/@floating-ui/core": { "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.12" @@ -2766,6 +2836,8 @@ }, "node_modules/@floating-ui/dom": { "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", "license": "MIT", "dependencies": { "@floating-ui/core": "^1.8.0", @@ -2774,6 +2846,8 @@ }, "node_modules/@floating-ui/react-dom": { "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.8.0" @@ -2785,10 +2859,14 @@ }, "node_modules/@floating-ui/utils": { "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", "license": "MIT" }, "node_modules/@fontsource-variable/geist": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource-variable/geist/-/geist-5.3.0.tgz", + "integrity": "sha512-j0m+vLQuG5XAYoHtGCVu0spvlGreR3EzpECUVzkFmI1mTVnAO38l/NEPDCFgZ177JxzYJCLSmTQibIiYPilGrA==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" @@ -2796,17 +2874,23 @@ }, "node_modules/@fontsource-variable/space-grotesk": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource-variable/space-grotesk/-/space-grotesk-5.3.0.tgz", + "integrity": "sha512-2IxmvfB08i9vnGB3Ym/AXvhRE+8XOjWMXIyDum03c+tPwH0FUoMNQfGpU8NXPxjbws0Vvss3AH0Zqt4oJBBAdw==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" } }, "node_modules/@grammyjs/types": { - "version": "4.0.0", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@grammyjs/types/-/types-5.0.0.tgz", + "integrity": "sha512-iq1Qrq1iPKkB8yAa0qSuIURMZOCuqTY5pWy5gHpCeL1oQ+GPadGhw/cDTVE8waJwuCzacUzuIjRv1sESvk7u7A==", "license": "MIT" }, "node_modules/@grpc/grpc-js": { - "version": "1.14.4", + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.5.tgz", + "integrity": "sha512-7VZM+SVdEcUUqSQeNI3zM8Qs/BhQKZndPo2h5VkYkAM8Iz0wJIa8mKV5ekQGqG8UUsnkQ0NMxIxwkIHYvj0qOw==", "license": "Apache-2.0", "dependencies": { "@grpc/proto-loader": "^0.8.0", @@ -2818,6 +2902,8 @@ }, "node_modules/@grpc/proto-loader": { "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", + "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", @@ -2832,8 +2918,103 @@ "node": ">=6" } }, + "node_modules/@grpc/proto-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/@grpc/proto-loader/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@grpc/proto-loader/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/@hapi/boom": { "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.4.tgz", + "integrity": "sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "9.x.x" @@ -2841,13 +3022,17 @@ }, "node_modules/@hapi/hoek": { "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", "license": "BSD-3-Clause" }, "node_modules/@hono/node-server": { - "version": "1.19.17", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.3.tgz", + "integrity": "sha512-TA//nWMqPhbfdfneACk6t5a9eqbS9lABEPyKn0/xZTah3H3U2XaVg85rJFl0/Fyit0I552YDHgXGVSf3GwqbUw==", "license": "MIT", "engines": { - "node": ">=18.14.1" + "node": ">=20" }, "peerDependencies": { "hono": "^4" @@ -2872,15 +3057,17 @@ }, "node_modules/@img/colour": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", - "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.5.tgz", + "integrity": "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==", "cpu": [ "arm64" ], @@ -2896,13 +3083,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.3" + "@img/sharp-libvips-darwin-arm64": "1.3.4" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", - "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.5.tgz", + "integrity": "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==", "cpu": [ "x64" ], @@ -2918,20 +3105,20 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.3" + "@img/sharp-libvips-darwin-x64": "1.3.4" } }, "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", - "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.5.tgz", + "integrity": "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==", "license": "Apache-2.0", "optional": true, "os": [ "freebsd" ], "dependencies": { - "@img/sharp-wasm32": "0.35.4" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -2941,9 +3128,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", - "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.4.tgz", + "integrity": "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==", "cpu": [ "arm64" ], @@ -2957,9 +3144,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", - "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.4.tgz", + "integrity": "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==", "cpu": [ "x64" ], @@ -2973,9 +3160,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", - "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.4.tgz", + "integrity": "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==", "cpu": [ "arm" ], @@ -2989,9 +3176,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", - "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.4.tgz", + "integrity": "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==", "cpu": [ "arm64" ], @@ -3005,9 +3192,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", - "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.4.tgz", + "integrity": "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==", "cpu": [ "ppc64" ], @@ -3021,9 +3208,9 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", - "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.4.tgz", + "integrity": "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==", "cpu": [ "riscv64" ], @@ -3037,9 +3224,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", - "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.4.tgz", + "integrity": "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==", "cpu": [ "s390x" ], @@ -3053,9 +3240,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", - "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.4.tgz", + "integrity": "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==", "cpu": [ "x64" ], @@ -3069,9 +3256,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", - "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.4.tgz", + "integrity": "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==", "cpu": [ "arm64" ], @@ -3085,9 +3272,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", - "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.4.tgz", + "integrity": "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==", "cpu": [ "x64" ], @@ -3101,9 +3288,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", - "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.5.tgz", + "integrity": "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==", "cpu": [ "arm" ], @@ -3119,13 +3306,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.3" + "@img/sharp-libvips-linux-arm": "1.3.4" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", - "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.5.tgz", + "integrity": "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==", "cpu": [ "arm64" ], @@ -3141,13 +3328,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.3" + "@img/sharp-libvips-linux-arm64": "1.3.4" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", - "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.5.tgz", + "integrity": "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==", "cpu": [ "ppc64" ], @@ -3163,13 +3350,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.3" + "@img/sharp-libvips-linux-ppc64": "1.3.4" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", - "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.5.tgz", + "integrity": "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==", "cpu": [ "riscv64" ], @@ -3185,13 +3372,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.3" + "@img/sharp-libvips-linux-riscv64": "1.3.4" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", - "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.5.tgz", + "integrity": "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==", "cpu": [ "s390x" ], @@ -3207,13 +3394,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.3" + "@img/sharp-libvips-linux-s390x": "1.3.4" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", - "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.5.tgz", + "integrity": "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==", "cpu": [ "x64" ], @@ -3229,13 +3416,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.3" + "@img/sharp-libvips-linux-x64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", - "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.5.tgz", + "integrity": "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==", "cpu": [ "arm64" ], @@ -3251,13 +3438,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", - "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.5.tgz", + "integrity": "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==", "cpu": [ "x64" ], @@ -3273,13 +3460,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.3" + "@img/sharp-libvips-linuxmusl-x64": "1.3.4" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", - "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.5.tgz", + "integrity": "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==", "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -3293,16 +3480,16 @@ } }, "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", - "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.5.tgz", + "integrity": "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==", "cpu": [ "wasm32" ], "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/sharp-wasm32": "0.35.4" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -3312,9 +3499,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", - "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.5.tgz", + "integrity": "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==", "cpu": [ "arm64" ], @@ -3331,9 +3518,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", - "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.5.tgz", + "integrity": "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==", "cpu": [ "ia32" ], @@ -3350,9 +3537,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", - "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.5.tgz", + "integrity": "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==", "cpu": [ "x64" ], @@ -3370,6 +3557,8 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -3378,6 +3567,8 @@ }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -3386,6 +3577,8 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -3393,6 +3586,8 @@ }, "node_modules/@jridgewell/source-map": { "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -3400,11 +3595,15 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3413,6 +3612,8 @@ }, "node_modules/@js-sdsl/ordered-map": { "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", "license": "MIT", "funding": { "type": "opencollective", @@ -3421,11 +3622,15 @@ }, "node_modules/@jsdevtools/ono": { "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", "dev": true, "license": "MIT" }, "node_modules/@jsonjoy.com/base64": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3440,6 +3645,8 @@ }, "node_modules/@jsonjoy.com/buffers": { "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3454,6 +3661,8 @@ }, "node_modules/@jsonjoy.com/codegen": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3467,11 +3676,13 @@ } }, "node_modules/@jsonjoy.com/fs-core": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.80.0.tgz", + "integrity": "sha512-qMKWshnyjbyhm+NbzqGE3w5y1mckFFEMj0aDPU2/JBNh1BzIjVy9esq9lBmRnNVmhMEkxwDzLZ8Gqh5G1P5Dag==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.68.1", - "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.80.0", + "@jsonjoy.com/fs-node-utils": "4.80.0", "thingies": "^2.5.0" }, "engines": { @@ -3486,12 +3697,14 @@ } }, "node_modules/@jsonjoy.com/fs-fsa": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.80.0.tgz", + "integrity": "sha512-ZBEKl7J6dbkRCfmrFV48Re211A/FHqniTUhsWCsaRteNSOqMgkX3qF1UreVgwB9oSPm81JLAwhIi6Lb/NH/PoA==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.68.1", - "@jsonjoy.com/fs-node-builtins": "4.68.1", - "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-core": "4.80.0", + "@jsonjoy.com/fs-node-builtins": "4.80.0", + "@jsonjoy.com/fs-node-utils": "4.80.0", "thingies": "^2.5.0" }, "engines": { @@ -3506,15 +3719,17 @@ } }, "node_modules/@jsonjoy.com/fs-node": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.80.0.tgz", + "integrity": "sha512-yiBlUfkMMRFFGy8CD/h2zd5rPnrM6bjlF+nx2LRAxNV6hOSiuObQIUEE7m7y2VTMisjxCRtzINH94bFGySWL7g==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.68.1", - "@jsonjoy.com/fs-node-builtins": "4.68.1", - "@jsonjoy.com/fs-node-utils": "4.68.1", - "@jsonjoy.com/fs-print": "4.68.1", - "@jsonjoy.com/fs-snapshot": "4.68.1", - "glob-to-regex.js": "^1.0.0", + "@jsonjoy.com/fs-core": "4.80.0", + "@jsonjoy.com/fs-node-builtins": "4.80.0", + "@jsonjoy.com/fs-node-utils": "4.80.0", + "@jsonjoy.com/fs-print": "4.80.0", + "@jsonjoy.com/fs-snapshot": "4.80.0", + "glob-to-regex.js": "^1.3.1", "thingies": "^2.5.0" }, "engines": { @@ -3529,7 +3744,9 @@ } }, "node_modules/@jsonjoy.com/fs-node-builtins": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.80.0.tgz", + "integrity": "sha512-OIOIhqaWiwUySFMny4epIAoviXsyMaQQ63PTc3zH+5HEOvarl5hpUmZIhp2m5+OfyKAh5ylxXnQIgew1OgJDVw==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3543,12 +3760,14 @@ } }, "node_modules/@jsonjoy.com/fs-node-to-fsa": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.80.0.tgz", + "integrity": "sha512-ljeaR5xwtX1EyRmB0wvXANUMQZ3mjKcm7z8s2N8D8SLQ04CcAGtUhHFRZQXFb9mhgFyEVMydQGQtSOFS7pcrFQ==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-fsa": "4.68.1", - "@jsonjoy.com/fs-node-builtins": "4.68.1", - "@jsonjoy.com/fs-node-utils": "4.68.1" + "@jsonjoy.com/fs-fsa": "4.80.0", + "@jsonjoy.com/fs-node-builtins": "4.80.0", + "@jsonjoy.com/fs-node-utils": "4.80.0" }, "engines": { "node": ">=10.0" @@ -3562,11 +3781,13 @@ } }, "node_modules/@jsonjoy.com/fs-node-utils": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.80.0.tgz", + "integrity": "sha512-xwHeVVi3f+Khg/Fmb8i5qoYVmQ08QznE5TWhQokUmIZjz4KBPzU+zt/+bahBI6G1ghtqajt27lWuAciIxApuzA==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.68.1", - "glob-to-regex.js": "^1.0.1" + "@jsonjoy.com/fs-node-builtins": "4.80.0", + "glob-to-regex.js": "^1.3.1" }, "engines": { "node": ">=10.0" @@ -3580,10 +3801,12 @@ } }, "node_modules/@jsonjoy.com/fs-print": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.80.0.tgz", + "integrity": "sha512-1ocZLJw/m/xlq0moaIHO7HV9nHRVBUvdc2zMzhsJGkFOrqfwWvexfCv5cYCPPLRhP+9p3yunoi4Ep5YhRORC9Q==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.80.0", "tree-dump": "^1.1.0" }, "engines": { @@ -3598,11 +3821,13 @@ } }, "node_modules/@jsonjoy.com/fs-snapshot": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.80.0.tgz", + "integrity": "sha512-3AV23Q1H228KTtJKTUE0nNq8FCtxSvtENOLrEat80wkAJCKHuqQEv8yjhpS8Bei2OEFJAnluGXp9Ri2SWBlROw==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/buffers": "^17.65.0", - "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.80.0", "@jsonjoy.com/json-pack": "^17.65.0", "@jsonjoy.com/util": "^17.65.0" }, @@ -3619,6 +3844,8 @@ }, "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3633,6 +3860,8 @@ }, "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3647,6 +3876,8 @@ }, "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/base64": "17.67.0", @@ -3671,6 +3902,8 @@ }, "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/util": "17.67.0" @@ -3688,6 +3921,8 @@ }, "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/buffers": "17.67.0", @@ -3706,6 +3941,8 @@ }, "node_modules/@jsonjoy.com/json-pack": { "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/base64": "^1.1.2", @@ -3730,6 +3967,8 @@ }, "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3744,6 +3983,8 @@ }, "node_modules/@jsonjoy.com/json-pointer": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/codegen": "^1.0.0", @@ -3762,6 +4003,8 @@ }, "node_modules/@jsonjoy.com/util": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/buffers": "^1.0.0", @@ -3780,6 +4023,8 @@ }, "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -3794,6 +4039,8 @@ }, "node_modules/@keyv/bigmap": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", "license": "MIT", "dependencies": { "hashery": "^1.4.0", @@ -3808,44 +4055,46 @@ }, "node_modules/@keyv/serialize": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", "license": "MIT" }, - "node_modules/@lightspeed-ai/agent-client": { - "resolved": "clients/typescript", - "link": true - }, - "node_modules/@lightspeed/configurator-mcp": { + "node_modules/@lightspeed-ai/configurator-mcp": { "resolved": "platform/configurator-mcp", "link": true }, - "node_modules/@lightspeed/connectors": { + "node_modules/@lightspeed-ai/connectors": { "resolved": "platform/connectors", "link": true }, - "node_modules/@lightspeed/docs": { + "node_modules/@lightspeed-ai/docs": { "resolved": "docs/site", "link": true }, - "node_modules/@lightspeed/platform-cli": { - "resolved": "platform/cli", + "node_modules/@lightspeed-ai/platform-backend": { + "resolved": "platform/backend", "link": true }, - "node_modules/@lightspeed/platform-db": { - "resolved": "platform/db", + "node_modules/@lightspeed-ai/platform-cli": { + "resolved": "platform/cli", "link": true }, - "node_modules/@lightspeed/platform-server": { - "resolved": "platform/server", + "node_modules/@lightspeed-ai/platform-db": { + "resolved": "platform/db", "link": true }, - "node_modules/@lightspeed/platform-shared": { + "node_modules/@lightspeed-ai/platform-shared": { "resolved": "platform/shared", "link": true }, - "node_modules/@lightspeed/platform-web": { + "node_modules/@lightspeed-ai/platform-web": { "resolved": "platform/web", "link": true }, + "node_modules/@lightspeed-ai/sdk": { + "resolved": "clients/typescript", + "link": true + }, "node_modules/@mdx-js/mdx": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", @@ -3893,16 +4142,16 @@ } }, "node_modules/@modelcontextprotocol/client": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/client/-/client-2.0.0.tgz", - "integrity": "sha512-8f1OghQ2rjzIOfqgUCP+8GiUWqRs89njoWLNqAe8kWmDePv3s1fZXseej+QXemssEuuOvLLmLO/kqM3IQHtISw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/client/-/client-2.3.0.tgz", + "integrity": "sha512-pbHtGj6EeFCHngFE8gtNPaKrsj8Mb1IMw45BLcaPML/m2WTxI7pyYmeNQvaux88Lw8BSO5r7nyRbUyIkICmGrg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@modelcontextprotocol/core": "2.0.0", + "@modelcontextprotocol/core": "2.3.0", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", - "eventsource-parser": "^3.0.0", + "eventsource-parser": "^3.0.8", "jose": "^6.1.3", "pkce-challenge": "^5.0.0", "zod": "^4.2.0" @@ -3912,10 +4161,10 @@ } }, "node_modules/@modelcontextprotocol/core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.0.0.tgz", - "integrity": "sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==", - "license": "MIT", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.3.0.tgz", + "integrity": "sha512-09BHFaNVBe5pB2AhzCfLj0cqmsKLERvZQ4FblzP90UMGLaXVqdZPByFjURwsUYCmxonUW2yAwgTTvle+8O2/8w==", + "license": "Apache-2.0", "dependencies": { "zod": "^4.2.0" }, @@ -3924,31 +4173,40 @@ } }, "node_modules/@modelcontextprotocol/node": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/node/-/node-2.0.0.tgz", - "integrity": "sha512-Y4hAC2XdGDUdDOCbLDOCA4+aL3NUldjsOWlDL/YwpAxrPhRm1xHd7lZ+mLacvZ9t3PaH28wgNoaLQGrIk1P2pg==", - "license": "MIT", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/node/-/node-2.1.1.tgz", + "integrity": "sha512-EY92OAXN2xYL7tNS/MVsWJW1v8VHAPwl9B4Ca3pCrjmvqyC+S1C/6UHsMxF2GoFPraS5Yyg56vFz9brVpFojMA==", + "license": "Apache-2.0", "dependencies": { - "@hono/node-server": "^1.19.9" + "@hono/node-server": "^1.19.9", + "hono": "^4.11.4" }, "engines": { "node": ">=20" }, "peerDependencies": { - "@modelcontextprotocol/server": "^2.0.0", - "hono": "^4.11.4" + "@modelcontextprotocol/server": "^2.3.0" + } + }, + "node_modules/@modelcontextprotocol/node/node_modules/@hono/node-server": { + "version": "1.19.17", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.17.tgz", + "integrity": "sha512-dSneS5qhiauZWGDCeK4o695Xd9nUNjviSZCMQrj10eetr8Uln1ucn6bbphOM6UynAMMtNIzZNSpL9vnASJwrPQ==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" }, - "peerDependenciesMeta": { - "hono": { - "optional": true - } + "peerDependencies": { + "hono": "^4" } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.29.0", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.0.tgz", + "integrity": "sha512-8BviX/hK4Gd2eL1KdTwm0gfl4d3wdoErW0Jd00h6nomUAtk6IJk5vwQJc6kfWtJTzN5OEV/lgIiJKI8fiDGAlA==", "license": "MIT", "dependencies": { - "@hono/node-server": "^1.19.9", + "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", @@ -3983,41 +4241,25 @@ } }, "node_modules/@modelcontextprotocol/server": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.0.0.tgz", - "integrity": "sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==", - "license": "MIT", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.3.0.tgz", + "integrity": "sha512-+6b0LdsQLmHsvS7J6sQJ4weTpzUn61fU1JKS+321/+IyDYoHW5CR2Tgqcs6GgAAQvlesCo6yX3xttgmx+XGtJw==", + "license": "Apache-2.0", "peer": true, "dependencies": { - "@modelcontextprotocol/core": "2.0.0", + "@modelcontextprotocol/core": "2.3.0", "zod": "^4.2.0" }, "engines": { "node": ">=20" } }, - "node_modules/@napi-rs/lzma-linux-x64-gnu": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", - "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz", - "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.4.tgz", + "integrity": "sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g==", + "devOptional": true, "license": "MIT", - "optional": true, "dependencies": { "@tybys/wasm-util": "^0.10.3" }, @@ -4034,7 +4276,9 @@ } }, "node_modules/@noble/ciphers": { - "version": "2.3.0", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.4.0.tgz", + "integrity": "sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw==", "license": "MIT", "engines": { "node": ">= 20.19.0" @@ -4044,7 +4288,9 @@ } }, "node_modules/@noble/hashes": { - "version": "2.2.0", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.4.0.tgz", + "integrity": "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==", "license": "MIT", "engines": { "node": ">= 20.19.0" @@ -4055,6 +4301,8 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -4066,6 +4314,8 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "license": "MIT", "engines": { "node": ">= 8" @@ -4073,6 +4323,8 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -4098,9 +4350,9 @@ "license": "MIT" }, "node_modules/@oxc-project/types": { - "version": "0.148.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", - "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", + "version": "0.152.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", + "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/oxc-project" @@ -4205,26 +4457,38 @@ }, "node_modules/@pinojs/redact": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", "license": "MIT" }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1" @@ -4232,24 +4496,32 @@ }, "node_modules/@protobufjs/float": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", "license": "BSD-3-Clause" }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", - "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", + "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", "cpu": [ "arm" ], @@ -4263,9 +4535,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", - "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", + "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", "cpu": [ "arm64" ], @@ -4279,9 +4551,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", - "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", + "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", "cpu": [ "arm64" ], @@ -4295,9 +4567,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", - "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", + "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", "cpu": [ "x64" ], @@ -4311,9 +4583,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", - "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", + "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", "cpu": [ "x64" ], @@ -4327,9 +4599,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", - "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", + "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", "cpu": [ "arm" ], @@ -4343,9 +4615,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", - "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", + "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", "cpu": [ "arm64" ], @@ -4359,9 +4631,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", - "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", + "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", "cpu": [ "arm64" ], @@ -4375,9 +4647,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", - "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", + "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", "cpu": [ "ppc64" ], @@ -4391,9 +4663,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", - "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", + "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", "cpu": [ "s390x" ], @@ -4407,9 +4679,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", - "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", + "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", "cpu": [ "x64" ], @@ -4423,9 +4695,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", - "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", + "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", "cpu": [ "x64" ], @@ -4439,9 +4711,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", - "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", + "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", "cpu": [ "arm64" ], @@ -4455,9 +4727,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", - "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", + "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", "cpu": [ "arm64" ], @@ -4471,9 +4743,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", - "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", + "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", "cpu": [ "x64" ], @@ -4487,1156 +4759,928 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "dev": true, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "license": "MIT" }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", - "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", - "cpu": [ - "arm" - ], + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@shadcn/react": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@shadcn/react/-/react-0.3.1.tgz", + "integrity": "sha512-2gOR0HDMtWeRsCZfNDaU0YDFdgH3zsDQ6lz67Fv/y/qjY9y+R8kJqAn6q56phqv7/zHi0wqURjntrNO9zL7vnQ==", "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "peerDependencies": { + "@types/react": ">=19", + "react": ">=19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", - "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", - "cpu": [ - "arm64" - ], + "node_modules/@shadcn/registry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@shadcn/registry/-/registry-0.1.0.tgz", + "integrity": "sha512-eMF6tPNi9SWZgPvqBvPQFhJN7gV9PcjRdF3kPiiWo5yZJocWqVgxFuspCHrOij3bIJ797NIGZ+j/v7AiXfA6qg==", "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/plugin-transform-typescript": "^7.28.0", + "@babel/preset-typescript": "^7.27.1", + "@dotenvx/dotenvx": "^1.48.4", + "cn": "^0.2.4", + "cosmiconfig": "^9.0.0", + "deepmerge": "^4.3.1", + "execa": "^9.6.0", + "fast-glob": "^3.3.3", + "fs-extra": "^11.3.1", + "fuzzysort": "^3.1.0", + "kleur": "^4.1.5", + "ora": "^8.2.0", + "postcss": "^8.5.23", + "prompts": "^2.4.2", + "recast": "^0.23.11", + "socks": "^2.8.8", + "stringify-object": "^5.0.0", + "ts-morph": "^26.0.0", + "tsconfig-paths": "^4.2.0", + "type-fest": "^4.41.0", + "undici": "^7.29.0", + "zod": "^3.24.1" + }, + "engines": { + "node": ">=20.18.1" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.62.4", - "cpu": [ - "arm64" - ], + "node_modules/@shadcn/registry/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", - "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", - "cpu": [ - "x64" - ], + "node_modules/@shikijs/core": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.5.0.tgz", + "integrity": "sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@shikijs/primitive": "4.5.0", + "@shikijs/types": "4.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5", + "hast-util-to-html": "^9.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.5.0.tgz", + "integrity": "sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.6" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.5.0.tgz", + "integrity": "sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.5.0", + "@shikijs/vscode-textmate": "^10.0.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/langs": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.5.0.tgz", + "integrity": "sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.5.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/primitive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.5.0.tgz", + "integrity": "sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/themes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.5.0.tgz", + "integrity": "sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.5.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/types": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.5.0.tgz", + "integrity": "sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@swc/core": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.16.13.tgz", + "integrity": "sha512-k4uUsIMS0IwOKVsrQs48IZK75O4roV3FnuJEdL7ES+DFESftdgvz73QBqN3VUAbUmUr78We4tzG0kgYj36M22Q==", + "hasInstallScript": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.28" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.16.13", + "@swc/core-darwin-x64": "1.16.13", + "@swc/core-linux-arm-gnueabihf": "1.16.13", + "@swc/core-linux-arm64-gnu": "1.16.13", + "@swc/core-linux-arm64-musl": "1.16.13", + "@swc/core-linux-ppc64-gnu": "1.16.13", + "@swc/core-linux-s390x-gnu": "1.16.13", + "@swc/core-linux-x64-gnu": "1.16.13", + "@swc/core-linux-x64-musl": "1.16.13", + "@swc/core-win32-arm64-msvc": "1.16.13", + "@swc/core-win32-ia32-msvc": "1.16.13", + "@swc/core-win32-x64-msvc": "1.16.13" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", - "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "node_modules/@swc/core-darwin-arm64": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.16.13.tgz", + "integrity": "sha512-JrMH2h7ohd4mOIneNRx/diqTmCDSdWfp9uOdQ8VJ2V2CA7jOJ1jWb+qp8RoZLqgiVmwDDC7eySKB1kbvZ+jVXQ==", "cpu": [ "arm64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ - "freebsd" - ] + "darwin" + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", - "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "node_modules/@swc/core-darwin-x64": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.16.13.tgz", + "integrity": "sha512-HauZMRxpOImRxgY6GXjw5gbD8ts2NcPZuLMM8htY8Mic7j1Izt/lxkXrKYUwqyU56YLwQZ4dHRT+6jFHkztcag==", "cpu": [ "x64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", - "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", - "cpu": [ - "arm" + "darwin" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", - "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.16.13.tgz", + "integrity": "sha512-tUSojGIythnHJKrElDM9OvuhBnK+FF39eM9iIBgj9kdfbAm6PhAM7dKbaSDcnX2gOLG2slkasjD0Z8m/YUlzOA==", "cpu": [ "arm" ], - "license": "MIT", + "license": "Apache-2.0", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", - "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.16.13.tgz", + "integrity": "sha512-qS3bk/ezRrLXGn1b764S/EG3/oKj6uRhnTNRAALpnuu8d9I0YwSiUkQghnX7lOH9X/yRr+qrFI3R0wAruO47Tg==", "cpu": [ "arm64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", - "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.16.13.tgz", + "integrity": "sha512-aeoYoG6fQsOS3mFOuTKvnJo1aaaxYNI0aRRlhdHaGP4q1YQx4XOc5Hkd35IFduWCBG3eZl3fPTjRuYvxpl7eTA==", "cpu": [ "arm64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", - "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.16.13.tgz", + "integrity": "sha512-eEFoueZXWZ2S1lsqL8Ve2C8RjhzH9+Ktj8U4IGTUQL6CNG04+VhQiYQWJOf5xfVBU6I+PbH80yvsYegqZOOSZQ==", "cpu": [ - "loong64" + "ppc64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", - "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.16.13.tgz", + "integrity": "sha512-K0q1ReVXL3d5bzBgZxS+yJq5q2xRjg4k2XXGj9yiCEpE5ZqJGQ4Gtk1sRrk8W2lo3KY0DCJD3Myt6x2SMvGArQ==", "cpu": [ - "loong64" + "s390x" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", - "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.16.13.tgz", + "integrity": "sha512-Qvpihw30irhIjy2f91BR1pamcJBCgf8hmr9XWenztAX1YLkneRkkTB/PFGWQubhaBqQhY2uZKViMj/xV61uMBQ==", "cpu": [ - "ppc64" + "x64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", - "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.16.13.tgz", + "integrity": "sha512-iCGxHbh3Cq5vqRvCPlw3XkkDz4RlkPSyQwfFKbOKTMj5tiEuojY/rLmf4BMfI9Z8yPJTf9VB07t3NbKInoC97g==", "cpu": [ - "ppc64" + "x64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", - "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.16.13.tgz", + "integrity": "sha512-iOabn6cd+hg3cnoKlAC8j3Yufv8nQHBVU5OIDX8dCPA95PjAZ0B0TlDn9sWivk8ezo/cLJux7p9n0B9vRej+1Q==", "cpu": [ - "riscv64" + "arm64" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ - "linux" - ] + "win32" + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", - "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.16.13.tgz", + "integrity": "sha512-+1b/3xBNuVbpnJIZUCAaSdscOPYRWq85eohKx44y/3qbPp56UMiCJWBiWtyr7K5F1nf1JENXm2IBSEJaLgWq6Q==", "cpu": [ - "riscv64" + "ia32" ], - "license": "MIT", + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ - "linux" - ] + "win32" + ], + "engines": { + "node": ">=10" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", - "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.16.13", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.16.13.tgz", + "integrity": "sha512-6kEJhYshk7OVoVIWryiHqjCNuwZeOlPTS6et+bKV/WhtHs8fLA01wyTLrQGi+4ultgRe/o0M4b25K/KKdvl0dQ==", "cpu": [ - "s390x" + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/types": { + "version": "0.1.28", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.28.tgz", + "integrity": "sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@tabler/icons": { + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.48.0.tgz", + "integrity": "sha512-lQk06gVHNVBnJp0UOgtth54mcZBJM7rdYKsAxKOProj1bbSAx+/xiuOWfHlyvgdL3M+Y+I0HINrjHa3ygp8eXQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-react": { + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.48.0.tgz", + "integrity": "sha512-OCeAlpaWHEMV+EsgdVeGQ3YuKfmfnThZhc++CaZ/ujYzi5+/DONDQlX4OGvH1ikYhIfmc0grI4otJgHy7QAvng==", + "license": "MIT", + "dependencies": { + "@tabler/icons": "3.48.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.3" + } + }, + "node_modules/@tailwindcss/node/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", + "cpu": [ + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "android" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", - "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", "cpu": [ - "x64" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", - "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" - ] + "darwin" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", - "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "openbsd" - ] + "freebsd" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", - "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", "cpu": [ - "arm64" + "arm" ], "license": "MIT", "optional": true, "os": [ - "openharmony" - ] + "linux" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", - "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", - "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", "cpu": [ - "ia32" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", - "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.62.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", - "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "win32" - ] - }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "license": "MIT" + "linux" + ], + "engines": { + "node": ">= 20" + } }, - "node_modules/@shadcn/react": { - "version": "0.2.1", + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], "license": "MIT", - "peerDependencies": { - "@types/react": ">=19", - "react": ">=19" + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - } + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@shikijs/core": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.4.3.tgz", - "integrity": "sha512-QCR4q2ZO/ILJEuwiBMel4wdcTDb1JGwfjKTxPDF6x8ixOaluPrVqIn06C99AcRPhmYlBR56d/Fb+GN58GzExpg==", + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz", + "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==", "license": "MIT", "dependencies": { - "@shikijs/primitive": "4.4.3", - "@shikijs/types": "4.4.3", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.5", - "hast-util-to-html": "^9.0.5" + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "tailwindcss": "4.3.3" }, - "engines": { - "node": ">=20" + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, - "node_modules/@shikijs/engine-javascript": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.4.3.tgz", - "integrity": "sha512-FbOjFJp9VLdo1Wevs10BBtVxiTWwNLqZh5Gkhjgda/ioL15YOgeSl9n+6XMa3qRlPQzfhFNe641SrynFHYG0nQ==", + "node_modules/@tanstack/query-core": { + "version": "5.104.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.104.1.tgz", + "integrity": "sha512-TiRghcrGkUTE+M4JBxvpPSpBhxvIzQairw+cksrHYGr+2uwC77yW1SY9nYxnYRYOppvucf8rEg6b5byoz4rTpw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.104.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.104.1.tgz", + "integrity": "sha512-Zz70EgjahNI7aCz8BZxM3vUGU44ycxEAzMuCUjLeA7SVhhOkg3ZgPjPJPvHjs6Rmky/dtmnu1WzjGHNHmhCoZQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.4.3", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.6" + "@tanstack/query-core": "5.104.1" }, - "engines": { - "node": ">=20" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" } }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.4.3.tgz", - "integrity": "sha512-EcOQkxdxGQrc1Row/cC2c96/v1dbZqGnEVu1qTuT/MJmp6+cXCvQussowVmCv5Tqr3KuY3c7IbM6HTW3LJ1k9w==", + "node_modules/@temporalio/activity": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/activity/-/activity-1.24.0.tgz", + "integrity": "sha512-eBBho/r9XHe2KczYGzmaSp6e9+6c9ta/GGOBldIBr00D/cV34kJ76iAY3Ue1pQTaP7YaX3phMuOz07uUg/IKyA==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.4.3", - "@shikijs/vscode-textmate": "^10.0.2" + "@temporalio/client": "1.24.0", + "@temporalio/common": "1.24.0" }, "engines": { - "node": ">=20" + "node": ">= 20.3.0" } }, - "node_modules/@shikijs/langs": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.4.3.tgz", - "integrity": "sha512-ePic0yfAJGOF83D5wBHK/00EjK65oahBYxFk5epgq33WRv7X9UuxLEV8PtR0szC0z8dl7INIpIodB99JRFlR+A==", + "node_modules/@temporalio/client": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/client/-/client-1.24.0.tgz", + "integrity": "sha512-/GGg6ZYl+pN/bQEvq414CyjDvyM+MM1WsMzi/7SCYb3UlivVXx9nOmH/6BGx8OfYFayp11fkmfSh6rt7vW/ePQ==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.4.3" + "@grpc/grpc-js": "^1.12.4", + "@temporalio/common": "1.24.0", + "@temporalio/proto": "1.24.0", + "abort-controller": "^3.0.0", + "long": "^5.3.2", + "nexus-rpc": "^0.0.3", + "uuid": "^11.1.0" }, "engines": { - "node": ">=20" + "node": ">= 20.3.0" } }, - "node_modules/@shikijs/primitive": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.4.3.tgz", - "integrity": "sha512-m0wBeLDQDeIxRdUmrCPdQqfuUamDwRL5isCfYbguKD6NiaKpVbsv+3J81DyIKgNW5h4WAIIr8T4EkgQrBBxvaQ==", + "node_modules/@temporalio/common": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/common/-/common-1.24.0.tgz", + "integrity": "sha512-jXp77fXwynBcVNc/CaGMT33TVYnhcN26S959HDv7Q71oc0rN6d8RHWR5z0nRCDAu5CQwZQRRhVK0TRdyAiEg7Q==", "license": "MIT", "dependencies": { - "@shikijs/types": "4.4.3", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.5" + "@temporalio/proto": "1.24.0", + "long": "^5.3.2", + "ms": "3.0.0-canary.1", + "nexus-rpc": "^0.0.3", + "protobufjs": "^8.7.1" }, "engines": { - "node": ">=20" + "node": ">= 20.3.0" } }, - "node_modules/@shikijs/themes": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.4.3.tgz", - "integrity": "sha512-w8UHjeUnIR965KMWJHUPXOc2mNJUnK3vpVLYLvw5IYU2mnTTJ89E24OrJDBNiJDQ0qzb0tc4l7mrIXx5cFeIyw==", - "license": "MIT", + "node_modules/@temporalio/common/node_modules/protobufjs": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.8.0.tgz", + "integrity": "sha512-N3xhQ5yyBx3vQq4gubBfASzYhJGNzeDbjqBpu61g7UVylsN/qyffU96TKWD3GbbLOKF82VGNRNvv1+BFgE31Eg==", + "license": "BSD-3-Clause", "dependencies": { - "@shikijs/types": "4.4.3" + "long": "^5.3.2" }, "engines": { - "node": ">=20" + "node": ">=12.0.0" } }, - "node_modules/@shikijs/types": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.4.3.tgz", - "integrity": "sha512-UEJxmRR++MAGR6hugn0vgVS2W/6lWAts84FFSrnlH9sP0LNol7E5+NQ792pH8liWUhyMyjhTgSUH3k7iD7tc5g==", + "node_modules/@temporalio/core-bridge": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/core-bridge/-/core-bridge-1.24.0.tgz", + "integrity": "sha512-6kzPB8RsHcPU6HDNUSDBFC0JG2UFrV3ThmPmJkeEafKh2DFrKARM8IzxgKeE5MzvdIXYmONFM0UmHg+TZ0/qrQ==", "license": "MIT", "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.5" + "@grpc/grpc-js": "^1.12.4", + "@temporalio/common": "1.24.0" }, "engines": { - "node": ">=20" + "node": ">= 20.3.0" } }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "license": "MIT" - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "4.0.0", + "node_modules/@temporalio/nexus": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/nexus/-/nexus-1.24.0.tgz", + "integrity": "sha512-SQOQia98KFowgpgH6Cn+7rcpWVEjmJbV5FlqQVQoDH82Q7yl5gT81GO9vN7YRYj5RE2P+DVzEsCc8ohT7Hy57g==", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "@temporalio/client": "1.24.0", + "@temporalio/common": "1.24.0", + "@temporalio/proto": "1.24.0", + "long": "^5.3.2", + "nexus-rpc": "^0.0.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 20.3.0" } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "license": "MIT" - }, - "node_modules/@swc/core": { - "version": "1.16.0", - "hasInstallScript": true, - "license": "Apache-2.0", - "peer": true, + "node_modules/@temporalio/proto": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/proto/-/proto-1.24.0.tgz", + "integrity": "sha512-vhlhB9GpoyJx+78r3lDahHywpdri6LKx7kt7djLIw6XzHyb8FQTIi4lX8DSJBqKp3+HVfL1CLwiqO26KFRzg/g==", + "license": "MIT", "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.28" + "long": "^5.3.2", + "protobufjs": "^8.7.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.16.0", - "@swc/core-darwin-x64": "1.16.0", - "@swc/core-linux-arm-gnueabihf": "1.16.0", - "@swc/core-linux-arm64-gnu": "1.16.0", - "@swc/core-linux-arm64-musl": "1.16.0", - "@swc/core-linux-ppc64-gnu": "1.16.0", - "@swc/core-linux-s390x-gnu": "1.16.0", - "@swc/core-linux-x64-gnu": "1.16.0", - "@swc/core-linux-x64-musl": "1.16.0", - "@swc/core-win32-arm64-msvc": "1.16.0", - "@swc/core-win32-ia32-msvc": "1.16.0", - "@swc/core-win32-x64-msvc": "1.16.0" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.17" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } + "node": ">= 20.3.0" } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.16.0", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@temporalio/proto/node_modules/protobufjs": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.8.0.tgz", + "integrity": "sha512-N3xhQ5yyBx3vQq4gubBfASzYhJGNzeDbjqBpu61g7UVylsN/qyffU96TKWD3GbbLOKF82VGNRNvv1+BFgE31Eg==", + "license": "BSD-3-Clause", + "dependencies": { + "long": "^5.3.2" + }, "engines": { - "node": ">=10" + "node": ">=12.0.0" } }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.16.0.tgz", - "integrity": "sha512-ql2JVch8V5t1i+HxiiuD4oVDI1dOku4/e3QiCkplONrm3SLitqNAP+nztHN51fSG2IgGuOwpAi3hgA+ukT5yQg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@temporalio/worker": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/worker/-/worker-1.24.0.tgz", + "integrity": "sha512-Lq79WAHOQFuCFJe1ZJcwcs/u8ZPhHyoTpnWZq1gr6mnB9IRMImAYrJFXY/MY/VdXVltTpy+7T6u/V+P327J+gQ==", + "license": "MIT", + "dependencies": { + "@grpc/grpc-js": "^1.12.4", + "@swc/core": "^1.3.102", + "@temporalio/activity": "1.24.0", + "@temporalio/client": "1.24.0", + "@temporalio/common": "1.24.0", + "@temporalio/core-bridge": "1.24.0", + "@temporalio/nexus": "1.24.0", + "@temporalio/proto": "1.24.0", + "@temporalio/workflow": "1.24.0", + "heap-js": "^2.6.0", + "memfs": "^4.6.0", + "nexus-rpc": "^0.0.3", + "protobufjs": "^8.7.1", + "rxjs": "^7.8.1", + "source-map": "^0.7.4", + "source-map-loader": "^5.0.0", + "supports-color": "^8.1.1", + "swc-loader": "^0.2.3", + "unionfs": "^4.5.1", + "webpack": "^5.108.4" + }, "engines": { - "node": ">=10" + "node": ">= 20.3.0" } }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.16.0.tgz", - "integrity": "sha512-PcdDBaRbe39y37h1rXVkhNy7mEU7f8b34KD761C68R23EsfMsj5oDPVddRzGdSRAvwwSfH0WSNEHgYmc/AJipg==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@temporalio/worker/node_modules/protobufjs": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.8.0.tgz", + "integrity": "sha512-N3xhQ5yyBx3vQq4gubBfASzYhJGNzeDbjqBpu61g7UVylsN/qyffU96TKWD3GbbLOKF82VGNRNvv1+BFgE31Eg==", + "license": "BSD-3-Clause", + "dependencies": { + "long": "^5.3.2" + }, "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.16.0.tgz", - "integrity": "sha512-t21IUztHQ/COucy7Kk9eIlehmq08H/hYq7aRA6fZox3S5ddi6TxWPK6e5S/+aTCf6+Od9qQ+LIpjHMiTy737vA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.16.0.tgz", - "integrity": "sha512-d9+iajbMB87b0umgbP+Gy3yBDSDgty4Q6H5pZ8fgTb/dOoKIwwynP4L4kvWCOFg2i49kxmAAUs1uJZh9s0E+RQ==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-ppc64-gnu": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.16.0.tgz", - "integrity": "sha512-QRpeKGOg+B0qmo3BFU+6rL/gpoKYYJ7OFSMf5DNMafohYZ/iq2qvAH9Gcrf8NxROj3iooKOVewJ+YgahH1nSLw==", - "cpu": [ - "ppc64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-s390x-gnu": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.16.0.tgz", - "integrity": "sha512-q+Vr/hmHCcRXT/WFzOJC+T6GGEEtq2iaTtmyLfxO7yzu4ckgcqSNkg9m181wfNhuMwfNBoBhOfwQCnLsGZ5F4g==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.16.0.tgz", - "integrity": "sha512-DWVBc3QnpsSgKoq8N4rmZeZa5r/XrHdLkITsExN/tvTdqPtAPDPt+Ysy33OfgBlyN8lNe4xwsXWe6DXlRkJeRQ==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.16.0.tgz", - "integrity": "sha512-6XCgDSc1HPf/5dpjvABhKHICiBcsuZyW3hQMkn8sxel0TqprkJGp+H4iaBYIUTPixhrBub2hBPtfjcZLE6yL3w==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.16.0.tgz", - "integrity": "sha512-T/+9VVCZJ3AKEth9IP3U9AJ2YscQq+7LUqRTvfR4a2q36+Ri22oOwUizpAKOqQ42vb2Y/kOa4TOcJOfHoDIT/w==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.16.0.tgz", - "integrity": "sha512-Pr1lsR/PMs8ndL0UWMrW8nLZ7H7sspIxBRDdjL8f+YJ/FJNASgzfunbVVXAqj0csgIJYHPZy+OW9smjFmk1Rcg==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.16.0.tgz", - "integrity": "sha512-ktdeYLgOQdaonvsj5tJijqgpb0wk7gfF80wCFVA0kucI1hhSUIyfcGbjo5+9sdqv38OhMnTdLoA6xbqgOgPQjw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "license": "Apache-2.0" - }, - "node_modules/@swc/types": { - "version": "0.1.28", - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3" - } - }, - "node_modules/@tabler/icons": { - "version": "3.46.0", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/codecalm" - } - }, - "node_modules/@tabler/icons-react": { - "version": "3.46.0", - "license": "MIT", - "dependencies": { - "@tabler/icons": "3.46.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/codecalm" - }, - "peerDependencies": { - "react": ">= 16" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.3.3", - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.24.1", - "jiti": "^2.7.0", - "lightningcss": "1.32.0", - "magic-string": "^0.30.21", - "source-map-js": "^1.2.1", - "tailwindcss": "4.3.3" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.3.3", - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.3.3", - "@tailwindcss/oxide-darwin-arm64": "4.3.3", - "@tailwindcss/oxide-darwin-x64": "4.3.3", - "@tailwindcss/oxide-freebsd-x64": "4.3.3", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", - "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", - "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", - "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", - "@tailwindcss/oxide-linux-x64-musl": "4.3.3", - "@tailwindcss/oxide-wasm32-wasi": "4.3.3", - "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", - "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", - "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.3.3", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", - "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", - "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", - "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", - "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", - "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", - "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", - "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", - "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.11.1", - "@emnapi/runtime": "^1.11.1", - "@emnapi/wasi-threads": "^1.2.2", - "@napi-rs/wasm-runtime": "^1.1.4", - "@tybys/wasm-util": "^0.10.2", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.1", - "inBundle": true, - "license": "0BSD", - "optional": true - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", - "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", - "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.3.3", - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.3.3", - "@tailwindcss/oxide": "4.3.3", - "tailwindcss": "4.3.3" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7 || ^8" - } - }, - "node_modules/@tanstack/query-core": { - "version": "5.101.4", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/react-query": { - "version": "5.101.4", - "license": "MIT", - "dependencies": { - "@tanstack/query-core": "5.101.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^18 || ^19" - } - }, - "node_modules/@temporalio/activity": { - "version": "1.21.1", - "license": "MIT", - "dependencies": { - "@temporalio/client": "1.21.1", - "@temporalio/common": "1.21.1" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/client": { - "version": "1.21.1", - "license": "MIT", - "dependencies": { - "@grpc/grpc-js": "^1.12.4", - "@temporalio/common": "1.21.1", - "@temporalio/proto": "1.21.1", - "abort-controller": "^3.0.0", - "long": "^5.2.3", - "nexus-rpc": "^0.0.2", - "uuid": "^11.1.0" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/common": { - "version": "1.21.1", - "license": "MIT", - "dependencies": { - "@temporalio/proto": "1.21.1", - "long": "^5.2.3", - "ms": "3.0.0-canary.1", - "nexus-rpc": "^0.0.2", - "proto3-json-serializer": "^2.0.0" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/core-bridge": { - "version": "1.21.1", - "license": "MIT", - "dependencies": { - "@grpc/grpc-js": "^1.12.4", - "@temporalio/common": "1.21.1" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/nexus": { - "version": "1.21.1", - "license": "MIT", - "dependencies": { - "@temporalio/client": "1.21.1", - "@temporalio/common": "1.21.1", - "@temporalio/proto": "1.21.1", - "long": "^5.2.3", - "nexus-rpc": "^0.0.2" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/proto": { - "version": "1.21.1", - "license": "MIT", - "dependencies": { - "long": "^5.2.3", - "protobufjs": "^7.6.4" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/worker": { - "version": "1.21.1", - "license": "MIT", - "dependencies": { - "@grpc/grpc-js": "^1.12.4", - "@swc/core": "^1.3.102", - "@temporalio/activity": "1.21.1", - "@temporalio/client": "1.21.1", - "@temporalio/common": "1.21.1", - "@temporalio/core-bridge": "1.21.1", - "@temporalio/nexus": "1.21.1", - "@temporalio/proto": "1.21.1", - "@temporalio/workflow": "1.21.1", - "heap-js": "^2.6.0", - "memfs": "^4.6.0", - "nexus-rpc": "^0.0.2", - "protobufjs": "^7.6.4", - "rxjs": "^7.8.1", - "source-map": "^0.7.4", - "source-map-loader": "^5.0.0", - "supports-color": "^8.1.1", - "swc-loader": "^0.2.3", - "unionfs": "^4.5.1", - "webpack": "^5.108.4" - }, - "engines": { - "node": ">= 20.3.0" + "node": ">=12.0.0" } }, "node_modules/@temporalio/workflow": { - "version": "1.21.1", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@temporalio/workflow/-/workflow-1.24.0.tgz", + "integrity": "sha512-pIA9nxkDCCbBnNuMSffQ44HWHYe3zXFfrDpDLwzh/FUSx8uLbsBM8jwf5oUMf+5eV/qVW9PknZhOu9IFO4XnPA==", "license": "MIT", "dependencies": { - "@temporalio/common": "1.21.1", - "@temporalio/proto": "1.21.1", - "nexus-rpc": "^0.0.2" + "@temporalio/common": "1.24.0", + "@temporalio/proto": "1.24.0", + "nexus-rpc": "^0.0.3" }, "engines": { "node": ">= 20.3.0" @@ -5644,6 +5688,8 @@ }, "node_modules/@tokenizer/inflate": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", "license": "MIT", "dependencies": { "debug": "^4.4.3", @@ -5659,66 +5705,35 @@ }, "node_modules/@tokenizer/token": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", "license": "MIT" }, - "node_modules/@ts-morph/common": { - "version": "0.27.0", - "license": "MIT", - "dependencies": { - "fast-glob": "^3.3.3", - "minimatch": "^10.0.1", - "path-browserify": "^1.0.1" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", - "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "dev": true, + "node_modules/@ts-morph/common": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz", + "integrity": "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "fast-glob": "^3.3.3", + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1" } }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "dev": true, + "node_modules/@tybys/wasm-util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz", + "integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==", + "devOptional": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "tslib": "^2.4.0" } }, "node_modules/@types/body-parser": { "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", "dependencies": { @@ -5728,6 +5743,8 @@ }, "node_modules/@types/chai": { "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -5737,6 +5754,8 @@ }, "node_modules/@types/connect": { "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dev": true, "license": "MIT", "dependencies": { @@ -5945,9 +5964,9 @@ "license": "MIT" }, "node_modules/@types/d3-selection": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", - "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.12.tgz", + "integrity": "sha512-Qe/KWYhEiIIxGs7HrAAjMfShxKldx19SJtr5zu53f3afPsdZNz7HHtdTLXo/kqeiWNXVycI24kSnfzBYkTzpgw==", "license": "MIT" }, "node_modules/@types/d3-shape": { @@ -5987,9 +6006,9 @@ } }, "node_modules/@types/d3-zoom": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.9.tgz", + "integrity": "sha512-0sE1406XBYJGiqD3AusTl9ZqC//2mIXix51tbom25gDCA8ri4xnSZg28CaSE8Srl6FClqABUKfsn0qghgdepMA==", "license": "MIT", "dependencies": { "@types/d3-interpolate": "*", @@ -5998,6 +6017,8 @@ }, "node_modules/@types/debug": { "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", "license": "MIT", "dependencies": { "@types/ms": "*" @@ -6005,15 +6026,21 @@ }, "node_modules/@types/deep-eql": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "devOptional": true, "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "license": "MIT" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", "license": "MIT", "dependencies": { "@types/estree": "*" @@ -6021,6 +6048,8 @@ }, "node_modules/@types/express": { "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", "dependencies": { @@ -6031,6 +6060,8 @@ }, "node_modules/@types/express-serve-static-core": { "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.3.tgz", + "integrity": "sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==", "dev": true, "license": "MIT", "dependencies": { @@ -6048,6 +6079,8 @@ }, "node_modules/@types/hast": { "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -6055,6 +6088,8 @@ }, "node_modules/@types/http-errors": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "dev": true, "license": "MIT" }, @@ -6066,15 +6101,21 @@ }, "node_modules/@types/json-schema": { "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, "node_modules/@types/lodash": { "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.25.tgz", + "integrity": "sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==", "dev": true, "license": "MIT" }, "node_modules/@types/mdast": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -6088,6 +6129,8 @@ }, "node_modules/@types/ms": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/nlcst": { @@ -6100,14 +6143,18 @@ } }, "node_modules/@types/node": { - "version": "24.13.3", + "version": "24.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.1.tgz", + "integrity": "sha512-aS3/DG0oM05K0RIXXP+hKjinGG5IgSSVGzswZxW3O0sS3pH4/fycXundUC9XsszgKCk4gHXylTEK6hyFxVxnoQ==", "license": "MIT", "dependencies": { - "undici-types": "~7.18.0" + "undici-types": ">=7.24.0 <7.24.7" } }, "node_modules/@types/pg": { - "version": "8.21.0", + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.23.1.tgz", + "integrity": "sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6118,21 +6165,29 @@ }, "node_modules/@types/qrcode-terminal": { "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/qrcode-terminal/-/qrcode-terminal-0.12.2.tgz", + "integrity": "sha512-v+RcIEJ+Uhd6ygSQ0u5YYY7ZM+la7GgPbs0V/7l/kFs2uO4S8BcIUEMoP7za4DNIqNnUD5npf0A/7kBhrCKG5Q==", "dev": true, "license": "MIT" }, "node_modules/@types/qs": { "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", "dev": true, "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true, "license": "MIT" }, "node_modules/@types/react": { - "version": "19.2.18", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", "license": "MIT", "peer": true, "dependencies": { @@ -6140,11 +6195,13 @@ } }, "node_modules/@types/react-dom": { - "version": "19.2.4", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", "dev": true, "license": "MIT", "peerDependencies": { - "@types/react": "^19.2.0" + "@types/react": "^19.3.0" } }, "node_modules/@types/sax": { @@ -6158,6 +6215,8 @@ }, "node_modules/@types/send": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6166,6 +6225,8 @@ }, "node_modules/@types/serve-static": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6182,14 +6243,20 @@ }, "node_modules/@types/unist": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, "node_modules/@types/validate-npm-package-name": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/validate-npm-package-name/-/validate-npm-package-name-4.0.2.tgz", + "integrity": "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==", "license": "MIT" }, "node_modules/@ungap/structured-clone": { - "version": "1.3.3", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", + "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", "license": "ISC" }, "node_modules/@upsetjs/venn.js": { @@ -6203,54 +6270,53 @@ } }, "node_modules/@vitejs/plugin-react": { - "version": "4.7.0", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.1.tgz", + "integrity": "sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.28.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" + "@rolldown/pluginutils": "^1.0.1" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/@vitest/expect": { - "version": "3.2.7", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.145.0", + "vite": "^8.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "oxc-transform-react": { + "optional": true + } } }, "node_modules/@vitest/mocker": { - "version": "3.2.7", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.3.tgz", + "integrity": "sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==", "devOptional": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.7", + "@jridgewell/trace-mapping": "0.3.31", + "@vitest/spy": "5.0.3", "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" + "magic-string": "^1.2.3" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -6261,63 +6327,12 @@ } } }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.7", - "devOptional": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "3.2.7", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "3.2.7", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "3.2.7", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.7", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/@vitest/spy": { - "version": "3.2.7", - "devOptional": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "3.2.7", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.3.tgz", + "integrity": "sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==", "devOptional": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.7", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, "funding": { "url": "https://opencollective.com/vitest" } @@ -6429,6 +6444,8 @@ }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", @@ -6437,18 +6454,26 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", @@ -6458,10 +6483,14 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6472,6 +6501,8 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" @@ -6479,6 +6510,8 @@ }, "node_modules/@webassemblyjs/leb128": { "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" @@ -6486,10 +6519,14 @@ }, "node_modules/@webassemblyjs/utf8": { "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6504,6 +6541,8 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6515,6 +6554,8 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6525,6 +6566,8 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6537,6 +6580,8 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -6545,14 +6590,20 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "license": "Apache-2.0" }, "node_modules/abort-controller": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -6563,6 +6614,8 @@ }, "node_modules/accepts": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { "mime-types": "^3.0.0", @@ -6574,763 +6627,350 @@ }, "node_modules/acorn": { "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/ajv": { - "version": "8.20.0", - "license": "MIT", - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-i18n": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-4.2.0.tgz", - "integrity": "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^8.0.0-beta.0" - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/am-i-vibing": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/am-i-vibing/-/am-i-vibing-0.4.0.tgz", - "integrity": "sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==", - "license": "MIT", - "dependencies": { - "process-ancestry": "^0.1.0" - }, - "bin": { - "am-i-vibing": "dist/cli.mjs" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array-iterate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/ast-types": { - "version": "0.16.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" + "peer": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=4" + "node": ">=0.4.0" } }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "license": "MIT", - "bin": { - "astring": "bin/astring" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/astro": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/astro/-/astro-7.3.1.tgz", - "integrity": "sha512-A/bJYHtc6n0UAdROY9W948fW6lX0pnUA+JWKW+IGCXRyDIGN2MsXC0OlS8onZGJjr+sv8htemwOc9W5PBRXCkw==", + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "peer": true, "dependencies": { - "@astrojs/compiler-rs": "^0.4.0", - "@astrojs/internal-helpers": "0.11.0", - "@astrojs/markdown-satteri": "0.4.0", - "@astrojs/telemetry": "3.3.3", - "@capsizecss/unpack": "^4.0.0", - "@clack/prompts": "^1.1.0", - "@oslojs/encoding": "^1.1.0", - "am-i-vibing": "^0.4.0", - "aria-query": "^5.3.2", - "axobject-query": "^4.1.0", - "ci-info": "^4.4.0", - "clsx": "^2.1.1", - "common-ancestor-path": "^2.0.0", - "cookie": "^2.0.1", - "devalue": "^5.8.1", - "diff": "^9.0.0", - "dset": "^3.1.4", - "es-module-lexer": "^2.0.0", - "esbuild": "^0.28.0", - "find-proc": "0.1.0", - "flattie": "^1.1.1", - "fontace": "~0.4.1", - "get-tsconfig": "5.0.0-beta.4", - "github-slugger": "^2.0.0", - "html-escaper": "3.0.3", - "http-cache-semantics": "^4.2.0", - "js-yaml": "^4.3.0", - "jsonc-parser": "^3.3.1", - "magic-string": "^1.0.0", - "magicast": "^0.5.2", - "mrmime": "^2.0.1", - "neotraverse": "^1.0.1", - "obug": "^2.1.1", - "p-limit": "^7.3.0", - "p-queue": "^9.1.0", - "package-manager-detector": "^1.6.0", - "piccolore": "^0.1.3", - "picomatch": "^4.0.4", - "semver": "^7.7.4", - "shiki": "^4.0.2", - "smol-toml": "^1.6.0", - "svgo": "^4.0.1", - "tinyclip": "^0.1.12", - "tinyexec": "^1.0.4", - "tinyglobby": "^0.2.15", - "ultrahtml": "^1.6.0", - "unifont": "~0.7.5", - "unstorage": "^1.17.5", - "vite": "^8.0.13", - "vitefu": "^1.1.2", - "xxhash-wasm": "^1.1.0", - "yargs-parser": "^22.0.0", - "zod": "^4.5.4" - }, - "bin": { - "astro": "bin/astro.mjs" - }, - "engines": { - "node": ">=22.12.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/astrodotbuild" - }, - "optionalDependencies": { - "sharp": "^0.35.4" - }, + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "license": "MIT", "peerDependencies": { - "@astrojs/markdown-remark": "^7.3.0" + "ajv": "^8.5.0" }, "peerDependenciesMeta": { - "@astrojs/markdown-remark": { + "ajv": { "optional": true } } }, - "node_modules/astro-expressive-code": { - "version": "0.44.2", - "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.44.2.tgz", - "integrity": "sha512-avop7nZcRwC7quvIxVguhwEZ9Tp6IoTzKUCLwP30Fb7+er+pWQgcysP01dcuzRIJo81kLGg30q/YAI2Yb1Sdzg==", - "license": "MIT", - "dependencies": { - "rehype-expressive-code": "^0.44.2", - "url-extras": "^0.1.0" - }, - "peerDependencies": { - "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta || ^7.0.0" - } - }, - "node_modules/astro-mermaid": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/astro-mermaid/-/astro-mermaid-2.1.0.tgz", - "integrity": "sha512-fFRUN0BTZh+DZhDiLyblXoO26XqJ1Rr+qK3JGgSu7OBspKHDm59jkztg/aHsrdo1vO/tIq/+xhP/vgT8Mp92XA==", + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "license": "MIT", "dependencies": { - "import-meta-resolve": "^4.2.0", - "mdast-util-to-string": "^4.0.0", - "unist-util-visit": "^5.0.0" + "ajv": "^8.0.0" }, "peerDependencies": { - "@mermaid-js/layout-elk": "^0.2.0", - "astro": ">=4", - "mermaid": "^10.0.0 || ^11.0.0" + "ajv": "^8.0.0" }, "peerDependenciesMeta": { - "@mermaid-js/layout-elk": { + "ajv": { "optional": true } } }, - "node_modules/astro/node_modules/cookie": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", - "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", + "node_modules/ajv-i18n": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-4.2.0.tgz", + "integrity": "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=22" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/astro/node_modules/diff": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz", - "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" + "peerDependencies": { + "ajv": "^8.0.0-beta.0" } }, - "node_modules/astro/node_modules/es-module-lexer": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", - "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", - "license": "MIT" - }, - "node_modules/astro/node_modules/get-tsconfig": { - "version": "5.0.0-beta.4", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz", - "integrity": "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==", + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "license": "MIT", "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "engines": { - "node": ">=20.20.0" + "fast-deep-equal": "^3.1.3" }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/astro/node_modules/lightningcss": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", - "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", - "license": "MPL-2.0", + "node_modules/am-i-vibing": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/am-i-vibing/-/am-i-vibing-0.4.0.tgz", + "integrity": "sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==", + "license": "MIT", "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.33.0", - "lightningcss-darwin-arm64": "1.33.0", - "lightningcss-darwin-x64": "1.33.0", - "lightningcss-freebsd-x64": "1.33.0", - "lightningcss-linux-arm-gnueabihf": "1.33.0", - "lightningcss-linux-arm64-gnu": "1.33.0", - "lightningcss-linux-arm64-musl": "1.33.0", - "lightningcss-linux-x64-gnu": "1.33.0", - "lightningcss-linux-x64-musl": "1.33.0", - "lightningcss-win32-arm64-msvc": "1.33.0", - "lightningcss-win32-x64-msvc": "1.33.0" - } - }, - "node_modules/astro/node_modules/lightningcss-android-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", - "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/astro/node_modules/lightningcss-darwin-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", - "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/astro/node_modules/lightningcss-darwin-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", - "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" + "process-ancestry": "^0.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "bin": { + "am-i-vibing": "dist/cli.mjs" } }, - "node_modules/astro/node_modules/lightningcss-freebsd-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", - "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=6" } }, - "node_modules/astro/node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", - "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=8" } }, - "node_modules/astro/node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", - "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 12.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/astro/node_modules/lightningcss-linux-arm64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", - "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "engines": { + "node": ">= 8" } }, - "node_modules/astro/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", - "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", "engines": { - "node": ">= 12.0.0" + "node": ">=8.6" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/astro/node_modules/lightningcss-linux-x64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", - "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">= 0.4" } }, - "node_modules/astro/node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", - "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/astro/node_modules/lightningcss-win32-x64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", - "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "devOptional": true, + "license": "MIT", "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=12" } }, - "node_modules/astro/node_modules/magic-string": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", - "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", + "node_modules/ast-types": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.3.tgz", + "integrity": "sha512-FvWoWYfSCM6kRxCSH+MGLHIKKGRL6A6AW7Zek2O32REPQRdg131428uRTKMBYAeRd3XXAaHDS60Wpri7CdKDrA==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" } }, - "node_modules/astro/node_modules/p-limit": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.2.tgz", - "integrity": "sha512-Ll0w3fU24vYpXoZmjjZIee6bJQDgG0oAyo1PdmFYI8UDwJJddaHAypxIH9avUu+t+lSsAwKVsb1jDCMIIChliw==", + "node_modules/astro": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/astro/-/astro-7.3.5.tgz", + "integrity": "sha512-1p/ernaq/RuESbM5NMjWzbO6SiebMGrGcYlGjMfBhzzgM+n/X7AUmVyw8BqW2QYCdivpsHwJBcD1fqmlTZjZHg==", "license": "MIT", + "peer": true, "dependencies": { - "yocto-queue": "^1.2.1" + "@astrojs/compiler-rs": "^0.5.0", + "@astrojs/internal-helpers": "0.11.0", + "@astrojs/markdown-satteri": "0.4.2", + "@astrojs/telemetry": "3.3.3", + "@capsizecss/unpack": "^4.0.0", + "@clack/prompts": "^1.1.0", + "@oslojs/encoding": "^1.1.0", + "am-i-vibing": "^0.4.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "ci-info": "^4.4.0", + "clsx": "^2.1.1", + "common-ancestor-path": "^2.0.0", + "cookie": "^2.0.1", + "devalue": "^5.8.1", + "diff": "^9.0.0", + "dset": "^3.1.4", + "es-module-lexer": "^2.0.0", + "esbuild": "^0.28.0", + "find-proc": "0.2.0", + "flattie": "^1.1.1", + "fontace": "~0.4.1", + "get-tsconfig": "5.0.0-beta.4", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "js-yaml": "^4.3.2", + "jsonc-parser": "^3.3.1", + "magic-string": "^1.0.0", + "magicast": "^0.5.2", + "mrmime": "^2.0.1", + "neotraverse": "^1.0.1", + "obug": "^3.0.0", + "p-limit": "^7.3.0", + "p-queue": "^9.1.0", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.4", + "shiki": "^4.0.2", + "smol-toml": "^1.8.0", + "svgo": "^4.1.0", + "tinyclip": "^1.0.1", + "tinyexec": "^1.0.4", + "tinyglobby": "^0.2.15", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.5", + "unstorage": "^1.17.5", + "verkit": "^0.4.0", + "vite": "^8.0.13", + "vitefu": "^1.1.2", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^22.0.0", + "zod": "^4.5.4" + }, + "bin": { + "astro": "bin/astro.mjs" }, "engines": { - "node": ">=20" + "node": ">=22.12.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/astro/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" }, - "engines": { - "node": ">=10" + "optionalDependencies": { + "sharp": "^0.35.4" + }, + "peerDependencies": { + "@astrojs/markdown-remark": "^7.3.0" + }, + "peerDependenciesMeta": { + "@astrojs/markdown-remark": { + "optional": true + } } }, - "node_modules/astro/node_modules/tinyexec": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", - "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "node_modules/astro-expressive-code": { + "version": "0.44.2", + "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.44.2.tgz", + "integrity": "sha512-avop7nZcRwC7quvIxVguhwEZ9Tp6IoTzKUCLwP30Fb7+er+pWQgcysP01dcuzRIJo81kLGg30q/YAI2Yb1Sdzg==", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "rehype-expressive-code": "^0.44.2", + "url-extras": "^0.1.0" + }, + "peerDependencies": { + "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta || ^7.0.0" } }, - "node_modules/astro/node_modules/vite": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", - "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "node_modules/astro-mermaid": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/astro-mermaid/-/astro-mermaid-2.1.0.tgz", + "integrity": "sha512-fFRUN0BTZh+DZhDiLyblXoO26XqJ1Rr+qK3JGgSu7OBspKHDm59jkztg/aHsrdo1vO/tIq/+xhP/vgT8Mp92XA==", "license": "MIT", "dependencies": { - "lightningcss": "^1.33.0", - "picomatch": "^4.0.5", - "postcss": "^8.5.26", - "rolldown": "~1.2.4", - "tinyglobby": "^0.2.17" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "import-meta-resolve": "^4.2.0", + "mdast-util-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" }, "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.4.0 || ^0.5.0", - "esbuild": "^0.27.0 || ^0.28.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" + "@mermaid-js/layout-elk": "^0.2.0", + "astro": ">=4", + "mermaid": "^10.0.0 || ^11.0.0" }, "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": { + "@mermaid-js/layout-elk": { "optional": true } } }, - "node_modules/astro/node_modules/yargs-parser": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", - "license": "ISC", - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, "node_modules/async-mutex": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", + "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==", "license": "MIT", "dependencies": { "tslib": "^2.4.0" @@ -7338,6 +6978,8 @@ }, "node_modules/atomic-sleep": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -7345,6 +6987,8 @@ }, "node_modules/atomically": { "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", "license": "MIT", "engines": { "node": ">=10.12.0" @@ -7374,6 +7018,8 @@ }, "node_modules/bail": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", "license": "MIT", "funding": { "type": "github", @@ -7381,7 +7027,9 @@ } }, "node_modules/baileys": { - "version": "7.0.0-rc13", + "version": "7.0.0-rc14", + "resolved": "https://registry.npmjs.org/baileys/-/baileys-7.0.0-rc14.tgz", + "integrity": "sha512-pewtrljhWx5JTUBvvkXZz1fL3JPiwzjBsnhx/DWf2LWBx1cZNH7J/sF22xDehba5mySWUQU4a1Pwt7lWARUxaA==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -7418,22 +7066,19 @@ } } }, - "node_modules/baileys/node_modules/lru-cache": { - "version": "11.5.2", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/balanced-match": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { "node": "18 || 20 || >=22" } }, "node_modules/baseline-browser-mapping": { - "version": "2.11.14", + "version": "2.11.27", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.27.tgz", + "integrity": "sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -7468,18 +7113,18 @@ } }, "node_modules/better-auth": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/better-auth/-/better-auth-1.7.6.tgz", - "integrity": "sha512-WTMqOpmTTj+oBoX7zzPOzL85342Upyf+/v0IkH1kvGRA85lV4JGRFIYMIRKqvjZ6ShsuL5VX/c9C13jtoZXcKA==", - "license": "MIT", - "dependencies": { - "@better-auth/core": "1.7.6", - "@better-auth/drizzle-adapter": "1.7.6", - "@better-auth/kysely-adapter": "1.7.6", - "@better-auth/memory-adapter": "1.7.6", - "@better-auth/mongo-adapter": "1.7.6", - "@better-auth/prisma-adapter": "1.7.6", - "@better-auth/telemetry": "1.7.6", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/better-auth/-/better-auth-1.7.7.tgz", + "integrity": "sha512-Zhgxi/c5ylmfB/sX+nwnBbsFf/j6k0L8DvL6CJXZSrXgxc5pPMC/e7j812zNd4L4B4ELmdURCPw3X8nAOUdcjw==", + "license": "MIT", + "dependencies": { + "@better-auth/core": "1.7.7", + "@better-auth/drizzle-adapter": "1.7.7", + "@better-auth/kysely-adapter": "1.7.7", + "@better-auth/memory-adapter": "1.7.7", + "@better-auth/mongo-adapter": "1.7.7", + "@better-auth/prisma-adapter": "1.7.7", + "@better-auth/telemetry": "1.7.7", "@better-auth/utils": "0.4.2", "@better-fetch/fetch": "1.3.2", "@noble/ciphers": "^2.2.0", @@ -7570,6 +7215,8 @@ }, "node_modules/better-call": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/better-call/-/better-call-1.4.0.tgz", + "integrity": "sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA==", "license": "MIT", "peer": true, "dependencies": { @@ -7589,13 +7236,27 @@ }, "node_modules/better-call/node_modules/@better-auth/utils": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@better-auth/utils/-/utils-0.5.0.tgz", + "integrity": "sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA==", "license": "MIT", "dependencies": { "@noble/hashes": "^2.0.1" } }, + "node_modules/bidi-js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.1.0.tgz", + "integrity": "sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/body-parser": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", @@ -7618,6 +7279,8 @@ }, "node_modules/body-parser/node_modules/content-type": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", "license": "MIT", "engines": { "node": ">=18" @@ -7627,6 +7290,22 @@ "url": "https://opencollective.com/express" } }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -7634,7 +7313,9 @@ "license": "ISC" }, "node_modules/brace-expansion": { - "version": "5.0.9", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -7645,6 +7326,8 @@ }, "node_modules/braces": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -7666,7 +7349,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.8", + "version": "4.29.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", + "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", "funding": [ { "type": "opencollective", @@ -7684,11 +7369,11 @@ "license": "MIT", "peer": true, "dependencies": { - "baseline-browser-mapping": "^2.11.12", - "caniuse-lite": "^1.0.30001809", - "electron-to-chromium": "^1.5.402", - "node-releases": "^2.0.53", - "update-browserslist-db": "^1.3.0" + "baseline-browser-mapping": "^2.11.26", + "caniuse-lite": "^1.0.30001813", + "electron-to-chromium": "^1.5.439", + "node-releases": "^2.0.57", + "update-browserslist-db": "^1.3.3" }, "bin": { "browserslist": "cli.js" @@ -7699,10 +7384,14 @@ }, "node_modules/buffer-from": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, "node_modules/bundle-name": { - "version": "4.1.0", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.1.tgz", + "integrity": "sha512-DdH81/zPLVS11EUgWq3tEu/xn+EzljlMYooDNdzWEnFha3R3NBMpMV1UqYIpjYHV/SgpFKMIX1Oh7o06SjM/oA==", "license": "MIT", "dependencies": { "run-applescript": "^7.0.0" @@ -7716,21 +7405,17 @@ }, "node_modules/bytes": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/cac": { - "version": "6.7.14", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/cacheable": { "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", "license": "MIT", "dependencies": { "@cacheable/memory": "^2.2.0", @@ -7742,6 +7427,8 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -7753,6 +7440,8 @@ }, "node_modules/call-bound": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -7767,13 +7456,17 @@ }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001809", + "version": "1.0.30001814", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001814.tgz", + "integrity": "sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==", "funding": [ { "type": "opencollective", @@ -7792,6 +7485,8 @@ }, "node_modules/ccount": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "license": "MIT", "funding": { "type": "github", @@ -7799,22 +7494,19 @@ } }, "node_modules/chai": { - "version": "5.3.3", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", "devOptional": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } }, "node_modules/chalk": { "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -7825,6 +7517,8 @@ }, "node_modules/character-entities": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "license": "MIT", "funding": { "type": "github", @@ -7833,6 +7527,8 @@ }, "node_modules/character-entities-html4": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "license": "MIT", "funding": { "type": "github", @@ -7841,6 +7537,8 @@ }, "node_modules/character-entities-legacy": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", "license": "MIT", "funding": { "type": "github", @@ -7849,20 +7547,14 @@ }, "node_modules/character-reference-invalid": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/check-error": { - "version": "2.1.3", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/cheerio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", @@ -7925,6 +7617,8 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "license": "MIT", "engines": { "node": ">=6.0" @@ -7947,6 +7641,8 @@ }, "node_modules/class-variance-authority": { "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", "license": "Apache-2.0", "dependencies": { "clsx": "^2.1.1" @@ -7957,6 +7653,8 @@ }, "node_modules/cli-cursor": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "license": "MIT", "dependencies": { "restore-cursor": "^5.0.0" @@ -7970,6 +7668,8 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "license": "MIT", "engines": { "node": ">=6" @@ -7979,42 +7679,74 @@ } }, "node_modules/cliui": { - "version": "8.0.1", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=12" + "node": ">=20" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/clsx": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/cn": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/cn/-/cn-0.2.6.tgz", + "integrity": "sha512-+i4L0zUGgRcEnhsxueVrP7iBGxBx5iD0WOTYg1MwFEu2ZyCmH5Ov2V1cul2Ht5UchRQQgftCf4be/RxspuW6QQ==", + "license": "MIT", + "bin": { + "cn": "bin/cn.mjs" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/code-block-writer": { "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", "license": "MIT" }, "node_modules/collapse-white-space": { @@ -8029,6 +7761,8 @@ }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -8039,10 +7773,14 @@ }, "node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/comma-separated-tokens": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "license": "MIT", "funding": { "type": "github", @@ -8050,10 +7788,12 @@ } }, "node_modules/commander": { - "version": "14.0.3", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.12.0" } }, "node_modules/common-ancestor-path": { @@ -8067,6 +7807,8 @@ }, "node_modules/conf": { "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", "license": "MIT", "dependencies": { "ajv": "^8.6.3", @@ -8089,6 +7831,8 @@ }, "node_modules/conf/node_modules/ajv-formats": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -8104,10 +7848,14 @@ }, "node_modules/conf/node_modules/json-schema-typed": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==", "license": "BSD-2-Clause" }, "node_modules/conf/node_modules/semver": { "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8118,6 +7866,8 @@ }, "node_modules/content-disposition": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", "engines": { "node": ">=18" @@ -8129,6 +7879,8 @@ }, "node_modules/content-type": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -8136,13 +7888,21 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "license": "MIT" }, "node_modules/cookie": { - "version": "0.7.2", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=22" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/cookie-es": { @@ -8153,6 +7913,8 @@ }, "node_modules/cookie-signature": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "license": "MIT", "engines": { "node": ">=6.6.0" @@ -8160,6 +7922,8 @@ }, "node_modules/cors": { "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -8184,6 +7948,8 @@ }, "node_modules/cosmiconfig": { "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz", + "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==", "license": "MIT", "dependencies": { "env-paths": "^2.2.1", @@ -8208,6 +7974,8 @@ }, "node_modules/cross-spawn": { "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -8288,6 +8056,8 @@ }, "node_modules/cssesc": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -8329,26 +8099,16 @@ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", "license": "CC0-1.0" }, - "node_modules/cssstyle": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/csstype": { "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, "node_modules/curve25519-js": { "version": "0.0.4", + "resolved": "https://registry.npmjs.org/curve25519-js/-/curve25519-js-0.0.4.tgz", + "integrity": "sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w==", "license": "MIT" }, "node_modules/cytoscape": { @@ -8579,18 +8339,6 @@ "node": ">= 10" } }, - "node_modules/d3-dsv/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -8874,54 +8622,42 @@ } }, "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/data-urls/node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.3.1" + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node_modules/data-urls/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=20" } }, "node_modules/data-urls/node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/dayjs": { @@ -8932,6 +8668,8 @@ }, "node_modules/debounce-fn": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", "license": "MIT", "dependencies": { "mimic-fn": "^3.0.0" @@ -8945,6 +8683,8 @@ }, "node_modules/debug": { "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -8960,6 +8700,8 @@ }, "node_modules/debug/node_modules/ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/decimal.js": { @@ -8971,6 +8713,8 @@ }, "node_modules/decode-named-character-reference": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", "license": "MIT", "dependencies": { "character-entities": "^2.0.0" @@ -8982,6 +8726,8 @@ }, "node_modules/dedent": { "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -8992,23 +8738,19 @@ } } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/deepmerge": { "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/default-browser": { - "version": "5.5.0", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.1.tgz", + "integrity": "sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==", "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", @@ -9023,6 +8765,8 @@ }, "node_modules/default-browser-id": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", "license": "MIT", "engines": { "node": ">=18" @@ -9033,6 +8777,8 @@ }, "node_modules/define-lazy-prop": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "license": "MIT", "engines": { "node": ">=12" @@ -9043,6 +8789,8 @@ }, "node_modules/defu": { "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", "license": "MIT" }, "node_modules/delaunator": { @@ -9056,6 +8804,8 @@ }, "node_modules/depd": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -9063,6 +8813,8 @@ }, "node_modules/dequal": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "license": "MIT", "engines": { "node": ">=6" @@ -9076,19 +8828,23 @@ }, "node_modules/detect-libc": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "engines": { "node": ">=8" } }, "node_modules/devalue": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.2.tgz", - "integrity": "sha512-po4PAY5c53tw5XMocSnf8A/5OHhbbUftpr93aEN6BBoAdntUmK7vu7wOATqvt7cXO7m1Cl4gMVn6p7n6n4mj0w==", + "version": "5.9.4", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.4.tgz", + "integrity": "sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==", "license": "MIT" }, "node_modules/devlop": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", "license": "MIT", "dependencies": { "dequal": "^2.0.0" @@ -9099,7 +8855,9 @@ } }, "node_modules/diff": { - "version": "8.0.4", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz", + "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -9132,18 +8890,6 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -9172,9 +8918,9 @@ } }, "node_modules/dompurify": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.15.tgz", - "integrity": "sha512-EUBjM+B+lkDE41iE82DDSCfkoPGfXx8IxFxPMjNzm/Uk4xDet77rTN9wqlxlVg71kK7XGuUMv6wUxJUwwv+Xyw==", + "version": "3.4.16", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.16.tgz", + "integrity": "sha512-sqo+pNp3qRhCIpbgRi1y8Tgk27Bo2Ry7w0dC1NBeNTdZChWjz9Xb/KOoZbRP/R6pQZ80Qw8YhXw13hWWBbMRnQ==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -9196,6 +8942,8 @@ }, "node_modules/dot-prop": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "license": "MIT", "dependencies": { "is-obj": "^2.0.0" @@ -9209,6 +8957,8 @@ }, "node_modules/dotenv": { "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -9218,7 +8968,9 @@ } }, "node_modules/drizzle-kit": { - "version": "0.31.10", + "version": "0.31.11", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.11.tgz", + "integrity": "sha512-YCYqxTLIB2OCqf6w9/Vef13baBVbwQIPcbT4Y56AfO6B9ajZhDhD8Jkveg/hJvT/iuMloKD/IYYkyMMNhr7Kqg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -9297,6 +9049,8 @@ }, "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], @@ -9647,6 +9401,8 @@ }, "node_modules/drizzle-kit/node_modules/esbuild": { "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "devOptional": true, "hasInstallScript": true, "license": "MIT", @@ -9686,7 +9442,9 @@ } }, "node_modules/drizzle-orm": { - "version": "0.45.2", + "version": "0.45.3", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.3.tgz", + "integrity": "sha512-CAloER21cDdcgZ1OmjrZX82EeRNsdP+y0onX/eyoYDaYzki/adrAa91lzM5jWh7zZPK4qUbw/6LGv9J+A+uizA==", "license": "Apache-2.0", "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", @@ -9695,6 +9453,7 @@ "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", + "@netlify/db": ">=0.4.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", @@ -9737,6 +9496,9 @@ "@neondatabase/serverless": { "optional": true }, + "@netlify/db": { + "optional": true + }, "@op-engineering/op-sqlite": { "optional": true }, @@ -9819,6 +9581,8 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -9831,10 +9595,14 @@ }, "node_modules/ee-first": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.406", + "version": "1.5.444", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.444.tgz", + "integrity": "sha512-5ss/uJfoDYDHT0lfJzT6FbcskIzROIOPf0BbbFkGcvDzoJU7i//9GDrwwIHQVmIsrAGiF3ihpADBRIsrEFt1rQ==", "license": "ISC" }, "node_modules/emmet": { @@ -9856,10 +9624,14 @@ }, "node_modules/emoji-regex": { "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -9879,21 +9651,10 @@ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" } }, - "node_modules/encoding-sniffer/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/enhanced-resolve": { - "version": "5.24.5", + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.26.0.tgz", + "integrity": "sha512-9vhedylFonb2YGogzUKX6+Ja72gOJbN1QHAqdrvqLwhdl/QWbKopzoUC9EbQNVsAns/bx/4uyqalrQAoy1IByw==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -9905,6 +9666,8 @@ }, "node_modules/enquirer": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1", @@ -9915,9 +9678,9 @@ } }, "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -9928,6 +9691,8 @@ }, "node_modules/env-paths": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "license": "MIT", "engines": { "node": ">=6" @@ -9935,6 +9700,8 @@ }, "node_modules/error-ex": { "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -9942,6 +9709,8 @@ }, "node_modules/es-define-property": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -9949,18 +9718,23 @@ }, "node_modules/es-errors": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "devOptional": true, + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -10015,9 +9789,10 @@ }, "node_modules/esbuild": { "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -10055,6 +9830,8 @@ }, "node_modules/escalade": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -10062,10 +9839,14 @@ }, "node_modules/escape-html": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "license": "MIT", "engines": { "node": ">=12" @@ -10074,19 +9855,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -10096,30 +9868,6 @@ "node": ">=4" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/estree-util-attach-comments": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", @@ -10151,6 +9899,8 @@ }, "node_modules/estree-util-is-identifier-name": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", "license": "MIT", "funding": { "type": "opencollective", @@ -10202,6 +9952,8 @@ }, "node_modules/estree-walker": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" @@ -10209,6 +9961,8 @@ }, "node_modules/etag": { "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -10216,6 +9970,8 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" @@ -10223,10 +9979,14 @@ }, "node_modules/eventemitter3": { "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, "node_modules/events": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" @@ -10234,6 +9994,8 @@ }, "node_modules/eventsource": { "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", "license": "MIT", "dependencies": { "eventsource-parser": "^3.0.1" @@ -10244,6 +10006,8 @@ }, "node_modules/eventsource-parser": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz", + "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -10251,6 +10015,8 @@ }, "node_modules/execa": { "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", @@ -10275,6 +10041,8 @@ }, "node_modules/expect-type": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "devOptional": true, "license": "Apache-2.0", "engines": { @@ -10283,8 +10051,9 @@ }, "node_modules/express": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -10324,7 +10093,9 @@ } }, "node_modules/express-rate-limit": { - "version": "8.6.2", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz", + "integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==", "license": "MIT", "dependencies": { "debug": "^4.4.3", @@ -10340,6 +10111,15 @@ "express": ">= 4.11" } }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/expressive-code": { "version": "0.44.2", "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.44.2.tgz", @@ -10354,6 +10134,8 @@ }, "node_modules/extend": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, "node_modules/extendable-media-recorder": { @@ -10396,10 +10178,14 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -10441,7 +10227,9 @@ } }, "node_modules/fast-uri": { - "version": "3.1.5", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", + "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", "funding": [ { "type": "github", @@ -10473,7 +10261,9 @@ } }, "node_modules/fastq": { - "version": "1.20.1", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -10481,6 +10271,8 @@ }, "node_modules/fdir": { "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -10502,6 +10294,8 @@ }, "node_modules/figures": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0" @@ -10515,6 +10309,8 @@ }, "node_modules/file-type": { "version": "21.3.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz", + "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", "license": "MIT", "dependencies": { "@tokenizer/inflate": "^0.4.1", @@ -10531,6 +10327,8 @@ }, "node_modules/fill-range": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -10541,6 +10339,8 @@ }, "node_modules/finalhandler": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -10559,9 +10359,9 @@ } }, "node_modules/find-proc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/find-proc/-/find-proc-0.1.0.tgz", - "integrity": "sha512-OaOpEYv2PiQ7SQ5LIrl+deA1XaWcxEjnpM6VuWXTUvn+teIXxeFTLDmu18/zDQpFmHN4o3oDBX+BT0AGwEhemg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/find-proc/-/find-proc-0.2.0.tgz", + "integrity": "sha512-a6h2nTrgB3g5Wrn4au9Ux4kMk7IJtyF6oA8uGn+mk3weLZssUtc1cp6meHIzzuW2o1srrBAxzkmXLbqjRkgB6w==", "license": "MIT", "engines": { "node": "^20.19.0 || >=22.12.0" @@ -10569,6 +10369,8 @@ }, "node_modules/find-up": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "license": "MIT", "dependencies": { "locate-path": "^3.0.0" @@ -10609,6 +10411,8 @@ }, "node_modules/forwarded": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -10616,13 +10420,17 @@ }, "node_modules/fresh": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/fs-extra": { - "version": "11.4.0", + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.1.tgz", + "integrity": "sha512-KYAb4c9BJQI6QqGKthV68OHe0badztdXJWKo0WtBA9IuCFPTKvE5ZdUBglP833aMjhaSPNO4A5j/EkzZtGlKjA==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -10635,10 +10443,15 @@ }, "node_modules/fs-monkey": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", "license": "Unlicense" }, "node_modules/fsevents": { "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -10650,6 +10463,8 @@ }, "node_modules/function-bind": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10657,10 +10472,14 @@ }, "node_modules/fuzzysort": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-3.1.0.tgz", + "integrity": "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==", "license": "MIT" }, "node_modules/gensync": { "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -10668,13 +10487,17 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-east-asian-width": { - "version": "1.6.0", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz", + "integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==", "license": "MIT", "engines": { "node": ">=18" @@ -10685,6 +10508,8 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -10707,6 +10532,8 @@ }, "node_modules/get-own-enumerable-keys": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-keys/-/get-own-enumerable-keys-1.0.0.tgz", + "integrity": "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==", "license": "MIT", "engines": { "node": ">=14.16" @@ -10717,6 +10544,8 @@ }, "node_modules/get-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -10728,6 +10557,8 @@ }, "node_modules/get-stream": { "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", @@ -10741,12 +10572,16 @@ } }, "node_modules/get-tsconfig": { - "version": "4.14.2", - "devOptional": true, + "version": "5.0.0-beta.4", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz", + "integrity": "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==", "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, + "engines": { + "node": ">=20.20.0" + }, "funding": { "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } @@ -10759,6 +10594,8 @@ }, "node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -10768,7 +10605,9 @@ } }, "node_modules/glob-to-regex.js": { - "version": "1.2.0", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.3.1.tgz", + "integrity": "sha512-zhWhMRsgnOym+1txhUmYJGD6eUsbUdrZv55gCYKuJX8t2p3+M8My23PD09bEIsreGUs5pnSa/idmcfp2/IlqGg==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -10783,6 +10622,8 @@ }, "node_modules/gopd": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -10793,13 +10634,17 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/grammy": { - "version": "1.45.1", + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/grammy/-/grammy-1.46.0.tgz", + "integrity": "sha512-/8Qw+iisrUdOMk+p2mjEHouMm/BBdBEN1DHh16wiTpRUZkxDG3PxexdjCvR+wvK3LWPdrEvnQbdrwpU954sPhg==", "license": "MIT", "dependencies": { - "@grammyjs/types": "4.0.0", + "@grammyjs/types": "5.0.0", "abort-controller": "^3.0.0", "debug": "^4.4.3", "node-fetch": "^2.7.0" @@ -10833,6 +10678,8 @@ }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -10840,6 +10687,8 @@ }, "node_modules/has-symbols": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -10850,6 +10699,8 @@ }, "node_modules/hashery": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", "license": "MIT", "dependencies": { "hookified": "^1.15.0" @@ -10860,6 +10711,8 @@ }, "node_modules/hasown": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -11130,6 +10983,8 @@ }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -11203,6 +11058,8 @@ }, "node_modules/hast-util-whitespace": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" @@ -11231,13 +11088,17 @@ }, "node_modules/heap-js": { "version": "2.7.1", + "resolved": "https://registry.npmjs.org/heap-js/-/heap-js-2.7.1.tgz", + "integrity": "sha512-EQfezRg0NCZGNlhlDR3Evrw1FVL2G3LhU7EgPoxufQKruNBSYA8MiRPHeWbU+36o+Fhel0wMwM+sLEiBAlNLJA==", "license": "BSD-3-Clause", "engines": { "node": ">=10.0.0" } }, "node_modules/hono": { - "version": "4.13.2", + "version": "4.13.12", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.12.tgz", + "integrity": "sha512-6E2QDAc9Ick9Sq77ZrGS/dk2WUYni91aufTw6LJKpV7w8kW5/GxVUc650FOADOmlwg3K+f7Pun6XlV+pYmW6gw==", "license": "MIT", "peer": true, "engines": { @@ -11246,19 +11107,21 @@ }, "node_modules/hookified": { "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", "license": "MIT" }, "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-7.0.0.tgz", + "integrity": "sha512-UikN5yr7xsCDAq87Or5or0PAlD3HJJOKVzM05az588WnpDJ4Ux7a2A53Qi6gofGg2/EtvF/H4hCi/TXfCW4Y6w==", "dev": true, "license": "MIT", "dependencies": { - "whatwg-encoding": "^3.1.1" + "@exodus/bytes": "^1.15.1" }, "engines": { - "node": ">=18" + "node": "^22.13.0 || >=24.0.0" } }, "node_modules/html-escaper": { @@ -11269,6 +11132,8 @@ }, "node_modules/html-url-attributes": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", "license": "MIT", "funding": { "type": "opencollective", @@ -11336,6 +11201,8 @@ }, "node_modules/http-errors": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -11352,36 +11219,10 @@ "url": "https://opencollective.com/express" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/human-signals": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", "license": "Apache-2.0", "engines": { "node": ">=18.18.0" @@ -11389,6 +11230,8 @@ }, "node_modules/hyperdyperid": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", "license": "MIT", "engines": { "node": ">=10.18" @@ -11423,21 +11266,21 @@ } }, "node_modules/iconv-lite": { - "version": "0.7.3", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -11456,6 +11299,8 @@ }, "node_modules/ignore": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -11463,6 +11308,8 @@ }, "node_modules/import-fresh": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -11487,10 +11334,14 @@ }, "node_modules/inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/inline-style-parser": { "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", "license": "MIT" }, "node_modules/internmap": { @@ -11503,7 +11354,9 @@ } }, "node_modules/ip-address": { - "version": "10.5.0", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.3.tgz", + "integrity": "sha512-A1kdq/tSb5QjvKvAMgIoEvDBIgL7qaqVP/jkvSwYYRZ9iEzvPpopxp2wQfu3SuZRHtpHNxMn8Fs0bS+gf5Xmwg==", "license": "MIT", "engines": { "node": ">= 12" @@ -11511,6 +11364,8 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -11527,6 +11382,8 @@ }, "node_modules/is-alphabetical": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "license": "MIT", "funding": { "type": "github", @@ -11535,6 +11392,8 @@ }, "node_modules/is-alphanumerical": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "license": "MIT", "dependencies": { "is-alphabetical": "^2.0.0", @@ -11547,10 +11406,14 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "license": "MIT" }, "node_modules/is-decimal": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "license": "MIT", "funding": { "type": "github", @@ -11558,13 +11421,15 @@ } }, "node_modules/is-docker": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-4.0.0.tgz", + "integrity": "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==", "license": "MIT", "bin": { "is-docker": "cli.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -11572,6 +11437,8 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11579,6 +11446,8 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" @@ -11586,6 +11455,8 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -11596,6 +11467,8 @@ }, "node_modules/is-hexadecimal": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", "license": "MIT", "funding": { "type": "github", @@ -11604,6 +11477,8 @@ }, "node_modules/is-in-ssh": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz", + "integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==", "license": "MIT", "engines": { "node": ">=20" @@ -11614,6 +11489,8 @@ }, "node_modules/is-inside-container": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "license": "MIT", "dependencies": { "is-docker": "^3.0.0" @@ -11628,8 +11505,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", "license": "MIT", "engines": { "node": ">=12" @@ -11640,6 +11534,8 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -11647,6 +11543,8 @@ }, "node_modules/is-obj": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "license": "MIT", "engines": { "node": ">=8" @@ -11654,6 +11552,8 @@ }, "node_modules/is-plain-obj": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "license": "MIT", "engines": { "node": ">=12" @@ -11671,10 +11571,14 @@ }, "node_modules/is-promise": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, "node_modules/is-regexp": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", + "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==", "license": "MIT", "engines": { "node": ">=12" @@ -11685,6 +11589,8 @@ }, "node_modules/is-stream": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "license": "MIT", "engines": { "node": ">=18" @@ -11695,6 +11601,8 @@ }, "node_modules/is-unicode-supported": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "license": "MIT", "engines": { "node": ">=18" @@ -11705,6 +11613,8 @@ }, "node_modules/is-wsl": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" @@ -11718,10 +11628,14 @@ }, "node_modules/isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/jest-worker": { "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -11734,14 +11648,17 @@ }, "node_modules/jiti": { "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "license": "MIT", - "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } }, "node_modules/jose": { - "version": "6.2.8", + "version": "6.2.12", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", + "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==", "license": "MIT", "peer": true, "funding": { @@ -11750,10 +11667,14 @@ }, "node_modules/js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "funding": [ { "type": "github", @@ -11773,38 +11694,38 @@ } }, "node_modules/jsdom": { - "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", - "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "version": "30.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.1.1.tgz", + "integrity": "sha512-FahmoPK5vbPc+jxV1iErMHmAZypCZ942NHF4+qqaWAuvaKKTBZxawnmAtrbGWLU7MtlxfqIP0qw6aSI+aWGtLg==", "dev": true, "license": "MIT", "dependencies": { - "cssstyle": "^4.2.1", - "data-urls": "^5.0.0", - "decimal.js": "^10.5.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", + "@asamuzakjp/css-color": "^7.0.0", + "@asamuzakjp/dom-selector": "^9.2.1", + "@bramus/specificity": "^2.4.2", + "@csstools/css-syntax-patches-for-csstree": "^1.1.13", + "@exodus/bytes": "^1.15.1", + "css-tree": "^3.2.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^7.0.0", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.16", - "parse5": "^7.2.1", - "rrweb-cssom": "^0.8.0", + "lru-cache": "^11.5.2", + "parse5": "^8.0.1", "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.1.1", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.1.1", - "ws": "^8.18.0", + "tough-cookie": "^6.0.2", + "undici": "^8.10.2", + "w3c-xmlserializer": "^6.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^17.1.1", "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=18" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" }, "peerDependencies": { - "canvas": "^3.0.0" + "canvas": "^3.2.3" }, "peerDependenciesMeta": { "canvas": { @@ -11812,45 +11733,56 @@ } } }, - "node_modules/jsdom/node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "node_modules/jsdom/node_modules/entities": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.1.0.tgz", + "integrity": "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/jsdom/node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.3.1" + "entities": "^8.0.0" }, - "engines": { - "node": ">=18" + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/jsdom/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "node_modules/jsdom/node_modules/undici": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.11.2.tgz", + "integrity": "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=22.19.0" } }, - "node_modules/jsdom/node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "node_modules/jsdom/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", "dev": true, "license": "MIT", - "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" - }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/jsesc": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -11861,22 +11793,25 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "license": "MIT" }, "node_modules/json-schema-to-typescript": { - "version": "15.0.4", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-16.0.0.tgz", + "integrity": "sha512-Ah6kK4q6SjlMzWBH1eNOQkdRh5Qhr5T/RCFwfjQqWZA7UDW+N47A8wfyoiN0L884s4L4bAEI54IjIuN3/u0B/A==", "dev": true, "license": "MIT", "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.5.5", + "@apidevtools/json-schema-ref-parser": "^11.9.3", "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.7", - "is-glob": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", + "@types/lodash": "^4.17.25", + "js-yaml": "^5.2.3", + "lodash": "^4.18.1", "minimist": "^1.2.8", - "prettier": "^3.2.5", - "tinyglobby": "^0.2.9" + "prettier": "^3.9.6", + "tinyglobby": "^0.2.17" }, "bin": { "json2ts": "dist/src/cli.js" @@ -11885,16 +11820,45 @@ "node": ">=16.0.0" } }, + "node_modules/json-schema-to-typescript/node_modules/js-yaml": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.2.tgz", + "integrity": "sha512-m+aqu+LwO1O6sIopafj8HUVl5aawITwZQe/yHpMCKjaWBaA/d07B/QdMb3529REftiU+RMMHL3Vlsw3hON7vWg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.mjs" + } + }, "node_modules/json-schema-traverse": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/json-schema-typed": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", "license": "BSD-2-Clause" }, "node_modules/json5": { "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -11911,6 +11875,8 @@ }, "node_modules/jsonfile": { "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -11946,6 +11912,8 @@ }, "node_modules/keyv": { "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "license": "MIT", "peer": true, "dependencies": { @@ -11959,6 +11927,8 @@ }, "node_modules/kleur": { "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "license": "MIT", "engines": { "node": ">=6" @@ -11974,7 +11944,9 @@ } }, "node_modules/kysely": { - "version": "0.29.5", + "version": "0.29.6", + "resolved": "https://registry.npmjs.org/kysely/-/kysely-0.29.6.tgz", + "integrity": "sha512-hHaB8C/rfzDDtr/t8YZwxAuPJTT0zHyaPoVzcXwDYhYNAgH/4sIfVhi/XLLIY+bL/FqaIJnjATDbi8ObSELmxg==", "license": "MIT", "peer": true, "engines": { @@ -11989,6 +11961,8 @@ }, "node_modules/libsignal": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/libsignal/-/libsignal-6.0.0.tgz", + "integrity": "sha512-d/5V3YFtDljbFMufz4ncyUYGYhJl+vzAe+c2EFFBQ6bz1h8Q3IOMEGXYMzlibU60I+e8GagMMpji18iez3P1hA==", "license": "GPL-3.0", "dependencies": { "curve25519-js": "^0.0.4", @@ -11997,6 +11971,8 @@ }, "node_modules/lightningcss": { "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -12044,6 +12020,8 @@ }, "node_modules/lightningcss-darwin-arm64": { "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], @@ -12242,10 +12220,14 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, "node_modules/locate-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "license": "MIT", "dependencies": { "p-locate": "^3.0.0", @@ -12257,6 +12239,8 @@ }, "node_modules/lodash": { "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, @@ -12268,10 +12252,14 @@ }, "node_modules/lodash.camelcase": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, "node_modules/log-symbols": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", "license": "MIT", "dependencies": { "chalk": "^5.3.0", @@ -12286,6 +12274,8 @@ }, "node_modules/log-symbols/node_modules/is-unicode-supported": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "license": "MIT", "engines": { "node": ">=12" @@ -12296,46 +12286,57 @@ }, "node_modules/long": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0" }, "node_modules/longest-streak": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/loupe": { - "version": "3.2.1", - "devOptional": true, - "license": "MIT" - }, "node_modules/lru-cache": { - "version": "5.1.1", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz", + "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, "node_modules/lucide-react": { - "version": "1.31.0", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.51.0.tgz", + "integrity": "sha512-9929jimol5y7VbXUlVKcgURMSeIxFJB7dtWCkRAaNnF7KiCRkSkhmqWPUmAmUFYPezNawFk6qvz3Mu0gEnfI4g==", "license": "ISC", "peerDependencies": { + "@types/react": "*", "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/magic-string": { - "version": "0.30.21", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.2.tgz", + "integrity": "sha512-vG+rjFRj1PqdIBozIxAGMjPlOhaVe+GXpbttY/iSK7rGcJRMlwNJO7dcUwmUqkymsFLJiNGI06t4D7Fr7yRC9g==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "@jridgewell/sourcemap-codec": "^1.6.0" } }, "node_modules/magicast": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.4.tgz", - "integrity": "sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.5.tgz", + "integrity": "sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.7", @@ -12357,6 +12358,8 @@ }, "node_modules/markdown-table": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", "license": "MIT", "funding": { "type": "github", @@ -12364,7 +12367,9 @@ } }, "node_modules/marked": { - "version": "18.0.9", + "version": "18.0.14", + "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.14.tgz", + "integrity": "sha512-mBHK6FBHuBAlhgRe88w9F0O1AbwwXJUcQibUbC/QcdTbVGAD7aWza+xt3N6oT/jCZx3/OMeS+8rnuiHZcQ9s7A==", "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -12375,6 +12380,8 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -12396,9 +12403,9 @@ } }, "node_modules/mdast-util-directive": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", - "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.1.tgz", + "integrity": "sha512-Gqpa3MHorXYEZ0VfbroyvBlVKUfz371V6mIERqOYMcb0W1D3LwmFq1ZW4O2TDrbn+4ZmGLwMWeFRJgYZ+bc5fQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12407,6 +12414,7 @@ "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", + "micromark-util-character": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-visit-parents": "^6.0.0" @@ -12418,6 +12426,8 @@ }, "node_modules/mdast-util-find-and-replace": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12431,7 +12441,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.3", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz", + "integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12454,6 +12466,8 @@ }, "node_modules/mdast-util-gfm": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", @@ -12471,6 +12485,8 @@ }, "node_modules/mdast-util-gfm-autolink-literal": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12486,6 +12502,8 @@ }, "node_modules/mdast-util-gfm-footnote": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12500,7 +12518,9 @@ } }, "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.1.tgz", + "integrity": "sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12514,6 +12534,8 @@ }, "node_modules/mdast-util-gfm-table": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12529,6 +12551,8 @@ }, "node_modules/mdast-util-gfm-task-list-item": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12560,6 +12584,8 @@ }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -12576,6 +12602,8 @@ }, "node_modules/mdast-util-mdx-jsx": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -12598,6 +12626,8 @@ }, "node_modules/mdast-util-mdxjs-esm": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -12614,6 +12644,8 @@ }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12626,6 +12658,8 @@ }, "node_modules/mdast-util-to-hast": { "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -12644,7 +12678,9 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.2.0.tgz", + "integrity": "sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -12652,8 +12688,10 @@ "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", + "micromark-util-character": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" }, @@ -12664,6 +12702,8 @@ }, "node_modules/mdast-util-to-string": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" @@ -12718,6 +12758,8 @@ }, "node_modules/media-typer": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-2.0.0.tgz", + "integrity": "sha512-kOy3OxT2HH39N70UnKgu4NWDZjLOz8W/mfyvniHjRH/DrL3f2pOfvWQ4p60offbbtDAnXWp0v9LfMIqMec269Q==", "license": "MIT", "engines": { "node": ">=18" @@ -12728,20 +12770,22 @@ } }, "node_modules/memfs": { - "version": "4.68.1", + "version": "4.80.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.80.0.tgz", + "integrity": "sha512-N70W2isi44XdGn7uPo9NJ4zRukcdkwSFHlnYx42SWOH/+hzqNc8P7+tVoA2up4z7faHvNi1RSNCFjxoYQ71VPQ==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.68.1", - "@jsonjoy.com/fs-fsa": "4.68.1", - "@jsonjoy.com/fs-node": "4.68.1", - "@jsonjoy.com/fs-node-builtins": "4.68.1", - "@jsonjoy.com/fs-node-to-fsa": "4.68.1", - "@jsonjoy.com/fs-node-utils": "4.68.1", - "@jsonjoy.com/fs-print": "4.68.1", - "@jsonjoy.com/fs-snapshot": "4.68.1", + "@jsonjoy.com/fs-core": "4.80.0", + "@jsonjoy.com/fs-fsa": "4.80.0", + "@jsonjoy.com/fs-node": "4.80.0", + "@jsonjoy.com/fs-node-builtins": "4.80.0", + "@jsonjoy.com/fs-node-to-fsa": "4.80.0", + "@jsonjoy.com/fs-node-utils": "4.80.0", + "@jsonjoy.com/fs-print": "4.80.0", + "@jsonjoy.com/fs-snapshot": "4.80.0", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", - "glob-to-regex.js": "^1.0.1", + "glob-to-regex.js": "^1.3.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" @@ -12753,6 +12797,8 @@ }, "node_modules/merge-descriptors": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", "engines": { "node": ">=18" @@ -12763,10 +12809,14 @@ }, "node_modules/merge-stream": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "license": "MIT", "engines": { "node": ">= 8" @@ -12816,7 +12866,9 @@ } }, "node_modules/micromark": { - "version": "4.0.2", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.3.tgz", + "integrity": "sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==", "funding": [ { "type": "GitHub Sponsors", @@ -12839,6 +12891,7 @@ "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", @@ -12849,7 +12902,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.3", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.4.tgz", + "integrity": "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==", "funding": [ { "type": "GitHub Sponsors", @@ -12866,18 +12921,19 @@ "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", + "micromark-factory-space": "^2.1.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" + "micromark-util-types": "^2.0.3" } }, "node_modules/micromark-extension-directive": { @@ -12901,6 +12957,8 @@ }, "node_modules/micromark-extension-gfm": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", "license": "MIT", "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", @@ -12919,6 +12977,8 @@ }, "node_modules/micromark-extension-gfm-autolink-literal": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", @@ -12933,6 +12993,8 @@ }, "node_modules/micromark-extension-gfm-footnote": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -12951,6 +13013,8 @@ }, "node_modules/micromark-extension-gfm-strikethrough": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -12966,7 +13030,9 @@ } }, "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.2.tgz", + "integrity": "sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -12982,6 +13048,8 @@ }, "node_modules/micromark-extension-gfm-tagfilter": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" @@ -12993,6 +13061,8 @@ }, "node_modules/micromark-extension-gfm-task-list-item": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -13110,6 +13180,8 @@ }, "node_modules/micromark-factory-destination": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", "funding": [ { "type": "GitHub Sponsors", @@ -13129,6 +13201,8 @@ }, "node_modules/micromark-factory-label": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", "funding": [ { "type": "GitHub Sponsors", @@ -13175,7 +13249,9 @@ } }, "node_modules/micromark-factory-space": { - "version": "2.0.1", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.1.0.tgz", + "integrity": "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==", "funding": [ { "type": "GitHub Sponsors", @@ -13194,6 +13270,8 @@ }, "node_modules/micromark-factory-title": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", "funding": [ { "type": "GitHub Sponsors", @@ -13214,6 +13292,8 @@ }, "node_modules/micromark-factory-whitespace": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", "funding": [ { "type": "GitHub Sponsors", @@ -13234,6 +13314,8 @@ }, "node_modules/micromark-util-character": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -13252,6 +13334,8 @@ }, "node_modules/micromark-util-chunked": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", "funding": [ { "type": "GitHub Sponsors", @@ -13269,6 +13353,8 @@ }, "node_modules/micromark-util-classify-character": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", "funding": [ { "type": "GitHub Sponsors", @@ -13288,6 +13374,8 @@ }, "node_modules/micromark-util-combine-extensions": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", "funding": [ { "type": "GitHub Sponsors", @@ -13306,6 +13394,8 @@ }, "node_modules/micromark-util-decode-numeric-character-reference": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", "funding": [ { "type": "GitHub Sponsors", @@ -13323,6 +13413,8 @@ }, "node_modules/micromark-util-decode-string": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", "funding": [ { "type": "GitHub Sponsors", @@ -13341,8 +13433,29 @@ "micromark-util-symbol": "^2.0.0" } }, + "node_modules/micromark-util-edit-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-edit-map/-/micromark-util-edit-map-1.0.0.tgz", + "integrity": "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, "node_modules/micromark-util-encode": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "funding": [ { "type": "GitHub Sponsors", @@ -13382,6 +13495,8 @@ }, "node_modules/micromark-util-html-tag-name": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", "funding": [ { "type": "GitHub Sponsors", @@ -13396,6 +13511,8 @@ }, "node_modules/micromark-util-normalize-identifier": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", "funding": [ { "type": "GitHub Sponsors", @@ -13413,6 +13530,8 @@ }, "node_modules/micromark-util-resolve-all": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", "funding": [ { "type": "GitHub Sponsors", @@ -13430,6 +13549,8 @@ }, "node_modules/micromark-util-sanitize-uri": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "funding": [ { "type": "GitHub Sponsors", @@ -13449,6 +13570,8 @@ }, "node_modules/micromark-util-subtokenize": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", "funding": [ { "type": "GitHub Sponsors", @@ -13469,6 +13592,8 @@ }, "node_modules/micromark-util-symbol": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -13482,7 +13607,9 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.2", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", + "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", "funding": [ { "type": "GitHub Sponsors", @@ -13497,6 +13624,8 @@ }, "node_modules/micromatch": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -13508,6 +13637,8 @@ }, "node_modules/micromatch/node_modules/picomatch": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -13518,6 +13649,8 @@ }, "node_modules/mime-db": { "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -13525,6 +13658,8 @@ }, "node_modules/mime-types": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" @@ -13539,6 +13674,8 @@ }, "node_modules/mimic-fn": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", "license": "MIT", "engines": { "node": ">=8" @@ -13546,6 +13683,8 @@ }, "node_modules/mimic-function": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", "license": "MIT", "engines": { "node": ">=18" @@ -13556,6 +13695,8 @@ }, "node_modules/minimatch": { "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.8" @@ -13569,19 +13710,23 @@ }, "node_modules/minimist": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minimizer-webpack-plugin": { - "version": "5.6.1", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.13.0.tgz", + "integrity": "sha512-OO1NF2zHj6sf4CNv2AsUWYcS8WEwkVKQDXxxKzlOxx1Xl+WlqYtVC+oNlGNwGkLAOnpj277BSHypWwRtd9w4JQ==", "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", + "@jridgewell/trace-mapping": "^0.3.31", "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "terser": "^5.31.1" + "schema-utils": "^4.3.3", + "terser": "^5.51.0" }, "engines": { "node": ">= 10.13.0" @@ -13597,6 +13742,9 @@ "@minify-html/node": { "optional": true }, + "@napi-rs/image": { + "optional": true + }, "@swc/core": { "optional": true }, @@ -13621,12 +13769,21 @@ "html-minifier-terser": { "optional": true }, + "imagemin": { + "optional": true + }, "lightningcss": { "optional": true }, "postcss": { "optional": true }, + "sharp": { + "optional": true + }, + "svgo": { + "optional": true + }, "uglify-js": { "optional": true } @@ -13643,6 +13800,8 @@ }, "node_modules/ms": { "version": "3.0.0-canary.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz", + "integrity": "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==", "license": "MIT", "engines": { "node": ">=12.13" @@ -13669,7 +13828,9 @@ } }, "node_modules/music-metadata": { - "version": "11.14.0", + "version": "11.16.1", + "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-11.16.1.tgz", + "integrity": "sha512-uR/mHK6eyfl8h3jVCobF5b38Mfg1IDJMiBxIVbmm5F+G1OXEFcUpQHveO84tJBAqvY93GCRY2R4kDyx7s06Rug==", "funding": [ { "type": "github", @@ -13684,7 +13845,7 @@ "dependencies": { "@borewit/text-codec": "^0.2.2", "@tokenizer/token": "^0.3.0", - "content-type": "^2.0.0", + "content-type": "^2.1.0", "debug": "^4.4.3", "file-type": "^21.3.4", "media-typer": "^2.0.0", @@ -13699,6 +13860,8 @@ }, "node_modules/music-metadata/node_modules/content-type": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", "license": "MIT", "engines": { "node": ">=18" @@ -13709,7 +13872,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.18", + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", "funding": [ { "type": "github", @@ -13725,7 +13890,9 @@ } }, "node_modules/nanostores": { - "version": "1.4.2", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-1.5.4.tgz", + "integrity": "sha512-4UXY7OAJEK0Y6V3SudBU7cXjAzTDc189R78dDOh0Xbm19gpKYto6WizSg58LJf12lTsRxKSLGyE117OiLpM4DQ==", "funding": [ { "type": "github", @@ -13739,15 +13906,33 @@ } }, "node_modules/negotiator": { - "version": "1.0.0", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz", + "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", "license": "MIT", + "dependencies": { + "content-type": "^2.1.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "license": "MIT" + "node_modules/negotiator/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, "node_modules/neotraverse": { "version": "1.0.1", @@ -13759,7 +13944,9 @@ } }, "node_modules/nexus-rpc": { - "version": "0.0.2", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/nexus-rpc/-/nexus-rpc-0.0.3.tgz", + "integrity": "sha512-ksIBeYHDv6FHAR1h3Vwk0kQ6REhdo1STqDHXMzu/yn/VN/XzgOor2IUjewG6paoA7IgxlIPZoOU/PD78PC6HTg==", "license": "MIT", "engines": { "node": ">= 20.0.0" @@ -13780,6 +13967,8 @@ }, "node_modules/node-fetch": { "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -13802,6 +13991,28 @@ "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", "license": "MIT" }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-mock-http": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.5.tgz", @@ -13809,7 +14020,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.53", + "version": "2.0.57", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz", + "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==", "license": "MIT", "engines": { "node": ">=18" @@ -13826,6 +14039,8 @@ }, "node_modules/npm-run-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", "license": "MIT", "dependencies": { "path-key": "^4.0.0", @@ -13840,6 +14055,8 @@ }, "node_modules/npm-run-path/node_modules/path-key": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "license": "MIT", "engines": { "node": ">=12" @@ -13860,15 +14077,10 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/nwsapi": { - "version": "2.2.27", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.27.tgz", - "integrity": "sha512-gQPNF78qebCQ6tvVFBYrvJdBNOrYZm90ZlXgpIFm06p6qHDHq/XC4TnJftN6OMbxVE0UTBAoRgcsDeJBBooITw==", - "dev": true, - "license": "MIT" - }, "node_modules/object-assign": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -13876,6 +14088,8 @@ }, "node_modules/object-inspect": { "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -13886,15 +14100,17 @@ }, "node_modules/object-treeify": { "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/obug": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", - "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/obug/-/obug-3.0.0.tgz", + "integrity": "sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==", "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" @@ -13923,6 +14139,8 @@ }, "node_modules/on-exit-leak-free": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -13930,6 +14148,8 @@ }, "node_modules/on-finished": { "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -13940,6 +14160,8 @@ }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "dependencies": { "wrappy": "1" @@ -13947,6 +14169,8 @@ }, "node_modules/onetime": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -13960,6 +14184,8 @@ }, "node_modules/onetime/node_modules/mimic-fn": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "license": "MIT", "engines": { "node": ">=6" @@ -13983,14 +14209,16 @@ } }, "node_modules/open": { - "version": "11.0.1", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/open/-/open-11.0.4.tgz", + "integrity": "sha512-++Zlftm0kVLPmzC06t6epuWmcRMDbI4z5P3NNX979WA/k23+NtSOynEGzsVfZwguKw2mi5umVgnBlJQMwRz4Pg==", "license": "MIT", "dependencies": { - "default-browser": "^5.4.0", + "default-browser": "^5.5.1", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", - "powershell-utils": "^0.2.0", + "powershell-utils": "^0.2.1", "wsl-utils": "^1.0.0" }, "engines": { @@ -14002,6 +14230,8 @@ }, "node_modules/ora": { "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", "license": "MIT", "dependencies": { "chalk": "^5.3.0", @@ -14022,7 +14252,9 @@ } }, "node_modules/ora/node_modules/ansi-regex": { - "version": "6.3.0", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", "license": "MIT", "engines": { "node": ">=12" @@ -14033,6 +14265,8 @@ }, "node_modules/ora/node_modules/strip-ansi": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" @@ -14045,13 +14279,15 @@ } }, "node_modules/p-limit": { - "version": "2.3.0", + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.3.tgz", + "integrity": "sha512-SKgVvDU5TNIxQ4r30U75BNLC6a+6GOEjngrk/ysM5+Zu3oJuk1SC5ApzIzY/7PjCEjoVPMWJ0zho/4QUiEB7TQ==", "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "yocto-queue": "^1.2.1" }, "engines": { - "node": ">=6" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -14059,6 +14295,8 @@ }, "node_modules/p-locate": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "license": "MIT", "dependencies": { "p-limit": "^2.0.0" @@ -14067,8 +14305,25 @@ "node": ">=6" } }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-queue": { "version": "9.3.3", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.3.3.tgz", + "integrity": "sha512-NXAOdnEe5FsZJfT4oK84lE1Y5cFFdWlRuOo5tww8DyNMxyRXwn39fIkUtNLKppcPC+UYU/bXujNCUGDv01y7CA==", "license": "MIT", "dependencies": { "eventemitter3": "^5.0.4", @@ -14082,7 +14337,9 @@ } }, "node_modules/p-timeout": { - "version": "7.0.1", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.2.tgz", + "integrity": "sha512-prbX4Z3YszrFNgH+MW5Zoeq3baXrMtP/MQnFeET90UB/GtGcGDQ5Usg9OCy6ETjTTntOw1SL2z9fMPUppN3Guw==", "license": "MIT", "engines": { "node": ">=20" @@ -14093,6 +14350,8 @@ }, "node_modules/p-try": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "license": "MIT", "engines": { "node": ">=6" @@ -14124,6 +14383,8 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -14134,6 +14395,8 @@ }, "node_modules/parse-entities": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", @@ -14151,10 +14414,14 @@ }, "node_modules/parse-entities/node_modules/@types/unist": { "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -14189,6 +14456,8 @@ }, "node_modules/parse-ms": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", "license": "MIT", "engines": { "node": ">=18" @@ -14236,8 +14505,22 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -14245,6 +14528,8 @@ }, "node_modules/path-browserify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "license": "MIT" }, "node_modules/path-data-parser": { @@ -14255,6 +14540,8 @@ }, "node_modules/path-exists": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "license": "MIT", "engines": { "node": ">=4" @@ -14262,6 +14549,8 @@ }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" @@ -14269,33 +14558,24 @@ }, "node_modules/path-to-regexp": { "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, - "node_modules/pathe": { - "version": "2.0.3", - "devOptional": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "node_modules/pg": { - "version": "8.23.0", + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.23.1.tgz", + "integrity": "sha512-aL96AHANtWjPLDOLqnhx+ngp9+UK7ETEU8VJrDCGvsSSi/mGLcWYsS6Herg7lmaBJe4uwrfqsa7gTEFaSizDoQ==", "license": "MIT", "peer": true, "dependencies": { - "pg-connection-string": "^2.14.0", + "pg-connection-string": "^2.14.1", "pg-pool": "^3.14.0", - "pg-protocol": "^1.16.0", + "pg-protocol": "^1.16.1", "pg-types": "2.2.0", "pgpass": "1.0.5" }, @@ -14303,7 +14583,7 @@ "node": ">= 16.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.4.0" + "pg-cloudflare": "^1.4.1" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -14315,16 +14595,22 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.4.0", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.1.tgz", + "integrity": "sha512-6PQbsFWZcp9EmJEwy5cGQ2La+AMWpP46lgbb8X+U/XsHIUweYDNCpeuKck5RxL2MdVFi7krbbEi5nX4Zh7JhrQ==", "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.14.0", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.1.tgz", + "integrity": "sha512-qR3kGNPBLpCNtz0evbKA0Y/MRFXwSSdT+pTJvYp/bXTcReZbvX1kzF0IyTc1QnxqF7AZbOeBhNL8R5mYQZV/MA==", "license": "MIT" }, "node_modules/pg-int8": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", "license": "ISC", "engines": { "node": ">=4.0.0" @@ -14332,17 +14618,23 @@ }, "node_modules/pg-pool": { "version": "3.14.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz", + "integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==", "license": "MIT", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.16.0", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.1.tgz", + "integrity": "sha512-p9VOFMiHB/ZbJATetbg+99PxssTVSQRnyuPSQ67mN1+1KBOjZaZ83ZQzltnxPhJwSsC3nwVjJ10DVJlerbFzLg==", "license": "MIT" }, "node_modules/pg-types": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", "license": "MIT", "dependencies": { "pg-int8": "1.0.1", @@ -14357,6 +14649,8 @@ }, "node_modules/pgpass": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", "license": "MIT", "dependencies": { "split2": "^4.1.0" @@ -14370,10 +14664,14 @@ }, "node_modules/picocolors": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.5", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "license": "MIT", "engines": { "node": ">=12" @@ -14384,6 +14682,8 @@ }, "node_modules/pino": { "version": "9.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", + "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", "license": "MIT", "dependencies": { "@pinojs/redact": "^0.4.0", @@ -14404,6 +14704,8 @@ }, "node_modules/pino-abstract-transport": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", "license": "MIT", "dependencies": { "split2": "^4.0.0" @@ -14411,10 +14713,14 @@ }, "node_modules/pino-std-serializers": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", "license": "MIT" }, "node_modules/pkce-challenge": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", "license": "MIT", "engines": { "node": ">=16.20.0" @@ -14422,6 +14728,8 @@ }, "node_modules/pkg-up": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "license": "MIT", "dependencies": { "find-up": "^3.0.0" @@ -14447,7 +14755,9 @@ } }, "node_modules/postcss": { - "version": "8.5.26", + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", "funding": [ { "type": "opencollective", @@ -14465,7 +14775,7 @@ "license": "MIT", "peer": true, "dependencies": { - "nanoid": "^3.3.17", + "nanoid": "^3.3.18", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -14498,7 +14808,7 @@ "postcss": "^8.2.14" } }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "node_modules/postcss-selector-parser": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", @@ -14511,19 +14821,10 @@ "node": ">=4" } }, - "node_modules/postcss-selector-parser": { - "version": "7.1.5", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postgres-array": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", "license": "MIT", "engines": { "node": ">=4" @@ -14531,6 +14832,8 @@ }, "node_modules/postgres-bytea": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14538,6 +14841,8 @@ }, "node_modules/postgres-date": { "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14545,6 +14850,8 @@ }, "node_modules/postgres-interval": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "license": "MIT", "dependencies": { "xtend": "^4.0.0" @@ -14554,7 +14861,9 @@ } }, "node_modules/powershell-utils": { - "version": "0.2.0", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.2.1.tgz", + "integrity": "sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==", "license": "MIT", "engines": { "node": ">=20" @@ -14564,7 +14873,9 @@ } }, "node_modules/prettier": { - "version": "3.9.6", + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.9.tgz", + "integrity": "sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==", "dev": true, "license": "MIT", "peer": true, @@ -14579,7 +14890,9 @@ } }, "node_modules/pretty-ms": { - "version": "9.3.0", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.1.tgz", + "integrity": "sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA==", "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" @@ -14611,6 +14924,8 @@ }, "node_modules/process-warning": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.1.0.tgz", + "integrity": "sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==", "funding": [ { "type": "github", @@ -14625,6 +14940,8 @@ }, "node_modules/prompts": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -14636,6 +14953,8 @@ }, "node_modules/prompts/node_modules/kleur": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "license": "MIT", "engines": { "node": ">=6" @@ -14643,24 +14962,18 @@ }, "node_modules/property-information": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/proto3-json-serializer": { - "version": "2.0.2", - "license": "Apache-2.0", - "dependencies": { - "protobufjs": "^7.2.5" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/protobufjs": { - "version": "7.6.5", + "version": "7.6.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz", + "integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -14681,7 +14994,9 @@ } }, "node_modules/proxy-addr": { - "version": "2.0.7", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz", + "integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -14689,6 +15004,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/punycode": { @@ -14703,6 +15022,8 @@ }, "node_modules/qified": { "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", "license": "MIT", "dependencies": { "hookified": "^2.1.1" @@ -14713,16 +15034,22 @@ }, "node_modules/qified/node_modules/hookified": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", "license": "MIT" }, "node_modules/qrcode-terminal": { "version": "0.12.0", + "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", + "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", "bin": { "qrcode-terminal": "bin/qrcode-terminal.js" } }, "node_modules/qs": { - "version": "6.15.3", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", "license": "BSD-3-Clause", "dependencies": { "es-define-property": "^1.0.1", @@ -14737,6 +15064,8 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "funding": [ { "type": "github", @@ -14755,6 +15084,8 @@ }, "node_modules/quick-format-unescaped": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", "license": "MIT" }, "node_modules/radix3": { @@ -14765,6 +15096,8 @@ }, "node_modules/range-parser": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -14776,6 +15109,8 @@ }, "node_modules/raw-body": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -14787,8 +15122,26 @@ "node": ">= 0.10" } }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/react": { - "version": "19.2.8", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", "license": "MIT", "peer": true, "engines": { @@ -14796,18 +15149,22 @@ } }, "node_modules/react-dom": { - "version": "19.2.8", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", "license": "MIT", "peer": true, "dependencies": { - "scheduler": "^0.27.0" + "scheduler": "^0.28.0" }, "peerDependencies": { - "react": "^19.2.8" + "react": "^19.3.0" } }, "node_modules/react-markdown": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -14831,16 +15188,10 @@ "react": ">=18" } }, - "node_modules/react-refresh": { - "version": "0.17.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-router": { - "version": "7.18.2", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.4.tgz", + "integrity": "sha512-PUPQcMhMGRAslLcvtlPz/kmzBEWPhLdgLFrL7pLNepBL6dX0lWj4WD2cUYVgYCuT3jxvghYFg81cDTj44DhetQ==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -14860,10 +15211,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.18.2", + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.4.tgz", + "integrity": "sha512-yrfmJHIpDG7taCpqKjT1G5B6q3O2K+RN8/fgNf0lTjCwiPbQ0ei6vXX9ZjQR+7ld8Tr7Z5xmyMnZ8YJrphWQUw==", "license": "MIT", "dependencies": { - "react-router": "7.18.2" + "react-router": "7.18.4" }, "engines": { "node": ">=20.0.0" @@ -14875,6 +15228,8 @@ }, "node_modules/react-router/node_modules/cookie": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", "engines": { "node": ">=18" @@ -14886,6 +15241,8 @@ }, "node_modules/react-router/node_modules/set-cookie-parser": { "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, "node_modules/readdirp": { @@ -14904,6 +15261,8 @@ }, "node_modules/real-require": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", "license": "MIT", "engines": { "node": ">= 12.13.0" @@ -14911,6 +15270,8 @@ }, "node_modules/recast": { "version": "0.23.21", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.21.tgz", + "integrity": "sha512-mFAyJq9vUbSTARLZUvAEf1z3YxlvAwswbmxMx2mPA/MSm4KmpwvwvhsH/NIrZhyOuwD60Lzyw2qh83uCbgTPYw==", "license": "MIT", "dependencies": { "ast-types": "^0.16.1", @@ -14925,6 +15286,8 @@ }, "node_modules/recast/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -15119,6 +15482,8 @@ }, "node_modules/remark-gfm": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -15165,6 +15530,8 @@ }, "node_modules/remark-rehype": { "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -15217,6 +15584,8 @@ }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -15224,17 +15593,23 @@ }, "node_modules/require-from-string": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/reselect": { - "version": "5.2.0", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.3.0.tgz", + "integrity": "sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==", "license": "MIT" }, "node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "license": "MIT", "engines": { "node": ">=4" @@ -15242,6 +15617,8 @@ }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -15249,6 +15626,8 @@ }, "node_modules/restore-cursor": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "license": "MIT", "dependencies": { "onetime": "^7.0.0", @@ -15263,6 +15642,8 @@ }, "node_modules/restore-cursor/node_modules/onetime": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" @@ -15337,6 +15718,8 @@ }, "node_modules/reusify": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -15350,12 +15733,12 @@ "license": "Unlicense" }, "node_modules/rolldown": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", - "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", + "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.148.0", + "@oxc-project/types": "=0.152.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -15365,74 +15748,27 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.7", - "@rolldown/binding-android-arm64": "1.2.7", - "@rolldown/binding-darwin-arm64": "1.2.7", - "@rolldown/binding-darwin-x64": "1.2.7", - "@rolldown/binding-freebsd-x64": "1.2.7", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", - "@rolldown/binding-linux-arm64-gnu": "1.2.7", - "@rolldown/binding-linux-arm64-musl": "1.2.7", - "@rolldown/binding-linux-ppc64-gnu": "1.2.7", - "@rolldown/binding-linux-s390x-gnu": "1.2.7", - "@rolldown/binding-linux-x64-gnu": "1.2.7", - "@rolldown/binding-linux-x64-musl": "1.2.7", - "@rolldown/binding-openharmony-arm64": "1.2.7", - "@rolldown/binding-win32-arm64-msvc": "1.2.7", - "@rolldown/binding-win32-x64-msvc": "1.2.7" - } - }, - "node_modules/rolldown/node_modules/@rolldown/pluginutils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", - "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.62.4", - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.9" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@napi-rs/lzma-linux-x64-gnu": "1.5.1", - "@rollup/rollup-android-arm-eabi": "4.62.4", - "@rollup/rollup-android-arm64": "4.62.4", - "@rollup/rollup-darwin-arm64": "4.62.4", - "@rollup/rollup-darwin-x64": "4.62.4", - "@rollup/rollup-freebsd-arm64": "4.62.4", - "@rollup/rollup-freebsd-x64": "4.62.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", - "@rollup/rollup-linux-arm-musleabihf": "4.62.4", - "@rollup/rollup-linux-arm64-gnu": "4.62.4", - "@rollup/rollup-linux-arm64-musl": "4.62.4", - "@rollup/rollup-linux-loong64-gnu": "4.62.4", - "@rollup/rollup-linux-loong64-musl": "4.62.4", - "@rollup/rollup-linux-ppc64-gnu": "4.62.4", - "@rollup/rollup-linux-ppc64-musl": "4.62.4", - "@rollup/rollup-linux-riscv64-gnu": "4.62.4", - "@rollup/rollup-linux-riscv64-musl": "4.62.4", - "@rollup/rollup-linux-s390x-gnu": "4.62.4", - "@rollup/rollup-linux-x64-gnu": "4.62.4", - "@rollup/rollup-linux-x64-musl": "4.62.4", - "@rollup/rollup-openbsd-x64": "4.62.4", - "@rollup/rollup-openharmony-arm64": "4.62.4", - "@rollup/rollup-win32-arm64-msvc": "4.62.4", - "@rollup/rollup-win32-ia32-msvc": "4.62.4", - "@rollup/rollup-win32-x64-gnu": "4.62.4", - "@rollup/rollup-win32-x64-msvc": "4.62.4", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm-eabi": "1.2.12", + "@rolldown/binding-android-arm64": "1.2.12", + "@rolldown/binding-darwin-arm64": "1.2.12", + "@rolldown/binding-darwin-x64": "1.2.12", + "@rolldown/binding-freebsd-x64": "1.2.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", + "@rolldown/binding-linux-arm64-gnu": "1.2.12", + "@rolldown/binding-linux-arm64-musl": "1.2.12", + "@rolldown/binding-linux-ppc64-gnu": "1.2.12", + "@rolldown/binding-linux-s390x-gnu": "1.2.12", + "@rolldown/binding-linux-x64-gnu": "1.2.12", + "@rolldown/binding-linux-x64-musl": "1.2.12", + "@rolldown/binding-openharmony-arm64": "1.2.12", + "@rolldown/binding-win32-arm64-msvc": "1.2.12", + "@rolldown/binding-win32-x64-msvc": "1.2.12" } }, "node_modules/rou3": { "version": "0.9.2", + "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.9.2.tgz", + "integrity": "sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==", "license": "MIT" }, "node_modules/roughjs": { @@ -15449,6 +15785,8 @@ }, "node_modules/router": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -15461,15 +15799,10 @@ "node": ">= 18" } }, - "node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "dev": true, - "license": "MIT" - }, "node_modules/run-applescript": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "license": "MIT", "engines": { "node": ">=18" @@ -15480,6 +15813,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "funding": [ { "type": "github", @@ -15507,6 +15842,8 @@ }, "node_modules/rxjs": { "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -15520,6 +15857,8 @@ }, "node_modules/safe-stable-stringify": { "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "license": "MIT", "engines": { "node": ">=10" @@ -15527,6 +15866,8 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, "node_modules/satteri": { @@ -15575,16 +15916,20 @@ } }, "node_modules/scheduler": { - "version": "0.27.0", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", "license": "MIT" }, "node_modules/schema-utils": { - "version": "4.3.3", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.5.0.tgz", + "integrity": "sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==", "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", + "@types/json-schema": "^7.0.15", + "ajv": "^8.20.0", + "ajv-formats": "^3.0.1", "ajv-keywords": "^5.1.0" }, "engines": { @@ -15595,23 +15940,10 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/schema-utils/node_modules/ajv-formats": { - "version": "2.1.1", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -15619,6 +15951,8 @@ }, "node_modules/send": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { "debug": "^4.4.3", @@ -15643,10 +15977,14 @@ }, "node_modules/send/node_modules/ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/serve-static": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", @@ -15664,14 +16002,20 @@ }, "node_modules/set-cookie-parser": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz", + "integrity": "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==", "license": "MIT" }, "node_modules/setprototypeof": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/shadcn": { - "version": "4.18.0", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/shadcn/-/shadcn-4.21.1.tgz", + "integrity": "sha512-keQmMdKI1eLKTtYpwFwrFfFegsskOpUgt1l3aF359pbCFt0taq0TMuZ75yK+q/StcV2YvjmBMenrs0diWoezXQ==", "license": "MIT", "dependencies": { "@babel/core": "^7.28.0", @@ -15680,8 +16024,10 @@ "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "@modelcontextprotocol/sdk": "^1.26.0", + "@shadcn/registry": "0.1.0", "@types/validate-npm-package-name": "^4.0.2", "browserslist": "^4.26.2", + "cn": "^0.2.4", "commander": "^14.0.0", "cosmiconfig": "^9.0.0", "dedent": "^1.6.0", @@ -15694,16 +16040,15 @@ "kleur": "^4.1.5", "open": "^11.0.0", "ora": "^8.2.0", - "postcss": "^8.5.6", - "postcss-selector-parser": "^7.1.0", + "postcss": "^8.5.23", + "postcss-selector-parser": "^7.1.3", "prompts": "^2.4.2", "recast": "^0.23.11", "socks": "^2.8.8", "stringify-object": "^5.0.0", - "tailwind-merge": "^3.0.1", "ts-morph": "^26.0.0", "tsconfig-paths": "^4.2.0", - "undici": "^7.27.2", + "undici": "^7.29.0", "validate-npm-package-name": "^7.0.1", "zod": "^3.24.1", "zod-to-json-schema": "^3.24.6" @@ -15715,17 +16060,50 @@ "node": ">=20.18.1" } }, + "node_modules/shadcn/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/shadcn/node_modules/diff": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/shadcn/node_modules/postcss-selector-parser": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz", + "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/shadcn/node_modules/zod": { "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } }, "node_modules/sharp": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", - "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.5.tgz", + "integrity": "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==", "license": "Apache-2.0", "dependencies": { "@img/colour": "^1.1.0", @@ -15739,31 +16117,31 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.4", - "@img/sharp-darwin-x64": "0.35.4", - "@img/sharp-freebsd-wasm32": "0.35.4", - "@img/sharp-libvips-darwin-arm64": "1.3.3", - "@img/sharp-libvips-darwin-x64": "1.3.3", - "@img/sharp-libvips-linux-arm": "1.3.3", - "@img/sharp-libvips-linux-arm64": "1.3.3", - "@img/sharp-libvips-linux-ppc64": "1.3.3", - "@img/sharp-libvips-linux-riscv64": "1.3.3", - "@img/sharp-libvips-linux-s390x": "1.3.3", - "@img/sharp-libvips-linux-x64": "1.3.3", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", - "@img/sharp-libvips-linuxmusl-x64": "1.3.3", - "@img/sharp-linux-arm": "0.35.4", - "@img/sharp-linux-arm64": "0.35.4", - "@img/sharp-linux-ppc64": "0.35.4", - "@img/sharp-linux-riscv64": "0.35.4", - "@img/sharp-linux-s390x": "0.35.4", - "@img/sharp-linux-x64": "0.35.4", - "@img/sharp-linuxmusl-arm64": "0.35.4", - "@img/sharp-linuxmusl-x64": "0.35.4", - "@img/sharp-webcontainers-wasm32": "0.35.4", - "@img/sharp-win32-arm64": "0.35.4", - "@img/sharp-win32-ia32": "0.35.4", - "@img/sharp-win32-x64": "0.35.4" + "@img/sharp-darwin-arm64": "0.35.5", + "@img/sharp-darwin-x64": "0.35.5", + "@img/sharp-freebsd-wasm32": "0.35.5", + "@img/sharp-libvips-darwin-arm64": "1.3.4", + "@img/sharp-libvips-darwin-x64": "1.3.4", + "@img/sharp-libvips-linux-arm": "1.3.4", + "@img/sharp-libvips-linux-arm64": "1.3.4", + "@img/sharp-libvips-linux-ppc64": "1.3.4", + "@img/sharp-libvips-linux-riscv64": "1.3.4", + "@img/sharp-libvips-linux-s390x": "1.3.4", + "@img/sharp-libvips-linux-x64": "1.3.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", + "@img/sharp-libvips-linuxmusl-x64": "1.3.4", + "@img/sharp-linux-arm": "0.35.5", + "@img/sharp-linux-arm64": "0.35.5", + "@img/sharp-linux-ppc64": "0.35.5", + "@img/sharp-linux-riscv64": "0.35.5", + "@img/sharp-linux-s390x": "0.35.5", + "@img/sharp-linux-x64": "0.35.5", + "@img/sharp-linuxmusl-arm64": "0.35.5", + "@img/sharp-linuxmusl-x64": "0.35.5", + "@img/sharp-webcontainers-wasm32": "0.35.5", + "@img/sharp-win32-arm64": "0.35.5", + "@img/sharp-win32-ia32": "0.35.5", + "@img/sharp-win32-x64": "0.35.5" }, "peerDependenciesMeta": { "@types/node": { @@ -15773,6 +16151,8 @@ }, "node_modules/sharp/node_modules/semver": { "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -15783,6 +16163,8 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -15793,23 +16175,25 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shiki": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.4.3.tgz", - "integrity": "sha512-Mb/GvXPHBAXdgGIcnfU5L3ldpn1XcxrGkPHwqgRx17/I2XRfqlFKk2vGkHWINn1kdXvzJZeuO3is6I9KLPFm0g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.5.0.tgz", + "integrity": "sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==", "license": "MIT", "dependencies": { - "@shikijs/core": "4.4.3", - "@shikijs/engine-javascript": "4.4.3", - "@shikijs/engine-oniguruma": "4.4.3", - "@shikijs/langs": "4.4.3", - "@shikijs/themes": "4.4.3", - "@shikijs/types": "4.4.3", + "@shikijs/core": "4.5.0", + "@shikijs/engine-javascript": "4.5.0", + "@shikijs/engine-oniguruma": "4.5.0", + "@shikijs/langs": "4.5.0", + "@shikijs/themes": "4.5.0", + "@shikijs/types": "4.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.5" }, @@ -15819,6 +16203,8 @@ }, "node_modules/side-channel": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -15836,6 +16222,8 @@ }, "node_modules/side-channel-list": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -15850,6 +16238,8 @@ }, "node_modules/side-channel-map": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -15866,6 +16256,8 @@ }, "node_modules/side-channel-weakmap": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -15881,13 +16273,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "devOptional": true, - "license": "ISC" - }, "node_modules/signal-exit": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "license": "ISC", "engines": { "node": ">=14" @@ -15898,6 +16287,8 @@ }, "node_modules/sisteransi": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "license": "MIT" }, "node_modules/sitemap": { @@ -15921,6 +16312,8 @@ }, "node_modules/smart-buffer": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "license": "MIT", "engines": { "node": ">= 6.0.0", @@ -15928,9 +16321,9 @@ } }, "node_modules/smol-toml": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.8.0.tgz", - "integrity": "sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.9.0.tgz", + "integrity": "sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 18" @@ -15940,7 +16333,9 @@ } }, "node_modules/socks": { - "version": "2.8.9", + "version": "2.8.10", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.10.tgz", + "integrity": "sha512-e0VyvkVTwVYViNovRkZ9aodhxVlyoMn7eJhVUPxZ+eK9P/7CBkxvvsBOHqFPEH416726W8tLXXXjKwqgTErrCQ==", "license": "MIT", "dependencies": { "ip-address": "^10.1.1", @@ -15953,6 +16348,8 @@ }, "node_modules/sonic-boom": { "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", "license": "MIT", "dependencies": { "atomic-sleep": "^1.0.0" @@ -15960,13 +16357,17 @@ }, "node_modules/source-map": { "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 12" } }, "node_modules/source-map-js": { - "version": "1.2.1", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -15974,6 +16375,8 @@ }, "node_modules/source-map-loader": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", "license": "MIT", "dependencies": { "iconv-lite": "^0.6.3", @@ -15990,18 +16393,10 @@ "webpack": "^5.72.1" } }, - "node_modules/source-map-loader/node_modules/iconv-lite": { - "version": "0.6.3", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-support": { "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -16010,6 +16405,8 @@ }, "node_modules/source-map-support/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -16017,6 +16414,8 @@ }, "node_modules/space-separated-tokens": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "license": "MIT", "funding": { "type": "github", @@ -16025,16 +16424,13 @@ }, "node_modules/split2": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "license": "ISC", "engines": { "node": ">= 10.x" } }, - "node_modules/stackback": { - "version": "0.0.2", - "devOptional": true, - "license": "MIT" - }, "node_modules/standardized-audio-context": { "version": "25.3.77", "resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.77.tgz", @@ -16048,18 +16444,24 @@ }, "node_modules/statuses": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/std-env": { - "version": "3.10.0", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", "devOptional": true, "license": "MIT" }, "node_modules/stdin-discarder": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", "license": "MIT", "engines": { "node": ">=18" @@ -16076,6 +16478,8 @@ }, "node_modules/string-width": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", @@ -16090,7 +16494,9 @@ } }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.3.0", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", "license": "MIT", "engines": { "node": ">=12" @@ -16101,6 +16507,8 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" @@ -16114,6 +16522,8 @@ }, "node_modules/stringify-entities": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", @@ -16126,6 +16536,8 @@ }, "node_modules/stringify-object": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-5.0.0.tgz", + "integrity": "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==", "license": "BSD-2-Clause", "dependencies": { "get-own-enumerable-keys": "^1.0.0", @@ -16141,6 +16553,8 @@ }, "node_modules/stringify-object/node_modules/is-obj": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz", + "integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==", "license": "MIT", "engines": { "node": ">=12" @@ -16151,6 +16565,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -16161,6 +16577,8 @@ }, "node_modules/strip-bom": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "license": "MIT", "engines": { "node": ">=4" @@ -16168,6 +16586,8 @@ }, "node_modules/strip-final-newline": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "license": "MIT", "engines": { "node": ">=18" @@ -16176,24 +16596,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "3.1.0", - "devOptional": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.1", - "devOptional": true, - "license": "MIT" - }, "node_modules/strtok3": { "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0" @@ -16208,6 +16614,8 @@ }, "node_modules/style-to-js": { "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", "license": "MIT", "dependencies": { "style-to-object": "1.0.14" @@ -16215,6 +16623,8 @@ }, "node_modules/style-to-object": { "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", "license": "MIT", "dependencies": { "inline-style-parser": "0.2.7" @@ -16239,6 +16649,8 @@ }, "node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -16314,6 +16726,8 @@ }, "node_modules/swc-loader": { "version": "0.2.7", + "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.7.tgz", + "integrity": "sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w==", "license": "MIT", "dependencies": { "@swc/counter": "^0.1.3" @@ -16323,15 +16737,10 @@ "webpack": ">=2" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, "node_modules/systeminformation": { - "version": "5.33.1", + "version": "5.33.15", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.33.15.tgz", + "integrity": "sha512-s5RloL0F7xhN0ZjfHtLGnbf7EW74EI0N8NFL+1xR7Oxz9QA33obNZsl7lyfnJOhN04E/kGFPoJPlvY7TZ5fzmw==", "license": "MIT", "os": [ "darwin", @@ -16355,7 +16764,9 @@ } }, "node_modules/tailwind-merge": { - "version": "3.6.0", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.7.0.tgz", + "integrity": "sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA==", "license": "MIT", "funding": { "type": "github", @@ -16364,10 +16775,14 @@ }, "node_modules/tailwindcss": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", "license": "MIT" }, "node_modules/tapable": { "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", "license": "MIT", "engines": { "node": ">=6" @@ -16378,9 +16793,10 @@ } }, "node_modules/terser": { - "version": "5.50.0", + "version": "5.51.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.51.2.tgz", + "integrity": "sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", @@ -16396,10 +16812,14 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, "node_modules/thingies": { "version": "2.6.1", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.1.tgz", + "integrity": "sha512-cV/CMGTK3M4MlnJ/0At6ismOw/A0EEniDNScajjz/Br3c1sqE72YD01rGpPTKwd27wAxI5Pr+6+0w8yofzFRYw==", "license": "MIT", "engines": { "node": ">=10.18" @@ -16414,6 +16834,8 @@ }, "node_modules/thread-stream": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.2.0.tgz", + "integrity": "sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==", "license": "MIT", "dependencies": { "real-require": "^0.2.0" @@ -16427,29 +16849,42 @@ }, "node_modules/tiny-invariant": { "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "license": "MIT" }, "node_modules/tinybench": { - "version": "2.9.0", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.0.tgz", + "integrity": "sha512-78U2TlB2CnVenajOFzf3BKSm0J6oz5L0NV7g32LCPccvYc0lbWvys4d3uUUCS2B1N8PAf2+aekR8i1KbC3HO7Q==", "devOptional": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } }, "node_modules/tinyclip": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/tinyclip/-/tinyclip-0.1.15.tgz", - "integrity": "sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tinyclip/-/tinyclip-1.0.3.tgz", + "integrity": "sha512-nTv2raKFMzGG6JJp0lpNDsRPdfFE6UHlu2rVEjXo8vkx1ZS3LW2CVXqIaLu8xZlu+6tbFs9V58Qc/Jmk/Ii7wA==", "license": "MIT", "engines": { "node": "^16.14.0 || >= 17.3.0" } }, "node_modules/tinyexec": { - "version": "0.3.2", - "devOptional": true, - "license": "MIT" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -16462,52 +16897,30 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "devOptional": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "2.0.0", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.4", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "version": "7.4.16", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.16.tgz", + "integrity": "sha512-QwBER5KMR86IIjpIiO7H/Z3IMJPsZ1A6RKPAqzTTgOyUQUSt9FdnKcqhTaJmkY6HVrgouZHZR0ncK5QxvmnQeg==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.86" + "tldts-core": "^7.4.16" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "version": "7.4.16", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.16.tgz", + "integrity": "sha512-MDolfaSJtlSK5Y0A1xl3277ekubZwobpBjugknDizI9O5Rm60a1m8k4ICK+MRsCDzPygT81mp3BBf5RKDlFRfA==", "dev": true, "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -16518,6 +16931,8 @@ }, "node_modules/toidentifier": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" @@ -16525,6 +16940,8 @@ }, "node_modules/token-types": { "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", "license": "MIT", "dependencies": { "@borewit/text-codec": "^0.2.1", @@ -16540,24 +16957,35 @@ } }, "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "tldts": "^6.1.32" + "tldts": "^7.0.5" }, "engines": { "node": ">=16" } }, "node_modules/tr46": { - "version": "0.0.3", - "license": "MIT" + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } }, "node_modules/tree-dump": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -16572,6 +17000,8 @@ }, "node_modules/trim-lines": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "license": "MIT", "funding": { "type": "github", @@ -16580,6 +17010,8 @@ }, "node_modules/trough": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "license": "MIT", "funding": { "type": "github", @@ -16597,6 +17029,8 @@ }, "node_modules/ts-morph": { "version": "26.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz", + "integrity": "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==", "license": "MIT", "dependencies": { "@ts-morph/common": "~0.27.0", @@ -16605,6 +17039,8 @@ }, "node_modules/tsconfig-paths": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "license": "MIT", "dependencies": { "json5": "^2.2.2", @@ -16617,13 +17053,16 @@ }, "node_modules/tslib": { "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD", "peer": true }, "node_modules/tsx": { - "version": "4.23.12", + "version": "4.23.15", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz", + "integrity": "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "~0.28.0" }, @@ -16639,13 +17078,29 @@ }, "node_modules/tw-animate-css": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/Wombosvideo" } }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", "license": "MIT", "dependencies": { "content-type": "^2.0.0", @@ -16662,6 +17117,8 @@ }, "node_modules/type-is/node_modules/content-type": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", "license": "MIT", "engines": { "node": ">=18" @@ -16673,6 +17130,8 @@ }, "node_modules/type-is/node_modules/media-typer": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -16690,7 +17149,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.9.3", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "devOptional": true, "license": "Apache-2.0", "peer": true, @@ -16732,7 +17193,9 @@ "license": "MIT" }, "node_modules/uint8array-extras": { - "version": "1.5.0", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.6.0.tgz", + "integrity": "sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q==", "license": "MIT", "engines": { "node": ">=18" @@ -16754,18 +17217,24 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.29.0", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.30.0.tgz", + "integrity": "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==", "license": "MIT", "engines": { "node": ">=20.18.1" } }, "node_modules/undici-types": { - "version": "7.18.2", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "license": "MIT" }, "node_modules/unicorn-magic": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "license": "MIT", "engines": { "node": ">=18" @@ -16805,9 +17274,9 @@ } }, "node_modules/unifont/node_modules/undici": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.2.tgz", - "integrity": "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.11.2.tgz", + "integrity": "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==", "license": "MIT", "engines": { "node": ">=22.19.0" @@ -16815,6 +17284,8 @@ }, "node_modules/unionfs": { "version": "4.6.0", + "resolved": "https://registry.npmjs.org/unionfs/-/unionfs-4.6.0.tgz", + "integrity": "sha512-fJAy3gTHjFi5S3TP5EGdjs/OUMFFvI/ady3T8qVuZfkv8Qi8prV/Q8BuFEgODJslhZTT2z2qdD2lGdee9qjEnA==", "dependencies": { "fs-monkey": "^1.0.0" } @@ -16835,6 +17306,8 @@ }, "node_modules/unist-util-is": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -16860,6 +17333,8 @@ }, "node_modules/unist-util-position": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -16898,6 +17373,8 @@ }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -16909,6 +17386,8 @@ }, "node_modules/unist-util-visit": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -16935,6 +17414,8 @@ }, "node_modules/unist-util-visit-parents": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -16947,6 +17428,8 @@ }, "node_modules/universalify": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -16954,6 +17437,8 @@ }, "node_modules/unpipe": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -17070,15 +17555,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/unstorage/node_modules/lru-cache": { - "version": "11.5.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", - "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/unstorage/node_modules/readdirp": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", @@ -17093,7 +17569,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.3.1", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz", + "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==", "funding": [ { "type": "opencollective", @@ -17133,7 +17611,9 @@ } }, "node_modules/use-sync-external-store": { - "version": "1.6.0", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.7.0.tgz", + "integrity": "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==", "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -17141,10 +17621,14 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/uuid": { "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -17156,6 +17640,8 @@ }, "node_modules/validate-npm-package-name": { "version": "7.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", + "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" @@ -17163,13 +17649,29 @@ }, "node_modules/vary": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/verkit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/verkit/-/verkit-0.4.1.tgz", + "integrity": "sha512-mMVzj0TXExtVdlDEq+Mzp0eyOuyznNpFobNM3uAqe3HVm/Ps2c+u17BligMkZjZCA6EiXpoon8iRTer3iu40SQ==", + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, "node_modules/vfile": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -17196,6 +17698,8 @@ }, "node_modules/vfile-message": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -17207,16 +17711,17 @@ } }, "node_modules/vite": { - "version": "7.3.6", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.2.tgz", + "integrity": "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==", "license": "MIT", "peer": true, "dependencies": { - "esbuild": "^0.27.0 || ^0.28.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.11", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" @@ -17232,9 +17737,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", @@ -17247,13 +17753,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { "optional": true }, - "lightningcss": { + "jiti": { + "optional": true + }, + "less": { "optional": true }, "sass": { @@ -17279,25 +17788,253 @@ } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "devOptional": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "node_modules/vite/node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/vite/node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" }, - "bin": { - "vite-node": "vite-node.mjs" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": ">= 12.0.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/vitefu": { @@ -17320,63 +18057,72 @@ } }, "node_modules/vitest": { - "version": "3.2.7", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.3.tgz", + "integrity": "sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==", "devOptional": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.7", - "@vitest/mocker": "3.2.7", - "@vitest/pretty-format": "^3.2.7", - "@vitest/runner": "3.2.7", - "@vitest/snapshot": "3.2.7", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", - "why-is-node-running": "^2.3.0" + "@vitest/mocker": "5.0.3", + "chai": "^6.2.2", + "es-module-lexer": "^2.3.2", + "expect-type": "^1.4.0", + "magic-string": "^1.2.3", + "obug": "^2.1.4", + "picomatch": "^4.0.7", + "std-env": "^4.2.0", + "tinybench": "^6.1.4", + "tinyexec": "^1.3.0", + "tinyglobby": "^0.2.17", + "why-is-node-running": "3.2.1" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^22.12.0 || ^24.0.0 || >=26.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.7", - "@vitest/ui": "3.2.7", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "5.0.3", + "@vitest/browser-preview": "5.0.3", + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", + "@vitest/coverage-istanbul": "5.0.3", + "@vitest/coverage-v8": "5.0.3", + "@vitest/ui": "5.0.3", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@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": { @@ -17387,9 +18133,26 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, + "node_modules/vitest/node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", + "devOptional": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/volar-service-css": { "version": "0.0.71", "resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.71.tgz", @@ -17597,9 +18360,9 @@ } }, "node_modules/vscode-jsonrpc": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.2.tgz", - "integrity": "sha512-SbQSV9yRemARxeXw6LU5sS6Zq0e9/DgCCX5yelH263ZQWukbTk8EF8fjTrr1dziasf4GwlJbvTwFnTrnQFWZXQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.3.tgz", + "integrity": "sha512-qETYf9PCl1lVfwR+oBmMfc4vP2nqLNA35ABxorw3j06+xlKRgDVxbLgKm4Y/xPL0YWdeDjLoI4ImICIT3nB0zQ==", "dev": true, "license": "MIT", "engines": { @@ -17620,27 +18383,27 @@ } }, "node_modules/vscode-languageserver-protocol": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.18.3.tgz", - "integrity": "sha512-DF49+WeV5py4zO5hhobp60jjsDSK0lAqA0OuKBLBvp423HPWQcCbhZz3JgyfIewsEz2f8U+X75xNIFHdiXZm2w==", + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.18.4.tgz", + "integrity": "sha512-CCXbyr99dafRJzJH/0Ryk7ly5T8XPmSR0//OuF2w4m+9JiOin7zcAT5iET8GRE7Z9taFBejb3GbM0a0mbjdbrg==", "dev": true, "license": "MIT", "dependencies": { - "vscode-jsonrpc": "9.0.2", - "vscode-languageserver-types": "3.18.3" + "vscode-jsonrpc": "9.0.3", + "vscode-languageserver-types": "3.18.4" } }, "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.14.tgz", - "integrity": "sha512-EQyqJMi552E4ZTf46izQ4Fj6XquqxCySR3J5ZSD1SisMf6RfpeOWHxGBE8Gr6V0/3GHIGdAzDn8F8+1nTGCnoQ==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.15.tgz", + "integrity": "sha512-Gsfr9S8LU3S6885cS+NaleasJ0n3V5y/SOTqHCifQiXWFw3G9w9/YItDfwHrlCz+dSZWWZ8ilYVMcJe7Sz7Sxw==", "dev": true, "license": "MIT" }, "node_modules/vscode-languageserver-types": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.18.3.tgz", - "integrity": "sha512-XIlzJ7Qp/jzSI1ds7/FwPAWrPeTZA7pAtlW4hdJ1J6xXWJL6dR9QYnDhJOdLzdKhUQ5Mm6mvUMw+3DcOQQasPw==", + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.18.4.tgz", + "integrity": "sha512-nQsacoiijvl0fRf2q28uFDrAVwRhdCa3QveiF7/CX0r18mLR5FU/1WskSsCKOjmEbtteKUnY8x8Yzxop+k0zwg==", "dev": true, "license": "MIT" }, @@ -17687,20 +18450,22 @@ "license": "MIT" }, "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-6.0.0.tgz", + "integrity": "sha512-4Nsy8K5Tr6SPDH9jhKJOHf7ChDrc1zufZTVSF7x72hwuEXBqxqk9G6cK+K2NRUtB3iELRJqjXb4JPDMBjMTl2Q==", "dev": true, "license": "MIT", "dependencies": { "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=18" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/watchpack": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2" @@ -17720,11 +18485,19 @@ } }, "node_modules/webidl-conversions": { - "version": "3.0.1", - "license": "BSD-2-Clause" + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } }, "node_modules/webpack": { - "version": "5.109.2", + "version": "5.111.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.111.1.tgz", + "integrity": "sha512-cNypaz0RP+S4cvQVi1M/3bRUkvNP0xZpL0TjFx+c6jg64VbxD+2weWDgY9UnjRI6dhZgtaj8DU76GGFcJ79xPQ==", "license": "MIT", "peer": true, "dependencies": { @@ -17733,18 +18506,15 @@ "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.16.0", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.24.4", + "enhanced-resolve": "^5.25.0", "es-module-lexer": "^2.1.0", - "eslint-scope": "5.1.1", "events": "^3.2.0", "graceful-fs": "^4.2.11", "mime-db": "^1.54.0", - "minimizer-webpack-plugin": "^5.6.1", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", + "minimizer-webpack-plugin": "^5.7.0", + "schema-utils": "^4.5.0", "tapable": "^2.3.0", "watchpack": "^2.5.2", "webpack-sources": "^3.5.1" @@ -17766,18 +18536,18 @@ } }, "node_modules/webpack-sources": { - "version": "3.5.1", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.6.0.tgz", + "integrity": "sha512-EIMmPVvNI0CYXyRPp34F2Qk7W37/BZVZIofS6LAUnrNjCVahS+hO4mxwFJDjQjODTGZDtVzLYoN2+1dYkhk9qA==", "license": "MIT", "engines": { "node": ">=10.13.0" } }, - "node_modules/webpack/node_modules/es-module-lexer": { - "version": "2.3.1", - "license": "MIT" - }, "node_modules/whatsapp-rust-bridge": { "version": "0.5.4", + "resolved": "https://registry.npmjs.org/whatsapp-rust-bridge/-/whatsapp-rust-bridge-0.5.4.tgz", + "integrity": "sha512-yYO1qSs0Fe7tGtnxOFHomocUD6IZtoAgmA4oDFyGIRZ67D3QZk3w7swA6XXFXNQngiyrg2k7tul6IrM3eUFh7A==", "license": "MIT" }, "node_modules/whatwg-encoding": { @@ -17794,19 +18564,6 @@ "node": ">=18" } }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/whatwg-mimetype": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", @@ -17818,15 +18575,24 @@ } }, "node_modules/whatwg-url": { - "version": "5.0.0", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.2.tgz", + "integrity": "sha512-TEZA+Zqxin7Jjsm2cjRohCmen5awh+hT6Zi3VZdqZlNRk7zvOI/9WpBFg/DWlA56bWnzwm6DuB8NS0EsxQH9uQ==", + "dev": true, "license": "MIT", "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "@exodus/bytes": "^1.15.1", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^22.14.0 || >=24.0.0" } }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -17839,22 +18605,22 @@ } }, "node_modules/why-is-node-running": { - "version": "2.3.0", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-3.2.1.tgz", + "integrity": "sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==", "devOptional": true, "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, "bin": { "why-is-node-running": "cli.js" }, "engines": { - "node": ">=8" + "node": ">=20.11" } }, "node_modules/win-guid": { "version": "0.2.1", + "resolved": "https://registry.npmjs.org/win-guid/-/win-guid-0.2.1.tgz", + "integrity": "sha512-gEIQU4mkgl2OPeoNrWflcJFJ3Ae2BPd4eCsHHA/XikslkIVms/nHhvnvzIZV7VLmBvtFlDOzLt9rrZT+n6D67A==", "license": "MIT" }, "node_modules/worker-factory": { @@ -17869,42 +18635,62 @@ } }, "node_modules/wrap-ansi": { - "version": "7.0.0", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, "node_modules/ws": { - "version": "8.21.3", + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz", + "integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -17923,22 +18709,14 @@ } }, "node_modules/wsl-utils": { - "version": "1.0.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-1.0.1.tgz", + "integrity": "sha512-c16PKLIRxBYpR3jSWsdS7SFp0COm5SOQdiFjY818dYFHJbMGuLBszpF07LBWmOS1uzrHa9VGdynsEgoeKy0oOQ==", "license": "MIT", "dependencies": { "is-wsl": "^3.1.0", - "powershell-utils": "^0.1.0" - }, - "engines": { - "node": ">=20" + "powershell-utils": "^0.2.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wsl-utils/node_modules/powershell-utils": { - "version": "0.1.0", - "license": "MIT", "engines": { "node": ">=20" }, @@ -17965,6 +18743,8 @@ }, "node_modules/xtend": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "license": "MIT", "engines": { "node": ">=0.4" @@ -17978,6 +18758,8 @@ }, "node_modules/y18n": { "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "license": "ISC", "engines": { "node": ">=10" @@ -17985,15 +18767,16 @@ }, "node_modules/yallist": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "license": "ISC" }, "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", "devOptional": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -18052,42 +18835,76 @@ } }, "node_modules/yargs": { - "version": "17.7.3", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.2.0.tgz", + "integrity": "sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==", + "dev": true, "license": "MIT", "dependencies": { - "cliui": "^8.0.1", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^8.2.1", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { - "version": "21.1.1", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "license": "ISC", "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.3.0.tgz", + "integrity": "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==", + "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=8" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/yocto-queue": { @@ -18104,6 +18921,8 @@ }, "node_modules/yocto-spinner": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-1.2.2.tgz", + "integrity": "sha512-DODGl1wJjA/s5pnJFKau9lIYHT81lnhob1i3e1TjxZRxEhWRKl74nTbWE6H5KlkViQQTo/Z29YFdxzTZAMY3ng==", "license": "MIT", "dependencies": { "yoctocolors": "^2.1.1" @@ -18117,6 +18936,8 @@ }, "node_modules/yoctocolors": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", + "integrity": "sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==", "license": "MIT", "engines": { "node": ">=18" @@ -18126,9 +18947,9 @@ } }, "node_modules/zod": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.5.4.tgz", - "integrity": "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==", + "version": "4.6.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.5.tgz", + "integrity": "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==", "license": "MIT", "peer": true, "funding": { @@ -18137,6 +18958,8 @@ }, "node_modules/zod-to-json-schema": { "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", "license": "ISC", "peerDependencies": { "zod": "^3.25.28 || ^4" @@ -18144,42 +18967,44 @@ }, "node_modules/zwitch": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "platform/bots": { - "name": "@lightspeed/bots", - "extraneous": true, + "platform/backend": { + "name": "@lightspeed-ai/platform-backend", "dependencies": { - "@lightspeed-ai/agent-client": "*", - "@lightspeed/platform-db": "*", - "@noble/hashes": "2.2.0", - "@temporalio/activity": "1.21.1", - "@temporalio/client": "1.21.1", - "@temporalio/common": "1.21.1", - "@temporalio/worker": "1.21.1", - "@temporalio/workflow": "1.21.1", - "cel-js": "^0.8.2", - "drizzle-orm": "^0.45.0", - "zod": "^4.4.0" + "@hono/node-server": "^2.1.3", + "@lightspeed-ai/platform-db": "*", + "@lightspeed-ai/platform-shared": "*", + "@lightspeed-ai/sdk": "*", + "better-auth": "1.7.7", + "drizzle-orm": "^0.45.3", + "hono": "^4.13.12", + "jose": "6.2.12", + "pg": "^8.23.1", + "tsx": "^4.23.15", + "zod": "^4.6.5" }, "devDependencies": { - "@temporalio/testing": "1.21.1", - "vitest": "^3.2.0" + "@electric-sql/pglite": "0.5.8", + "@types/pg": "^8.23.1", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" } }, "platform/cli": { - "name": "@lightspeed/platform-cli", + "name": "@lightspeed-ai/platform-cli", "dependencies": { - "@lightspeed/platform-shared": "*", - "commander": "^14.0.0", - "tsx": "^4.20.0" + "@lightspeed-ai/platform-shared": "*", + "commander": "^15.0.0", + "tsx": "^4.23.15" }, "bin": { "lightspeed-platform": "bin/lightspeed-platform" @@ -18189,148 +19014,116 @@ } }, "platform/configurator-mcp": { - "name": "@lightspeed/configurator-mcp", + "name": "@lightspeed-ai/configurator-mcp", "version": "0.0.0", "dependencies": { - "@lightspeed-ai/agent-client": "file:../../clients/typescript", - "@modelcontextprotocol/node": "2.0.0", - "@modelcontextprotocol/server": "2.0.0", - "ajv": "^8.17.1", + "@lightspeed-ai/sdk": "file:../../clients/typescript", + "@modelcontextprotocol/node": "2.1.1", + "@modelcontextprotocol/server": "2.3.0", + "ajv": "^8.20.0", "ajv-formats": "^3.0.1", "express": "^5.2.1", - "zod": "^4.4.3" + "zod": "^4.6.5" }, "bin": { "lightspeed-configurator-mcp": "dist/bin.js" }, "devDependencies": { - "@modelcontextprotocol/client": "2.0.0", + "@modelcontextprotocol/client": "2.3.0", "@types/express": "^5.0.6", - "@types/node": "^24.0.0", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "@types/node": "^24.19.1", + "typescript": "^6.0.3", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" } }, "platform/connectors": { - "name": "@lightspeed/connectors", - "dependencies": { - "@lightspeed-ai/agent-client": "*", - "@temporalio/activity": "1.21.1", - "@temporalio/common": "1.21.1", - "@temporalio/worker": "1.21.1", - "baileys": "7.0.0-rc13", - "grammy": "^1.43.0", - "marked": "^18.0.5", + "name": "@lightspeed-ai/connectors", + "dependencies": { + "@lightspeed-ai/sdk": "*", + "@temporalio/activity": "1.24.0", + "@temporalio/common": "1.24.0", + "@temporalio/worker": "1.24.0", + "baileys": "7.0.0-rc14", + "grammy": "^1.46.0", + "marked": "^18.0.14", "qrcode-terminal": "^0.12.0", - "tsx": "^4.20.0" + "tsx": "^4.23.15" }, "devDependencies": { "@types/qrcode-terminal": "^0.12.2", - "vitest": "^3.2.0" + "vitest": "^5.0.3" }, "engines": { "node": ">=24" } }, "platform/db": { - "name": "@lightspeed/platform-db", - "dependencies": { - "drizzle-orm": "^0.45.0", - "pg": "^8.16.0" - }, - "devDependencies": { - "@types/pg": "^8.15.0", - "drizzle-kit": "^0.31.0" - }, - "engines": { - "node": ">=24" - } - }, - "platform/server": { - "name": "@lightspeed/platform-server", + "name": "@lightspeed-ai/platform-db", "dependencies": { - "@hono/node-server": "^1.14.0", - "@lightspeed-ai/agent-client": "*", - "@lightspeed/platform-db": "*", - "@lightspeed/platform-shared": "*", - "better-auth": "1.7.6", - "drizzle-orm": "^0.45.0", - "hono": "^4.7.0", - "jose": "6.2.3", - "pg": "^8.16.0", - "tsx": "^4.20.0", - "zod": "^4.4.0" + "drizzle-orm": "^0.45.3", + "pg": "^8.23.1" }, "devDependencies": { - "@electric-sql/pglite": "0.5.8", - "@types/pg": "^8.15.0", - "vitest": "^3.2.0" + "@types/pg": "^8.23.1", + "better-auth": "1.7.7", + "drizzle-kit": "^0.31.11" }, "engines": { "node": ">=24" } }, - "platform/server/node_modules/jose": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", - "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, "platform/shared": { - "name": "@lightspeed/platform-shared", + "name": "@lightspeed-ai/platform-shared", "dependencies": { "fflate": "^0.8.3", - "zod": "^4.4.0" + "zod": "^4.6.5" }, "engines": { "node": ">=24" } }, "platform/web": { - "name": "@lightspeed/platform-web", - "dependencies": { - "@base-ui/react": "^1.6.0", - "@fontsource-variable/geist": "^5.2.9", - "@fontsource-variable/space-grotesk": "^5.2.10", - "@lightspeed-ai/agent-client": "*", - "@lightspeed/platform-shared": "*", - "@shadcn/react": "^0.2.0", - "@tabler/icons-react": "^3.44.0", - "@tailwindcss/vite": "^4.3.2", - "@tanstack/react-query": "^5.80.0", - "better-auth": "1.7.6", + "name": "@lightspeed-ai/platform-web", + "dependencies": { + "@base-ui/react": "^1.8.0", + "@fontsource-variable/geist": "^5.3.0", + "@fontsource-variable/space-grotesk": "^5.3.0", + "@lightspeed-ai/platform-shared": "*", + "@lightspeed-ai/sdk": "*", + "@shadcn/react": "^0.3.1", + "@tabler/icons-react": "^3.48.0", + "@tailwindcss/vite": "^4.3.3", + "@tanstack/react-query": "^5.104.1", + "better-auth": "1.7.7", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "extendable-media-recorder": "^9.2.40", - "hono": "^4.7.0", - "lucide-react": "^1.23.0", - "react": "^19.1.0", - "react-dom": "^19.1.0", + "hono": "^4.13.12", + "lucide-react": "^1.51.0", + "react": "^19.3.0", + "react-dom": "^19.3.0", "react-markdown": "^10.1.0", - "react-router-dom": "^7.6.0", + "react-router-dom": "^7.18.4", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", - "shadcn": "^4.13.0", - "tailwind-merge": "^3.6.0", - "tailwindcss": "^4.3.2", + "shadcn": "^4.21.1", + "tailwind-merge": "^3.7.0", + "tailwindcss": "^4.3.3", "tw-animate-css": "^1.4.0", "unified": "^11.0.5", - "zod": "^4.4.3" + "zod": "^4.6.5" }, "devDependencies": { - "@types/react": "^19.1.0", - "@types/react-dom": "^19.1.0", - "@vitejs/plugin-react": "^4.5.0", - "jsdom": "^26.1.0", - "vite": "^7.0.0", - "vitest": "^3.2.6" + "@types/react": "^19.3.0", + "@types/react-dom": "^19.3.0", + "@vitejs/plugin-react": "^6.1.1", + "jsdom": "^30.1.1", + "vite": "^8.3.2", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" diff --git a/package.json b/package.json index 6bb953475..38f99dc55 100644 --- a/package.json +++ b/package.json @@ -9,40 +9,40 @@ "platform/configurator-mcp", "platform/connectors", "platform/db", - "platform/server", + "platform/backend", "platform/shared", "platform/web" ], "scripts": { "release:prepare": "node scripts/release/prepare-version.mjs", - "dev:docs": "npm run dev --workspace @lightspeed/docs --", - "build:docs": "npm run build --workspace @lightspeed/docs", - "preview:docs": "npm run preview --workspace @lightspeed/docs --", - "check:docs": "npm run check --workspace @lightspeed/docs", - "build": "npm run build --workspace @lightspeed-ai/agent-client && npm run build --workspace @lightspeed/configurator-mcp && npm run build --workspace @lightspeed/platform-web && npm run build:demo --workspace @lightspeed/platform-web", - "build:web": "npm run build --workspace @lightspeed/platform-web", + "dev:docs": "npm run dev --workspace @lightspeed-ai/docs --", + "build:docs": "npm run build --workspace @lightspeed-ai/docs", + "preview:docs": "npm run preview --workspace @lightspeed-ai/docs --", + "check:docs": "npm run check --workspace @lightspeed-ai/docs", + "build": "npm run build --workspace @lightspeed-ai/sdk && npm run build --workspace @lightspeed-ai/configurator-mcp && npm run build --workspace @lightspeed-ai/platform-web && npm run build:demo --workspace @lightspeed-ai/platform-web", + "build:web": "npm run build --workspace @lightspeed-ai/platform-web", "check": "npm run check:dev && npm run check:identity && npm run check:generated && npm run typecheck && npm run test:consumers && npm run build", "check:ci": "npm run check && npm run test:build && npm run test:migrations && npm run test:release-packaging", "check:dev": "bash -n dev.sh scripts/dev/env.sh scripts/dev/lib/common.sh scripts/dev/infra/*.sh && node --check scripts/dev/stack.mjs && node --test scripts/dev/*.test.mjs && ./dev.sh --help >/dev/null && LIGHTSPEED_CHANNELS_CONNECTORS= node scripts/dev/stack.mjs --plan infra >/dev/null && LIGHTSPEED_CHANNELS_CONNECTORS= node scripts/dev/stack.mjs --plan runtime >/dev/null && LIGHTSPEED_CHANNELS_CONNECTORS= node scripts/dev/stack.mjs --plan platform >/dev/null && LIGHTSPEED_CHANNELS_CONNECTORS= node scripts/dev/stack.mjs --plan demo >/dev/null && LIGHTSPEED_CHANNELS_CONNECTORS= node scripts/dev/stack.mjs --plan full >/dev/null", "check:identity": "node platform/scripts/check-product-identity.mjs", - "check:generated": "npm run check:generated --workspace @lightspeed-ai/agent-client && npm run check:generated --workspace @lightspeed/configurator-mcp && node platform/scripts/generate-config-reference.mjs && node platform/scripts/generate-method-roles.mjs && git diff --exit-code -- platform/web/src/lib/profile-config-reference.ts platform/server/src/routes/method-roles.ts", + "check:generated": "npm run check:generated --workspace @lightspeed-ai/sdk && npm run check:generated --workspace @lightspeed-ai/configurator-mcp && node platform/scripts/generate-config-reference.mjs && node platform/scripts/generate-method-roles.mjs && git diff --exit-code -- platform/web/src/lib/profile-config-reference.ts platform/backend/src/routes/method-roles.ts", "dev": "./dev.sh", - "generate": "npm run generate --workspace @lightspeed/platform-db", + "generate": "npm run generate --workspace @lightspeed-ai/platform-db", "test": "npm run test --workspaces --if-present", "test:consumers": "npm run test --workspace clients/typescript --workspace platform --if-present", "test:build": "node --test scripts/ci/*.test.mjs scripts/release/*.test.mjs", - "test:migrations": "npm run test:migrations --workspace @lightspeed/platform-db", + "test:migrations": "npm run test:migrations --workspace @lightspeed-ai/platform-db", "test:release-packaging": "npm --prefix clients/typescript ci --ignore-scripts && npm --prefix platform/configurator-mcp ci --ignore-scripts && scripts/release/stage-runtimes.sh", - "typecheck": "tsc --noEmit && npm run typecheck --workspace @lightspeed/connectors && npm run typecheck --workspace @lightspeed/platform-web && npm run typecheck --workspace @lightspeed-ai/agent-client && npm run typecheck --workspace @lightspeed/configurator-mcp", - "build:demo": "npm run build:demo --workspace @lightspeed/platform-web", - "demo": "npm run dev:demo --workspace @lightspeed/platform-web" + "typecheck": "tsc --noEmit && npm run typecheck --workspace @lightspeed-ai/connectors && npm run typecheck --workspace @lightspeed-ai/platform-web && npm run typecheck --workspace @lightspeed-ai/sdk && npm run typecheck --workspace @lightspeed-ai/configurator-mcp", + "build:demo": "npm run build:demo --workspace @lightspeed-ai/platform-web", + "demo": "npm run dev:demo --workspace @lightspeed-ai/platform-web" }, "devDependencies": { - "@types/node": "^24.0.0", - "tsx": "^4.20.0", - "typescript": "^5.8.3" + "@types/node": "^24.19.1", + "tsx": "^4.23.15", + "typescript": "^6.0.3" }, "engines": { - "node": ">=24" + "node": ">=24.21.0" } } diff --git a/platform/README.md b/platform/README.md index 810ddfa3c..d50770f33 100644 --- a/platform/README.md +++ b/platform/README.md @@ -6,7 +6,7 @@ run Node commands from there. ## Components -- `server/` — Hono API, better-auth integration, universe-scoped gateway +- `backend/` — Hono API, better-auth integration, universe-scoped gateway passthrough, database migration startup, and static SPA hosting. - `web/` — Vite/React management UI served under `/app`. - `cli/` — `lightspeed-platform`, the platform administration CLI. @@ -22,7 +22,7 @@ run Node commands from there. - `scripts/` — product-identity check and the generated profile configuration reference. - `web/src/demo/` — the in-browser demo backend: an in-memory stand-in for - the platform server and engine that the demo build loads instead of a + the platform backend and engine that the demo build loads instead of a real API (see "Demo build" below). The generated public API client lives separately at `clients/typescript/`. @@ -72,7 +72,7 @@ for the user controls. The authoritative configuration reference is [environment-variable reference](../docs/documentation/reference/environment-variables.md), with separate sections for the -Platform server, connector host, Configurator MCP, and development-only +Platform backend, connector host, Configurator MCP, and development-only settings. The universe sidebar groups the work (Bots, Sessions), the **Setup** agents are @@ -145,10 +145,10 @@ through the universe routes. **The gate.** The server decides before a request reaches core. Every core call a route makes for a member goes through one client -(`server/src/runtime-client.ts`), which: +(`backend/src/runtime-client.ts`), which: - requires the member's role to meet the method's role, from - `server/src/routes/method-roles.ts`. That table is generated from the core + `backend/src/routes/method-roles.ts`. That table is generated from the core method manifest by `node platform/scripts/generate-method-roles.mjs`, and `npm run check` fails when it is stale; - for a method that names a session, unless the member is an admin, requires the @@ -216,13 +216,13 @@ product. For the focused Platform loop against an already running runtime at ./dev.sh platform ``` -The focused profile starts shared infrastructure, the Platform server on port +The focused profile starts shared infrastructure, the Platform backend on port 3000, and Vite on port 5173. ### Demo build The web UI has two build paths. `npm run build:web` produces the live SPA that -the Platform server hosts under `/app`. `npm run build:demo` produces +the Platform backend hosts under `/app`. `npm run build:demo` produces `platform/web/dist-demo/`: the same SPA with `web/src/demo/main.ts` as its entry, which installs an in-browser backend (a Hono router behind a `fetch` shim, seeded from `web/src/demo/fixtures/`) before loading the app. It needs no diff --git a/platform/backend/package.json b/platform/backend/package.json new file mode 100644 index 000000000..c9354b46c --- /dev/null +++ b/platform/backend/package.json @@ -0,0 +1,32 @@ +{ + "name": "@lightspeed-ai/platform-backend", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx watch src/main.ts", + "start": "tsx src/main.ts", + "test": "vitest run --passWithNoTests", + "test:sso": "tsx scripts/check-sso.ts" + }, + "dependencies": { + "@hono/node-server": "^2.1.3", + "@lightspeed-ai/sdk": "*", + "@lightspeed-ai/platform-db": "*", + "@lightspeed-ai/platform-shared": "*", + "better-auth": "1.7.7", + "drizzle-orm": "^0.45.3", + "hono": "^4.13.12", + "jose": "6.2.12", + "pg": "^8.23.1", + "tsx": "^4.23.15", + "zod": "^4.6.5" + }, + "devDependencies": { + "@electric-sql/pglite": "0.5.8", + "@types/pg": "^8.23.1", + "vitest": "^5.0.3" + }, + "engines": { + "node": ">=24" + } +} diff --git a/platform/server/scripts/check-sso.ts b/platform/backend/scripts/check-sso.ts similarity index 99% rename from platform/server/scripts/check-sso.ts rename to platform/backend/scripts/check-sso.ts index 7eaa36326..79f5ab280 100644 --- a/platform/server/scripts/check-sso.ts +++ b/platform/backend/scripts/check-sso.ts @@ -2,7 +2,7 @@ // No production provider or credentials are accepted here. import assert from "node:assert/strict"; import { eq } from "drizzle-orm"; -import { schema } from "@lightspeed/platform-db"; +import { schema } from "@lightspeed-ai/platform-db"; import { identityEnv, identityFixture, responseCookies } from "../test/identity-fixture.js"; import { companyProviderId } from "../src/company-identity.js"; diff --git a/platform/server/src/api.test.ts b/platform/backend/src/api.test.ts similarity index 100% rename from platform/server/src/api.test.ts rename to platform/backend/src/api.test.ts diff --git a/platform/server/src/api.ts b/platform/backend/src/api.ts similarity index 98% rename from platform/server/src/api.ts rename to platform/backend/src/api.ts index 780ee408c..4b991776c 100644 --- a/platform/server/src/api.ts +++ b/platform/backend/src/api.ts @@ -1,7 +1,7 @@ import { withGateway } from "./routes/gateway.js"; import { Hono } from "hono"; import { and, desc, eq, or } from "drizzle-orm"; -import { schema } from "@lightspeed/platform-db"; +import { schema } from "@lightspeed-ai/platform-db"; import type { AppContext, ApiVariables } from "./context.js"; import { botRoutes } from "./routes/bots.js"; import { channelAccountAdminRoutes, channelUniverseRoutes } from "./routes/channel-accounts.js"; diff --git a/platform/server/src/auth-access.test.ts b/platform/backend/src/auth-access.test.ts similarity index 100% rename from platform/server/src/auth-access.test.ts rename to platform/backend/src/auth-access.test.ts diff --git a/platform/server/src/auth-access.ts b/platform/backend/src/auth-access.ts similarity index 100% rename from platform/server/src/auth-access.ts rename to platform/backend/src/auth-access.ts diff --git a/platform/server/src/auth.integration.test.ts b/platform/backend/src/auth.integration.test.ts similarity index 99% rename from platform/server/src/auth.integration.test.ts rename to platform/backend/src/auth.integration.test.ts index 610f058d8..107764d2f 100644 --- a/platform/server/src/auth.integration.test.ts +++ b/platform/backend/src/auth.integration.test.ts @@ -2,7 +2,7 @@ import { createHash } from "node:crypto"; import { afterAll, beforeAll, beforeEach, expect, it, vi } from "vitest"; import { exportJWK, generateKeyPair, SignJWT, type JWTPayload } from "jose"; import { eq } from "drizzle-orm"; -import { schema } from "@lightspeed/platform-db"; +import { schema } from "@lightspeed-ai/platform-db"; import { identityFixture, identityEnv, responseCookies } from "../test/identity-fixture.js"; import { companyProviderId } from "./company-identity.js"; import { createAuth } from "./auth.js"; diff --git a/platform/server/src/auth.ts b/platform/backend/src/auth.ts similarity index 99% rename from platform/server/src/auth.ts rename to platform/backend/src/auth.ts index 19671168a..c82136758 100644 --- a/platform/server/src/auth.ts +++ b/platform/backend/src/auth.ts @@ -6,7 +6,7 @@ import { bearer } from "better-auth/plugins/bearer"; import { genericOAuth } from "better-auth/plugins/generic-oauth"; import { organization } from "better-auth/plugins/organization"; import { eq, sql } from "drizzle-orm"; -import { schema, identityUserFields, identitySessionFields, type Db } from "@lightspeed/platform-db"; +import { schema, identityUserFields, identitySessionFields, type Db } from "@lightspeed-ai/platform-db"; import type { ServerEnv } from "./env.js"; import { admitCompanyIdentity, companyClaimsReader, companyProviderId, type LoginIdentity } from "./company-identity.js"; import { canUsePassword, passwordMode, sessionAllowed } from "./auth-access.js"; diff --git a/platform/server/src/bootstrap.ts b/platform/backend/src/bootstrap.ts similarity index 97% rename from platform/server/src/bootstrap.ts rename to platform/backend/src/bootstrap.ts index 7bf42980b..8b2a2c75a 100644 --- a/platform/server/src/bootstrap.ts +++ b/platform/backend/src/bootstrap.ts @@ -1,6 +1,6 @@ import { and, count, eq } from "drizzle-orm"; import { hashPassword } from "better-auth/crypto"; -import { schema, type Db } from "@lightspeed/platform-db"; +import { schema, type Db } from "@lightspeed-ai/platform-db"; import type { ServerEnv } from "./env.js"; import { auditIdentity } from "./identity-audit.js"; diff --git a/platform/server/src/channel-connections.test.ts b/platform/backend/src/channel-connections.test.ts similarity index 100% rename from platform/server/src/channel-connections.test.ts rename to platform/backend/src/channel-connections.test.ts diff --git a/platform/server/src/channel-connections.ts b/platform/backend/src/channel-connections.ts similarity index 97% rename from platform/server/src/channel-connections.ts rename to platform/backend/src/channel-connections.ts index 49c697de6..2f8cef05d 100644 --- a/platform/server/src/channel-connections.ts +++ b/platform/backend/src/channel-connections.ts @@ -1,4 +1,4 @@ -import { slugify } from "@lightspeed/platform-shared"; +import { slugify } from "@lightspeed-ai/platform-shared"; export interface TelegramBotIdentity { id: number; diff --git a/platform/server/src/channels-status.test.ts b/platform/backend/src/channels-status.test.ts similarity index 100% rename from platform/server/src/channels-status.test.ts rename to platform/backend/src/channels-status.test.ts diff --git a/platform/server/src/channels-status.ts b/platform/backend/src/channels-status.ts similarity index 100% rename from platform/server/src/channels-status.ts rename to platform/backend/src/channels-status.ts diff --git a/platform/server/src/company-identity.ts b/platform/backend/src/company-identity.ts similarity index 99% rename from platform/server/src/company-identity.ts rename to platform/backend/src/company-identity.ts index 104ffa8b8..c461ced03 100644 --- a/platform/server/src/company-identity.ts +++ b/platform/backend/src/company-identity.ts @@ -2,7 +2,7 @@ import { createHash } from "node:crypto"; import { and, eq, sql } from "drizzle-orm"; import { createRemoteJWKSet, decodeJwt, jwtVerify, type JWTPayload } from "jose"; import { z } from "zod"; -import { schema, type Db } from "@lightspeed/platform-db"; +import { schema, type Db } from "@lightspeed-ai/platform-db"; import type { OidcConfig } from "./env.js"; import { auditIdentity } from "./identity-audit.js"; diff --git a/platform/server/src/context.ts b/platform/backend/src/context.ts similarity index 88% rename from platform/server/src/context.ts rename to platform/backend/src/context.ts index 257ec2cac..30b628b3d 100644 --- a/platform/server/src/context.ts +++ b/platform/backend/src/context.ts @@ -1,4 +1,4 @@ -import type { Db, DbHandle } from "@lightspeed/platform-db"; +import type { Db, DbHandle } from "@lightspeed-ai/platform-db"; import type { Auth, Session } from "./auth.js"; import type { ServerEnv } from "./env.js"; diff --git a/platform/server/src/development-seed.test.ts b/platform/backend/src/development-seed.test.ts similarity index 98% rename from platform/server/src/development-seed.test.ts rename to platform/backend/src/development-seed.test.ts index d69091550..703cdcf1b 100644 --- a/platform/server/src/development-seed.test.ts +++ b/platform/backend/src/development-seed.test.ts @@ -1,5 +1,5 @@ import { afterEach, expect, it, vi } from "vitest"; -import { schema, type Db } from "@lightspeed/platform-db"; +import { schema, type Db } from "@lightspeed-ai/platform-db"; import type { ServerEnv } from "./env.js"; import { seedDevelopment } from "./development-seed.js"; diff --git a/platform/server/src/development-seed.ts b/platform/backend/src/development-seed.ts similarity index 96% rename from platform/server/src/development-seed.ts rename to platform/backend/src/development-seed.ts index f740dddd9..9e29fee0e 100644 --- a/platform/server/src/development-seed.ts +++ b/platform/backend/src/development-seed.ts @@ -1,7 +1,7 @@ import { and, eq } from "drizzle-orm"; import { hashPassword } from "better-auth/crypto"; -import { schema, type Db } from "@lightspeed/platform-db"; -import type { UniverseRole } from "@lightspeed/platform-shared"; +import { schema, type Db } from "@lightspeed-ai/platform-db"; +import type { UniverseRole } from "@lightspeed-ai/platform-shared"; import type { ServerEnv } from "./env.js"; import { deploymentClient } from "./runtime-client.js"; diff --git a/platform/server/src/env.test.ts b/platform/backend/src/env.test.ts similarity index 100% rename from platform/server/src/env.test.ts rename to platform/backend/src/env.test.ts diff --git a/platform/server/src/env.ts b/platform/backend/src/env.ts similarity index 100% rename from platform/server/src/env.ts rename to platform/backend/src/env.ts diff --git a/platform/server/src/http.ts b/platform/backend/src/http.ts similarity index 100% rename from platform/server/src/http.ts rename to platform/backend/src/http.ts diff --git a/platform/server/src/identity-audit.ts b/platform/backend/src/identity-audit.ts similarity index 88% rename from platform/server/src/identity-audit.ts rename to platform/backend/src/identity-audit.ts index ef2dfdde1..85a3a46c8 100644 --- a/platform/server/src/identity-audit.ts +++ b/platform/backend/src/identity-audit.ts @@ -1,4 +1,4 @@ -import { schema, type Db } from "@lightspeed/platform-db"; +import { schema, type Db } from "@lightspeed-ai/platform-db"; type AuditStore = Pick; export type AuditEvent = Pick & { diff --git a/platform/server/src/main.ts b/platform/backend/src/main.ts similarity index 93% rename from platform/server/src/main.ts rename to platform/backend/src/main.ts index 8a6069493..3d6a5de9c 100644 --- a/platform/server/src/main.ts +++ b/platform/backend/src/main.ts @@ -1,5 +1,5 @@ import { serve } from "@hono/node-server"; -import { createDb, migrateDb } from "@lightspeed/platform-db"; +import { createDb, migrateDb } from "@lightspeed-ai/platform-db"; import { buildApp } from "./api.js"; import { createAuth } from "./auth.js"; import { bootstrapAdmin } from "./bootstrap.js"; diff --git a/platform/server/src/routes/api-keys-admin.test.ts b/platform/backend/src/routes/api-keys-admin.test.ts similarity index 98% rename from platform/server/src/routes/api-keys-admin.test.ts rename to platform/backend/src/routes/api-keys-admin.test.ts index 087d5f17f..97fe5401c 100644 --- a/platform/server/src/routes/api-keys-admin.test.ts +++ b/platform/backend/src/routes/api-keys-admin.test.ts @@ -1,6 +1,6 @@ import { Hono } from "hono"; import { afterEach, expect, it, vi } from "vitest"; -import { schema } from "@lightspeed/platform-db"; +import { schema } from "@lightspeed-ai/platform-db"; import type { ApiVariables, AppContext } from "../context.js"; import { apiKeyAdminRoutes } from "./api-keys-admin.js"; diff --git a/platform/server/src/routes/api-keys-admin.ts b/platform/backend/src/routes/api-keys-admin.ts similarity index 97% rename from platform/server/src/routes/api-keys-admin.ts rename to platform/backend/src/routes/api-keys-admin.ts index 1e1b887f8..5a1182c30 100644 --- a/platform/server/src/routes/api-keys-admin.ts +++ b/platform/backend/src/routes/api-keys-admin.ts @@ -1,8 +1,8 @@ import { Hono } from "hono"; import { z } from "zod"; import { eq } from "drizzle-orm"; -import type { MethodGroup } from "@lightspeed-ai/agent-client"; -import { schema } from "@lightspeed/platform-db"; +import type { MethodGroup } from "@lightspeed-ai/sdk"; +import { schema } from "@lightspeed-ai/platform-db"; import type { AppContext, ApiVariables } from "../context.js"; import { isPlatformAdmin } from "../context.js"; import { auditIdentity } from "../identity-audit.js"; diff --git a/platform/server/src/routes/bots.ts b/platform/backend/src/routes/bots.ts similarity index 99% rename from platform/server/src/routes/bots.ts rename to platform/backend/src/routes/bots.ts index d294fe46f..12b1dabcc 100644 --- a/platform/server/src/routes/bots.ts +++ b/platform/backend/src/routes/bots.ts @@ -7,7 +7,7 @@ import type { BotFilterTestParams, BotPutParams, BotTriggerPutParams, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { Hono } from "hono"; import type { AppContext, ApiVariables } from "../context.js"; import { engineClientFor, withGateway } from "./gateway.js"; diff --git a/platform/server/src/routes/channel-accounts.ts b/platform/backend/src/routes/channel-accounts.ts similarity index 99% rename from platform/server/src/routes/channel-accounts.ts rename to platform/backend/src/routes/channel-accounts.ts index ad0c1a092..4201754a8 100644 --- a/platform/server/src/routes/channel-accounts.ts +++ b/platform/backend/src/routes/channel-accounts.ts @@ -4,7 +4,7 @@ import type { ChannelAccountListParams, ChannelAccountPutParams, ChannelPairingListParams, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { Hono } from "hono"; import { z } from "zod"; import { diff --git a/platform/server/src/routes/environment-deployment.ts b/platform/backend/src/routes/environment-deployment.ts similarity index 98% rename from platform/server/src/routes/environment-deployment.ts rename to platform/backend/src/routes/environment-deployment.ts index 4e683664e..ae45ea749 100644 --- a/platform/server/src/routes/environment-deployment.ts +++ b/platform/backend/src/routes/environment-deployment.ts @@ -3,8 +3,8 @@ import { z } from "zod"; import type { DeploymentEnvironmentProviderPutParams, DeploymentProviderBindingPutParams, -} from "@lightspeed-ai/agent-client"; -import { schema } from "@lightspeed/platform-db"; +} from "@lightspeed-ai/sdk"; +import { schema } from "@lightspeed-ai/platform-db"; import type { AppContext, ApiVariables } from "../context.js"; import { isPlatformAdmin } from "../context.js"; import { parseBody } from "../http.js"; diff --git a/platform/server/src/routes/gateway-origin.test.ts b/platform/backend/src/routes/gateway-origin.test.ts similarity index 100% rename from platform/server/src/routes/gateway-origin.test.ts rename to platform/backend/src/routes/gateway-origin.test.ts diff --git a/platform/server/src/routes/gateway.test.ts b/platform/backend/src/routes/gateway.test.ts similarity index 100% rename from platform/server/src/routes/gateway.test.ts rename to platform/backend/src/routes/gateway.test.ts diff --git a/platform/server/src/routes/gateway.ts b/platform/backend/src/routes/gateway.ts similarity index 99% rename from platform/server/src/routes/gateway.ts rename to platform/backend/src/routes/gateway.ts index fa03373cc..2f854ce16 100644 --- a/platform/server/src/routes/gateway.ts +++ b/platform/backend/src/routes/gateway.ts @@ -24,8 +24,8 @@ import { type ModelListParams, type ProfileSource, type SessionConfig, -} from "@lightspeed-ai/agent-client"; -import { schema } from "@lightspeed/platform-db"; +} from "@lightspeed-ai/sdk"; +import { schema } from "@lightspeed-ai/platform-db"; import { MAX_ATTACHMENT_BYTES, MAX_DICTATION_AUDIO_BYTES, @@ -50,7 +50,7 @@ import { workspaceEntryRenameSchema, renameWorkspaceEntry, removeWorkspaceEntry, -} from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/platform-shared"; import type { AppContext, ApiVariables } from "../context.js"; import { parseBody } from "../http.js"; import { diff --git a/platform/server/src/routes/messages.test.ts b/platform/backend/src/routes/messages.test.ts similarity index 100% rename from platform/server/src/routes/messages.test.ts rename to platform/backend/src/routes/messages.test.ts diff --git a/platform/server/src/routes/method-roles.ts b/platform/backend/src/routes/method-roles.ts similarity index 98% rename from platform/server/src/routes/method-roles.ts rename to platform/backend/src/routes/method-roles.ts index efebc2f39..a619a3d9d 100644 --- a/platform/server/src/routes/method-roles.ts +++ b/platform/backend/src/routes/method-roles.ts @@ -2,7 +2,7 @@ * Generated by platform/scripts/generate-method-roles.mjs from the core * method manifest. Do not edit by hand. */ -import type { UniverseRole } from "@lightspeed/platform-shared"; +import type { UniverseRole } from "@lightspeed-ai/platform-shared"; /** The least member role each universe method needs. */ export const METHOD_ROLES: Readonly> = { diff --git a/platform/server/src/routes/model-defaults.test.ts b/platform/backend/src/routes/model-defaults.test.ts similarity index 97% rename from platform/server/src/routes/model-defaults.test.ts rename to platform/backend/src/routes/model-defaults.test.ts index c3da70a12..4638cc4be 100644 --- a/platform/server/src/routes/model-defaults.test.ts +++ b/platform/backend/src/routes/model-defaults.test.ts @@ -1,9 +1,9 @@ import { Hono } from "hono"; import { afterEach, beforeEach, expect, it, vi } from "vitest"; -import type { ModelDefaults } from "@lightspeed-ai/agent-client"; +import type { ModelDefaults } from "@lightspeed-ai/sdk"; import type { ApiVariables, AppContext } from "../context.js"; import { gatewayRoutes, withGateway } from "./gateway.js"; -import { LightspeedRpcError } from "@lightspeed-ai/agent-client"; +import { LightspeedRpcError } from "@lightspeed-ai/sdk"; const auth = vi.hoisted(() => ({ role: "operator" })); vi.mock("./universes.js", () => ({ universeForSession: vi.fn(async (_ctx, _c, id: string) => ({ diff --git a/platform/server/src/routes/setups.test.ts b/platform/backend/src/routes/setups.test.ts similarity index 98% rename from platform/server/src/routes/setups.test.ts rename to platform/backend/src/routes/setups.test.ts index aa2a9413f..07d0b2687 100644 --- a/platform/server/src/routes/setups.test.ts +++ b/platform/backend/src/routes/setups.test.ts @@ -1,7 +1,7 @@ import { Hono } from "hono"; import { afterEach, expect, it, vi } from "vitest"; -import { LightspeedRpcError, type LightspeedClient, type MethodGroup } from "@lightspeed-ai/agent-client"; -import type { UniverseRole } from "@lightspeed/platform-shared"; +import { LightspeedRpcError, type LightspeedClient, type MethodGroup } from "@lightspeed-ai/sdk"; +import type { UniverseRole } from "@lightspeed-ai/platform-shared"; import type { ApiVariables, AppContext } from "../context.js"; import { ensureCredential, ensureMcpServer, setupRoutes, type KeyChoice } from "./setups.js"; import { universeForSession } from "./universes.js"; diff --git a/platform/server/src/routes/setups.ts b/platform/backend/src/routes/setups.ts similarity index 99% rename from platform/server/src/routes/setups.ts rename to platform/backend/src/routes/setups.ts index 287ddee34..401aaa5c7 100644 --- a/platform/server/src/routes/setups.ts +++ b/platform/backend/src/routes/setups.ts @@ -6,10 +6,10 @@ import { type LightspeedClient, type McpServerInput, type MethodGroup, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { z } from "zod"; -import { schema } from "@lightspeed/platform-db"; -import type { UniverseSetupState } from "@lightspeed/platform-db/schema"; +import { schema } from "@lightspeed-ai/platform-db"; +import type { UniverseSetupState } from "@lightspeed-ai/platform-db/schema"; import type { AppContext, ApiVariables } from "../context.js"; import { parseBody } from "../http.js"; import { auditIdentity } from "../identity-audit.js"; diff --git a/platform/server/src/routes/transcriptions.test.ts b/platform/backend/src/routes/transcriptions.test.ts similarity index 100% rename from platform/server/src/routes/transcriptions.test.ts rename to platform/backend/src/routes/transcriptions.test.ts diff --git a/platform/server/src/routes/universe-adoption.test.ts b/platform/backend/src/routes/universe-adoption.test.ts similarity index 99% rename from platform/server/src/routes/universe-adoption.test.ts rename to platform/backend/src/routes/universe-adoption.test.ts index 35522c777..d5b5f92ba 100644 --- a/platform/server/src/routes/universe-adoption.test.ts +++ b/platform/backend/src/routes/universe-adoption.test.ts @@ -1,6 +1,6 @@ import { Hono } from "hono"; import { afterEach, expect, it, vi } from "vitest"; -import { schema } from "@lightspeed/platform-db"; +import { schema } from "@lightspeed-ai/platform-db"; import type { ApiVariables, AppContext } from "../context.js"; import { universeRoutes } from "./universes.js"; diff --git a/platform/server/src/routes/universe-api-keys.test.ts b/platform/backend/src/routes/universe-api-keys.test.ts similarity index 100% rename from platform/server/src/routes/universe-api-keys.test.ts rename to platform/backend/src/routes/universe-api-keys.test.ts diff --git a/platform/server/src/routes/universe-appearance.test.ts b/platform/backend/src/routes/universe-appearance.test.ts similarity index 98% rename from platform/server/src/routes/universe-appearance.test.ts rename to platform/backend/src/routes/universe-appearance.test.ts index d2ff0f31c..f39be2cbf 100644 --- a/platform/server/src/routes/universe-appearance.test.ts +++ b/platform/backend/src/routes/universe-appearance.test.ts @@ -2,7 +2,7 @@ import { readFile } from "node:fs/promises"; import { PGlite } from "@electric-sql/pglite"; import { drizzle } from "drizzle-orm/pglite"; import { Hono } from "hono"; -import { UNIVERSE_ICONS } from "@lightspeed/platform-shared"; +import { UNIVERSE_ICONS } from "@lightspeed-ai/platform-shared"; import { afterAll, beforeAll, expect, it } from "vitest"; import type { ApiVariables, AppContext } from "../context.js"; import { universeRoutes } from "./universes.js"; diff --git a/platform/server/src/routes/universe-features.test.ts b/platform/backend/src/routes/universe-features.test.ts similarity index 99% rename from platform/server/src/routes/universe-features.test.ts rename to platform/backend/src/routes/universe-features.test.ts index f20f07943..5b107bf99 100644 --- a/platform/server/src/routes/universe-features.test.ts +++ b/platform/backend/src/routes/universe-features.test.ts @@ -1,6 +1,6 @@ import { Hono } from "hono"; import { expect, it } from "vitest"; -import { effectiveFeatures, mergeFeatureOverrides } from "@lightspeed/platform-shared"; +import { effectiveFeatures, mergeFeatureOverrides } from "@lightspeed-ai/platform-shared"; import type { ApiVariables, AppContext } from "../context.js"; import { universeRoutes } from "./universes.js"; diff --git a/platform/server/src/routes/universe-members.test.ts b/platform/backend/src/routes/universe-members.test.ts similarity index 98% rename from platform/server/src/routes/universe-members.test.ts rename to platform/backend/src/routes/universe-members.test.ts index 36fd7f325..f828575d8 100644 --- a/platform/server/src/routes/universe-members.test.ts +++ b/platform/backend/src/routes/universe-members.test.ts @@ -1,4 +1,4 @@ -import { schema } from "@lightspeed/platform-db"; +import { schema } from "@lightspeed-ai/platform-db"; import { Hono } from "hono"; import { expect, it, vi } from "vitest"; import type { ApiVariables, AppContext } from "../context.js"; diff --git a/platform/server/src/routes/universe-slug-sync.test.ts b/platform/backend/src/routes/universe-slug-sync.test.ts similarity index 100% rename from platform/server/src/routes/universe-slug-sync.test.ts rename to platform/backend/src/routes/universe-slug-sync.test.ts diff --git a/platform/server/src/routes/universes.ts b/platform/backend/src/routes/universes.ts similarity index 99% rename from platform/server/src/routes/universes.ts rename to platform/backend/src/routes/universes.ts index 4fc30115d..a65d9ded6 100644 --- a/platform/server/src/routes/universes.ts +++ b/platform/backend/src/routes/universes.ts @@ -2,8 +2,8 @@ import { syncUniverseSlugs, requireAvailableCachedSlug } from "../universe-slugs import { Hono } from "hono"; import { z } from "zod"; import { and, eq, ne } from "drizzle-orm"; -import { LightspeedRpcError, type MethodGroup } from "@lightspeed-ai/agent-client"; -import { schema } from "@lightspeed/platform-db"; +import { LightspeedRpcError, type MethodGroup } from "@lightspeed-ai/sdk"; +import { schema } from "@lightspeed-ai/platform-db"; import { effectiveFeatures, memberAddSchema, @@ -15,7 +15,7 @@ import { universeRoleSchema, universeUpdateSchema, type UniverseRole, -} from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/platform-shared"; import type { AppContext, ApiVariables } from "../context.js"; import { isPlatformAdmin } from "../context.js"; import { auditIdentity } from "../identity-audit.js"; diff --git a/platform/server/src/routes/workspace-transfers.test.ts b/platform/backend/src/routes/workspace-transfers.test.ts similarity index 99% rename from platform/server/src/routes/workspace-transfers.test.ts rename to platform/backend/src/routes/workspace-transfers.test.ts index 9883d9302..181d1bcfb 100644 --- a/platform/server/src/routes/workspace-transfers.test.ts +++ b/platform/backend/src/routes/workspace-transfers.test.ts @@ -3,7 +3,7 @@ import { unzipSync } from "fflate"; import { MAX_WORKSPACE_UPLOAD_BYTES, workspaceUploadSchema, -} from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/platform-shared"; import { afterEach, beforeEach, expect, it, vi } from "vitest"; import type { ApiVariables, AppContext } from "../context.js"; import { emptyManifest, type VfsManifest } from "../vfs.js"; diff --git a/platform/server/src/runtime-client.test.ts b/platform/backend/src/runtime-client.test.ts similarity index 98% rename from platform/server/src/runtime-client.test.ts rename to platform/backend/src/runtime-client.test.ts index b08592989..4b76bf544 100644 --- a/platform/server/src/runtime-client.test.ts +++ b/platform/backend/src/runtime-client.test.ts @@ -1,6 +1,6 @@ import { afterEach, describe, expect, it, vi } from "vitest"; -import { LightspeedRpcError, METHODS } from "@lightspeed-ai/agent-client"; -import type { UniverseRole } from "@lightspeed/platform-shared"; +import { LightspeedRpcError, METHODS } from "@lightspeed-ai/sdk"; +import type { UniverseRole } from "@lightspeed-ai/platform-shared"; import { deploymentClient, GateRefusal, memberClient } from "./runtime-client.js"; import { METHOD_ROLES, UNMEMBERED_METHODS } from "./routes/method-roles.js"; import type { ServerEnv } from "./env.js"; diff --git a/platform/server/src/runtime-client.ts b/platform/backend/src/runtime-client.ts similarity index 97% rename from platform/server/src/runtime-client.ts rename to platform/backend/src/runtime-client.ts index dabcbdb2f..135b22515 100644 --- a/platform/server/src/runtime-client.ts +++ b/platform/backend/src/runtime-client.ts @@ -5,8 +5,8 @@ import { type Method, type MethodParams, type MethodResult, -} from "@lightspeed-ai/agent-client"; -import { roleAtLeast, type UniverseRole } from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/sdk"; +import { roleAtLeast, type UniverseRole } from "@lightspeed-ai/platform-shared"; import type { ServerEnv } from "./env.js"; import { METHOD_ROLES, SESSION_TARGET_METHODS } from "./routes/method-roles.js"; diff --git a/platform/server/src/static.ts b/platform/backend/src/static.ts similarity index 100% rename from platform/server/src/static.ts rename to platform/backend/src/static.ts diff --git a/platform/server/src/subscriptions.test.ts b/platform/backend/src/subscriptions.test.ts similarity index 100% rename from platform/server/src/subscriptions.test.ts rename to platform/backend/src/subscriptions.test.ts diff --git a/platform/server/src/subscriptions.ts b/platform/backend/src/subscriptions.ts similarity index 100% rename from platform/server/src/subscriptions.ts rename to platform/backend/src/subscriptions.ts diff --git a/platform/server/src/universe-slugs.test.ts b/platform/backend/src/universe-slugs.test.ts similarity index 100% rename from platform/server/src/universe-slugs.test.ts rename to platform/backend/src/universe-slugs.test.ts diff --git a/platform/server/src/universe-slugs.ts b/platform/backend/src/universe-slugs.ts similarity index 98% rename from platform/server/src/universe-slugs.ts rename to platform/backend/src/universe-slugs.ts index 0eb848e81..baf6c4ac4 100644 --- a/platform/server/src/universe-slugs.ts +++ b/platform/backend/src/universe-slugs.ts @@ -1,5 +1,5 @@ import { and, eq, ne } from "drizzle-orm"; -import { schema } from "@lightspeed/platform-db"; +import { schema } from "@lightspeed-ai/platform-db"; import type { AppContext } from "./context.js"; import { deploymentClient } from "./runtime-client.js"; diff --git a/platform/server/src/vfs.ts b/platform/backend/src/vfs.ts similarity index 100% rename from platform/server/src/vfs.ts rename to platform/backend/src/vfs.ts diff --git a/platform/server/test/identity-fixture.ts b/platform/backend/test/identity-fixture.ts similarity index 97% rename from platform/server/test/identity-fixture.ts rename to platform/backend/test/identity-fixture.ts index 7b3955421..46cad4c3a 100644 --- a/platform/server/test/identity-fixture.ts +++ b/platform/backend/test/identity-fixture.ts @@ -1,7 +1,7 @@ import { readFile } from "node:fs/promises"; import { PGlite } from "@electric-sql/pglite"; import { drizzle } from "drizzle-orm/pglite"; -import { schema, type Db } from "@lightspeed/platform-db"; +import { schema, type Db } from "@lightspeed-ai/platform-db"; import { createAuth } from "../src/auth.js"; import { buildApp } from "../src/api.js"; import { bootstrapAdmin } from "../src/bootstrap.js"; diff --git a/platform/cli/package.json b/platform/cli/package.json index 9ca2a8aae..aa736952f 100644 --- a/platform/cli/package.json +++ b/platform/cli/package.json @@ -1,14 +1,14 @@ { - "name": "@lightspeed/platform-cli", + "name": "@lightspeed-ai/platform-cli", "private": true, "type": "module", "bin": { "lightspeed-platform": "./bin/lightspeed-platform" }, "dependencies": { - "@lightspeed/platform-shared": "*", - "commander": "^14.0.0", - "tsx": "^4.20.0" + "@lightspeed-ai/platform-shared": "*", + "commander": "^15.0.0", + "tsx": "^4.23.15" }, "engines": { "node": ">=24" diff --git a/platform/configurator-mcp/README.md b/platform/configurator-mcp/README.md index 609cdc875..3b9b3e0b6 100644 --- a/platform/configurator-mcp/README.md +++ b/platform/configurator-mcp/README.md @@ -25,7 +25,7 @@ Build the TypeScript client and Configurator, then start the server: ```bash npm install -npm run build --workspace @lightspeed/configurator-mcp +npm run build --workspace @lightspeed-ai/configurator-mcp LIGHTSPEED_AUTH_MODE=single node platform/configurator-mcp/dist/bin.js ``` @@ -72,5 +72,5 @@ surface profiles, or tool approval overlay. ## Regenerate and verify ```bash -npm run check --workspace @lightspeed/configurator-mcp +npm run check --workspace @lightspeed-ai/configurator-mcp ``` diff --git a/platform/configurator-mcp/package-lock.json b/platform/configurator-mcp/package-lock.json index 5ecbde9e6..d3085bbd8 100644 --- a/platform/configurator-mcp/package-lock.json +++ b/platform/configurator-mcp/package-lock.json @@ -1,527 +1,106 @@ { - "name": "@lightspeed/configurator-mcp", + "name": "@lightspeed-ai/configurator-mcp", "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@lightspeed/configurator-mcp", + "name": "@lightspeed-ai/configurator-mcp", "version": "0.0.0", "dependencies": { - "@lightspeed-ai/agent-client": "file:../../clients/typescript", - "@modelcontextprotocol/node": "2.0.0", - "@modelcontextprotocol/server": "2.0.0", - "ajv": "^8.17.1", + "@lightspeed-ai/sdk": "file:../../clients/typescript", + "@modelcontextprotocol/node": "2.1.1", + "@modelcontextprotocol/server": "2.3.0", + "ajv": "^8.20.0", "ajv-formats": "^3.0.1", "express": "^5.2.1", - "zod": "^4.4.3" + "zod": "^4.6.5" }, "bin": { "lightspeed-configurator-mcp": "dist/bin.js" }, "devDependencies": { - "@modelcontextprotocol/client": "2.0.0", + "@modelcontextprotocol/client": "2.3.0", "@types/express": "^5.0.6", - "@types/node": "^24.0.0", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "@types/node": "^24.19.1", + "typescript": "^6.0.3", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" } }, "../../clients/typescript": { - "name": "@lightspeed-ai/agent-client", + "name": "@lightspeed-ai/sdk", "version": "0.0.0", "dependencies": { - "@noble/hashes": "2.2.0" + "@noble/hashes": "2.4.0" }, "devDependencies": { - "@types/node": "^24.0.0", - "json-schema-to-typescript": "^15.0.4", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "@types/node": "^24.19.1", + "json-schema-to-typescript": "^16.0.0", + "typescript": "^6.0.3", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", - "cpu": [ - "x64" - ], - "dev": true, + "node_modules/@hono/node-server": { + "version": "1.19.17", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.17.tgz", + "integrity": "sha512-dSneS5qhiauZWGDCeK4o695Xd9nUNjviSZCMQrj10eetr8Uln1ucn6bbphOM6UynAMMtNIzZNSpL9vnASJwrPQ==", "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], "engines": { - "node": ">=18" + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", - "cpu": [ - "arm64" - ], + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=18" + "node": ">=6.0.0" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", - "cpu": [ - "ia32" - ], + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", - "cpu": [ - "x64" - ], + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", - "license": "MIT", - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "hono": "^4" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@lightspeed-ai/agent-client": { + "node_modules/@lightspeed-ai/sdk": { "resolved": "../../clients/typescript", "link": true }, "node_modules/@modelcontextprotocol/client": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/client/-/client-2.0.0.tgz", - "integrity": "sha512-8f1OghQ2rjzIOfqgUCP+8GiUWqRs89njoWLNqAe8kWmDePv3s1fZXseej+QXemssEuuOvLLmLO/kqM3IQHtISw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/client/-/client-2.3.0.tgz", + "integrity": "sha512-pbHtGj6EeFCHngFE8gtNPaKrsj8Mb1IMw45BLcaPML/m2WTxI7pyYmeNQvaux88Lw8BSO5r7nyRbUyIkICmGrg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@modelcontextprotocol/core": "2.0.0", + "@modelcontextprotocol/core": "2.3.0", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", - "eventsource-parser": "^3.0.0", + "eventsource-parser": "^3.0.8", "jose": "^6.1.3", "pkce-challenge": "^5.0.0", "zod": "^4.2.0" @@ -531,10 +110,10 @@ } }, "node_modules/@modelcontextprotocol/core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.0.0.tgz", - "integrity": "sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==", - "license": "MIT", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/core/-/core-2.3.0.tgz", + "integrity": "sha512-09BHFaNVBe5pB2AhzCfLj0cqmsKLERvZQ4FblzP90UMGLaXVqdZPByFjURwsUYCmxonUW2yAwgTTvle+8O2/8w==", + "license": "Apache-2.0", "dependencies": { "zod": "^4.2.0" }, @@ -543,44 +122,49 @@ } }, "node_modules/@modelcontextprotocol/node": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/node/-/node-2.0.0.tgz", - "integrity": "sha512-Y4hAC2XdGDUdDOCbLDOCA4+aL3NUldjsOWlDL/YwpAxrPhRm1xHd7lZ+mLacvZ9t3PaH28wgNoaLQGrIk1P2pg==", - "license": "MIT", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/node/-/node-2.1.1.tgz", + "integrity": "sha512-EY92OAXN2xYL7tNS/MVsWJW1v8VHAPwl9B4Ca3pCrjmvqyC+S1C/6UHsMxF2GoFPraS5Yyg56vFz9brVpFojMA==", + "license": "Apache-2.0", "dependencies": { - "@hono/node-server": "^1.19.9" + "@hono/node-server": "^1.19.9", + "hono": "^4.11.4" }, "engines": { "node": ">=20" }, "peerDependencies": { - "@modelcontextprotocol/server": "^2.0.0", - "hono": "^4.11.4" - }, - "peerDependenciesMeta": { - "hono": { - "optional": true - } + "@modelcontextprotocol/server": "^2.3.0" } }, "node_modules/@modelcontextprotocol/server": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.0.0.tgz", - "integrity": "sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==", - "license": "MIT", - "peer": true, + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.3.0.tgz", + "integrity": "sha512-+6b0LdsQLmHsvS7J6sQJ4weTpzUn61fU1JKS+321/+IyDYoHW5CR2Tgqcs6GgAAQvlesCo6yX3xttgmx+XGtJw==", + "license": "Apache-2.0", "dependencies": { - "@modelcontextprotocol/core": "2.0.0", + "@modelcontextprotocol/core": "2.3.0", "zod": "^4.2.0" }, "engines": { "node": ">=20" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", - "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "node_modules/@oxc-project/types": { + "version": "0.152.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", + "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", + "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", "cpu": [ "arm" ], @@ -589,12 +173,16 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", - "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", + "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", "cpu": [ "arm64" ], @@ -603,12 +191,16 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", - "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", + "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", "cpu": [ "arm64" ], @@ -617,12 +209,16 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", - "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", + "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", "cpu": [ "x64" ], @@ -631,26 +227,16 @@ "optional": true, "os": [ "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", - "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", - "cpu": [ - "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", - "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", + "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", "cpu": [ "x64" ], @@ -659,26 +245,16 @@ "optional": true, "os": [ "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", - "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", - "cpu": [ - "arm" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", - "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", + "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", "cpu": [ "arm" ], @@ -687,194 +263,142 @@ "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", - "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", - "cpu": [ - "arm64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", - "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", + "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", - "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", - "cpu": [ - "loong64" + "libc": [ + "glibc" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", - "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", - "cpu": [ - "loong64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", - "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", + "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", "cpu": [ - "ppc64" + "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", - "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", + "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", - "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", - "cpu": [ - "riscv64" + "libc": [ + "glibc" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", - "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", - "cpu": [ - "riscv64" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", - "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", + "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", "cpu": [ "s390x" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", - "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", - "cpu": [ - "x64" + "libc": [ + "glibc" ], - "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", - "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", + "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", - "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", + "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", - "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", - "cpu": [ - "arm64" + "libc": [ + "musl" ], - "dev": true, "license": "MIT", "optional": true, "os": [ - "openharmony" - ] + "linux" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", - "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", + "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", "cpu": [ "arm64" ], @@ -882,27 +406,35 @@ "license": "MIT", "optional": true, "os": [ - "win32" - ] + "openharmony" + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", - "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", + "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", "cpu": [ - "ia32" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", - "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", + "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", "cpu": [ "x64" ], @@ -911,21 +443,19 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", - "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", - "cpu": [ - "x64" ], + "peer": true, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "peer": true }, "node_modules/@types/body-parser": { "version": "1.19.6", @@ -986,9 +516,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.2.tgz", - "integrity": "sha512-d3KvEXBSo/lOAMc2u6fkyDHBvetBHeqD7wm/AcXfLpSOQwlmG9D/aQ0SFswVjv05p7ullQS7Mjohj6/VdbZuTg==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.3.tgz", + "integrity": "sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==", "dev": true, "license": "MIT", "dependencies": { @@ -1006,13 +536,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.13.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", - "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", + "version": "24.19.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.1.tgz", + "integrity": "sha512-aS3/DG0oM05K0RIXXP+hKjinGG5IgSSVGzswZxW3O0sS3pH4/fycXundUC9XsszgKCk4gHXylTEK6hyFxVxnoQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.18.0" + "undici-types": ">=7.24.0 <7.24.7" } }, "node_modules/@types/qs": { @@ -1050,40 +580,24 @@ "@types/node": "*" } }, - "node_modules/@vitest/expect": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", - "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/@vitest/mocker": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", - "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.3.tgz", + "integrity": "sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.7", + "@jridgewell/trace-mapping": "0.3.31", + "@vitest/spy": "5.0.3", "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" + "magic-string": "^1.2.3" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -1094,73 +608,12 @@ } } }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", - "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^2.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", - "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "3.2.7", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", - "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.7", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/@vitest/spy": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", - "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^4.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", - "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.3.tgz", + "integrity": "sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==", "dev": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "3.2.7", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, "funding": { "url": "https://opencollective.com/vitest" } @@ -1246,9 +699,9 @@ } }, "node_modules/body-parser/node_modules/content-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", - "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", "license": "MIT", "engines": { "node": ">=18" @@ -1267,16 +720,6 @@ "node": ">= 0.8" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1307,32 +750,15 @@ } }, "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/content-disposition": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", @@ -1405,16 +831,6 @@ } } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1424,6 +840,17 @@ "node": ">= 0.8" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -1472,9 +899,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", "dev": true, "license": "MIT" }, @@ -1490,48 +917,6 @@ "node": ">= 0.4" } }, - "node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "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" - } - }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1571,9 +956,9 @@ } }, "node_modules/eventsource-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz", - "integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz", + "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==", "dev": true, "license": "MIT", "engines": { @@ -1595,7 +980,6 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -1641,9 +1025,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", - "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", + "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", "funding": [ { "type": "github", @@ -1724,6 +1108,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -1811,11 +1196,10 @@ } }, "node_modules/hono": { - "version": "4.12.29", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.29.tgz", - "integrity": "sha512-1hNiRjawYrLq/4m3DQQjPGFg0VZkk4RjQJDff/excI6Dm9BiL75qxGrd7/c6YOxPdq6AscP3LiXhQ6fKFC1Waw==", + "version": "4.13.12", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.12.tgz", + "integrity": "sha512-6E2QDAc9Ick9Sq77ZrGS/dk2WUYni91aufTw6LJKpV7w8kW5/GxVUc650FOADOmlwg3K+f7Pun6XlV+pYmW6gw==", "license": "MIT", - "peer": true, "engines": { "node": ">=16.9.0" } @@ -1837,91 +1221,362 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jose": { + "version": "6.2.12", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", + "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "peer": true, + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/iconv-lite": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", - "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://opencollective.com/parcel" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": ">= 0.10" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "ISC" + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/jose": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", - "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, "funding": { - "url": "https://github.com/sponsors/panva" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.2.tgz", + "integrity": "sha512-vG+rjFRj1PqdIBozIxAGMjPlOhaVe+GXpbttY/iSK7rGcJRMlwNJO7dcUwmUqkymsFLJiNGI06t4D7Fr7yRC9g==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "@jridgewell/sourcemap-codec": "^1.6.0" } }, "node_modules/math-intrinsics": { @@ -1934,12 +1589,16 @@ } }, "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", "license": "MIT", "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/merge-descriptors": { @@ -1986,9 +1645,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", "dev": true, "funding": [ { @@ -1997,6 +1656,7 @@ } ], "license": "MIT", + "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -2005,12 +1665,32 @@ } }, "node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz", + "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", "license": "MIT", + "dependencies": { + "content-type": "^2.1.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/negotiator/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/object-inspect": { @@ -2025,6 +1705,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -2075,37 +1769,20 @@ "url": "https://opencollective.com/express" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/picomatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2124,9 +1801,9 @@ } }, "node_modules/postcss": { - "version": "8.5.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", - "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", "dev": true, "funding": [ { @@ -2143,8 +1820,9 @@ } ], "license": "MIT", + "peer": true, "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.18", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -2153,9 +1831,9 @@ } }, "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz", + "integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -2163,12 +1841,16 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/qs": { - "version": "6.15.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", - "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", "license": "BSD-3-Clause", "dependencies": { "es-define-property": "^1.0.1", @@ -2218,49 +1900,39 @@ "node": ">=0.10.0" } }, - "node_modules/rollup": { - "version": "4.62.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", - "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "node_modules/rolldown": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", + "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@types/estree": "1.0.9" + "@oxc-project/types": "=0.152.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { - "rollup": "dist/bin/rollup" + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.62.2", - "@rollup/rollup-android-arm64": "4.62.2", - "@rollup/rollup-darwin-arm64": "4.62.2", - "@rollup/rollup-darwin-x64": "4.62.2", - "@rollup/rollup-freebsd-arm64": "4.62.2", - "@rollup/rollup-freebsd-x64": "4.62.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", - "@rollup/rollup-linux-arm-musleabihf": "4.62.2", - "@rollup/rollup-linux-arm64-gnu": "4.62.2", - "@rollup/rollup-linux-arm64-musl": "4.62.2", - "@rollup/rollup-linux-loong64-gnu": "4.62.2", - "@rollup/rollup-linux-loong64-musl": "4.62.2", - "@rollup/rollup-linux-ppc64-gnu": "4.62.2", - "@rollup/rollup-linux-ppc64-musl": "4.62.2", - "@rollup/rollup-linux-riscv64-gnu": "4.62.2", - "@rollup/rollup-linux-riscv64-musl": "4.62.2", - "@rollup/rollup-linux-s390x-gnu": "4.62.2", - "@rollup/rollup-linux-x64-gnu": "4.62.2", - "@rollup/rollup-linux-x64-musl": "4.62.2", - "@rollup/rollup-openbsd-x64": "4.62.2", - "@rollup/rollup-openharmony-arm64": "4.62.2", - "@rollup/rollup-win32-arm64-msvc": "4.62.2", - "@rollup/rollup-win32-ia32-msvc": "4.62.2", - "@rollup/rollup-win32-x64-gnu": "4.62.2", - "@rollup/rollup-win32-x64-msvc": "4.62.2", - "fsevents": "~2.3.2" + "@rolldown/binding-android-arm-eabi": "1.2.12", + "@rolldown/binding-android-arm64": "1.2.12", + "@rolldown/binding-darwin-arm64": "1.2.12", + "@rolldown/binding-darwin-x64": "1.2.12", + "@rolldown/binding-freebsd-x64": "1.2.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", + "@rolldown/binding-linux-arm64-gnu": "1.2.12", + "@rolldown/binding-linux-arm64-musl": "1.2.12", + "@rolldown/binding-linux-ppc64-gnu": "1.2.12", + "@rolldown/binding-linux-s390x-gnu": "1.2.12", + "@rolldown/binding-linux-x64-gnu": "1.2.12", + "@rolldown/binding-linux-x64-musl": "1.2.12", + "@rolldown/binding-openharmony-arm64": "1.2.12", + "@rolldown/binding-win32-arm64-msvc": "1.2.12", + "@rolldown/binding-win32-x64-msvc": "1.2.12" } }, "node_modules/router": { @@ -2431,30 +2103,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -2465,38 +2124,31 @@ } }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", "dev": true, "license": "MIT" }, - "node_modules/strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "node_modules/tinybench": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.0.tgz", + "integrity": "sha512-78U2TlB2CnVenajOFzf3BKSm0J6oz5L0NV7g32LCPccvYc0lbWvys4d3uUUCS2B1N8PAf2+aekR8i1KbC3HO7Q==", "dev": true, "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "engines": { + "node": ">=20.0.0" } }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.17", @@ -2515,36 +2167,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -2573,9 +2195,9 @@ } }, "node_modules/type-is/node_modules/content-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", - "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", "license": "MIT", "engines": { "node": ">=18" @@ -2586,9 +2208,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2600,9 +2222,9 @@ } }, "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "dev": true, "license": "MIT" }, @@ -2625,19 +2247,18 @@ } }, "node_modules/vite": { - "version": "7.3.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", - "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.2.tgz", + "integrity": "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "esbuild": "^0.27.0 || ^0.28.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.11", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" @@ -2653,9 +2274,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", - "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", @@ -2668,13 +2290,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -2700,89 +2325,73 @@ } } }, - "node_modules/vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, "node_modules/vitest": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", - "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.3.tgz", + "integrity": "sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.7", - "@vitest/mocker": "3.2.7", - "@vitest/pretty-format": "^3.2.7", - "@vitest/runner": "3.2.7", - "@vitest/snapshot": "3.2.7", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", - "why-is-node-running": "^2.3.0" + "@vitest/mocker": "5.0.3", + "chai": "^6.2.2", + "es-module-lexer": "^2.3.2", + "expect-type": "^1.4.0", + "magic-string": "^1.2.3", + "obug": "^2.1.4", + "picomatch": "^4.0.7", + "std-env": "^4.2.0", + "tinybench": "^6.1.4", + "tinyexec": "^1.3.0", + "tinyglobby": "^0.2.17", + "why-is-node-running": "3.2.1" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^22.12.0 || ^24.0.0 || >=26.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.7", - "@vitest/ui": "3.2.7", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "5.0.3", + "@vitest/browser-preview": "5.0.3", + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", + "@vitest/coverage-istanbul": "5.0.3", + "@vitest/coverage-v8": "5.0.3", + "@vitest/ui": "5.0.3", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { "optional": true }, - "@vitest/browser": { + "@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": { @@ -2793,6 +2402,9 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, @@ -2813,20 +2425,16 @@ } }, "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-3.2.1.tgz", + "integrity": "sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==", "dev": true, "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, "bin": { "why-is-node-running": "cli.js" }, "engines": { - "node": ">=8" + "node": ">=20.11" } }, "node_modules/wrappy": { @@ -2836,11 +2444,10 @@ "license": "ISC" }, "node_modules/zod": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", - "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "version": "4.6.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.5.tgz", + "integrity": "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/platform/configurator-mcp/package.json b/platform/configurator-mcp/package.json index 62e1d7ae3..b0d4efca9 100644 --- a/platform/configurator-mcp/package.json +++ b/platform/configurator-mcp/package.json @@ -1,5 +1,5 @@ { - "name": "@lightspeed/configurator-mcp", + "name": "@lightspeed-ai/configurator-mcp", "version": "0.0.0", "private": true, "type": "module", @@ -27,19 +27,19 @@ "check": "npm run check:generated && npm run typecheck && npm run test && npm run build" }, "dependencies": { - "@lightspeed-ai/agent-client": "file:../../clients/typescript", - "@modelcontextprotocol/node": "2.0.0", - "@modelcontextprotocol/server": "2.0.0", - "ajv": "^8.17.1", + "@lightspeed-ai/sdk": "file:../../clients/typescript", + "@modelcontextprotocol/node": "2.1.1", + "@modelcontextprotocol/server": "2.3.0", + "ajv": "^8.20.0", "ajv-formats": "^3.0.1", "express": "^5.2.1", - "zod": "^4.4.3" + "zod": "^4.6.5" }, "devDependencies": { - "@modelcontextprotocol/client": "2.0.0", + "@modelcontextprotocol/client": "2.3.0", "@types/express": "^5.0.6", - "@types/node": "^24.0.0", - "typescript": "^5.8.3", - "vitest": "^3.2.4" + "@types/node": "^24.19.1", + "typescript": "^6.0.3", + "vitest": "^5.0.3" } } diff --git a/platform/configurator-mcp/src/generated/tools.ts b/platform/configurator-mcp/src/generated/tools.ts index 43795a8d9..76c7c1ce8 100644 --- a/platform/configurator-mcp/src/generated/tools.ts +++ b/platform/configurator-mcp/src/generated/tools.ts @@ -208,7 +208,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -536,7 +536,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "additionalProperties": { "not": {} }, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", @@ -1349,7 +1349,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -1622,7 +1622,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "additionalProperties": { "not": {} }, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", @@ -3647,7 +3647,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -3975,7 +3975,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "additionalProperties": { "not": {} }, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", @@ -5693,7 +5693,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -5966,7 +5966,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "additionalProperties": { "not": {} }, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", @@ -6721,7 +6721,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "type": "null" } ], - "description": "Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." + "description": "Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery." }, "inputLimitTokens": { "description": "Optional input capacity override for this model route. Omission uses reported capacity where available; unknown limits recover from context-length errors.", @@ -6994,7 +6994,7 @@ export const GENERATED_TOOLS: readonly GeneratedToolDescriptor[] = [ "additionalProperties": { "not": {} }, - "description": "Run budget defaults enforced by the engine drive loop.", + "description": "Run budget defaults enforced by the harness drive loop.", "properties": { "maxToolRounds": { "format": "uint32", diff --git a/platform/configurator-mcp/src/mcp-server.ts b/platform/configurator-mcp/src/mcp-server.ts index 6091ba767..f207b9f6e 100644 --- a/platform/configurator-mcp/src/mcp-server.ts +++ b/platform/configurator-mcp/src/mcp-server.ts @@ -1,4 +1,4 @@ -import type { CallerAccess, LightspeedClient, MethodParams } from "@lightspeed-ai/agent-client"; +import type { CallerAccess, LightspeedClient, MethodParams } from "@lightspeed-ai/sdk"; import { ProtocolError, ProtocolErrorCode, diff --git a/platform/configurator-mcp/src/tool-descriptor.ts b/platform/configurator-mcp/src/tool-descriptor.ts index 18ff77319..5abae17d9 100644 --- a/platform/configurator-mcp/src/tool-descriptor.ts +++ b/platform/configurator-mcp/src/tool-descriptor.ts @@ -1,4 +1,4 @@ -import type { Method, MethodGroup } from "@lightspeed-ai/agent-client"; +import type { Method, MethodGroup } from "@lightspeed-ai/sdk"; export interface JsonSchema { [key: string]: unknown; diff --git a/platform/configurator-mcp/src/tool-result.ts b/platform/configurator-mcp/src/tool-result.ts index ed5f6afd9..0cbd2e73f 100644 --- a/platform/configurator-mcp/src/tool-result.ts +++ b/platform/configurator-mcp/src/tool-result.ts @@ -1,7 +1,7 @@ import { LightspeedRpcError, LightspeedTransportError, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; // Exactly one representation of every result: the JSON text block that all diff --git a/platform/configurator-mcp/src/transport.ts b/platform/configurator-mcp/src/transport.ts index 2cdfceb9d..93fbf7c25 100644 --- a/platform/configurator-mcp/src/transport.ts +++ b/platform/configurator-mcp/src/transport.ts @@ -1,6 +1,6 @@ import type { Server as HttpServer } from "node:http"; import type { AddressInfo } from "node:net"; -import { LightspeedRpcError, LightspeedTransportError } from "@lightspeed-ai/agent-client"; +import { LightspeedRpcError, LightspeedTransportError } from "@lightspeed-ai/sdk"; import { toNodeHandler } from "@modelcontextprotocol/node"; import { createMcpHandler } from "@modelcontextprotocol/server"; import express, { diff --git a/platform/configurator-mcp/src/upstream-client.ts b/platform/configurator-mcp/src/upstream-client.ts index 77d093519..0a982ada2 100644 --- a/platform/configurator-mcp/src/upstream-client.ts +++ b/platform/configurator-mcp/src/upstream-client.ts @@ -3,7 +3,7 @@ import { LightspeedTransportError, type CallerAccess, type LightspeedClientOptions, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import type { RequestAuthContext } from "./request-auth.js"; import { upstreamHeaders } from "./request-auth.js"; diff --git a/platform/configurator-mcp/test/generated.test.ts b/platform/configurator-mcp/test/generated.test.ts index ef1ff5f82..01a698f45 100644 --- a/platform/configurator-mcp/test/generated.test.ts +++ b/platform/configurator-mcp/test/generated.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { METHOD_INFO } from "@lightspeed-ai/agent-client"; +import { METHOD_INFO } from "@lightspeed-ai/sdk"; import { GENERATED_TOOLS } from "../src/generated/tools.js"; describe("generated universe tools", () => { diff --git a/platform/configurator-mcp/test/http.test.ts b/platform/configurator-mcp/test/http.test.ts index 2df65de10..c7a0494ab 100644 --- a/platform/configurator-mcp/test/http.test.ts +++ b/platform/configurator-mcp/test/http.test.ts @@ -2,7 +2,7 @@ import { request as httpRequest } from "node:http"; import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/client"; import { afterEach, describe, expect, it } from "vitest"; import type { ConfiguratorConfig } from "../src/config.js"; -import type { MethodGroup } from "@lightspeed-ai/agent-client"; +import type { MethodGroup } from "@lightspeed-ai/sdk"; import { GENERATED_TOOLS } from "../src/generated/tools.js"; import { startConfigurator, type RunningConfigurator } from "../src/transport.js"; diff --git a/platform/configurator-mcp/test/tool-result.test.ts b/platform/configurator-mcp/test/tool-result.test.ts index a004675e0..90ccb25b4 100644 --- a/platform/configurator-mcp/test/tool-result.test.ts +++ b/platform/configurator-mcp/test/tool-result.test.ts @@ -1,7 +1,7 @@ import { LightspeedRpcError, LightspeedTransportError, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { describe, expect, it } from "vitest"; import { failedToolResult, diff --git a/platform/connectors/README.md b/platform/connectors/README.md index f07f0b78e..635509627 100644 --- a/platform/connectors/README.md +++ b/platform/connectors/README.md @@ -1,6 +1,6 @@ # Lightspeed connector host -`@lightspeed/connectors` bridges chat providers (Telegram, WhatsApp) to the +`@lightspeed-ai/connectors` bridges chat providers (Telegram, WhatsApp) to the Lightspeed core. It is **one process serving many accounts across many universes**: one grammy long-poller or Baileys socket per account, one Temporal activity worker per account queue, all in one Node process. Its only @@ -59,9 +59,9 @@ The minimum is `LIGHTSPEED_API_URL`; WhatsApp additionally needs `LIGHTSPEED_CONNECTOR_WHATSAPP_MEDIA_LOCATOR_KEY`. ```bash -npm run test --workspace @lightspeed/connectors -npm run typecheck --workspace @lightspeed/connectors -LIGHTSPEED_API_URL=http://127.0.0.1:18080/rpc npm run dev --workspace @lightspeed/connectors +npm run test --workspace @lightspeed-ai/connectors +npm run typecheck --workspace @lightspeed-ai/connectors +LIGHTSPEED_API_URL=http://127.0.0.1:18080/rpc npm run dev --workspace @lightspeed-ai/connectors ``` `./dev.sh` starts the host as part of the `full` profile when diff --git a/platform/connectors/package.json b/platform/connectors/package.json index a77ad2e84..7a2776c92 100644 --- a/platform/connectors/package.json +++ b/platform/connectors/package.json @@ -1,5 +1,5 @@ { - "name": "@lightspeed/connectors", + "name": "@lightspeed-ai/connectors", "private": true, "type": "module", "description": "Lightspeed connector host: Telegram and WhatsApp bridges over the core API, one process serving many accounts.", @@ -10,19 +10,19 @@ "test": "vitest run" }, "dependencies": { - "@lightspeed-ai/agent-client": "*", - "@temporalio/activity": "1.21.1", - "@temporalio/common": "1.21.1", - "@temporalio/worker": "1.21.1", - "baileys": "7.0.0-rc13", - "grammy": "^1.43.0", - "marked": "^18.0.5", + "@lightspeed-ai/sdk": "*", + "@temporalio/activity": "1.24.0", + "@temporalio/common": "1.24.0", + "@temporalio/worker": "1.24.0", + "baileys": "7.0.0-rc14", + "grammy": "^1.46.0", + "marked": "^18.0.14", "qrcode-terminal": "^0.12.0", - "tsx": "^4.20.0" + "tsx": "^4.23.15" }, "devDependencies": { "@types/qrcode-terminal": "^0.12.2", - "vitest": "^3.2.0" + "vitest": "^5.0.3" }, "engines": { "node": ">=24" diff --git a/platform/connectors/src/core/client.ts b/platform/connectors/src/core/client.ts index fb8ee2cfb..925e4f0cd 100644 --- a/platform/connectors/src/core/client.ts +++ b/platform/connectors/src/core/client.ts @@ -1,4 +1,4 @@ -import { LightspeedClient } from "@lightspeed-ai/agent-client"; +import { LightspeedClient } from "@lightspeed-ai/sdk"; export const UNIVERSE_HEADER = "x-lightspeed-universe"; diff --git a/platform/connectors/src/core/leases.ts b/platform/connectors/src/core/leases.ts index 8dde23ba7..b267ce8a7 100644 --- a/platform/connectors/src/core/leases.ts +++ b/platform/connectors/src/core/leases.ts @@ -1,4 +1,4 @@ -import type { LightspeedClient } from "@lightspeed-ai/agent-client"; +import type { LightspeedClient } from "@lightspeed-ai/sdk"; /** Re-lease this long before the broker's expiry. */ export const LEASE_EXPIRY_MARGIN_MS = 30_000; diff --git a/platform/connectors/src/host/account-runner.ts b/platform/connectors/src/host/account-runner.ts index fcfcd4256..e7ae4ee64 100644 --- a/platform/connectors/src/host/account-runner.ts +++ b/platform/connectors/src/host/account-runner.ts @@ -1,8 +1,8 @@ -import type { LightspeedClient, DeploymentChannelAccountView } from "@lightspeed-ai/agent-client"; +import type { LightspeedClient, DeploymentChannelAccountView } from "@lightspeed-ai/sdk"; import { CHANNEL_CONNECTOR_ACTIVITIES, connectorTaskQueue, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; import { Worker, type NativeConnection } from "@temporalio/worker"; import type { CoreClient } from "../core/client.js"; import { accountKey } from "../core/identity.js"; diff --git a/platform/connectors/src/host/admission.ts b/platform/connectors/src/host/admission.ts index 4f70d22f4..e3fb35626 100644 --- a/platform/connectors/src/host/admission.ts +++ b/platform/connectors/src/host/admission.ts @@ -2,7 +2,7 @@ import type { ChannelInbound, ChannelInboundDecision, LightspeedClient, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import type { InboundGate, InboundVerdict } from "../providers/connector.js"; import type { ConnectorMetrics } from "./metrics.js"; import type { FixedWindowRateLimiter } from "./rate-limit.js"; diff --git a/platform/connectors/src/host/config.ts b/platform/connectors/src/host/config.ts index 7c3d4ae7b..fbbb3f6ac 100644 --- a/platform/connectors/src/host/config.ts +++ b/platform/connectors/src/host/config.ts @@ -1,4 +1,4 @@ -import type { ChannelProvider } from "@lightspeed-ai/agent-client"; +import type { ChannelProvider } from "@lightspeed-ai/sdk"; import { parseAccountSelector, type AccountSelector } from "../core/identity.js"; import { parseWhatsAppMediaLocatorKey } from "../providers/whatsapp/media.js"; import { parsePositiveInteger } from "./rate-limit.js"; diff --git a/platform/connectors/src/host/discovery.ts b/platform/connectors/src/host/discovery.ts index 705972496..d0a508930 100644 --- a/platform/connectors/src/host/discovery.ts +++ b/platform/connectors/src/host/discovery.ts @@ -1,4 +1,4 @@ -import type { ChannelProvider, DeploymentChannelAccountView } from "@lightspeed-ai/agent-client"; +import type { ChannelProvider, DeploymentChannelAccountView } from "@lightspeed-ai/sdk"; import { accountKey, type AccountSelector } from "../core/identity.js"; export interface AccountFilter { diff --git a/platform/connectors/src/host/host.ts b/platform/connectors/src/host/host.ts index 2a3fd5a68..ac3bd6601 100644 --- a/platform/connectors/src/host/host.ts +++ b/platform/connectors/src/host/host.ts @@ -1,4 +1,4 @@ -import type { ChannelProvider, DeploymentChannelAccountView } from "@lightspeed-ai/agent-client"; +import type { ChannelProvider, DeploymentChannelAccountView } from "@lightspeed-ai/sdk"; import type { CoreClient } from "../core/client.js"; import type { AccountSelector } from "../core/identity.js"; import type { AccountRunnerLike } from "./account-runner.js"; diff --git a/platform/connectors/src/host/lifecycle.ts b/platform/connectors/src/host/lifecycle.ts index 23a57b20e..4ae359f03 100644 --- a/platform/connectors/src/host/lifecycle.ts +++ b/platform/connectors/src/host/lifecycle.ts @@ -1,4 +1,4 @@ -import type { ChannelProvider } from "@lightspeed-ai/agent-client"; +import type { ChannelProvider } from "@lightspeed-ai/sdk"; import type { IngressHealth } from "../providers/connector.js"; export type AccountHealthState = diff --git a/platform/connectors/src/host/metrics.ts b/platform/connectors/src/host/metrics.ts index 27f292e1b..49bd934b0 100644 --- a/platform/connectors/src/host/metrics.ts +++ b/platform/connectors/src/host/metrics.ts @@ -1,4 +1,4 @@ -import type { ChannelInboundDecision } from "@lightspeed-ai/agent-client"; +import type { ChannelInboundDecision } from "@lightspeed-ai/sdk"; import type { ConnectorHostHealth } from "./health.js"; import type { AccountHealth } from "./lifecycle.js"; diff --git a/platform/connectors/src/media/inbound.ts b/platform/connectors/src/media/inbound.ts index cac4e9ad8..7625a5064 100644 --- a/platform/connectors/src/media/inbound.ts +++ b/platform/connectors/src/media/inbound.ts @@ -1,4 +1,4 @@ -import type { ChannelInboundMedia, ChannelMediaKind } from "@lightspeed-ai/agent-client"; +import type { ChannelInboundMedia, ChannelMediaKind } from "@lightspeed-ai/sdk"; import { audioMime, documentMime, imageMime, mediaByteLimit } from "./validation.js"; export const MAX_CHANNEL_MEDIA_PER_MESSAGE = 8; diff --git a/platform/connectors/src/media/validation.ts b/platform/connectors/src/media/validation.ts index 015a67058..ac21c160a 100644 --- a/platform/connectors/src/media/validation.ts +++ b/platform/connectors/src/media/validation.ts @@ -1,4 +1,4 @@ -import type { ChannelMediaKind } from "@lightspeed-ai/agent-client"; +import type { ChannelMediaKind } from "@lightspeed-ai/sdk"; const IMAGE_MIMES = new Set(["image/jpeg", "image/png", "image/webp", "image/gif"]); const DOCUMENT_MIMES = new Set([ diff --git a/platform/connectors/src/providers/connector.ts b/platform/connectors/src/providers/connector.ts index fed10b326..fb2bef15d 100644 --- a/platform/connectors/src/providers/connector.ts +++ b/platform/connectors/src/providers/connector.ts @@ -1,11 +1,11 @@ -import type { ChannelInbound, ChannelInboundDecision } from "@lightspeed-ai/agent-client"; +import type { ChannelInbound, ChannelInboundDecision } from "@lightspeed-ai/sdk"; import type { ChannelDeliveryCommand, ChannelDeliveryResult, MaintainChannelTypingInput, PrepareChannelMediaInput, PrepareChannelMediaResult, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; /** The three activities a connector serves on its account's task queue, by manifest name. */ export interface ConnectorActivities { diff --git a/platform/connectors/src/providers/delivery.ts b/platform/connectors/src/providers/delivery.ts index fca449e03..eeb083a89 100644 --- a/platform/connectors/src/providers/delivery.ts +++ b/platform/connectors/src/providers/delivery.ts @@ -1,7 +1,7 @@ import type { ChannelDeliveryCommand, ChannelDeliveryResult, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; /** The delivery command/result shape this connector implements. */ export const CHANNEL_DELIVERY_VERSION = 1; diff --git a/platform/connectors/src/providers/telegram/connector.ts b/platform/connectors/src/providers/telegram/connector.ts index 7afab3980..f84aaaf70 100644 --- a/platform/connectors/src/providers/telegram/connector.ts +++ b/platform/connectors/src/providers/telegram/connector.ts @@ -1,5 +1,5 @@ import { Bot, GrammyError, type Context } from "grammy"; -import type { LightspeedClient } from "@lightspeed-ai/agent-client"; +import type { LightspeedClient } from "@lightspeed-ai/sdk"; import type { TokenSource } from "../../core/leases.js"; import type { ConnectorActivities, diff --git a/platform/connectors/src/providers/telegram/delivery.ts b/platform/connectors/src/providers/telegram/delivery.ts index c4b2533a6..a5020640b 100644 --- a/platform/connectors/src/providers/telegram/delivery.ts +++ b/platform/connectors/src/providers/telegram/delivery.ts @@ -2,7 +2,7 @@ import { ApplicationFailure } from "@temporalio/common"; import type { ChannelDeliveryCommand, ChannelDeliveryResult, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; import { renderTelegramHtml } from "../../presentation/telegram.js"; import { splitMessageText } from "../../presentation/text.js"; import { diff --git a/platform/connectors/src/providers/telegram/ingress.ts b/platform/connectors/src/providers/telegram/ingress.ts index b48422cff..ebbe0cc14 100644 --- a/platform/connectors/src/providers/telegram/ingress.ts +++ b/platform/connectors/src/providers/telegram/ingress.ts @@ -1,4 +1,4 @@ -import type { ChannelInbound, ChannelInboundMedia } from "@lightspeed-ai/agent-client"; +import type { ChannelInbound, ChannelInboundMedia } from "@lightspeed-ai/sdk"; import { mediaPlaceholder } from "../../media/inbound.js"; import { MAX_AUDIO_BYTES, diff --git a/platform/connectors/src/providers/telegram/media.ts b/platform/connectors/src/providers/telegram/media.ts index 3d8cf400b..16e2e69a4 100644 --- a/platform/connectors/src/providers/telegram/media.ts +++ b/platform/connectors/src/providers/telegram/media.ts @@ -1,8 +1,8 @@ -import type { LightspeedClient } from "@lightspeed-ai/agent-client"; +import type { LightspeedClient } from "@lightspeed-ai/sdk"; import type { PrepareChannelMediaInput, PrepareChannelMediaResult, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; import { ApplicationFailure } from "@temporalio/common"; import type { TokenSource } from "../../core/leases.js"; import { parseChannelInboundMedia } from "../../media/inbound.js"; diff --git a/platform/connectors/src/providers/typing.ts b/platform/connectors/src/providers/typing.ts index 03b448f4c..8ad7defaa 100644 --- a/platform/connectors/src/providers/typing.ts +++ b/platform/connectors/src/providers/typing.ts @@ -1,6 +1,6 @@ import { Context } from "@temporalio/activity"; -import type { ChannelProvider } from "@lightspeed-ai/agent-client"; -import type { MaintainChannelTypingInput } from "@lightspeed-ai/agent-client/workflow"; +import type { ChannelProvider } from "@lightspeed-ai/sdk"; +import type { MaintainChannelTypingInput } from "@lightspeed-ai/sdk/workflow"; export interface TypingLoopRuntime { cancelled: Promise; diff --git a/platform/connectors/src/providers/whatsapp/connector.ts b/platform/connectors/src/providers/whatsapp/connector.ts index 84edbbb4c..2950aa869 100644 --- a/platform/connectors/src/providers/whatsapp/connector.ts +++ b/platform/connectors/src/providers/whatsapp/connector.ts @@ -8,7 +8,7 @@ import { type WASocket, } from "baileys"; import qrcode from "qrcode-terminal"; -import type { LightspeedClient } from "@lightspeed-ai/agent-client"; +import type { LightspeedClient } from "@lightspeed-ai/sdk"; import type { ConnectorActivities, InboundGate, diff --git a/platform/connectors/src/providers/whatsapp/delivery.ts b/platform/connectors/src/providers/whatsapp/delivery.ts index f9aa46514..30e1270e6 100644 --- a/platform/connectors/src/providers/whatsapp/delivery.ts +++ b/platform/connectors/src/providers/whatsapp/delivery.ts @@ -2,7 +2,7 @@ import { ApplicationFailure } from "@temporalio/common"; import type { ChannelDeliveryCommand, ChannelDeliveryResult, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; import { renderWhatsAppText } from "../../presentation/whatsapp.js"; import { splitMessageText } from "../../presentation/text.js"; import { diff --git a/platform/connectors/src/providers/whatsapp/ingress.ts b/platform/connectors/src/providers/whatsapp/ingress.ts index 5d5d3c99b..83e912e68 100644 --- a/platform/connectors/src/providers/whatsapp/ingress.ts +++ b/platform/connectors/src/providers/whatsapp/ingress.ts @@ -1,4 +1,4 @@ -import type { ChannelInbound, ChannelInboundMedia } from "@lightspeed-ai/agent-client"; +import type { ChannelInbound, ChannelInboundMedia } from "@lightspeed-ai/sdk"; import { mediaPlaceholder } from "../../media/inbound.js"; export interface WhatsAppInboundMessage { diff --git a/platform/connectors/src/providers/whatsapp/media.ts b/platform/connectors/src/providers/whatsapp/media.ts index 930c47cb2..88c16434e 100644 --- a/platform/connectors/src/providers/whatsapp/media.ts +++ b/platform/connectors/src/providers/whatsapp/media.ts @@ -1,9 +1,9 @@ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto"; -import type { ChannelInboundMedia, LightspeedClient } from "@lightspeed-ai/agent-client"; +import type { ChannelInboundMedia, LightspeedClient } from "@lightspeed-ai/sdk"; import type { PrepareChannelMediaInput, PrepareChannelMediaResult, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; import { ApplicationFailure } from "@temporalio/common"; import { downloadContentFromMessage } from "baileys"; import { parseChannelInboundMedia } from "../../media/inbound.js"; diff --git a/platform/connectors/test/account-runner.test.ts b/platform/connectors/test/account-runner.test.ts index 66520265a..7e9cca97a 100644 --- a/platform/connectors/test/account-runner.test.ts +++ b/platform/connectors/test/account-runner.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { CHANNEL_CONNECTOR_ACTIVITIES, connectorTaskQueue } from "@lightspeed-ai/agent-client/workflow"; +import { CHANNEL_CONNECTOR_ACTIVITIES, connectorTaskQueue } from "@lightspeed-ai/sdk/workflow"; import type { NativeConnection } from "@temporalio/worker"; import { CoreClient } from "../src/core/client.js"; import { AccountRunner, whatsAppAuthDir, type WorkerLike } from "../src/host/account-runner.js"; diff --git a/platform/connectors/test/admission.test.ts b/platform/connectors/test/admission.test.ts index 1501c7e87..37df5c4fb 100644 --- a/platform/connectors/test/admission.test.ts +++ b/platform/connectors/test/admission.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import type { ChannelInbound, ChannelInboundDecision } from "@lightspeed-ai/agent-client"; +import type { ChannelInbound, ChannelInboundDecision } from "@lightspeed-ai/sdk"; import { CoreClient, UNIVERSE_HEADER } from "../src/core/client.js"; import { PAIRING_CONFIRMED_REPLY, diff --git a/platform/connectors/test/fixtures.ts b/platform/connectors/test/fixtures.ts index 35b3be765..9dc1d02e7 100644 --- a/platform/connectors/test/fixtures.ts +++ b/platform/connectors/test/fixtures.ts @@ -1,4 +1,4 @@ -import type { DeploymentChannelAccountView } from "@lightspeed-ai/agent-client"; +import type { DeploymentChannelAccountView } from "@lightspeed-ai/sdk"; export const UNIVERSE_A = "6f3a1a52-58c1-4f0e-9c2d-1a2b3c4d5e6f"; export const UNIVERSE_B = "00000000-0000-0000-0000-000000000001"; diff --git a/platform/connectors/test/host.test.ts b/platform/connectors/test/host.test.ts index f1c5c3ba4..72cda4339 100644 --- a/platform/connectors/test/host.test.ts +++ b/platform/connectors/test/host.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import type { DeploymentChannelAccountView } from "@lightspeed-ai/agent-client"; +import type { DeploymentChannelAccountView } from "@lightspeed-ai/sdk"; import { CoreClient } from "../src/core/client.js"; import type { AccountRunnerLike } from "../src/host/account-runner.js"; import { ConnectorHost } from "../src/host/host.js"; diff --git a/platform/connectors/test/ids.test.ts b/platform/connectors/test/ids.test.ts index 4703fd9f8..e7d9ed7f5 100644 --- a/platform/connectors/test/ids.test.ts +++ b/platform/connectors/test/ids.test.ts @@ -3,7 +3,7 @@ import { WORKFLOW_CONTRACT_VECTORS, connectorTaskQueue, sessionWorkflowId, -} from "@lightspeed-ai/agent-client/workflow"; +} from "@lightspeed-ai/sdk/workflow"; import { accountKey, parseAccountSelector } from "../src/core/identity.js"; import { UNIVERSE_A, UNIVERSE_B } from "./fixtures.js"; diff --git a/platform/connectors/test/leases.test.ts b/platform/connectors/test/leases.test.ts index 0dfa81c61..1c9b84c4f 100644 --- a/platform/connectors/test/leases.test.ts +++ b/platform/connectors/test/leases.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import type { LightspeedClient } from "@lightspeed-ai/agent-client"; +import type { LightspeedClient } from "@lightspeed-ai/sdk"; import { GrantLease, LEASE_EXPIRY_MARGIN_MS, LEASE_MAX_AGE_MS } from "../src/core/leases.js"; function client(responses: Array<{ token: string; expiresAtMs?: number | null }>) { diff --git a/platform/connectors/test/telegram-delivery.test.ts b/platform/connectors/test/telegram-delivery.test.ts index 07b313b56..2a6784138 100644 --- a/platform/connectors/test/telegram-delivery.test.ts +++ b/platform/connectors/test/telegram-delivery.test.ts @@ -1,6 +1,6 @@ import { ApplicationFailure } from "@temporalio/common"; import { describe, expect, it, vi } from "vitest"; -import type { ChannelDeliveryCommand } from "@lightspeed-ai/agent-client/workflow"; +import type { ChannelDeliveryCommand } from "@lightspeed-ai/sdk/workflow"; import { createTelegramDeliveryActivities, type TelegramDeliveryApi, diff --git a/platform/connectors/test/telegram-media.test.ts b/platform/connectors/test/telegram-media.test.ts index 417cee409..7c2be5c3b 100644 --- a/platform/connectors/test/telegram-media.test.ts +++ b/platform/connectors/test/telegram-media.test.ts @@ -6,8 +6,8 @@ import { UNIVERSE_A } from "./fixtures.js"; const route = { provider: "telegram" as const, accountId: "primary", chatId: "123" }; -function token(value = "secret-token"): TokenSource & { invalidate: ReturnType } { - return { get: async () => value, invalidate: vi.fn() }; +function token(value = "secret-token") { + return { get: async () => value, invalidate: vi.fn<() => void>() } satisfies TokenSource; } describe("Telegram media activities", () => { diff --git a/platform/connectors/test/whatsapp-delivery.test.ts b/platform/connectors/test/whatsapp-delivery.test.ts index 8ecb4b03b..97ea14ac1 100644 --- a/platform/connectors/test/whatsapp-delivery.test.ts +++ b/platform/connectors/test/whatsapp-delivery.test.ts @@ -1,6 +1,6 @@ import { ApplicationFailure } from "@temporalio/common"; import { describe, expect, it, vi } from "vitest"; -import type { ChannelDeliveryCommand } from "@lightspeed-ai/agent-client/workflow"; +import type { ChannelDeliveryCommand } from "@lightspeed-ai/sdk/workflow"; import { createWhatsAppDeliveryActivities, type WhatsAppDeliveryApi, diff --git a/platform/db/package.json b/platform/db/package.json index 0a12c2d5a..a04bc93cb 100644 --- a/platform/db/package.json +++ b/platform/db/package.json @@ -1,5 +1,5 @@ { - "name": "@lightspeed/platform-db", + "name": "@lightspeed-ai/platform-db", "private": true, "type": "module", "exports": { @@ -11,12 +11,13 @@ "test:migrations": "tsx scripts/check-migrations.ts" }, "dependencies": { - "drizzle-orm": "^0.45.0", - "pg": "^8.16.0" + "drizzle-orm": "^0.45.3", + "pg": "^8.23.1" }, "devDependencies": { - "@types/pg": "^8.15.0", - "drizzle-kit": "^0.31.0" + "@types/pg": "^8.23.1", + "better-auth": "1.7.7", + "drizzle-kit": "^0.31.11" }, "engines": { "node": ">=24" diff --git a/platform/db/scripts/auth-codegen.ts b/platform/db/scripts/auth-codegen.ts index 9e912714b..5397b820f 100644 --- a/platform/db/scripts/auth-codegen.ts +++ b/platform/db/scripts/auth-codegen.ts @@ -1,6 +1,6 @@ // Codegen-only better-auth config: mirrors the server's plugin set so // `@better-auth/cli generate` emits the matching drizzle schema. Not -// imported at runtime — the runtime config lives in @lightspeed/platform-server. +// imported at runtime — the runtime config lives in @lightspeed-ai/platform-backend. import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { drizzle } from "drizzle-orm/node-postgres"; diff --git a/platform/scripts/generate-config-reference.mjs b/platform/scripts/generate-config-reference.mjs index 1effba3c4..ae4d57a6d 100644 --- a/platform/scripts/generate-config-reference.mjs +++ b/platform/scripts/generate-config-reference.mjs @@ -1,10 +1,10 @@ -// Regenerates web/src/lib/profile-config-reference.ts from the engine's +// Regenerates web/src/lib/profile-config-reference.ts from the harness's // canonical API contract schema (SessionConfig subtree). Run after -// the engine's config schema changes: +// the harness's config schema changes: // // node scripts/generate-config-reference.mjs [path-to-api.schema.json] // -// The schema ships inside @lightspeed-ai/agent-client and is also committed at +// The schema ships inside @lightspeed-ai/sdk and is also committed at // the Rust API ownership boundary. import { existsSync, readFileSync, writeFileSync } from "node:fs"; import path from "node:path"; @@ -12,7 +12,7 @@ import { fileURLToPath } from "node:url"; const here = path.dirname(fileURLToPath(import.meta.url)); const candidates = [ - path.resolve(here, "../../node_modules/@lightspeed-ai/agent-client/schema/api.schema.json"), + path.resolve(here, "../../node_modules/@lightspeed-ai/sdk/schema/api.schema.json"), path.resolve(here, "../../crates/api/contract/api.schema.json"), ]; const schemaPath = process.argv[2] ?? candidates.find(existsSync); @@ -146,7 +146,7 @@ const banner = [ "/// Source: crates/api/contract/api.schema.json (SessionConfig).", "/// Regenerate with: node platform/scripts/generate-config-reference.mjs", "", - "export const PROFILE_CONFIG_REFERENCE = `// Every field is optional — omit anything to keep engine defaults.", + "export const PROFILE_CONFIG_REFERENCE = `// Every field is optional — omit anything to keep harness defaults.", "// Union values are written a | b — pick one.", ].join("\n"); diff --git a/platform/scripts/generate-method-roles.mjs b/platform/scripts/generate-method-roles.mjs index c7f286bb5..3d5c59dd7 100644 --- a/platform/scripts/generate-method-roles.mjs +++ b/platform/scripts/generate-method-roles.mjs @@ -1,4 +1,4 @@ -// Regenerates server/src/routes/method-roles.ts from the core method +// Regenerates backend/src/routes/method-roles.ts from the core method // manifest: the least member role each universe method needs, the methods // that act on one session, and the methods no member calls through a // universe (deployment and service methods). Run after core methods change: @@ -10,7 +10,7 @@ import { fileURLToPath } from "node:url"; const here = path.dirname(fileURLToPath(import.meta.url)); const manifestPath = path.resolve(here, "../../crates/api/contract/methods.json"); -const outPath = path.resolve(here, "../server/src/routes/method-roles.ts"); +const outPath = path.resolve(here, "../backend/src/routes/method-roles.ts"); const { methods } = JSON.parse(readFileSync(manifestPath, "utf8")); const roles = []; @@ -26,7 +26,7 @@ writeFileSync(outPath, `/* * Generated by platform/scripts/generate-method-roles.mjs from the core * method manifest. Do not edit by hand. */ -import type { UniverseRole } from "@lightspeed/platform-shared"; +import type { UniverseRole } from "@lightspeed-ai/platform-shared"; /** The least member role each universe method needs. */ export const METHOD_ROLES: Readonly> = { diff --git a/platform/server/package.json b/platform/server/package.json deleted file mode 100644 index bee3ba9a6..000000000 --- a/platform/server/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@lightspeed/platform-server", - "private": true, - "type": "module", - "scripts": { - "dev": "tsx watch src/main.ts", - "start": "tsx src/main.ts", - "test": "vitest run --passWithNoTests", - "test:sso": "tsx scripts/check-sso.ts" - }, - "dependencies": { - "@hono/node-server": "^1.14.0", - "@lightspeed-ai/agent-client": "*", - "@lightspeed/platform-db": "*", - "@lightspeed/platform-shared": "*", - "better-auth": "1.7.6", - "drizzle-orm": "^0.45.0", - "hono": "^4.7.0", - "jose": "6.2.3", - "pg": "^8.16.0", - "tsx": "^4.20.0", - "zod": "^4.4.0" - }, - "devDependencies": { - "@electric-sql/pglite": "0.5.8", - "@types/pg": "^8.15.0", - "vitest": "^3.2.0" - }, - "engines": { - "node": ">=24" - } -} diff --git a/platform/shared/package.json b/platform/shared/package.json index 472f6d186..37d04a1e3 100644 --- a/platform/shared/package.json +++ b/platform/shared/package.json @@ -1,5 +1,5 @@ { - "name": "@lightspeed/platform-shared", + "name": "@lightspeed-ai/platform-shared", "private": true, "type": "module", "exports": { @@ -7,7 +7,7 @@ }, "dependencies": { "fflate": "^0.8.3", - "zod": "^4.4.0" + "zod": "^4.6.5" }, "engines": { "node": ">=24" diff --git a/platform/web/package.json b/platform/web/package.json index dcb8d92cd..e30cdbe09 100644 --- a/platform/web/package.json +++ b/platform/web/package.json @@ -1,5 +1,5 @@ { - "name": "@lightspeed/platform-web", + "name": "@lightspeed-ai/platform-web", "private": true, "type": "module", "scripts": { @@ -11,42 +11,42 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@base-ui/react": "^1.6.0", - "@fontsource-variable/geist": "^5.2.9", - "@fontsource-variable/space-grotesk": "^5.2.10", - "@lightspeed-ai/agent-client": "*", - "@lightspeed/platform-shared": "*", - "@shadcn/react": "^0.2.0", - "@tabler/icons-react": "^3.44.0", - "@tailwindcss/vite": "^4.3.2", - "@tanstack/react-query": "^5.80.0", - "better-auth": "1.7.6", + "@base-ui/react": "^1.8.0", + "@fontsource-variable/geist": "^5.3.0", + "@fontsource-variable/space-grotesk": "^5.3.0", + "@lightspeed-ai/sdk": "*", + "@lightspeed-ai/platform-shared": "*", + "@shadcn/react": "^0.3.1", + "@tabler/icons-react": "^3.48.0", + "@tailwindcss/vite": "^4.3.3", + "@tanstack/react-query": "^5.104.1", + "better-auth": "1.7.7", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "extendable-media-recorder": "^9.2.40", - "hono": "^4.7.0", - "lucide-react": "^1.23.0", - "react": "^19.1.0", - "react-dom": "^19.1.0", + "hono": "^4.13.12", + "lucide-react": "^1.51.0", + "react": "^19.3.0", + "react-dom": "^19.3.0", "react-markdown": "^10.1.0", - "react-router-dom": "^7.6.0", + "react-router-dom": "^7.18.4", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", - "shadcn": "^4.13.0", - "tailwind-merge": "^3.6.0", - "tailwindcss": "^4.3.2", + "shadcn": "^4.21.1", + "tailwind-merge": "^3.7.0", + "tailwindcss": "^4.3.3", "tw-animate-css": "^1.4.0", "unified": "^11.0.5", - "zod": "^4.4.3" + "zod": "^4.6.5" }, "devDependencies": { - "@types/react": "^19.1.0", - "@types/react-dom": "^19.1.0", - "@vitejs/plugin-react": "^4.5.0", - "jsdom": "^26.1.0", - "vite": "^7.0.0", - "vitest": "^3.2.6" + "@types/react": "^19.3.0", + "@types/react-dom": "^19.3.0", + "@vitejs/plugin-react": "^6.1.1", + "jsdom": "^30.1.1", + "vite": "^8.3.2", + "vitest": "^5.0.3" }, "engines": { "node": ">=24" diff --git a/platform/web/src/api.ts b/platform/web/src/api.ts index aa2f92cfc..79fa23310 100644 --- a/platform/web/src/api.ts +++ b/platform/web/src/api.ts @@ -1,5 +1,5 @@ -import type { FeatureStates, UniverseRole, UniverseIconName, UniverseIconColor } from "@lightspeed/platform-shared"; -export type { ToolAttachmentView, ModelConfig, ModelDefaults, ModelDefaultsPutParams } from "@lightspeed-ai/agent-client"; +import type { FeatureStates, UniverseRole, UniverseIconName, UniverseIconColor } from "@lightspeed-ai/platform-shared"; +export type { ToolAttachmentView, ModelConfig, ModelDefaults, ModelDefaultsPutParams } from "@lightspeed-ai/sdk"; import type { Attribution, ResourceAccessSummary, @@ -20,7 +20,7 @@ import type { SessionEventView, SessionEventsReadResponse, ToolCallDisplayView, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; /// Thin fetch wrapper for /api/v1 (cookie-authenticated, same origin). @@ -669,15 +669,15 @@ export type { SessionSummaryView, WebhookPreset, WebhookVerification, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; -import type { BotView } from "@lightspeed-ai/agent-client"; +import type { BotView } from "@lightspeed-ai/sdk"; export function botLabel(bot: Pick): string { return bot.displayName ?? bot.botId; } -/// Connector host health, aggregated by the platform server from each +/// Connector host health, aggregated by the platform backend from each /// connector's /healthz (`GET /api/v1/status/channels`). Platform-owned; /// unrelated to the core channel account records. export interface ChannelConnectorHealth { diff --git a/platform/web/src/components/activity-dot.tsx b/platform/web/src/components/activity-dot.tsx index 38bd9b588..02559ad53 100644 --- a/platform/web/src/components/activity-dot.tsx +++ b/platform/web/src/components/activity-dot.tsx @@ -1,4 +1,4 @@ -import type { SessionActivity } from "@lightspeed-ai/agent-client"; +import type { SessionActivity } from "@lightspeed-ai/sdk"; import { StatusDot, type BotTone } from "@/components/bot/status"; /** The dot for what a session is doing: working, waiting, idle or closed. */ diff --git a/platform/web/src/components/api-keys/method-group-picker.tsx b/platform/web/src/components/api-keys/method-group-picker.tsx index 72638e5a8..53d88c71e 100644 --- a/platform/web/src/components/api-keys/method-group-picker.tsx +++ b/platform/web/src/components/api-keys/method-group-picker.tsx @@ -1,4 +1,4 @@ -import type { MethodGroup } from "@lightspeed-ai/agent-client"; +import type { MethodGroup } from "@lightspeed-ai/sdk"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"; diff --git a/platform/web/src/components/api-keys/rotate-key-dialog.tsx b/platform/web/src/components/api-keys/rotate-key-dialog.tsx index 0af422d0e..420dc79e8 100644 --- a/platform/web/src/components/api-keys/rotate-key-dialog.tsx +++ b/platform/web/src/components/api-keys/rotate-key-dialog.tsx @@ -1,5 +1,5 @@ import { useMutation } from "@tanstack/react-query"; -import type { DeploymentApiKeyCreateResponse, DeploymentApiKeyView } from "@lightspeed-ai/agent-client"; +import type { DeploymentApiKeyCreateResponse, DeploymentApiKeyView } from "@lightspeed-ai/sdk"; import { api } from "@/api"; import { ApiKeySecret } from "./secret-once"; import { Button } from "@/components/ui/button"; diff --git a/platform/web/src/components/bot/detail.tsx b/platform/web/src/components/bot/detail.tsx index ee8a10f83..58e783856 100644 --- a/platform/web/src/components/bot/detail.tsx +++ b/platform/web/src/components/bot/detail.tsx @@ -30,7 +30,7 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { activityTone, foldActivity } from "@/components/activity-dot"; -import type { SessionActivity } from "@lightspeed-ai/agent-client"; +import type { SessionActivity } from "@lightspeed-ai/sdk"; import { cn } from "@/lib/utils"; import { useActionPermissions } from "@/lib/permissions"; import { BotActivity } from "./activity"; diff --git a/platform/web/src/components/bot/status.tsx b/platform/web/src/components/bot/status.tsx index 624eb5369..9c5796e2b 100644 --- a/platform/web/src/components/bot/status.tsx +++ b/platform/web/src/components/bot/status.tsx @@ -1,6 +1,6 @@ import type { ReactNode } from "react"; import { Badge } from "@/components/ui/badge"; -import type { SessionActivity } from "@lightspeed-ai/agent-client"; +import type { SessionActivity } from "@lightspeed-ai/sdk"; import type { BotControllerSnapshot, BotControllerStatus, BotView } from "@/api"; import { cn } from "@/lib/utils"; diff --git a/platform/web/src/components/environment/idle-policy-fields.tsx b/platform/web/src/components/environment/idle-policy-fields.tsx index 24cb89daa..43f188c22 100644 --- a/platform/web/src/components/environment/idle-policy-fields.tsx +++ b/platform/web/src/components/environment/idle-policy-fields.tsx @@ -1,4 +1,4 @@ -import type { EnvironmentIdlePolicyView } from "@lightspeed-ai/agent-client"; +import type { EnvironmentIdlePolicyView } from "@lightspeed-ai/sdk"; import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/input"; diff --git a/platform/web/src/components/feature-gate.tsx b/platform/web/src/components/feature-gate.tsx index 99581b281..475f3cdc9 100644 --- a/platform/web/src/components/feature-gate.tsx +++ b/platform/web/src/components/feature-gate.tsx @@ -1,7 +1,7 @@ import type { ReactNode } from "react"; import { Link } from "react-router-dom"; import { PowerOff } from "lucide-react"; -import { FEATURES, type FeatureKey } from "@lightspeed/platform-shared"; +import { FEATURES, type FeatureKey } from "@lightspeed-ai/platform-shared"; import { EmptyState } from "@/components/page"; import { useActionPermissions } from "@/lib/permissions"; import { useActiveUniverse, useFeature } from "@/lib/universes"; diff --git a/platform/web/src/components/models/model-defaults.tsx b/platform/web/src/components/models/model-defaults.tsx index 53a95bea8..2c3ac36ec 100644 --- a/platform/web/src/components/models/model-defaults.tsx +++ b/platform/web/src/components/models/model-defaults.tsx @@ -1,6 +1,6 @@ import { useId, useState } from "react"; import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { AGENT_MODEL_API_KINDS, modelDefaultsPutSchema } from "@lightspeed/platform-shared"; +import { AGENT_MODEL_API_KINDS, modelDefaultsPutSchema } from "@lightspeed-ai/platform-shared"; import { api, ApiError, type ModelConfig, type ModelDefaults, type ModelDefaultsPutParams } from "@/api"; import { modelDefaultsKey, modelLabel, useModelDefaults, useModelDiscovery } from "@/lib/model-defaults"; import { summarizeProviderReadiness } from "@/lib/provider-readiness"; diff --git a/platform/web/src/components/session/composer-voice.tsx b/platform/web/src/components/session/composer-voice.tsx index 36ac3ee41..fd640a67e 100644 --- a/platform/web/src/components/session/composer-voice.tsx +++ b/platform/web/src/components/session/composer-voice.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef } from "react"; import { Link } from "react-router-dom"; import { LoaderCircle, Mic, MicOff, RotateCw, Square, X } from "lucide-react"; -import { MAX_DICTATION_SECONDS } from "@lightspeed/platform-shared"; +import { MAX_DICTATION_SECONDS } from "@lightspeed-ai/platform-shared"; import type { useDictation } from "@/lib/use-dictation"; import { Button } from "@/components/ui/button"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; diff --git a/platform/web/src/components/session/composer.dictation.test.tsx b/platform/web/src/components/session/composer.dictation.test.tsx index 39fbed97d..fdf20cc4a 100644 --- a/platform/web/src/components/session/composer.dictation.test.tsx +++ b/platform/web/src/components/session/composer.dictation.test.tsx @@ -1,7 +1,7 @@ // @vitest-environment jsdom import { act, type ComponentProps } from "react"; import { createRoot, type Root } from "react-dom/client"; -import { afterEach, beforeEach, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, expect, it, vi, type Mock } from "vitest"; import { waitForUi } from "@/test/wait-for-ui"; import { SessionComposer } from "./composer"; @@ -15,8 +15,8 @@ let container: HTMLDivElement; let finish: (text: string) => void; let failTranscription: (error: Error) => void; let finishUpload: (result: unknown) => void; -let stop: ReturnType; -let onSend: ReturnType; +let stop: Mock<() => void>; +let onSend: Mock["onSend"]>; beforeEach(() => { vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true); vi.clearAllMocks(); diff --git a/platform/web/src/components/session/composer.test.tsx b/platform/web/src/components/session/composer.test.tsx index 00eb72b62..c09a930d8 100644 --- a/platform/web/src/components/session/composer.test.tsx +++ b/platform/web/src/components/session/composer.test.tsx @@ -98,7 +98,7 @@ it("uploads attachments on pick and sends them with the message", async () => { await act(async () => button("Send message").click()); expect(onSend).toHaveBeenCalledWith({ text: "Change direction", - attachments: [{ blobRef: `sha256:${"a".repeat(64)}`, mime: "image/png", kind: "image", name: "screen.png", size: 3 }], + attachments: [{ blobRef: `sha256:${"a".repeat(64)}`, mime: "image/png", kind: "image", name: "screen.png", size: 3, previewUrl: expect.stringMatching(/^blob:/) }], }, null); expect(container.querySelector('[aria-label="Attachments"]')).toBeNull(); }); diff --git a/platform/web/src/components/session/composer.tsx b/platform/web/src/components/session/composer.tsx index 6bef8e6b7..28b545d5a 100644 --- a/platform/web/src/components/session/composer.tsx +++ b/platform/web/src/components/session/composer.tsx @@ -1,6 +1,6 @@ import { useEffect, useRef, useState, type DragEvent, type KeyboardEvent, type ReactNode } from "react"; import { ArrowUp, ChevronDown, CornerDownRight, ListPlus, LoaderCircle, Lock, Plus, Square, TriangleAlert, X } from "lucide-react"; -import { ATTACHMENT_ACCEPT, ATTACHMENT_SUMMARY, type MessageRunOptions } from "@lightspeed/platform-shared"; +import { ATTACHMENT_ACCEPT, ATTACHMENT_SUMMARY, type MessageRunOptions } from "@lightspeed-ai/platform-shared"; import type { ModelOption } from "@/api"; import { useDictation } from "@/lib/use-dictation"; import { isDemoDictation } from "@/lib/audio-capture"; diff --git a/platform/web/src/components/session/reply-copy.test.ts b/platform/web/src/components/session/reply-copy.test.ts index 47a61fd03..d09335081 100644 --- a/platform/web/src/components/session/reply-copy.test.ts +++ b/platform/web/src/components/session/reply-copy.test.ts @@ -1,5 +1,7 @@ // @vitest-environment jsdom import { expect, it } from "vitest"; +import { unified } from "unified"; +import remarkParse from "remark-parse"; import { replyFormatted, replyMarkdown } from "./reply-copy"; function content(html: string) { @@ -18,7 +20,12 @@ it("copies inline and reference-style attachments as stable viewer links, leavin const body = content('ReportPhoto'); const copied = replyMarkdown(text, body); const report = new URL("/blobs/report?workspace=w&path=a.md", window.location.href).href; - expect(copied).toContain(`[**Report**](${report})`); + expect(unified().use(remarkParse).parse(copied).children[0]).toMatchObject({ + type: "paragraph", + children: [{ type: "link", url: report, children: [ + { type: "strong", children: [{ type: "text", value: "Report" }] }, + ] }], + }); expect(copied).toContain(`[Photo](${new URL("/blobs/photo", window.location.href).href})`); expect(copied).toContain(`[ref]: ${report} "Report"`); expect(copied).toContain("`[Report](file:report)`"); diff --git a/platform/web/src/components/session/session-config-editor.tsx b/platform/web/src/components/session/session-config-editor.tsx index aeddb8854..a30b03a4a 100644 --- a/platform/web/src/components/session/session-config-editor.tsx +++ b/platform/web/src/components/session/session-config-editor.tsx @@ -1,4 +1,4 @@ -import { AGENT_MODEL_API_KINDS } from "@lightspeed/platform-shared"; +import { AGENT_MODEL_API_KINDS } from "@lightspeed-ai/platform-shared"; import { useEffect, useId, useState, type ReactNode } from "react"; import type { WorkspaceAttachmentDraft } from "@/api"; import { diff --git a/platform/web/src/components/session/sharing.tsx b/platform/web/src/components/session/sharing.tsx index eedde6c39..848e12956 100644 --- a/platform/web/src/components/session/sharing.tsx +++ b/platform/web/src/components/session/sharing.tsx @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; import { LockKeyhole, Users } from "lucide-react"; -import type { ResourceAccessSummary } from "@lightspeed-ai/agent-client"; +import type { ResourceAccessSummary } from "@lightspeed-ai/sdk"; import { api } from "@/api"; import { AlertDialog, diff --git a/platform/web/src/components/session/transcript-view.tsx b/platform/web/src/components/session/transcript-view.tsx index 890874ed0..6c9286c4a 100644 --- a/platform/web/src/components/session/transcript-view.tsx +++ b/platform/web/src/components/session/transcript-view.tsx @@ -1,6 +1,6 @@ import { useContext, useId, useLayoutEffect, useRef, useState } from "react"; import { ChevronDown, ChevronUp, Check, Inbox, Loader2, ShieldQuestion, TriangleAlert, X } from "lucide-react"; -import type { PendingApprovalView } from "@lightspeed-ai/agent-client"; +import type { PendingApprovalView } from "@lightspeed-ai/sdk"; import { BotIcon } from "@/components/icons/bot"; import { Bubble, BubbleContent } from "@/components/ui/bubble"; import { Button } from "@/components/ui/button"; diff --git a/platform/web/src/components/session/user-band.test.tsx b/platform/web/src/components/session/user-band.test.tsx index b2333fb89..80784ce53 100644 --- a/platform/web/src/components/session/user-band.test.tsx +++ b/platform/web/src/components/session/user-band.test.tsx @@ -44,6 +44,8 @@ it.each([ }); it.each(["user:operator", "event"])("collapses and expands overflowing messages from %s", async (origin) => { + // jsdom does not retain gradient stops containing calc() in its CSSOM. + const maskImage = vi.spyOn(CSSStyleProperties.prototype, "maskImage", "set"); height = 700; const text = "Long input\n".repeat(50) + "Last line"; await act(async () => root.render()); @@ -52,13 +54,13 @@ it.each(["user:operator", "event"])("collapses and expands overflowing messages expect(button.textContent).toBe("Show more"); expect(button.getAttribute("aria-expanded")).toBe("false"); expect(content.style.maxHeight).toBe("160px"); - expect(content.style.maskImage).toContain("linear-gradient"); + expect(maskImage).toHaveBeenLastCalledWith("linear-gradient(to bottom, black calc(100% - 48px), transparent)"); expect(content.textContent).toContain("Last line"); await act(async () => button.click()); expect(button.textContent).toBe("Show less"); expect(button.getAttribute("aria-expanded")).toBe("true"); expect(content.style.maxHeight).toBe(""); - expect(content.style.maskImage).toBe(""); + expect(maskImage).toHaveBeenLastCalledWith(""); await act(async () => button.click()); expect(content.style.maxHeight).toBe("160px"); }); diff --git a/platform/web/src/components/universe-appearance-card.test.tsx b/platform/web/src/components/universe-appearance-card.test.tsx index e1a0b9a12..7596a253d 100644 --- a/platform/web/src/components/universe-appearance-card.test.tsx +++ b/platform/web/src/components/universe-appearance-card.test.tsx @@ -5,7 +5,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { MemoryRouter } from "react-router-dom"; import { afterEach, beforeEach, expect, it, vi } from "vitest"; import type { Universe } from "@/api"; -import { UNIVERSE_ICONS } from "@lightspeed/platform-shared"; +import { UNIVERSE_ICONS } from "@lightspeed-ai/platform-shared"; import { PermissionIdentityProvider } from "@/lib/permissions"; import { GeneralSettingsPage } from "@/pages/GeneralSettingsPage"; import { UniverseAppearanceCard } from "./universe-appearance-card"; diff --git a/platform/web/src/components/universe-appearance-card.tsx b/platform/web/src/components/universe-appearance-card.tsx index 680559c58..752df8be0 100644 --- a/platform/web/src/components/universe-appearance-card.tsx +++ b/platform/web/src/components/universe-appearance-card.tsx @@ -1,6 +1,6 @@ import { useState, type FormEvent } from "react"; import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { UNIVERSE_ICONS, UNIVERSE_ICON_COLORS, type UniverseIconName, type UniverseIconColor } from "@lightspeed/platform-shared"; +import { UNIVERSE_ICONS, UNIVERSE_ICON_COLORS, type UniverseIconName, type UniverseIconColor } from "@lightspeed-ai/platform-shared"; import { api, type Universe } from "@/api"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; diff --git a/platform/web/src/components/universe-icon.tsx b/platform/web/src/components/universe-icon.tsx index f8df3429d..c2af7a32b 100644 --- a/platform/web/src/components/universe-icon.tsx +++ b/platform/web/src/components/universe-icon.tsx @@ -3,7 +3,7 @@ import { Mountain, Leaf, Flame, Heart, Code, Briefcase, House, Music, Shield, Bot, type LucideIcon, Anchor, Book, Camera, Coffee, Crown, Gem, Palette, Puzzle, Telescope, Cpu, } from "lucide-react"; -import type { UniverseIconName, UniverseIconColor } from "@lightspeed/platform-shared"; +import type { UniverseIconName, UniverseIconColor } from "@lightspeed-ai/platform-shared"; import { cn } from "@/lib/utils"; import { UNIVERSE_ICON_BACKGROUNDS } from "@/lib/identity-colors"; diff --git a/platform/web/src/components/universe-nav.tsx b/platform/web/src/components/universe-nav.tsx index da9f73b1e..da257ede9 100644 --- a/platform/web/src/components/universe-nav.tsx +++ b/platform/web/src/components/universe-nav.tsx @@ -14,7 +14,7 @@ import { Users, } from "lucide-react"; import { Navigate } from "react-router-dom"; -import type { FeatureKey, FeatureStates } from "@lightspeed/platform-shared"; +import type { FeatureKey, FeatureStates } from "@lightspeed-ai/platform-shared"; import { BotFaceIcon } from "@/components/icons/bot"; import { useActionPermissions, type PermissionAction } from "@/lib/permissions"; import { universeHome, useActiveUniverse } from "@/lib/universes"; diff --git a/platform/web/src/components/universe-switcher.tsx b/platform/web/src/components/universe-switcher.tsx index b6683f1e5..596fee61c 100644 --- a/platform/web/src/components/universe-switcher.tsx +++ b/platform/web/src/components/universe-switcher.tsx @@ -1,4 +1,4 @@ -import { slugify, universeSlugSchema } from "@lightspeed/platform-shared"; +import { slugify, universeSlugSchema } from "@lightspeed-ai/platform-shared"; import { useState, type FormEvent } from "react"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useNavigate } from "react-router-dom"; diff --git a/platform/web/src/components/workspace-transfers.tsx b/platform/web/src/components/workspace-transfers.tsx index af137c939..25396aa72 100644 --- a/platform/web/src/components/workspace-transfers.tsx +++ b/platform/web/src/components/workspace-transfers.tsx @@ -24,7 +24,7 @@ import { workspaceUploadConflicts, renameWorkspaceEntry, workspaceRenameSchema, -} from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/platform-shared"; import { api, ApiError, type WorkspaceTree, type WorkspaceRow } from "@/api"; import { useActionPermissions } from "@/lib/permissions"; import { diff --git a/platform/web/src/demo/compaction.test.ts b/platform/web/src/demo/compaction.test.ts index 383c40aeb..ccd275997 100644 --- a/platform/web/src/demo/compaction.test.ts +++ b/platform/web/src/demo/compaction.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import type { ContextEntryView, SessionEventView } from "@lightspeed-ai/agent-client"; +import type { ContextEntryView, SessionEventView } from "@lightspeed-ai/sdk"; import { applyEvents, emptyTranscript } from "@/lib/sessions/transcript"; import { createDemoStore } from "./fixtures"; import { SOFTWARE_FACTORY_UNIVERSE_ID } from "./fixtures/software-factory"; diff --git a/platform/web/src/demo/engine.ts b/platform/web/src/demo/engine.ts index 59421a06c..7b7d6f531 100644 --- a/platform/web/src/demo/engine.ts +++ b/platform/web/src/demo/engine.ts @@ -1,5 +1,5 @@ /// Engine simulation: sessions, runs, and the event log the transcript -/// tail reads. Shapes follow the generated `@lightspeed-ai/agent-client` +/// tail reads. Shapes follow the generated `@lightspeed-ai/sdk` /// contract so the real transcript reducer renders them unchanged. import type { ContextEntryView, @@ -16,8 +16,8 @@ import type { SessionEventView, SessionEventsReadResponse, ToolCallEventView, -} from "@lightspeed-ai/agent-client"; -import type { MessageAttachment } from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/sdk"; +import type { MessageAttachment } from "@lightspeed-ai/platform-shared"; import type { SessionManagement, SessionOrigin, SessionView } from "@/api"; import type { DemoResponder, diff --git a/platform/web/src/demo/fixtures/builders.ts b/platform/web/src/demo/fixtures/builders.ts index 13ad65295..a1d489d2e 100644 --- a/platform/web/src/demo/fixtures/builders.ts +++ b/platform/web/src/demo/fixtures/builders.ts @@ -47,10 +47,10 @@ import type { ToolCallDisplayView, WebhookPreset, WebhookVerification, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { DEFAULT_MODEL, newSession } from "../engine"; import type { DemoStore, DemoToolCall, SessionRecord, UniverseState } from "../store"; -import type { UniverseRole } from "@lightspeed/platform-shared"; +import type { UniverseRole } from "@lightspeed-ai/platform-shared"; import { INCUS_PROVIDER_ID } from "./platform"; // --------------------------------------------------------------------------- diff --git a/platform/web/src/demo/fixtures/personal-assistant.ts b/platform/web/src/demo/fixtures/personal-assistant.ts index 68ddfabf0..1a2485a26 100644 --- a/platform/web/src/demo/fixtures/personal-assistant.ts +++ b/platform/web/src/demo/fixtures/personal-assistant.ts @@ -7,7 +7,7 @@ /// takes the Monday numbers from a metrics bot — the personal-agent pattern /// built from bots, triggers, workspaces, skills, and one Mac mini at home. import type { Environment, SecretGrant, UniverseSetup } from "@/api"; -import type { SessionSummaryView } from "@lightspeed-ai/agent-client"; +import type { SessionSummaryView } from "@lightspeed-ai/sdk"; import { appendExchange, appendScriptedRun, closeSession, newSession, refreshDemoCompactionView } from "../engine"; import { universeApiKey, type DemoResponder, type DemoStore, type DemoToolCall, type DemoTurn, type SessionRecord, type UniverseState } from "../store"; import { diff --git a/platform/web/src/demo/fixtures/software-factory.ts b/platform/web/src/demo/fixtures/software-factory.ts index 2ef6fa9d6..d52a08cbd 100644 --- a/platform/web/src/demo/fixtures/software-factory.ts +++ b/platform/web/src/demo/fixtures/software-factory.ts @@ -7,7 +7,7 @@ /// release-scribe drafts the changelog. Everything the universe pages show /// is seeded here, with timestamps hung off boot time. import type { Environment, GitHubApp, SecretGrant, SessionOrigin, UniverseSetup } from "@/api"; -import type { BotEventOutcome, ModelConfig, SessionSummaryView } from "@lightspeed-ai/agent-client"; +import type { BotEventOutcome, ModelConfig, SessionSummaryView } from "@lightspeed-ai/sdk"; import { groupsFor } from "@/lib/method-groups"; import { appendExchange, appendScriptedRun, closeSession, newSession, refreshDemoCompactionView } from "../engine"; import { universeApiKey, type DemoResponder, type DemoStore, type DemoToolCall, type DemoTurn, type SessionRecord, type UniverseState } from "../store"; diff --git a/platform/web/src/demo/router.ts b/platform/web/src/demo/router.ts index 1ad4dd2fb..ec9545e82 100644 --- a/platform/web/src/demo/router.ts +++ b/platform/web/src/demo/router.ts @@ -1,4 +1,4 @@ -/// The in-browser stand-in for the platform server: one Hono app the fetch +/// The in-browser stand-in for the platform backend: one Hono app the fetch /// shim hands every same-origin `/api/*` request to. import { Hono } from "hono"; import type { DemoStore } from "./store"; diff --git a/platform/web/src/demo/routes/admin.ts b/platform/web/src/demo/routes/admin.ts index f21239ea6..2879e04b5 100644 --- a/platform/web/src/demo/routes/admin.ts +++ b/platform/web/src/demo/routes/admin.ts @@ -8,7 +8,7 @@ import type { DeploymentChannelAccountView, DeploymentEnvironmentProviderView, MethodGroup, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { groupsFor } from "@/lib/method-groups"; import type { DemoStore, UniverseState } from "../store"; import { badRequest, conflict, notFound, readBody } from "./common"; diff --git a/platform/web/src/demo/routes/bots.ts b/platform/web/src/demo/routes/bots.ts index 6c8532a15..8abbfb609 100644 --- a/platform/web/src/demo/routes/bots.ts +++ b/platform/web/src/demo/routes/bots.ts @@ -1,6 +1,6 @@ /// Bots: durable event routers over managed sessions, with a small in-page /// controller standing in for the Temporal one. The routes mirror the -/// platform server's passthroughs to the core `bots/*` API: the +/// platform backend's passthroughs to the core `bots/*` API: the /// same paths, envelopes, and status codes, over the core wire shapes. /// Every event — manual, webhook, replay, fixture — goes through /// `admitBotEvent`: numbered, routed by its trigger's policy to one of the @@ -24,7 +24,7 @@ import type { RunView, SessionSummaryView, WebhookPreset, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import type { ProfileDocument } from "@/api"; import { EVENT_ORIGIN, diff --git a/platform/web/src/demo/routes/channels.ts b/platform/web/src/demo/routes/channels.ts index b28d0a54a..dfb317dfe 100644 --- a/platform/web/src/demo/routes/channels.ts +++ b/platform/web/src/demo/routes/channels.ts @@ -7,7 +7,7 @@ import { Hono } from "hono"; import type { ChannelAccountView, ChannelPairingView, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { connectorAccountHealth, type ChannelConnectorHealth, type ChannelConnectorStatus } from "@/api"; import type { DemoStore, UniverseState } from "../store"; import { badRequest, conflict, notFound, readBody, universeFor } from "./common"; diff --git a/platform/web/src/demo/routes/platform.ts b/platform/web/src/demo/routes/platform.ts index 2d71f45e7..bf7f9716b 100644 --- a/platform/web/src/demo/routes/platform.ts +++ b/platform/web/src/demo/routes/platform.ts @@ -2,8 +2,8 @@ /// universe API keys. The demo user is a platform admin, so every gate the /// real server applies passes. import { Hono } from "hono"; -import { effectiveFeatures, featureOverridesSchema, memberUpdateSchema, mergeFeatureOverrides, slugify, universeRoleSchema, universeSlugSchema, universeUpdateSchema } from "@lightspeed/platform-shared"; -import type { MethodGroup } from "@lightspeed-ai/agent-client"; +import { effectiveFeatures, featureOverridesSchema, memberUpdateSchema, mergeFeatureOverrides, slugify, universeRoleSchema, universeSlugSchema, universeUpdateSchema } from "@lightspeed-ai/platform-shared"; +import type { MethodGroup } from "@lightspeed-ai/sdk"; import type { EngineUniverse, Member, Universe } from "@/api"; import { universeApiKey, type DemoStore, type UniverseState } from "../store"; import { conflict, badRequest, notFound, nowIso, readBody, universeFor } from "./common"; diff --git a/platform/web/src/demo/routes/secrets.ts b/platform/web/src/demo/routes/secrets.ts index 2d7317cd0..d399c7911 100644 --- a/platform/web/src/demo/routes/secrets.ts +++ b/platform/web/src/demo/routes/secrets.ts @@ -3,7 +3,7 @@ /// installation. Secret values are accepted and dropped; only the non-secret /// views the real gateway returns are kept. import { Hono } from "hono"; -import { modelDefaultsPutSchema } from "@lightspeed/platform-shared"; +import { modelDefaultsPutSchema } from "@lightspeed-ai/platform-shared"; import type { GitHubApp, GitHubInstallation, @@ -16,7 +16,7 @@ import type { SecretProvider, UniverseSetup, } from "@/api"; -import type { MethodGroup } from "@lightspeed-ai/agent-client"; +import type { MethodGroup } from "@lightspeed-ai/sdk"; import { base64ToText, universeApiKey, type DemoStore, type UniverseState } from "../store"; import { badRequest, conflict, notFound, readBody, universeFor } from "./common"; diff --git a/platform/web/src/demo/routes/sessions.ts b/platform/web/src/demo/routes/sessions.ts index 34e776620..18e5b1716 100644 --- a/platform/web/src/demo/routes/sessions.ts +++ b/platform/web/src/demo/routes/sessions.ts @@ -2,7 +2,7 @@ import { defaultEnvironmentAttachment, environmentAttachments, isEnvironmentAtta import { modelFromConfig } from "@/lib/model-defaults"; /// Session routes over the engine simulation: the sessions browser, the /// transcript's long-poll tail, run control, and the settings sheet. Shapes -/// and status codes follow the platform server's gateway so the UI cannot +/// and status codes follow the platform backend's gateway so the UI cannot /// tell the difference. import { Hono, type Context } from "hono"; import { @@ -12,9 +12,9 @@ import { sessionMessageSchema, sessionSteerSchema, type MessageAttachment, -} from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/platform-shared"; import type { Environment, ModelConfig, ProfileSessionRetention, ProfileSource, SessionView } from "@/api"; -import type { ProfileInstructions } from "@lightspeed-ai/agent-client"; +import type { ProfileInstructions } from "@lightspeed-ai/sdk"; import { refreshDemoCompactionView, PROFILE_INSTRUCTIONS_KEY, diff --git a/platform/web/src/demo/routes/transcriptions.ts b/platform/web/src/demo/routes/transcriptions.ts index 28051dd8d..01cbd199c 100644 --- a/platform/web/src/demo/routes/transcriptions.ts +++ b/platform/web/src/demo/routes/transcriptions.ts @@ -1,6 +1,6 @@ import { Hono } from "hono"; -import type { TranscriptionView } from "@lightspeed-ai/agent-client"; -import { MAX_DICTATION_AUDIO_BYTES, roleAtLeast, transcriptionStartSchema, transcriptionUploadSchema } from "@lightspeed/platform-shared"; +import type { TranscriptionView } from "@lightspeed-ai/sdk"; +import { MAX_DICTATION_AUDIO_BYTES, roleAtLeast, transcriptionStartSchema, transcriptionUploadSchema } from "@lightspeed-ai/platform-shared"; import type { DemoStore } from "../store"; import { badRequest, conflict, notFound, readBody, universeFor } from "./common"; diff --git a/platform/web/src/demo/routes/workspaces.ts b/platform/web/src/demo/routes/workspaces.ts index 66aa07149..23c1c9ba3 100644 --- a/platform/web/src/demo/routes/workspaces.ts +++ b/platform/web/src/demo/routes/workspaces.ts @@ -5,8 +5,8 @@ /// bump on the workspace row; the head manifest lives on the record. import { Hono } from "hono"; import { bodyLimit } from "hono/body-limit"; -import { MAX_WORKSPACE_UPLOAD_BODY_BYTES, workspaceUploadSchema, prepareWorkspaceUpload, workspaceDownload, WorkspaceTransferError, workspaceEntryDeleteSchema, removeWorkspaceEntry } from "@lightspeed/platform-shared"; -import { workspaceEntryRenameSchema, renameWorkspaceEntry, workspaceRenameSchema } from "@lightspeed/platform-shared"; +import { MAX_WORKSPACE_UPLOAD_BODY_BYTES, workspaceUploadSchema, prepareWorkspaceUpload, workspaceDownload, WorkspaceTransferError, workspaceEntryDeleteSchema, removeWorkspaceEntry } from "@lightspeed-ai/platform-shared"; +import { workspaceEntryRenameSchema, renameWorkspaceEntry, workspaceRenameSchema } from "@lightspeed-ai/platform-shared"; import type { VfsDirEntry, VfsFileEntry, VfsTreeEntry, WorkspaceRow, WorkspaceTree } from "@/api"; import { base64ToBytes, type DemoStore, type WorkspaceRecord } from "../store"; import { badRequest, conflict, notFound, readBody, universeFor } from "./common"; @@ -297,7 +297,7 @@ export function workspaceRoutes(store: DemoStore): Hono { } // --------------------------------------------------------------------------- -// Manifest surgery (port of platform/server/src/vfs.ts) +// Manifest surgery (port of platform/backend/src/vfs.ts) // --------------------------------------------------------------------------- export function emptyManifest(): Manifest { diff --git a/platform/web/src/demo/store.ts b/platform/web/src/demo/store.ts index 4f62df132..74e15e7ab 100644 --- a/platform/web/src/demo/store.ts +++ b/platform/web/src/demo/store.ts @@ -1,6 +1,6 @@ /// In-memory state behind the browser demo. Fixtures fill it at boot, the /// stub routes read and mutate it, and nothing survives a reload. -import { effectiveFeatures, type FeatureOverrides, type MessageAttachment, type UniverseRole, type UniverseIconName, type UniverseIconColor } from "@lightspeed/platform-shared"; +import { effectiveFeatures, type FeatureOverrides, type MessageAttachment, type UniverseRole, type UniverseIconName, type UniverseIconColor } from "@lightspeed-ai/platform-shared"; import type { BlobContent, ChannelsStatus, @@ -40,7 +40,7 @@ import type { SessionEventView, SessionSummaryView, ToolCallDisplayView, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; /// better-auth user shape as the client sees it (`admin` plugin fields /// included); everything the demo user is. diff --git a/platform/web/src/demo/transcriptions.test.ts b/platform/web/src/demo/transcriptions.test.ts index 9a6f24c63..2943881fe 100644 --- a/platform/web/src/demo/transcriptions.test.ts +++ b/platform/web/src/demo/transcriptions.test.ts @@ -1,7 +1,7 @@ import { afterEach, expect, it, vi } from "vitest"; import { createDemoStore } from "./fixtures"; import { createDemoRouter } from "./router"; -import type { TranscriptionView } from "@lightspeed-ai/agent-client"; +import type { TranscriptionView } from "@lightspeed-ai/sdk"; function boot() { const store = createDemoStore(); const app = createDemoRouter(store); diff --git a/platform/web/src/lib/audio-capture.ts b/platform/web/src/lib/audio-capture.ts index 1f621b5d9..137db7284 100644 --- a/platform/web/src/lib/audio-capture.ts +++ b/platform/web/src/lib/audio-capture.ts @@ -1,4 +1,4 @@ -import { MAX_DICTATION_AUDIO_BYTES } from "@lightspeed/platform-shared"; +import { MAX_DICTATION_AUDIO_BYTES } from "@lightspeed-ai/platform-shared"; export interface AudioCapture { result: Promise; diff --git a/platform/web/src/lib/composer-attachments.ts b/platform/web/src/lib/composer-attachments.ts index dcf4d1c95..5e59e29b0 100644 --- a/platform/web/src/lib/composer-attachments.ts +++ b/platform/web/src/lib/composer-attachments.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useRef, useState } from "react"; -import type { BlobPutResponse } from "@lightspeed-ai/agent-client"; +import type { BlobPutResponse } from "@lightspeed-ai/sdk"; import { ATTACHMENT_SUMMARY, MAX_MESSAGE_ATTACHMENTS, @@ -7,7 +7,7 @@ import { attachmentType, type AttachmentKind, type MessageAttachment, -} from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/platform-shared"; import { api } from "@/api"; import { blobBase64 } from "@/lib/blob-base64"; diff --git a/platform/web/src/lib/composer-model.ts b/platform/web/src/lib/composer-model.ts index 887704b41..405fa0759 100644 --- a/platform/web/src/lib/composer-model.ts +++ b/platform/web/src/lib/composer-model.ts @@ -1,4 +1,4 @@ -import { reasoningEffortTiers, type MessageRunOptions } from "@lightspeed/platform-shared"; +import { reasoningEffortTiers, type MessageRunOptions } from "@lightspeed-ai/platform-shared"; import type { ModelConfig, ModelOption } from "@/api"; import { modelFromConfig } from "@/lib/model-defaults"; diff --git a/platform/web/src/lib/dictation.ts b/platform/web/src/lib/dictation.ts index 1ea5dcc64..3658fc431 100644 --- a/platform/web/src/lib/dictation.ts +++ b/platform/web/src/lib/dictation.ts @@ -1,5 +1,5 @@ -import type { BlobPutResponse, TranscriptionView } from "@lightspeed-ai/agent-client"; -import { MAX_DICTATION_AUDIO_BYTES } from "@lightspeed/platform-shared"; +import type { BlobPutResponse, TranscriptionView } from "@lightspeed-ai/sdk"; +import { MAX_DICTATION_AUDIO_BYTES } from "@lightspeed-ai/platform-shared"; import { api } from "@/api"; import { blobBase64 } from "@/lib/blob-base64"; diff --git a/platform/web/src/lib/file-references.ts b/platform/web/src/lib/file-references.ts index b89eb4ea0..3b864fe33 100644 --- a/platform/web/src/lib/file-references.ts +++ b/platform/web/src/lib/file-references.ts @@ -1,4 +1,4 @@ -import { validWorkspaceTransferPath } from "@lightspeed/platform-shared"; +import { validWorkspaceTransferPath } from "@lightspeed-ai/platform-shared"; import { blobDigest } from "./blob-view"; import type { SessionEventsPage, ToolAttachmentView } from "@/api"; import type { TranscriptEntry } from "./sessions/transcript"; diff --git a/platform/web/src/lib/identity-colors.ts b/platform/web/src/lib/identity-colors.ts index 5cc4507c9..dc73263c6 100644 --- a/platform/web/src/lib/identity-colors.ts +++ b/platform/web/src/lib/identity-colors.ts @@ -1,4 +1,4 @@ -import type { UniverseIconColor } from "@lightspeed/platform-shared"; +import type { UniverseIconColor } from "@lightspeed-ai/platform-shared"; /// Shared lightness and saturation keep identity badges visually consistent. export function identityColor(hue: number, chroma = 0.11): string { diff --git a/platform/web/src/lib/method-groups.ts b/platform/web/src/lib/method-groups.ts index 9d61543ed..f91c78c80 100644 --- a/platform/web/src/lib/method-groups.ts +++ b/platform/web/src/lib/method-groups.ts @@ -1,4 +1,4 @@ -import type { MethodGroup } from "@lightspeed-ai/agent-client"; +import type { MethodGroup } from "@lightspeed-ai/sdk"; /** * What each core method group lets a key call. Deployment groups address the diff --git a/platform/web/src/lib/permissions.test.tsx b/platform/web/src/lib/permissions.test.tsx index 95e837ba1..54a36b489 100644 --- a/platform/web/src/lib/permissions.test.tsx +++ b/platform/web/src/lib/permissions.test.tsx @@ -4,7 +4,7 @@ import { createRoot, type Root } from "react-dom/client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { MemoryRouter } from "react-router-dom"; import { afterEach, beforeEach, expect, it, vi } from "vitest"; -import { UNIVERSE_ROLES } from "@lightspeed/platform-shared"; +import { UNIVERSE_ROLES } from "@lightspeed-ai/platform-shared"; import { allowsAction, PermissionIdentityProvider, useActionPermissions, type PermissionAction } from "./permissions"; const mocks = vi.hoisted(() => ({ api: vi.fn() })); diff --git a/platform/web/src/lib/permissions.tsx b/platform/web/src/lib/permissions.tsx index addff1282..527c6bb5e 100644 --- a/platform/web/src/lib/permissions.tsx +++ b/platform/web/src/lib/permissions.tsx @@ -1,6 +1,6 @@ import { createContext, useContext, type ReactNode } from "react"; -import type { UniverseAction } from "@lightspeed-ai/agent-client"; -import { roleAtLeast, universeRoleSchema, type UniverseRole } from "@lightspeed/platform-shared"; +import type { UniverseAction } from "@lightspeed-ai/sdk"; +import { roleAtLeast, universeRoleSchema, type UniverseRole } from "@lightspeed-ai/platform-shared"; import { useActiveUniverse } from "@/lib/universes"; type Identity = { userId: string; platformAdmin: boolean }; diff --git a/platform/web/src/lib/profile-config-reference.ts b/platform/web/src/lib/profile-config-reference.ts index e8d110617..28f34ac97 100644 --- a/platform/web/src/lib/profile-config-reference.ts +++ b/platform/web/src/lib/profile-config-reference.ts @@ -2,11 +2,11 @@ /// Source: crates/api/contract/api.schema.json (SessionConfig). /// Regenerate with: node platform/scripts/generate-config-reference.mjs -export const PROFILE_CONFIG_REFERENCE = `// Every field is optional — omit anything to keep engine defaults. +export const PROFILE_CONFIG_REFERENCE = `// Every field is optional — omit anything to keep harness defaults. // Union values are written a | b — pick one. { "context": { - // Omitted policies resolve to engine-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery. + // Omitted policies resolve to harness-managed standalone compaction. Disabled permits explicit API compaction but never automatic compaction or context-limit recovery. "compaction": // one of: { "mode": "disabled" } | { "compactThresholdTokens": 0, "mode": "providerTriggered" } | @@ -129,7 +129,7 @@ export const PROFILE_CONFIG_REFERENCE = `// Every field is optional — omit any { "type": "requiredAny" } | { "toolId": "string", "type": "specific" }, }, - // Run budget defaults enforced by the engine drive loop. + // Run budget defaults enforced by the harness drive loop. "limits": { "maxToolRounds": 0, "maxTurns": 0, diff --git a/platform/web/src/lib/provider-readiness.ts b/platform/web/src/lib/provider-readiness.ts index 9f8d8d9b6..137b0b1b1 100644 --- a/platform/web/src/lib/provider-readiness.ts +++ b/platform/web/src/lib/provider-readiness.ts @@ -1,4 +1,4 @@ -import { AGENT_MODEL_API_KINDS } from "@lightspeed/platform-shared"; +import { AGENT_MODEL_API_KINDS } from "@lightspeed-ai/platform-shared"; import type { ModelConfig, ModelProviderDiscovery } from "@/api"; import { useModelDefaults, useModelDiscovery } from "./model-defaults"; diff --git a/platform/web/src/lib/sessions/resource-features.ts b/platform/web/src/lib/sessions/resource-features.ts index eb5a663c6..fa2fdfda0 100644 --- a/platform/web/src/lib/sessions/resource-features.ts +++ b/platform/web/src/lib/sessions/resource-features.ts @@ -1,4 +1,4 @@ -import type { EnvironmentAttachment } from "@lightspeed-ai/agent-client"; +import type { EnvironmentAttachment } from "@lightspeed-ai/sdk"; export type ResourceFeature = "vfs" | "environments" | "mcp"; diff --git a/platform/web/src/lib/sessions/transcript.ts b/platform/web/src/lib/sessions/transcript.ts index 5858a4452..8eb5970ce 100644 --- a/platform/web/src/lib/sessions/transcript.ts +++ b/platform/web/src/lib/sessions/transcript.ts @@ -1,4 +1,4 @@ -import type { LlmUsageView, ToolItemStatus } from "@lightspeed-ai/agent-client"; +import type { LlmUsageView, ToolItemStatus } from "@lightspeed-ai/sdk"; import type { SessionEvent, SessionItem, SessionRunView, ToolCallDisplay, ToolAttachmentView } from "@/api"; /// Folded chat model for a session. The event log is the source of truth; diff --git a/platform/web/src/lib/universes.ts b/platform/web/src/lib/universes.ts index 670eca9ae..d38dc2d2b 100644 --- a/platform/web/src/lib/universes.ts +++ b/platform/web/src/lib/universes.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { useMatch } from "react-router-dom"; -import { FEATURES, type FeatureKey, type FeatureStates } from "@lightspeed/platform-shared"; +import { FEATURES, type FeatureKey, type FeatureStates } from "@lightspeed-ai/platform-shared"; import { api, type Universe } from "@/api"; const LAST_UNIVERSE_KEY = "lightspeed:last-universe"; diff --git a/platform/web/src/lib/use-dictation.ts b/platform/web/src/lib/use-dictation.ts index 132a5b726..02761a49a 100644 --- a/platform/web/src/lib/use-dictation.ts +++ b/platform/web/src/lib/use-dictation.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useRef, useState } from "react"; -import { MAX_DICTATION_SECONDS } from "@lightspeed/platform-shared"; +import { MAX_DICTATION_SECONDS } from "@lightspeed-ai/platform-shared"; import { useModelDefaults, useModelDiscovery } from "./model-defaults"; import { summarizeProviderReadiness } from "./provider-readiness"; import { audioCaptureUnavailableReason, startAudioCapture, type AudioCapture } from "./audio-capture"; diff --git a/platform/web/src/lib/workspace-transfers.ts b/platform/web/src/lib/workspace-transfers.ts index 2dba4a5cd..124ed20db 100644 --- a/platform/web/src/lib/workspace-transfers.ts +++ b/platform/web/src/lib/workspace-transfers.ts @@ -3,7 +3,7 @@ import { MAX_WORKSPACE_UPLOAD_ENTRIES, validWorkspaceTransferPath, type WorkspaceUpload, -} from "@lightspeed/platform-shared"; +} from "@lightspeed-ai/platform-shared"; export type UploadEntry = | { kind: "file"; path: string; file: File } diff --git a/platform/web/src/pages/AdminApiKeysPage.tsx b/platform/web/src/pages/AdminApiKeysPage.tsx index 2c84ab655..0a354cebf 100644 --- a/platform/web/src/pages/AdminApiKeysPage.tsx +++ b/platform/web/src/pages/AdminApiKeysPage.tsx @@ -1,7 +1,7 @@ import { useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { KeyRound, Plus, RotateCw, ShieldOff } from "lucide-react"; -import type { DeploymentApiKeyCreateResponse, DeploymentApiKeyView, MethodGroup } from "@lightspeed-ai/agent-client"; +import type { DeploymentApiKeyCreateResponse, DeploymentApiKeyView, MethodGroup } from "@lightspeed-ai/sdk"; import { api, type Universe } from "@/api"; import { GroupSummary, MethodGroupPicker } from "@/components/api-keys/method-group-picker"; import { RotateKeyDialog } from "@/components/api-keys/rotate-key-dialog"; diff --git a/platform/web/src/pages/AdminEnvironmentProvidersPage.tsx b/platform/web/src/pages/AdminEnvironmentProvidersPage.tsx index ddd1ee0b9..1dcc6e1bb 100644 --- a/platform/web/src/pages/AdminEnvironmentProvidersPage.tsx +++ b/platform/web/src/pages/AdminEnvironmentProvidersPage.tsx @@ -5,7 +5,7 @@ import { Plus, Trash2 } from "lucide-react"; import type { EnvironmentProviderBindingView, DeploymentEnvironmentProviderView, -} from "@lightspeed-ai/agent-client"; +} from "@lightspeed-ai/sdk"; import { api } from "@/api"; import { AlertDialog, diff --git a/platform/web/src/pages/AdminUniversesPage.tsx b/platform/web/src/pages/AdminUniversesPage.tsx index 99ace0f4c..2b0565102 100644 --- a/platform/web/src/pages/AdminUniversesPage.tsx +++ b/platform/web/src/pages/AdminUniversesPage.tsx @@ -1,4 +1,4 @@ -import { universeSlugSchema } from "@lightspeed/platform-shared"; +import { universeSlugSchema } from "@lightspeed-ai/platform-shared"; import { ReadError } from "@/components/read-error"; import { useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; diff --git a/platform/web/src/pages/ApiKeysPage.tsx b/platform/web/src/pages/ApiKeysPage.tsx index 6b8fe4836..b2fe9e532 100644 --- a/platform/web/src/pages/ApiKeysPage.tsx +++ b/platform/web/src/pages/ApiKeysPage.tsx @@ -2,7 +2,7 @@ import { ReadError } from "@/components/read-error"; import { useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { KeyRound, Plus, RotateCw, ShieldOff } from "lucide-react"; -import type { DeploymentApiKeyCreateResponse, DeploymentApiKeyView, MethodGroup } from "@lightspeed-ai/agent-client"; +import type { DeploymentApiKeyCreateResponse, DeploymentApiKeyView, MethodGroup } from "@lightspeed-ai/sdk"; import { GroupSummary, KeyPresetField, MethodGroupPicker } from "@/components/api-keys/method-group-picker"; import { RotateKeyDialog } from "@/components/api-keys/rotate-key-dialog"; import { ApiKeySecret } from "@/components/api-keys/secret-once"; diff --git a/platform/web/src/pages/BlobPage.tsx b/platform/web/src/pages/BlobPage.tsx index 2fbd21317..e37d45d83 100644 --- a/platform/web/src/pages/BlobPage.tsx +++ b/platform/web/src/pages/BlobPage.tsx @@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from "react"; import { Link, useParams, useSearchParams } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { Check, Download, FileQuestion, Link2 } from "lucide-react"; -import { validWorkspaceTransferPath } from "@lightspeed/platform-shared"; +import { validWorkspaceTransferPath } from "@lightspeed-ai/platform-shared"; import { api, type SessionView, type WorkspaceTree, type VfsTreeEntry } from "@/api"; import { LoadingNote, UniverseNotFound } from "@/components/page"; import { ReadError } from "@/components/read-error"; diff --git a/platform/web/src/pages/BotsPage.tsx b/platform/web/src/pages/BotsPage.tsx index efd9a6245..db5092797 100644 --- a/platform/web/src/pages/BotsPage.tsx +++ b/platform/web/src/pages/BotsPage.tsx @@ -1,4 +1,4 @@ -import type { BotReadResponse } from "@lightspeed-ai/agent-client"; +import type { BotReadResponse } from "@lightspeed-ai/sdk"; import { ReadError } from "@/components/read-error"; import { useQuery } from "@tanstack/react-query"; import { Plus } from "lucide-react"; diff --git a/platform/web/src/pages/GeneralSettingsPage.tsx b/platform/web/src/pages/GeneralSettingsPage.tsx index 70b4d15a5..41d7db409 100644 --- a/platform/web/src/pages/GeneralSettingsPage.tsx +++ b/platform/web/src/pages/GeneralSettingsPage.tsx @@ -31,7 +31,7 @@ import { UniverseNotFound, } from "@/components/page"; import { Switch } from "@/components/ui/switch"; -import { universeSlugSchema, FEATURES, FEATURE_KEYS, type FeatureKey } from "@lightspeed/platform-shared"; +import { universeSlugSchema, FEATURES, FEATURE_KEYS, type FeatureKey } from "@lightspeed-ai/platform-shared"; import { useActiveUniverse } from "@/lib/universes"; import { UniverseAppearanceCard } from "@/components/universe-appearance-card"; diff --git a/platform/web/src/pages/McpServersPage.tsx b/platform/web/src/pages/McpServersPage.tsx index 03afd3fc3..dd169f4bc 100644 --- a/platform/web/src/pages/McpServersPage.tsx +++ b/platform/web/src/pages/McpServersPage.tsx @@ -4,7 +4,7 @@ import { McpToolPicker } from "@/components/mcp/tool-picker"; import { useMcpToolDiscoverySource } from "@/lib/mcp/tool-discovery"; import { useEffect, useRef, useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { slugify } from "@lightspeed/platform-shared"; +import { slugify } from "@lightspeed-ai/platform-shared"; import { CheckCircle2, ExternalLink, Loader2, LogIn, Pencil, Plus, RotateCcw, Server, Trash2 } from "lucide-react"; import { api, diff --git a/platform/web/src/pages/MembersPage.tsx b/platform/web/src/pages/MembersPage.tsx index 4c19a2a5f..22e80b203 100644 --- a/platform/web/src/pages/MembersPage.tsx +++ b/platform/web/src/pages/MembersPage.tsx @@ -4,7 +4,7 @@ import { useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Pencil, Plus, Trash2 } from "lucide-react"; import { api, type Member } from "@/api"; -import { UNIVERSE_ROLES, type UniverseRole } from "@lightspeed/platform-shared"; +import { UNIVERSE_ROLES, type UniverseRole } from "@lightspeed-ai/platform-shared"; import { AlertDialog, AlertDialogAction, diff --git a/platform/web/src/pages/ProfilesPage.tsx b/platform/web/src/pages/ProfilesPage.tsx index a20b30d8f..f1fae9cba 100644 --- a/platform/web/src/pages/ProfilesPage.tsx +++ b/platform/web/src/pages/ProfilesPage.tsx @@ -2,7 +2,7 @@ import { ReadError } from "@/components/read-error"; import { useEffect, useMemo, useState, type FormEvent, type ReactNode } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { NavLink, useNavigate, useParams } from "react-router-dom"; -import { slugify } from "@lightspeed/platform-shared"; +import { slugify } from "@lightspeed-ai/platform-shared"; import { ChevronRight, Plus, SlidersHorizontal, Trash2 } from "lucide-react"; import { api, diff --git a/platform/web/src/pages/SetupsPage.tsx b/platform/web/src/pages/SetupsPage.tsx index f4cc3795d..2726a1647 100644 --- a/platform/web/src/pages/SetupsPage.tsx +++ b/platform/web/src/pages/SetupsPage.tsx @@ -3,7 +3,7 @@ import { ReadError } from "@/components/read-error"; import { useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { CheckCircle2, PackageOpen, RefreshCw, Sparkles } from "lucide-react"; -import type { DeploymentApiKeyView, MethodGroup } from "@lightspeed-ai/agent-client"; +import type { DeploymentApiKeyView, MethodGroup } from "@lightspeed-ai/sdk"; import { api, type UniverseSetup } from "@/api"; import { KeyPresetField, MethodGroupPicker } from "@/components/api-keys/method-group-picker"; import { Badge } from "@/components/ui/badge"; diff --git a/platform/web/src/pages/WorkspacesPage.tsx b/platform/web/src/pages/WorkspacesPage.tsx index 7332fb1c7..ee8c679c6 100644 --- a/platform/web/src/pages/WorkspacesPage.tsx +++ b/platform/web/src/pages/WorkspacesPage.tsx @@ -3,7 +3,7 @@ import { ReadError } from "@/components/read-error"; import { useEffect, useMemo, useState, type FormEvent } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { NavLink, useNavigate, useParams } from "react-router-dom"; -import { slugify, workspaceCreateSchema, validWorkspaceTransferPath } from "@lightspeed/platform-shared"; +import { slugify, workspaceCreateSchema, validWorkspaceTransferPath } from "@lightspeed-ai/platform-shared"; import { ChevronRight, File, diff --git a/platform/web/tsconfig.json b/platform/web/tsconfig.json index 0e6c7f79c..9217177db 100644 --- a/platform/web/tsconfig.json +++ b/platform/web/tsconfig.json @@ -12,7 +12,6 @@ "noEmit": true, "isolatedModules": true, "useDefineForClassFields": true, - "baseUrl": ".", "paths": { "@/*": ["./src/*"] } diff --git a/release/build-env.Dockerfile b/release/build-env.Dockerfile index d2aa881f3..36a42a281 100644 --- a/release/build-env.Dockerfile +++ b/release/build-env.Dockerfile @@ -1,5 +1,5 @@ -FROM node:24.13.0-bookworm-slim@sha256:46feb5752989c05b8606e6323fbbc3db667d14ade1c24f5d0d44d9ca9909d607 AS node -FROM rust:1.97.1-bookworm@sha256:0e2bcaef56d041a486784e54104a81aebe0da44bd03019bd70bc0401e42e4a97 +FROM node:24.21.0-bookworm-slim@sha256:0e0ff40c39bc087845bfb27465a0df4ea419520094bc35842ff83dd8cbe6f9b6 AS node +FROM rust:1.99.0-bookworm@sha256:59037199c44290f2befcdd58dcc540164763fc296950255aaefeef096a1866b0 COPY --from=node /usr/local/ /usr/local/ RUN apt-get update \ diff --git a/release/configurator-mcp.Dockerfile b/release/configurator-mcp.Dockerfile index 7c8bde6ee..2d26b5c2a 100644 --- a/release/configurator-mcp.Dockerfile +++ b/release/configurator-mcp.Dockerfile @@ -1,4 +1,4 @@ -FROM node:24.13.0-bookworm-slim@sha256:46feb5752989c05b8606e6323fbbc3db667d14ade1c24f5d0d44d9ca9909d607 +FROM node:24.21.0-bookworm-slim@sha256:0e0ff40c39bc087845bfb27465a0df4ea419520094bc35842ff83dd8cbe6f9b6 ENV NODE_ENV=production ARG LIGHTSPEED_RELEASE_VERSION=0.0.0 diff --git a/release/metadata.env b/release/metadata.env index 269721b7e..6c3dee5f4 100644 --- a/release/metadata.env +++ b/release/metadata.env @@ -5,8 +5,8 @@ LIGHTSPEED_RELEASE_TARGET=x86_64-unknown-linux-gnu # any Linux image regardless of its glibc. LIGHTSPEED_ENVD_TARGET=x86_64-unknown-linux-musl LIGHTSPEED_PRODUCT_VERSION=0.3.0 -LIGHTSPEED_RELEASE_RUST_VERSION=1.97.1 -LIGHTSPEED_RELEASE_BUILD_BASE_IMAGE=rust:1.97.1-bookworm@sha256:0e2bcaef56d041a486784e54104a81aebe0da44bd03019bd70bc0401e42e4a97 +LIGHTSPEED_RELEASE_RUST_VERSION=1.99.0 +LIGHTSPEED_RELEASE_BUILD_BASE_IMAGE=rust:1.99.0-bookworm@sha256:59037199c44290f2befcdd58dcc540164763fc296950255aaefeef096a1866b0 LIGHTSPEED_API_PROTOCOL_VERSION=lightspeed.agent.api.v1 # The environment protocol number the gateway and envd must agree on exactly; # a change here is the release event that stops older daemons from registering. diff --git a/release/notes/v0.3.0.md b/release/notes/v0.3.0.md index 66d460f9a..e5c3ed07a 100644 --- a/release/notes/v0.3.0.md +++ b/release/notes/v0.3.0.md @@ -6,7 +6,7 @@ Lightspeed v0.3.0 introduces a unified resource attachment model and moves sessi - Resource configuration now uses explicit attachments: `vfs.workspaces` with `read`/`edit` access, `environments.environments` with per-machine `read`/`edit`/`exec`/`jobs` grants, MCP server attachments with optional tool subsets, and sub-agent profile attachments. Environment provider/registration-key filters and the previous session-wide tool grants are replaced by attachment membership and access. Update API callers, saved profiles, bot configuration overrides, and other persisted configuration documents to the new generated contract. - Profiles no longer provision environments or carry a separate existing-environment selection. Session creation no longer accepts an environment override. Provision environments independently and attach them through configuration; an attachment can supply the default selection. Closing a session no longer closes an environment. - Before shutting down the old runtime, quiesce ingress and scheduled work, finish or cancel active runs, and close sessions being retired. Preserve a coordinated recovery set of PostgreSQL, Temporal, object storage, configuration, keys, and machine state. Retained old session documents are not automatically converted or guaranteed readable by the new runtime; preserve a compatible recovery copy for historical access. -- Apply runtime schema migration 10 with the new `lightspeed-server migrate`, then deploy matching runtime, Platform, connectors, Configurator, CLI, and client artifacts. Migration 10 removes environment session-origin columns while retaining environment resources. It does not rewrite saved profiles or migrate workflow histories. Platform remains at schema revision 1. There is no automated in-place conversion of old session/configuration state in this release. +- Apply runtime schema migration 10 with the new `lightspeed-runtime migrate`, then deploy matching runtime, Platform, connectors, Configurator, CLI, and client artifacts. Migration 10 removes environment session-origin columns while retaining environment resources. It does not rewrite saved profiles or migrate workflow histories. Platform remains at schema revision 1. There is no automated in-place conversion of old session/configuration state in this release. - Update installed environment daemons to the matching release for the new transfer and scan capabilities. Environment protocol 2 remains unchanged, so protocol-mismatch automatic upgrade will not install v0.3.0 merely because its product version is newer. The API protocol identifier remains `lightspeed.agent.api.v1`; it is not a guarantee that v0.2 configuration shapes remain compatible. Use the client and contracts from this release. See [Upgrades and recovery](https://ls.bot/docs/deployment/upgrades-and-recovery/) for recovery planning and the release-specific procedure. diff --git a/release/platform-workers.Dockerfile b/release/platform-workers.Dockerfile index 5109f9128..722ae4b19 100644 --- a/release/platform-workers.Dockerfile +++ b/release/platform-workers.Dockerfile @@ -1,4 +1,4 @@ -FROM node:24.13.0-bookworm-slim@sha256:46feb5752989c05b8606e6323fbbc3db667d14ade1c24f5d0d44d9ca9909d607 +FROM node:24.21.0-bookworm-slim@sha256:0e0ff40c39bc087845bfb27465a0df4ea419520094bc35842ff83dd8cbe6f9b6 ENV NODE_ENV=production ARG LIGHTSPEED_RELEASE_VERSION=0.0.0 diff --git a/release/platform.Dockerfile b/release/platform.Dockerfile index 55eec6482..be704cad8 100644 --- a/release/platform.Dockerfile +++ b/release/platform.Dockerfile @@ -1,4 +1,4 @@ -FROM node:24.13.0-bookworm-slim@sha256:46feb5752989c05b8606e6323fbbc3db667d14ade1c24f5d0d44d9ca9909d607 +FROM node:24.21.0-bookworm-slim@sha256:0e0ff40c39bc087845bfb27465a0df4ea419520094bc35842ff83dd8cbe6f9b6 ENV NODE_ENV=production ARG LIGHTSPEED_RELEASE_VERSION=0.0.0 @@ -12,4 +12,4 @@ WORKDIR /app ADD --chown=node:node dist/runtime/platform.tar.gz /app/ USER node EXPOSE 3000 -CMD ["node", "--import", "tsx", "platform/server/src/main.ts"] +CMD ["node", "--import", "tsx", "platform/backend/src/main.ts"] diff --git a/release/release-manifest.schema.json b/release/release-manifest.schema.json index 6263fe27d..e0f608835 100644 --- a/release/release-manifest.schema.json +++ b/release/release-manifest.schema.json @@ -56,9 +56,9 @@ "binaries": { "type": "object", "additionalProperties": false, - "required": ["server", "providerIncus", "envd", "cli"], + "required": ["runtime", "providerIncus", "envd", "cli"], "properties": { - "server": { "$ref": "#/$defs/binaryArtifact" }, + "runtime": { "$ref": "#/$defs/binaryArtifact" }, "providerIncus": { "$ref": "#/$defs/binaryArtifact" }, "envd": { "$ref": "#/$defs/binaryArtifact" }, "cli": { "$ref": "#/$defs/binaryArtifact" } @@ -86,7 +86,7 @@ "additionalProperties": false, "required": ["name", "version", "sha256"], "properties": { - "name": { "const": "@lightspeed-ai/agent-client" }, + "name": { "const": "@lightspeed-ai/sdk" }, "version": { "type": "string", "minLength": 1 }, "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" } } diff --git a/release/runtime.Dockerfile b/release/runtime.Dockerfile index 3066eeb81..5483cadce 100644 --- a/release/runtime.Dockerfile +++ b/release/runtime.Dockerfile @@ -11,6 +11,6 @@ RUN apt-get update \ && apt-get install --yes --no-install-recommends ca-certificates ffmpeg \ && rm -rf /var/lib/apt/lists/* -COPY dist/bin/lightspeed-server /usr/local/bin/lightspeed-server +COPY dist/bin/lightspeed-runtime /usr/local/bin/lightspeed-runtime USER 65532:65532 -ENTRYPOINT ["/usr/local/bin/lightspeed-server"] +ENTRYPOINT ["/usr/local/bin/lightspeed-runtime"] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 3caff2a7c..eb39547ce 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.97.1" +channel = "1.99.0" profile = "minimal" components = ["clippy", "rustfmt"] diff --git a/scripts/ci/classify-changes.test.mjs b/scripts/ci/classify-changes.test.mjs index 2c18845e4..7ec584fc2 100644 --- a/scripts/ci/classify-changes.test.mjs +++ b/scripts/ci/classify-changes.test.mjs @@ -23,7 +23,7 @@ test('manual, styles, assets, and included references select docs checks', () => }); test('unrelated code and internal prose do not run docs checks', () => { - assert.deepEqual(classifyPaths(['crates/engine/src/lib.rs']), { ...none, rust: true }); + assert.deepEqual(classifyPaths(['crates/harness/src/lib.rs']), { ...none, rust: true }); assert.deepEqual(classifyPaths(['crates/api/src/lib.rs']), { ...none, rust: true, consumers: true }); assert.deepEqual(classifyPaths(['platform/web/src/main.tsx', 'clients/typescript/src/index.ts']), { ...none, consumers: true }); @@ -64,7 +64,7 @@ test('git classification covers pushed ranges, PR merge bases, removals, and ren git('init', '-q'); write('docs/documentation/guide with spaces.md', '# Guide\n'); const baseSha = commit('Initial manual'); - write('crates/engine/src/lib.rs', '// main branch change\n'); + write('crates/harness/src/lib.rs', '// main branch change\n'); const mainSha = commit('Advance main'); git('checkout', '-q', '--detach', baseSha); mkdirSync(join(cwd, 'docs/internal'), { recursive: true }); diff --git a/scripts/dev/README.md b/scripts/dev/README.md index 2f9da7395..969286202 100644 --- a/scripts/dev/README.md +++ b/scripts/dev/README.md @@ -204,7 +204,7 @@ scripts/dev/infra/minio-reset.sh `reset.sh` recreates both databases, applies the runtime's ledgered schema, and clears the Lightspeed MinIO prefix. Platform applies its independently owned -database migrations when the Platform server starts. +database migrations when the Platform backend starts. The runtime's fresh PostgreSQL baseline is organized into eleven domain migrations in `crates/store-pg/migrations/`: identity and scoped API keys share a definition; @@ -266,27 +266,27 @@ For debugging a specific executable role manually: ```bash source scripts/dev/env.sh -cargo run -p temporal-server -- migrate -cargo run -p temporal-server +cargo run -p temporal-runtime -- migrate +cargo run -p temporal-runtime ``` -With no flags, the `lightspeed-server` binary runs every role — the JSON-RPC +With no flags, the `lightspeed-runtime` binary runs every role — the JSON-RPC `gateway`, the `environment-gateway` (worker environment routes, the public daemon registration routes, and the environment reconcilers), plus the `sessions`, `bots`, and `channels` Temporal workers, each on its own task -queue — in one process. For split-role runs, select roles per shell -(`--task-types workflows|activities` splits a worker role further); keep the -`environment-gateway` role on exactly one process and point the others at it +queue — in one process. Each worker runs its workflows and activities together. +For split-role runs, select roles per shell; keep the `environment-gateway` +role on exactly one process and point the others at it through `LIGHTSPEED_ENVIRONMENT_GATEWAY_URL`: ```bash source scripts/dev/env.sh -cargo run -p temporal-server -- --roles sessions,bots,channels +cargo run -p temporal-runtime -- --roles sessions,bots,channels ``` ```bash source scripts/dev/env.sh -cargo run -p temporal-server -- --roles gateway,environment-gateway +cargo run -p temporal-runtime -- --roles gateway,environment-gateway ``` Then chat through the regular CLI over the gateway transport from another @@ -304,7 +304,7 @@ Run the fake hosted-agent live integration test against the same stack: ```bash source scripts/dev/env.sh -cargo test -p temporal-server --test sessions_live temporal_live_session_start_then_run_start_completes_fake_runs -- --ignored --test-threads=1 --nocapture +cargo test -p temporal-runtime --test sessions_live temporal_live_session_start_then_run_start_completes_fake_runs -- --ignored --test-threads=1 --nocapture ``` Run the minimal live environment control-plane acceptance test. This uses real @@ -313,7 +313,7 @@ does not require Incus: ```bash source scripts/dev/env.sh -cargo test -p temporal-server --test environment_provider_live \ +cargo test -p temporal-runtime --test environment_provider_live \ -- --ignored --test-threads=1 --nocapture ``` @@ -322,7 +322,7 @@ Run only the OpenAI-backed hosted-agent live test: ```bash source scripts/dev/env.sh export OPENAI_API_KEY=... -cargo test -p temporal-server --test sessions_live temporal_live_session_start_then_run_start_completes_openai_run -- --ignored --test-threads=1 --nocapture +cargo test -p temporal-runtime --test sessions_live temporal_live_session_start_then_run_start_completes_openai_run -- --ignored --test-threads=1 --nocapture ``` Set `LIGHTSPEED_OPENAI_MODEL`, `OPENAI_RESPONSES_MODEL`, or diff --git a/scripts/dev/cli-connection.mjs b/scripts/dev/cli-connection.mjs index 561015e4a..3881ac33d 100644 --- a/scripts/dev/cli-connection.mjs +++ b/scripts/dev/cli-connection.mjs @@ -25,7 +25,7 @@ export async function prepareCliConnection({ root, env, full, noBootstrap, run } const statePath = path.join(directory, "provisioned.json"); const state = existsSync(statePath) ? JSON.parse(readPrivate(statePath)) : {}; const universe = env.LIGHTSPEED_PG_UNIVERSE_ID; - await run("development universe", "cargo", ["run", "-p", "temporal-server", "--", "universe", "create", "--universe-id", universe, "--slug", "development"], env); + await run("development universe", "cargo", ["run", "-p", "temporal-runtime", "--", "universe", "create", "--universe-id", universe, "--slug", "development"], env); if (env.LIGHTSPEED_AUTH_MODE === "single") { writePrivate(handoff, JSON.stringify({ endpoint: env.LIGHTSPEED_API_URL, single: true, ownedCredential: false }, null, 2)); return { handoff }; @@ -42,7 +42,7 @@ export async function prepareCliConnection({ root, env, full, noBootstrap, run } if (previous && supplied && previous !== supplied.trim()) throw new DevError(`The supplied ${kind} key differs from the saved development key.`, { hint: "Explicitly provision the replacement and update the protected credential file." }); const secret = previous ?? supplied?.trim(); if (noBootstrap && !secret) return null; - const args = ["run", "-p", "temporal-server", "--", "api-key", "provision", "--name", `Development ${kind}: ${root}`]; + const args = ["run", "-p", "temporal-runtime", "--", "api-key", "provision", "--name", `Development ${kind}: ${root}`]; if (assertActor) args.push("--assert-actor"); if (exists || noBootstrap) args.push("--require-existing"); const provisioningEnv = { ...env, RUST_LOG: "off" }; diff --git a/scripts/dev/cli-connection.test.mjs b/scripts/dev/cli-connection.test.mjs index 87b04bf73..deaaca576 100644 --- a/scripts/dev/cli-connection.test.mjs +++ b/scripts/dev/cli-connection.test.mjs @@ -53,6 +53,13 @@ test("key bootstrap opt-out preserves universe setup and requires existing servi assert.equal(supplied.platformSecret, "external"); assert.equal(f.keys.size, 0); }); +test("ordinary startup refuses saved credentials absent from the database", async t => { + const f = fixture(t); + await prepareCliConnection({ ...f, full: true }); + f.keys.clear(); + await assert.rejects(prepareCliConnection({ ...f, full: true }), /restart must use an active key/); + assert.equal(f.keys.size, 0, "startup does not recreate missing administrator keys"); +}); test("single mode writes a credential-free handoff", async t => { const f = fixture(t); const result = await prepareCliConnection({ ...f, env: { ...f.env, LIGHTSPEED_AUTH_MODE: "single" }, full: false }); diff --git a/scripts/dev/infra/pg-migrate.sh b/scripts/dev/infra/pg-migrate.sh index 61785e3e7..36cf1f47c 100755 --- a/scripts/dev/infra/pg-migrate.sh +++ b/scripts/dev/infra/pg-migrate.sh @@ -8,4 +8,4 @@ source "${SCRIPT_DIR}/../lib/common.sh" # create an unledgered schema that the server correctly refuses to start. export LIGHTSPEED_POSTGRES_URL cd "${REPO_ROOT}" -cargo run -p temporal-server -- migrate +cargo run -p temporal-runtime -- migrate diff --git a/scripts/dev/stack.mjs b/scripts/dev/stack.mjs index 6289a62c3..c505545fa 100644 --- a/scripts/dev/stack.mjs +++ b/scripts/dev/stack.mjs @@ -300,13 +300,13 @@ function createPlan(profile, sourceEnv) { preparations.push({ name: "runtime migration", command: "cargo", - args: ["run", "-p", "temporal-server", "--", "migrate"], + args: ["run", "-p", "temporal-runtime", "--", "migrate"], env, }); processes.push({ name: "runtime", command: "cargo", - args: ["run", "-p", "temporal-server"], + args: ["run", "-p", "temporal-runtime"], cwd: repoRoot, env, }); @@ -340,7 +340,7 @@ function createPlan(profile, sourceEnv) { { name: "platform", command: tsx, - args: ["watch", "platform/server/src/main.ts"], + args: ["watch", "platform/backend/src/main.ts"], cwd: repoRoot, env, // First-login bootstrap checks the canonical administrator through RPC. @@ -361,7 +361,7 @@ function createPlan(profile, sourceEnv) { } // The demo is the web UI over its in-browser backend: no infrastructure, - // no runtime, no Platform server — just Vite in demo mode. + // no runtime, no Platform backend — just Vite in demo mode. if (profile === "demo") { ports.push({ name: "demo web", port: 5_175 }); readiness.push({ name: "demo web", url: "http://localhost:5175/demo/" }); @@ -572,6 +572,10 @@ async function runDevelopmentAction(options, env) { infrastructureTouched = true; await runChecked("infra", path.join(infraDir, "reset.sh"), [], env); infrastructureTouched = false; + // An explicit reset invalidates the saved keys along with their database records. + // Only clear them after success; ordinary startup must still require existing keys. + rmSync(path.join(repoRoot, ".lightspeed", "cli"), { recursive: true, force: true }); + console.log("[reset] Cleared saved development credentials. Start ./dev.sh to provision keys, then run lightspeed connect dev to refresh the CLI connection."); return; } const supervisor = readSupervisorState(); diff --git a/scripts/dev/stack.test.mjs b/scripts/dev/stack.test.mjs index 935d6e3e0..c63f22375 100644 --- a/scripts/dev/stack.test.mjs +++ b/scripts/dev/stack.test.mjs @@ -7,6 +7,7 @@ import { tmpdir } from "node:os"; import path from "node:path"; import { once } from "node:events"; import { createServer } from "node:http"; +import { prepareCliConnection } from "./cli-connection.mjs"; const root = fileURLToPath(new URL("../../", import.meta.url)); @@ -81,6 +82,54 @@ function launcherFixture(t) { return directory; } +for (const resetExitCode of [0, 7]) { + test(`database reset ${resetExitCode === 0 ? "clears credentials for fresh startup" : "failure preserves credentials"}`, async (t) => { + const directory = launcherFixture(t); + const env = { + ...process.env, + LIGHTSPEED_AUTH_MODE: "authenticated", + LIGHTSPEED_BOOTSTRAP_API_KEY: "", + LIGHTSPEED_PLATFORM_API_KEY: "", + LIGHTSPEED_API_URL: "http://127.0.0.1:18080/rpc", + LIGHTSPEED_PG_UNIVERSE_ID: "00000000-0000-0000-0000-000000000001", + }; + const keys = new Set(); + let sequence = 0; + const run = async (_name, _command, args, provisioningEnv) => { + if (args.includes("universe")) return { stdout: "" }; + const secret = provisioningEnv.LIGHTSPEED_BOOTSTRAP_API_KEY ?? `lsk_reset_${++sequence}`; + if (args.includes("--require-existing")) assert.ok(keys.has(secret), "saved key must exist in the database"); + keys.add(secret); + return { stdout: JSON.stringify({ secret }) }; + }; + const options = { root: directory, env, full: true, run }; + const before = await prepareCliConnection(options); + const unrelated = path.join(directory, ".lightspeed", "unrelated"); + writeFileSync(unrelated, "preserve"); + writeFileSync(path.join(directory, "scripts/dev/infra/reset.sh"), `#!/bin/sh\nexit ${resetExitCode}\n`, { mode: 0o755 }); + const result = spawnSync(process.execPath, ["scripts/dev/stack.mjs", "reset"], { + cwd: directory, encoding: "utf8", env, + }); + assert.equal(result.status, resetExitCode === 0 ? 0 : 1, result.stderr); + assert.ok(existsSync(unrelated)); + const credentialDirectory = path.join(directory, ".lightspeed", "cli"); + if (resetExitCode === 0) { + assert.ok(!existsSync(credentialDirectory)); + assert.match(result.stdout, /lightspeed connect dev/); + keys.clear(); + const after = await prepareCliConnection(options); + assert.notEqual(after.platformSecret, before.platformSecret); + assert.equal(sequence, 4, "both CLI and Platform receive fresh keys"); + assert.ok(existsSync(after.handoff)); + } else { + assert.ok(existsSync(before.handoff)); + const after = await prepareCliConnection(options); + assert.equal(after.platformSecret, before.platformSecret); + assert.equal(sequence, 2, "failed reset retains both saved keys"); + } + }); +} + for (const failure of ["migration", "runtime"]) { test(`${failure} failure is reported once with recent output and cleanup state`, { timeout: 10_000 }, async (t) => { const directory = launcherFixture(t); diff --git a/scripts/release/build-dist.sh b/scripts/release/build-dist.sh index 59f71be4c..93395fb56 100755 --- a/scripts/release/build-dist.sh +++ b/scripts/release/build-dist.sh @@ -25,12 +25,12 @@ export LIGHTSPEED_GIT_SHA="$git_sha" # The server reports which daemon targets this release publishes. export LIGHTSPEED_ENVD_TARGETS="$envd_target" cargo build --release --locked --target "$target" \ - -p temporal-server -p environment-provider-incus -p cli + -p temporal-runtime -p environment-provider-incus -p cli # The environment daemon alone is a static musl binary, so it runs on any # Linux image whatever glibc that image carries. cargo build --release --locked --target "$envd_target" -p environment-daemon -for binary in lightspeed-server lightspeed-provider-incus lightspeed; do +for binary in lightspeed-runtime lightspeed-provider-incus lightspeed; do install -m 0755 "target/$target/release/$binary" "$dist_dir/bin/$binary" strip "$dist_dir/bin/$binary" done @@ -64,15 +64,16 @@ client_tgz="$(find "$dist_dir/npm" -maxdepth 1 -name '*.tgz' -print -quit)" cp -R platform/configurator-mcp/dist "$dist_dir/configurator-mcp/dist" cp platform/configurator-mcp/package.json platform/configurator-mcp/package-lock.json \ "$dist_dir/configurator-mcp/" -cp "$client_tgz" "$dist_dir/configurator-mcp/agent-client.tgz" -node scripts/release/stage-package.mjs configurator "$dist_dir/configurator-mcp" "$version" "$git_sha" +cp "$client_tgz" "$dist_dir/configurator-mcp/sdk.tgz" +node scripts/release/stage-package.mjs configurator "$dist_dir/configurator-mcp" "$version" "$git_sha" \ + "$stage_root/ts-client/package-lock.json" (cd "$dist_dir/configurator-mcp" && \ npm ci --omit=dev --offline --ignore-scripts) scripts/release/stage-runtimes.sh "$dist_dir" for spec in \ - "lightspeed-server:server:$target" \ + "lightspeed-runtime:runtime:$target" \ "lightspeed-provider-incus:provider-incus:$target" \ "lightspeed-envd:envd:$envd_target" \ "lightspeed:cli:$target"; do diff --git a/scripts/release/build-images.sh b/scripts/release/build-images.sh index 42583cd45..e5610bbf3 100755 --- a/scripts/release/build-images.sh +++ b/scripts/release/build-images.sh @@ -27,13 +27,13 @@ container_id="$(docker create "${tag}-runtime" --version)" trap 'docker rm -f "$container_id" >/dev/null 2>&1 || true' EXIT tmp_dir="$(mktemp -d)" trap 'docker rm -f "$container_id" >/dev/null 2>&1 || true; rm -rf "$tmp_dir"' EXIT -docker cp "$container_id:/usr/local/bin/lightspeed-server" "$tmp_dir/lightspeed-server" -cmp dist/bin/lightspeed-server "$tmp_dir/lightspeed-server" +docker cp "$container_id:/usr/local/bin/lightspeed-runtime" "$tmp_dir/lightspeed-runtime" +cmp dist/bin/lightspeed-runtime "$tmp_dir/lightspeed-runtime" docker run --rm "${tag}-runtime" --version docker run --rm --entrypoint node "${tag}-configurator-mcp" \ --input-type=module -e 'await import("/app/dist/index.js")' docker run --rm --entrypoint node "${tag}-platform" -e \ - 'for (const file of ["/app/platform/server/src/main.ts", "/app/platform/web/dist/index.html"]) require("node:fs").accessSync(file)' + 'for (const file of ["/app/platform/backend/src/main.ts", "/app/platform/web/dist/index.html"]) require("node:fs").accessSync(file)' for image in runtime platform platform-workers; do test "$(docker image inspect "${tag}-${image}" \ --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}')" = "$git_sha" @@ -45,7 +45,7 @@ docker run --rm --entrypoint node "${tag}-platform-workers" -e \ docker run --rm --entrypoint node "${tag}-platform-workers" \ --import tsx --input-type=module -e ' const { parseHostConfig } = await import("./platform/connectors/src/host/config.ts"); - const { connectorTaskQueue, WORKFLOW_CONTRACT_VECTORS } = await import("@lightspeed-ai/agent-client/workflow"); + const { connectorTaskQueue, WORKFLOW_CONTRACT_VECTORS } = await import("@lightspeed-ai/sdk/workflow"); const config = parseHostConfig({ LIGHTSPEED_API_URL: "http://runtime:18080/rpc", LIGHTSPEED_CONNECTOR_PROVIDERS: "telegram" }); if (config.providers.join(",") !== "telegram") process.exit(1); const vector = WORKFLOW_CONTRACT_VECTORS.channels; diff --git a/scripts/release/create-manifest.mjs b/scripts/release/create-manifest.mjs index 67e89a308..8a1077e89 100755 --- a/scripts/release/create-manifest.mjs +++ b/scripts/release/create-manifest.mjs @@ -123,7 +123,7 @@ const manifest = { platformWorkers: process.env.LIGHTSPEED_PLATFORM_WORKERS_IMAGE ?? null, }, binaries: { - server: archive("SERVER", "-server-"), + runtime: archive("RUNTIME", "-runtime-"), providerIncus: archive("PROVIDER_INCUS", "-provider-incus-"), envd: archive("ENVD", "-envd-"), cli: archive("CLI", "-cli-"), @@ -139,7 +139,7 @@ const manifest = { }, }, typescriptClient: { - name: "@lightspeed-ai/agent-client", + name: "@lightspeed-ai/sdk", version, sha256: sha256(path.join("dist/npm", clientFile)), }, diff --git a/scripts/release/prepare-version.mjs b/scripts/release/prepare-version.mjs index c2e12eaf7..42cdbc261 100644 --- a/scripts/release/prepare-version.mjs +++ b/scripts/release/prepare-version.mjs @@ -4,7 +4,7 @@ import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; export const releasePackages = [ - 'release-info', 'temporal-server', 'environment-provider-incus', + 'release-info', 'temporal-runtime', 'environment-provider-incus', 'environment-daemon', 'cli', ]; diff --git a/scripts/release/publish-aliases.sh b/scripts/release/publish-aliases.sh index c7e833d96..7743f3b92 100755 --- a/scripts/release/publish-aliases.sh +++ b/scripts/release/publish-aliases.sh @@ -99,7 +99,7 @@ while IFS=$'\t' read -r manifest_key target_name; do [[ "$source_ref" != "$source_url" ]] copy_oras_alias "$source_ref" "$root/${target_name}-bundle:$alias_name" done <<'EOF' -server server +runtime runtime providerIncus provider-incus envd envd cli cli diff --git a/scripts/release/smoke-images.sh b/scripts/release/smoke-images.sh index 573c72cc5..cc23be608 100755 --- a/scripts/release/smoke-images.sh +++ b/scripts/release/smoke-images.sh @@ -54,7 +54,7 @@ docker run --rm --entrypoint node "$platform_workers_image" -e \ docker run --rm --entrypoint node "$platform_workers_image" \ --import tsx --input-type=module -e ' const { parseHostConfig } = await import("./platform/connectors/src/host/config.ts"); - const { connectorTaskQueue, WORKFLOW_CONTRACT_VECTORS } = await import("@lightspeed-ai/agent-client/workflow"); + const { connectorTaskQueue, WORKFLOW_CONTRACT_VECTORS } = await import("@lightspeed-ai/sdk/workflow"); const config = parseHostConfig({ LIGHTSPEED_API_URL: "http://runtime:18080/rpc", LIGHTSPEED_CONNECTOR_API_KEY: "lsk_release_smoke_test", diff --git a/scripts/release/smoke.sh b/scripts/release/smoke.sh index 1cb4c9280..200db3e18 100755 --- a/scripts/release/smoke.sh +++ b/scripts/release/smoke.sh @@ -4,7 +4,7 @@ cd "$(dirname "${BASH_SOURCE[0]}")/../.." source release/metadata.env expected_sha="${LIGHTSPEED_GIT_SHA:-$(git rev-parse HEAD)}" -for binary in dist/bin/lightspeed-server dist/bin/lightspeed-provider-incus \ +for binary in dist/bin/lightspeed-runtime dist/bin/lightspeed-provider-incus \ dist/bin/lightspeed-envd dist/bin/lightspeed; do version_output="$($binary --version)" grep -F "$expected_sha" <<<"$version_output" >/dev/null @@ -56,13 +56,13 @@ for entry in package/package.json package/release.json package/dist/index.js \ tar -tzf "$client_tgz" "$entry" >/dev/null done test -f dist/configurator-mcp/dist/bin.js -test -f dist/configurator-mcp/node_modules/@lightspeed-ai/agent-client/dist/index.js +test -f dist/configurator-mcp/node_modules/@lightspeed-ai/sdk/dist/index.js for runtime in platform platform-workers; do test -f "dist/runtime/$runtime.tar.gz" tar -tzf "dist/runtime/$runtime.tar.gz" ./package.json >/dev/null done -tar -tzf dist/runtime/platform.tar.gz ./platform/server/src/main.ts >/dev/null +tar -tzf dist/runtime/platform.tar.gz ./platform/backend/src/main.ts >/dev/null tar -tzf dist/runtime/platform.tar.gz ./platform/web/dist/index.html >/dev/null tar -tzf dist/runtime/platform-workers.tar.gz ./platform/connectors/src/host/main.ts >/dev/null tar -tzf dist/runtime/platform-workers.tar.gz ./platform/connectors/src/providers/telegram/connector.ts >/dev/null diff --git a/scripts/release/stage-package.mjs b/scripts/release/stage-package.mjs index 990500fb4..ca269cca6 100755 --- a/scripts/release/stage-package.mjs +++ b/scripts/release/stage-package.mjs @@ -3,9 +3,9 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; -const [kind, directory, version, gitSha] = process.argv.slice(2); +const [kind, directory, version, gitSha, clientLockPath] = process.argv.slice(2); if (!kind || !directory || !version || !gitSha) { - throw new Error("usage: stage-package.mjs "); + throw new Error("usage: stage-package.mjs [client-lockfile]"); } const packagePath = path.join(directory, "package.json"); @@ -21,7 +21,7 @@ if (kind === "client") { ); } else if (kind === "configurator") { manifest.private = true; - manifest.dependencies["@lightspeed-ai/agent-client"] = "file:./agent-client.tgz"; + manifest.dependencies["@lightspeed-ai/sdk"] = "file:./sdk.tgz"; delete manifest.scripts?.prepare; } else { throw new Error(`unknown package kind: ${kind}`); @@ -40,13 +40,24 @@ if (!lock.packages?.[""]) { lock.packages[""].version = version; if (kind === "configurator") { + if (!clientLockPath) { + throw new Error("Configurator staging requires the packed client's lockfile"); + } + const clientLock = JSON.parse(fs.readFileSync(clientLockPath, "utf8")); + const clientMetadata = { ...clientLock.packages?.[""] }; + if (clientMetadata.name !== "@lightspeed-ai/sdk") { + throw new Error(`${clientLockPath}: expected the SDK's standalone lockfile`); + } + delete clientMetadata.devDependencies; + const clientLocation = "node_modules/@lightspeed-ai/sdk"; lock.packages[""].dependencies = manifest.dependencies; for (const [location, item] of Object.entries(lock.packages)) { - if (location && item?.name === "@lightspeed-ai/agent-client") { + if ((location && item?.name === "@lightspeed-ai/sdk") + || location.startsWith(`${clientLocation}/`)) { delete lock.packages[location]; } } - const clientTarball = path.join(directory, "agent-client.tgz"); + const clientTarball = path.join(directory, "sdk.tgz"); if (!fs.existsSync(clientTarball)) { throw new Error(`${clientTarball}: staged client tarball is missing`); } @@ -54,12 +65,19 @@ if (kind === "configurator") { .createHash("sha512") .update(fs.readFileSync(clientTarball)) .digest("base64"); - lock.packages["node_modules/@lightspeed-ai/agent-client"] = { + lock.packages[clientLocation] = { + ...clientMetadata, version, - resolved: "file:agent-client.tgz", + resolved: "file:sdk.tgz", integrity: `sha512-${integrity}`, - engines: { node: ">=24" }, }; + // Keep the SDK's production graph at its tested versions. Nest it under the + // SDK so Configurator's own locked dependencies can retain different versions. + for (const [location, item] of Object.entries(clientLock.packages)) { + if (location.startsWith("node_modules/") && !item.dev) { + lock.packages[`${clientLocation}/${location}`] = item; + } + } } fs.writeFileSync(lockPath, `${JSON.stringify(lock, null, 2)}\n`); diff --git a/scripts/release/stage-package.test.mjs b/scripts/release/stage-package.test.mjs new file mode 100644 index 000000000..363946056 --- /dev/null +++ b/scripts/release/stage-package.test.mjs @@ -0,0 +1,75 @@ +import assert from 'node:assert/strict'; +import { createHash } from 'node:crypto'; +import { execFileSync } from 'node:child_process'; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { test } from 'node:test'; + +const stageScript = fileURLToPath(new URL('./stage-package.mjs', import.meta.url)); + +test('staged Configurator installs the SDK production graph from its lockfile offline', (t) => { + const root = mkdtempSync(join(tmpdir(), 'lightspeed-package-test-')); + t.after(() => rmSync(root, { recursive: true, force: true })); + const writeJson = (file, data) => writeFileSync(file, JSON.stringify(data)); + const pack = (directory, name, version, dependencies, source) => { + const packageDir = join(root, directory, 'package'); + mkdirSync(packageDir, { recursive: true }); + writeJson(join(packageDir, 'package.json'), { + name, version, type: 'module', exports: './index.js', dependencies, + }); + writeFileSync(join(packageDir, 'index.js'), source); + const tarball = join(root, `${directory}.tgz`); + execFileSync('tar', ['-czf', tarball, '-C', join(root, directory), 'package']); + return { + version, resolved: `file:${tarball}`, + integrity: `sha512-${createHash('sha512').update(readFileSync(tarball)).digest('base64')}`, + dependencies, + }; + }; + const core = pack('core', 'fixture-core', '1.0.0', {}, 'export default "locked core";'); + const hash = pack('hash', 'fixture-hash', '1.0.0', { 'fixture-core': '1.0.0' }, + 'export { default } from "fixture-core";'); + const client = pack('sdk', '@lightspeed-ai/sdk', '0.3.0', { 'fixture-hash': '1.0.0' }, + 'export { default } from "fixture-hash";'); + const clientLockPath = join(root, 'client-lock.json'); + writeJson(clientLockPath, { + name: '@lightspeed-ai/sdk', version: '0.3.0', lockfileVersion: 3, + packages: { + '': { + name: '@lightspeed-ai/sdk', version: '0.3.0', + dependencies: client.dependencies, devDependencies: { 'fixture-dev': '1.0.0' }, + }, + 'node_modules/fixture-hash': hash, + 'node_modules/fixture-core': core, + 'node_modules/fixture-dev': { version: '1.0.0', dev: true }, + }, + }); + const config = join(root, 'configurator'); + mkdirSync(config); + writeFileSync(join(config, 'sdk.tgz'), readFileSync(join(root, 'sdk.tgz'))); + const manifest = { + name: '@lightspeed-ai/configurator-mcp', version: '0.0.0', private: true, + dependencies: { '@lightspeed-ai/sdk': 'file:../old-sdk' }, + }; + writeJson(join(config, 'package.json'), manifest); + writeJson(join(config, 'package-lock.json'), { + name: manifest.name, version: manifest.version, lockfileVersion: 3, + packages: { + '': manifest, + '../old-sdk': { name: '@lightspeed-ai/sdk', version: '0.0.0' }, + 'node_modules/@lightspeed-ai/sdk': { resolved: '../old-sdk', link: true }, + }, + }); + execFileSync(process.execPath, [stageScript, 'configurator', config, '0.3.0', 'a'.repeat(40), clientLockPath]); + const lockBeforeInstall = readFileSync(join(config, 'package-lock.json'), 'utf8'); + execFileSync('npm', ['ci', '--omit=dev', '--offline', '--ignore-scripts', '--no-audit', '--cache', join(root, 'cache')], + { cwd: config, stdio: 'pipe' }); + assert.equal(readFileSync(join(config, 'package-lock.json'), 'utf8'), lockBeforeInstall); + const result = execFileSync(process.execPath, + ['--input-type=module', '-e', 'import value from "@lightspeed-ai/sdk"; console.log(value);'], + { cwd: config, encoding: 'utf8' }); + assert.equal(result.trim(), 'locked core'); + assert.ok(!existsSync(join(config, 'node_modules/@lightspeed-ai/sdk/node_modules/fixture-dev'))); +}); diff --git a/scripts/release/stage-runtimes.sh b/scripts/release/stage-runtimes.sh index 5c60b2ef9..723d3c5c8 100755 --- a/scripts/release/stage-runtimes.sh +++ b/scripts/release/stage-runtimes.sh @@ -24,7 +24,7 @@ copy_workspace_manifests() { platform/configurator-mcp \ platform/connectors \ platform/db \ - platform/server \ + platform/backend \ platform/shared \ platform/web; do mkdir -p "$root/$workspace" @@ -55,16 +55,16 @@ stage_runtime() { "$root/platform/connectors" else rm -rf "$root/platform/cli" "$root/platform/configurator-mcp" \ - "$root/platform/db" "$root/platform/server" "$root/platform/shared" \ + "$root/platform/db" "$root/platform/backend" "$root/platform/shared" \ "$root/platform/web" fi "$tar_command" --sort=name --mtime='UTC 1970-01-01' --owner=0 --group=0 --numeric-owner \ -C "$root" -czf "$dist_dir/runtime/$name.tar.gz" . } -stage_runtime platform @lightspeed/platform-server \ +stage_runtime platform @lightspeed-ai/platform-backend \ clients/typescript/dist \ - platform/server/src \ + platform/backend/src \ platform/db/src \ platform/db/migrations \ platform/shared/src \ @@ -72,6 +72,6 @@ stage_runtime platform @lightspeed/platform-server \ # The "platform-workers" runtime is the connector host (platform/connectors): # Bots and Channels core moved into the Rust runtime. The artifact keeps its # name so image references and manifest keys stay stable. -stage_runtime platform-workers @lightspeed/connectors \ +stage_runtime platform-workers @lightspeed-ai/connectors \ clients/typescript/dist \ platform/connectors/src diff --git a/scripts/release/static-sites.test.mjs b/scripts/release/static-sites.test.mjs index bec23e9b0..43daab52f 100644 --- a/scripts/release/static-sites.test.mjs +++ b/scripts/release/static-sites.test.mjs @@ -31,17 +31,17 @@ function fixture(t) { for (const contract of ['api.schema.json', 'methods.json', 'openrpc.json', 'api-reference.md']) { write(`dist/contracts/${contract}`, `fixture ${contract}`); } - for (const component of ['server', 'provider-incus', 'cli', 'demo']) { + for (const component of ['runtime', 'provider-incus', 'cli', 'demo']) { write(`dist/archives/lightspeed-${component}-${version}.tar.gz`, `fixture ${component}`); } write(`dist/archives/lightspeed-envd-${version}-${metadata.LIGHTSPEED_ENVD_TARGET}.tar.gz`, 'fixture envd'); write(`dist/archives/lightspeed-docs-${version}.tar.gz`, 'fixture documentation archive'); - write('dist/npm/client.tgz', 'fixture client'); + write('dist/npm/sdk.tgz', 'fixture client'); const env = { ...cleanEnv, LIGHTSPEED_RELEASE_BUILD_IMAGE: `${registry}/build-env@${digest}`, SOURCE_DATE_EPOCH: '1700000000', }; - for (const name of ['SERVER', 'PROVIDER_INCUS', 'ENVD', 'CLI']) { + for (const name of ['RUNTIME', 'PROVIDER_INCUS', 'ENVD', 'CLI']) { env[`LIGHTSPEED_BINARY_URL_${name}`] = `oci://${registry}/${name.toLowerCase().replaceAll('_', '-')}-bundle@${digest}`; } for (const name of ['DEMO', 'DOCS']) { @@ -64,7 +64,12 @@ for (const channel of ['main', 'release']) { f.env.LIGHTSPEED_RELEASE_CHANNEL = channel; if (channel === 'release') f.env.LIGHTSPEED_ENVD_PUBLIC_URL_BASE = 'https://example.test/releases/v1'; f.create(); - const docs = f.manifest().artifacts.docs; + const manifest = f.manifest(); + assert.equal(manifest.typescriptClient.name, "@lightspeed-ai/sdk"); + assert.deepEqual(Object.keys(manifest.binaries).sort(), ['cli', 'envd', 'providerIncus', 'runtime']); + assert.equal(manifest.binaries.runtime.file, `lightspeed-runtime-${version}.tar.gz`); + assert.equal(manifest.binaries.runtime.url, `oci://${registry}/runtime-bundle@${digest}`); + const docs = manifest.artifacts.docs; assert.equal(docs.file, `lightspeed-docs-${version}.tar.gz`); assert.equal(docs.sha256, hash(readFileSync(join(f.cwd, 'dist/archives', docs.file)))); assert.equal(docs.basePath, '/docs/'); diff --git a/scripts/release/verify-manifest.mjs b/scripts/release/verify-manifest.mjs index 06e5e2f92..e1efbb625 100755 --- a/scripts/release/verify-manifest.mjs +++ b/scripts/release/verify-manifest.mjs @@ -118,7 +118,7 @@ for (const [target, artifact] of Object.entries(discovery.artifacts)) { if (discovery.artifacts[value.envdTarget].sha256 !== value.binaries.envd.sha256) { dfail("envd checksum differs from the manifest"); } -if (value.typescriptClient.name !== "@lightspeed-ai/agent-client") fail("unexpected client package"); +if (value.typescriptClient.name !== "@lightspeed-ai/sdk") fail("unexpected client package"); if (!/^[0-9a-f]{64}$/.test(value.typescriptClient.sha256)) fail("invalid client checksum"); if (value.typescriptClient.version !== value.version) fail("client version mismatch"); const clientFiles = fs.readdirSync("dist/npm").filter((entry) => entry.endsWith(".tgz")); diff --git a/tsconfig.json b/tsconfig.json index b265c2040..4cb36798c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,9 +20,9 @@ "platform/db/scripts/**/*.ts", "platform/db/drizzle.config.ts", "platform/shared/src/**/*.ts", - "platform/server/src/**/*.ts", - "platform/server/test/**/*.ts", - "platform/server/scripts/**/*.ts", + "platform/backend/src/**/*.ts", + "platform/backend/test/**/*.ts", + "platform/backend/scripts/**/*.ts", "platform/cli/src/**/*.ts" ] }