From 7bb21675a29166ff7229eda7d6758f8310aef730 Mon Sep 17 00:00:00 2001 From: johan Date: Mon, 13 Jul 2026 15:21:39 +0200 Subject: [PATCH 1/5] feat: add release governance and guardrails --- .github/CODEOWNERS | 20 + .github/PULL_REQUEST_TEMPLATE.md | 15 + .github/dependabot.yml | 39 + .github/workflows/ci.yml | 22 +- .github/workflows/docs.yml | 8 +- .github/workflows/policy.yml | 105 ++ .github/workflows/release.yml | 239 ++-- .github/workflows/snapshot.yml | 6 +- .gitignore | 4 + AGENTS.md | 82 +- CHANGELOG.md | 8 + CLAUDE.md | 45 +- Cargo.lock | 1644 ++++++++++++++------------- deny.toml | 56 + governance/agent-workflow.md | 46 + governance/contracts/cli.json | 794 +++++++++++++ governance/current-state.md | 79 ++ governance/guardrails.md | 72 ++ governance/releasing.md | 78 ++ governance/versioning.md | 92 ++ perf/Cargo.lock | 28 +- scripts/check-agent-docs.sh | 4 + scripts/check-contracts.py | 262 +++++ scripts/check-governance.py | 191 ++++ scripts/ci.sh | 18 + scripts/release-check.sh | 29 + scripts/version.py | 500 ++++++++ tests/versioning/test_governance.py | 66 ++ tests/versioning/test_version.py | 101 ++ 29 files changed, 3712 insertions(+), 941 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/policy.yml create mode 100644 deny.toml create mode 100644 governance/agent-workflow.md create mode 100644 governance/contracts/cli.json create mode 100644 governance/current-state.md create mode 100644 governance/guardrails.md create mode 100644 governance/releasing.md create mode 100644 governance/versioning.md create mode 100755 scripts/check-agent-docs.sh create mode 100755 scripts/check-contracts.py create mode 100755 scripts/check-governance.py create mode 100755 scripts/ci.sh create mode 100755 scripts/release-check.sh create mode 100755 scripts/version.py create mode 100644 tests/versioning/test_governance.py create mode 100644 tests/versioning/test_version.py diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..50cb6bc --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,20 @@ +# Default review ownership +* @saldestechnology + +# Release, security, compatibility, and governance surfaces +/.github/ @saldestechnology +/governance/ @saldestechnology +/scripts/ @saldestechnology +/Cargo.toml @saldestechnology +/Cargo.lock @saldestechnology +/perf/Cargo.lock @saldestechnology +/CHANGELOG.md @saldestechnology +/deny.toml @saldestechnology +/src/cli.rs @saldestechnology +/src/config.rs @saldestechnology +/src/exit.rs @saldestechnology +/src/json.rs @saldestechnology +/src/db/schema.rs @saldestechnology +/src/mcp/ @saldestechnology +/src/update.rs @saldestechnology +/src/harness/templates/ @saldestechnology diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d291b09..dbc5f90 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,12 +9,27 @@ Brief description of the changes. - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update +## Compatibility and release impact + +- [ ] No compatibility-sensitive contract changed +- [ ] Contract changed additively; I updated the CLI snapshot if applicable +- [ ] Breaking change; the PR has `contract-review` and `breaking-change` + maintainer acknowledgement, a compatible version bump, migration notes, + and a prominent `BREAKING:` changelog entry +- [ ] Release preparation; the PR has the `release-preparation` label and used + `scripts/version.py` + ## Checklist - [ ] I have run `cargo fmt` - [ ] I have run `cargo clippy` and addressed any warnings - [ ] I have added tests that prove my fix/feature works - [ ] I have updated documentation if needed +- [ ] I added a categorized `CHANGELOG.md` Unreleased entry, or a maintainer + confirmed `skip-changelog` is appropriate +- [ ] I reviewed CLI, JSON, config, schema/index, Rust API, MCP/plugin, exit-code, + platform/package, and self-update compatibility as applicable +- [ ] I ran `python3 scripts/check-governance.py check` - [ ] All tests pass (`cargo test`) ## Related Issues diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..975f8b8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,39 @@ +version: 2 +updates: + - package-ecosystem: cargo + directory: "/" + schedule: + interval: weekly + day: monday + groups: + rust-runtime: + dependency-type: production + rust-development: + dependency-type: development + + - package-ecosystem: cargo + directory: "/perf" + schedule: + interval: weekly + day: monday + groups: + perf-harness: + patterns: ["*"] + + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + day: monday + groups: + github-actions: + patterns: ["*"] + + - package-ecosystem: npm + directory: "/docs/website" + schedule: + interval: weekly + day: monday + groups: + documentation-site: + patterns: ["*"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e96c26b..50845f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,13 +36,13 @@ jobs: features: "--no-default-features" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 - name: Cache cargo - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: | ~/.cargo/bin/ @@ -64,10 +64,10 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with: components: rustfmt, clippy @@ -80,10 +80,10 @@ jobs: publish-dry-run: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 - name: Dry-run publish (with features) run: cargo publish --dry-run @@ -94,17 +94,17 @@ jobs: perf: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: # ctx score/check diff against git history; the harness also # records the commit SHA in its results. fetch-depth: 0 - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 - name: Cache cargo - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: | ~/.cargo/bin/ @@ -151,7 +151,7 @@ jobs: - name: Upload perf results if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: perf-results path: perf-results.json diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f3842ec..805cb48 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -31,10 +31,10 @@ jobs: run: working-directory: docs/website steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: 20 cache: npm @@ -47,7 +47,7 @@ jobs: run: npm run build - name: Upload Pages artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 with: path: docs/website/build @@ -62,4 +62,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 diff --git a/.github/workflows/policy.yml b/.github/workflows/policy.yml new file mode 100644 index 0000000..504af11 --- /dev/null +++ b/.github/workflows/policy.yml @@ -0,0 +1,105 @@ +name: Policy + +on: + pull_request: + branches: [main] + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] + push: + branches: [main] + schedule: + - cron: "29 4 * * 1" + workflow_dispatch: + +permissions: + contents: read + pull-requests: read + +concurrency: + group: policy-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + +jobs: + repository-policy: + name: repository policy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + + - uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" + + - name: Test governance tooling + run: | + python3 scripts/check-governance.py check + python3 -m unittest discover -s tests/versioning -p 'test_*.py' + + - name: Build the governed binary surface + run: cargo build --locked --release --no-default-features + + - name: Check version and CLI contract + run: | + python3 scripts/version.py check --binary target/release/ctx + python3 scripts/check-contracts.py check --binary target/release/ctx + + - name: Check pull-request policy and compatibility acknowledgement + if: github.event_name == 'pull_request' + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }} + run: | + python3 scripts/check-governance.py pr --base "$BASE_SHA" --labels "$PR_LABELS" + python3 scripts/check-contracts.py pr-policy --base "$BASE_SHA" --labels "$PR_LABELS" + + msrv: + name: Rust 1.91 MSRV + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" + - run: cargo check --locked --all-targets --no-default-features + + rust-api: + name: Rust public API compatibility + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false + - uses: obi1kenobi/cargo-semver-checks-action@5b298c9520f7096a4683c0bd981a7ac5a7e249ae # v2.8 + with: + package: agentis-ctx + baseline-rev: ${{ github.event.pull_request.base.sha }} + feature-group: all-features + rust-toolchain: "1.91" + + supply-chain: + name: dependency, license, and source policy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - name: Check root dependency graph + uses: EmbarkStudios/cargo-deny-action@43cf000bced7a828a6e01af0596dd7e99b5b4e13 # v2.0.12 + with: + command: check + arguments: --all-features + - name: Check perf harness dependency graph + uses: EmbarkStudios/cargo-deny-action@43cf000bced7a828a6e01af0596dd7e99b5b4e13 # v2.0.12 + with: + manifest-path: ./perf/Cargo.toml + command: check + arguments: --all-features diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30b5ecb..fed486a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,39 +7,67 @@ on: env: CARGO_TERM_COLOR: always -permissions: - contents: write +permissions: {} + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false jobs: - check-version: + release-gates: + name: release gates runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + persist-credentials: false - - name: Verify tag matches Cargo.toml version + - name: Require an annotated tag on reviewed main history + shell: bash run: | - CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version') - TAG_VERSION="${GITHUB_REF_NAME#v}" - if [ "$CARGO_VERSION" != "$TAG_VERSION" ]; then - echo "Tag $TAG_VERSION does not match Cargo.toml version $CARGO_VERSION" - exit 1 - fi - - test: - needs: check-version - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + set -euo pipefail + git fetch --no-tags origin main:refs/remotes/origin/main + test "$(git cat-file -t "refs/tags/${GITHUB_REF_NAME}")" = tag + tagged_commit="$(git rev-parse "refs/tags/${GITHUB_REF_NAME}^{commit}")" + test "$tagged_commit" = "$GITHUB_SHA" + git merge-base --is-ancestor "$tagged_commit" origin/main + + - uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" + components: rustfmt, clippy - - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + - name: Run deterministic release checks + run: scripts/release-check.sh "${GITHUB_REF_NAME}" - - name: Run tests - run: cargo test --verbose + - name: Check dependency, license, advisory, and source policy + uses: EmbarkStudios/cargo-deny-action@43cf000bced7a828a6e01af0596dd7e99b5b4e13 # v2.0.12 + with: + command: check + arguments: --all-features + + - name: Check published Rust API compatibility + uses: obi1kenobi/cargo-semver-checks-action@5b298c9520f7096a4683c0bd981a7ac5a7e249ae # v2.8 + with: + package: agentis-ctx + feature-group: all-features + rust-toolchain: "1.91" + + - name: Upload reviewed release notes + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: release-notes + path: release-notes.md + if-no-files-found: error build: - needs: [check-version, test] + needs: release-gates runs-on: ${{ matrix.os }} + permissions: + contents: read strategy: fail-fast: false matrix: @@ -47,40 +75,40 @@ jobs: - os: ubuntu-latest target: x86_64-unknown-linux-gnu features: "" - # macos-latest runners are arm64; use the Intel runner for x86_64 - # so the bundled DuckDB C++ compiles natively - os: macos-15-intel target: x86_64-apple-darwin features: "" - os: macos-latest target: aarch64-apple-darwin features: "" - # DuckDB does not compile on Windows MSVC - os: windows-latest target: x86_64-pc-windows-msvc features: "--no-default-features" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with: + toolchain: "1.91" targets: ${{ matrix.target }} - name: Build release - run: cargo build --release --target ${{ matrix.target }} ${{ matrix.features }} + run: cargo build --locked --release --target ${{ matrix.target }} ${{ matrix.features }} - - name: Package (unix) + - name: Package and checksum (Unix) if: runner.os != 'Windows' run: | - NAME="ctx-${GITHUB_REF_NAME}-${{ matrix.target }}" - mkdir "$NAME" - cp "target/${{ matrix.target }}/release/ctx" README.md CHANGELOG.md LICENSE-MIT LICENSE-APACHE "$NAME/" - tar czf "$NAME.tar.gz" "$NAME" - shasum -a 256 "$NAME.tar.gz" > "$NAME.tar.gz.sha256" - - - name: Package (windows) + set -euo pipefail + name="ctx-${GITHUB_REF_NAME}-${{ matrix.target }}" + mkdir "$name" + cp "target/${{ matrix.target }}/release/ctx" README.md CHANGELOG.md LICENSE-MIT LICENSE-APACHE "$name/" + tar czf "$name.tar.gz" "$name" + shasum -a 256 "$name.tar.gz" > "$name.tar.gz.sha256" + + - name: Package and checksum (Windows) if: runner.os == 'Windows' shell: pwsh run: | @@ -88,80 +116,117 @@ jobs: New-Item -ItemType Directory -Path $name Copy-Item target/${{ matrix.target }}/release/ctx.exe, README.md, CHANGELOG.md, LICENSE-MIT, LICENSE-APACHE $name/ Compress-Archive -Path $name -DestinationPath "$name.zip" - (Get-FileHash "$name.zip" -Algorithm SHA256).Hash.ToLower() + " $name.zip" | Out-File -Encoding ascii "$name.zip.sha256" + $hash = (Get-FileHash "$name.zip" -Algorithm SHA256).Hash.ToLower() + [IO.File]::WriteAllText("$name.zip.sha256", "$hash $name.zip`n", [Text.Encoding]::ASCII) - - name: Upload artifact - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: ctx-${{ matrix.target }} path: | ctx-*.tar.gz* ctx-*.zip* + if-no-files-found: error - # Plugin/binary version lockstep: plugin.json is generated from the crate - # version by `ctx harness init --mode plugin`, so both target plugins match the tag by - # construction -- this job asserts that (failing the release otherwise) - # and packages the plugin scaffold as a release artifact. plugin: - needs: [check-version, test] + needs: release-gates runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v4 - - - name: Setup Rust - uses: dtolnay/rust-toolchain@stable - - - name: Verify plugin version lockstep and package plugin - run: ./scripts/release-plugin-check.sh "${GITHUB_REF_NAME#v}" - - - name: Upload plugin artifacts - uses: actions/upload-artifact@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" + - name: Verify plugin/binary lockstep and package plugins + run: | + scripts/release-plugin-check.sh "${GITHUB_REF_NAME#v}" + sha256sum ctx-*-plugin-*.zip > plugin-SHA256SUMS + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: ctx-agent-plugins path: | ctx-claude-plugin-*.zip ctx-codex-plugin-*.zip + plugin-SHA256SUMS + if-no-files-found: error - github-release: - needs: [build, plugin] + publish: + name: publish crate + needs: [release-gates, build, plugin] runs-on: ubuntu-latest + environment: release + permissions: + contents: read steps: - - name: Download artifacts - uses: actions/download-artifact@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: - path: dist - merge-multiple: true - - # One aggregated SHA256SUMS over every artifact (consumed by - # `ctx self-update` for download verification); the per-artifact - # .sha256 files are kept for manual spot checks. - - name: Aggregate SHA256SUMS - run: | - cd dist - sha256sum ctx-*.tar.gz ctx-*.zip > SHA256SUMS - cat SHA256SUMS - - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 + persist-credentials: false + - uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with: - files: dist/* - generate_release_notes: true + toolchain: "1.91" + - name: Publish agentis-ctx + run: cargo publish --locked + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - publish: - needs: build + github-release: + name: publish GitHub Release and provenance + needs: [release-gates, build, plugin, publish] runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + attestations: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + with: + path: downloaded - - name: Verify both feature combos package cleanly + - name: Assemble release payload and aggregate checksums run: | - cargo publish --dry-run - cargo publish --dry-run --no-default-features + set -euo pipefail + mkdir dist + version="${GITHUB_REF_NAME#v}" + expected=( + "ctx-${GITHUB_REF_NAME}-x86_64-unknown-linux-gnu.tar.gz" + "ctx-${GITHUB_REF_NAME}-x86_64-apple-darwin.tar.gz" + "ctx-${GITHUB_REF_NAME}-aarch64-apple-darwin.tar.gz" + "ctx-${GITHUB_REF_NAME}-x86_64-pc-windows-msvc.zip" + "ctx-claude-plugin-${version}.zip" + "ctx-codex-plugin-${version}.zip" + ) + for archive in "${expected[@]}"; do + mapfile -t matches < <(find downloaded -type f -name "$archive") + test "${#matches[@]}" -eq 1 + cp -n "${matches[0]}" "dist/$archive" + done + while IFS= read -r checksum; do + (cd "$(dirname "$checksum")" && sha256sum -c "$(basename "$checksum")") + done < <(find downloaded -type f -name '*.sha256') + (cd downloaded/ctx-agent-plugins && sha256sum -c plugin-SHA256SUMS) + find downloaded -type f -name '*.sha256' -exec cp -n {} dist/ \; + cp downloaded/ctx-agent-plugins/plugin-SHA256SUMS dist/ + cp downloaded/release-notes/release-notes.md release-notes.md + cd dist + sha256sum "${expected[@]}" > SHA256SUMS + cat SHA256SUMS - - name: Publish to crates.io - run: cargo publish - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + - name: Attest release artifact provenance + uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 + with: + subject-checksums: dist/SHA256SUMS + + - name: Create GitHub Release from reviewed changelog notes + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2 + with: + body_path: release-notes.md + files: | + dist/* + fail_on_unmatched_files: true + generate_release_notes: false diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index db8615f..48a2f25 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -23,16 +23,16 @@ jobs: if: github.repository == 'agentis-tools/ctx' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: # Full history: churn metrics look back over a 90-day window fetch-depth: 0 - name: Setup Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 - name: Cache cargo - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: | ~/.cargo/bin/ diff --git a/.gitignore b/.gitignore index 484d618..c492f10 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,7 @@ specs/ # Release plugin packaging output (scripts/release-plugin-check.sh) ctx-claude-plugin-*.zip +ctx-codex-plugin-*.zip +release-notes.md +__pycache__/ +*.pyc diff --git a/AGENTS.md b/AGENTS.md index 14aeddd..13a4bd9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,32 +1,54 @@ -# context Development Guidelines - -Auto-generated from all feature plans. Last updated: 2025-12-16 - -## Active Technologies -- Rust 1.91+ (Edition 2021) + rusqlite 0.32, tree-sitter, reqwest 0.12, tiktoken-rs 0.9, sqlite-vec 0.1.6, rmcp 0.11.0, rayon 1.10, rustyline 17 (001-ctx-roadmap) -- SQLite (rusqlite) + DuckDB (analytical queries via analytics module) (001-ctx-roadmap) - -- Rust 1.91+ (Edition 2021) (001-ctx-roadmap) - -## Project Structure - -```text -src/ -tests/ +# ctx contributor instructions + + + +ctx is the `agentis-ctx` Rust package and installs the `ctx` binary. The root +package is not a Cargo workspace; `perf/` is an isolated, unpublished harness. +Rust 1.91 is the minimum supported version and the edition is 2021. + +## Read before changing the repository + +- [`governance/agent-workflow.md`](governance/agent-workflow.md) defines the + contributor workflow. +- [`governance/versioning.md`](governance/versioning.md) is the canonical SemVer + and compatibility policy. +- [`governance/guardrails.md`](governance/guardrails.md) distinguishes + automated enforcement from human review. +- [`governance/releasing.md`](governance/releasing.md) is maintainer-only release + procedure. + +`docs/ is public product documentation` and the user manual. Internal policy, +maintainer procedures, CI governance, and agent rules belong in `governance/`, +never in `docs/`. + +## Invariants + +- Root `Cargo.toml` `[package].version` is the only manually edited product + version. Use `python3 scripts/version.py`; do not hand-edit lockfile versions. +- Ordinary PRs do not bump versions. Release preparation must use the tooling, + update reviewed changelog notes, and receive the required labels/review. +- Treat CLI flags/defaults, JSON, config, persisted schemas/indexes, Rust API, + MCP/plugins, exits, platforms/packaging, and self-update as contracts. +- Add an Unreleased `CHANGELOG.md` entry for product behavior. Never hide a + break in prose or update a contract snapshot without reviewing SemVer impact. +- Generated harness hooks/plugins/checksums/release notes are not hand-edited. +- Never tag, publish, release, push unrelated changes, weaken gates, or change + repository settings without explicit authorization. + +## Validation + +```bash +python3 scripts/version.py show +python3 scripts/check-governance.py check +python3 -m unittest discover -s tests/versioning -p 'test_*.py' +cargo fmt --all -- --check +cargo clippy --all-targets --all-features -- -D warnings +cargo test --locked --all-features +cargo test --locked --no-default-features +scripts/ci.sh ``` -## Commands - -cargo test [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNOLOGIES] cargo clippy - -## Code Style - -Rust 1.91+ (Edition 2021): Follow standard conventions - -## Recent Changes -- 001-ctx-roadmap: Added Rust 1.91+ (Edition 2021) + rusqlite 0.32, tree-sitter, reqwest 0.12, tiktoken-rs 0.9, sqlite-vec 0.1.6, rmcp 0.11.0, rayon 1.10, rustyline 17 - -- 001-ctx-roadmap: Added Rust 1.91+ (Edition 2021) - - - +Use `rg` for text discovery. When a current ctx binary/index is available, use +`ctx map`, `ctx query`, `ctx similar`, `ctx check`, and +`ctx score --against ` to complement source inspection. Report checks +that sandbox/network/platform limits prevent; do not call them passed. diff --git a/CHANGELOG.md b/CHANGELOG.md index a21955f..de9c25e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Internal + +- Add deterministic versioning, release governance, compatibility checks, supply-chain policy, and artifact provenance guardrails. + +### Security + +- Refresh compatible locked dependencies to remediate actionable RustSec advisories and document narrowly scoped, time-bounded transitive exceptions. + ## [0.3.4] - 2026-07-12 ### Added diff --git a/CLAUDE.md b/CLAUDE.md index 2f1629b..2e2da97 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,27 +1,30 @@ -## Code intelligence (ctx) +# Claude operating instructions for ctx -This project uses [ctx](https://github.com/saldestechnology/ctx) for code -intelligence. Prefer its index over grepping when exploring: + -- `ctx map --budget 2000` -- token-budgeted architectural overview (also runs - automatically at session start via hooks). -- `ctx query find ` / `ctx search ` -- locate symbols; follow up - with `ctx source ` and `ctx explain `. -- `ctx similar ` -- check for an existing implementation before - writing a new function. -- `ctx check` -- architecture rules from `.ctx/rules.toml`; keep it clean. - Do not edit `.ctx/rules.toml` -- it encodes project policy. -- `ctx score --against main` -- quality delta of your changes - (complexity, duplication, rule violations, symbol churn). Address - regressions before finishing. +Follow [`AGENTS.md`](AGENTS.md) as the root contributor contract. Read +[`governance/agent-workflow.md`](governance/agent-workflow.md) before editing +and [`governance/versioning.md`](governance/versioning.md) before touching any +compatibility or release surface. `docs/ is public product documentation`; +internal instructions and maintainer policy belong only under `governance/`. -Hook scripts under `.claude/hooks/ctx/` are generated by `ctx harness init`; -never edit them by hand. +## ctx-assisted development -## Project tracking (Linear) +Prefer the repository index for code intelligence, then verify against source: -Work is tracked in Linear under the **agentis** team (key `AGE`), project -**ctx**: https://linear.app/itkonsult/project/ctx-7625ddcc6dcb +- `ctx map --budget 2000` +- `ctx query find ` / `ctx search ` +- `ctx source ` / `ctx explain ` +- `ctx similar ` before adding an implementation +- `ctx check` and `ctx score --against ` before handoff -When creating issues for this repo, file them under the `AGE` team and the -`ctx` project. +Do not edit generated `.claude/hooks/ctx/`, `.codex/` harness files, plugin +manifests, release notes, lockfile versions, or CLI contract snapshots by hand. +Use their repository scripts. Never bypass a compatibility/version/security +gate or describe a human-review rule as automatically enforced. + +## Project tracking + +Work is tracked in Linear under team **agentis** (`AGE`), project **ctx**: +https://linear.app/itkonsult/project/ctx-7625ddcc6dcb. New repository issues +belong to that team/project when issue creation is explicitly requested. diff --git a/Cargo.lock b/Cargo.lock index c0de8b0..0afbebd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,7 +60,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "version_check", ] @@ -77,7 +77,7 @@ dependencies = [ "once_cell", "serde", "version_check", - "zerocopy 0.8.31", + "zerocopy 0.8.54", ] [[package]] @@ -107,6 +107,12 @@ dependencies = [ "equator", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -118,9 +124,9 @@ dependencies = [ [[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", @@ -133,15 +139,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", ] @@ -168,9 +174,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arbitrary" @@ -189,20 +195,20 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "arrow" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e833808ff2d94ed40d9379848a950d995043c7fb3e81a30b383f4c6033821cc" +checksum = "378530e55cd479eda3c14eb345310799717e6f76d0c332041e8487022166b471" dependencies = [ "arrow-arith", "arrow-array", @@ -218,23 +224,23 @@ dependencies = [ [[package]] name = "arrow-arith" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad08897b81588f60ba983e3ca39bda2b179bdd84dced378e7df81a5313802ef8" +checksum = "a0ab212d2c1886e802f51c5212d78ebbcbb0bec980fff9dadc1eb8d45cd0b738" dependencies = [ "arrow-array", "arrow-buffer", "arrow-data", "arrow-schema", "chrono", - "num", + "num-traits", ] [[package]] name = "arrow-array" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8548ca7c070d8db9ce7aa43f37393e4bfcf3f2d3681df278490772fd1673d08d" +checksum = "cfd33d3e92f207444098c75b42de99d329562be0cf686b307b097cc52b4e999e" dependencies = [ "ahash 0.8.12", "arrow-buffer", @@ -242,30 +248,34 @@ dependencies = [ "arrow-schema", "chrono", "half", - "hashbrown 0.16.1", - "num", + "hashbrown 0.17.1", + "num-complex", + "num-integer", + "num-traits", ] [[package]] name = "arrow-buffer" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e003216336f70446457e280807a73899dd822feaf02087d31febca1363e2fccc" +checksum = "0c6cd424c2693bcdbc150d843dc9d4d137dd2de4782ce6df491ad11a3a0416c0" dependencies = [ "bytes", "half", - "num", + "num-bigint", + "num-traits", ] [[package]] name = "arrow-cast" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919418a0681298d3a77d1a315f625916cb5678ad0d74b9c60108eb15fd083023" +checksum = "4c5aefb56a2c02e9e2b30746241058b85f8983f0fcff2ba0c6d09006e1cded7f" dependencies = [ "arrow-array", "arrow-buffer", "arrow-data", + "arrow-ord", "arrow-schema", "arrow-select", "atoi", @@ -274,27 +284,28 @@ dependencies = [ "comfy-table", "half", "lexical-core", - "num", + "num-traits", "ryu", ] [[package]] name = "arrow-data" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5c64fff1d142f833d78897a772f2e5b55b36cb3e6320376f0961ab0db7bd6d0" +checksum = "3c88210023a2bfee1896af366309a3028fc3bcbd6515fa29a7990ee1baa08ee0" dependencies = [ "arrow-buffer", "arrow-schema", "half", - "num", + "num-integer", + "num-traits", ] [[package]] name = "arrow-ord" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8f82583eb4f8d84d4ee55fd1cb306720cddead7596edce95b50ee418edf66f" +checksum = "1bffd8fd2579286a5d63bac898159873e5094a79009940bcb42bbfce4f19f1d0" dependencies = [ "arrow-array", "arrow-buffer", @@ -305,9 +316,9 @@ dependencies = [ [[package]] name = "arrow-row" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d07ba24522229d9085031df6b94605e0f4b26e099fb7cdeec37abd941a73753" +checksum = "bab5994731204603c73ba69267616c50f80780774c6bb0476f1f830625115e0c" dependencies = [ "arrow-array", "arrow-buffer", @@ -318,32 +329,32 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3aa9e59c611ebc291c28582077ef25c97f1975383f1479b12f3b9ffee2ffabe" +checksum = "f633dbfdf39c039ada1bf9e34c694816eb71fbb7dc78f613993b7245e078a1ed" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", ] [[package]] name = "arrow-select" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c41dbbd1e97bfcaee4fcb30e29105fb2c75e4d82ae4de70b792a5d3f66b2e7a" +checksum = "8cd065c54172ac787cf3f2f8d4107e0d3fdc26edba76fdf4f4cc170258942222" dependencies = [ "ahash 0.8.12", "arrow-array", "arrow-buffer", "arrow-data", "arrow-schema", - "num", + "num-traits", ] [[package]] name = "arrow-string" -version = "56.2.0" +version = "58.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f5183c150fbc619eede22b861ea7c0eebed8eaac0333eaa7f6da5205fd504d" +checksum = "29dd7cda3ab9692f43a2e4acc444d760cc17b12bb6d8232ddf64e9bab7c06b42" dependencies = [ "arrow-array", "arrow-buffer", @@ -351,7 +362,7 @@ dependencies = [ "arrow-schema", "arrow-select", "memchr", - "num", + "num-traits", "regex", "regex-syntax", ] @@ -389,28 +400,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "async-trait" version = "0.1.89" @@ -419,7 +408,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -439,9 +428,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "av-scenechange" @@ -458,7 +447,7 @@ dependencies = [ "num-traits", "pastey 0.1.1", "rayon", - "thiserror 2.0.17", + "thiserror 2.0.18", "v_frame", "y4m", ] @@ -479,9 +468,9 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.6" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f" +checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38" dependencies = [ "arrayvec", ] @@ -500,9 +489,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.1" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bit-set" @@ -533,24 +522,24 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bitstream-io" -version = "4.9.0" +version = "4.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757" +checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f" dependencies = [ - "core2", + "no_std_io2", ] [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -569,49 +558,50 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "2f3f6da4992df95bbcd9af42a6c7dcb994498fc9048230405f3b36ff7cd3f145" dependencies = [ "borsh-derive", + "bytes", "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +checksum = "3ae8fb4fb5740e4b2c4884ff95f5f32f5e8479db1e8fd8eb49ddbe09eb09bb7c" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "bstr" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" dependencies = [ "memchr", "regex-automata", - "serde", + "serde_core", ] [[package]] name = "built" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" +checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9" [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytecheck" @@ -637,9 +627,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "d6aedf8ae72766347502cf3cb4f41cf5e9cc37d28bee90f1fdaaae15f9cf9424" [[package]] name = "byteorder" @@ -655,9 +645,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cast" @@ -697,11 +687,22 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -713,9 +714,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -723,9 +724,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -735,21 +736,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clipboard-win" @@ -768,26 +769,26 @@ 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 = "comfy-table" -version = "7.1.2" +version = "7.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d05af1e006a2407bedef5af410552494ce5be9090444dbbcb57258c1af3d56" +checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" dependencies = [ - "strum 0.26.3", - "strum_macros 0.26.4", + "crossterm", + "unicode-segmentation", "unicode-width", ] [[package]] name = "compact_str" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" +checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab" dependencies = [ "castaway", "cfg-if", @@ -800,15 +801,14 @@ dependencies = [ [[package]] name = "console" -version = "0.15.11" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", - "once_cell", "unicode-width", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -826,11 +826,40 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "tiny-keccak", ] +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" +dependencies = [ + "cookie", + "document-features", + "idna", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -841,6 +870,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -848,19 +887,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "core2" -version = "0.4.0" +name = "cpufeatures" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ - "memchr", + "libc", ] [[package]] name = "cpufeatures" -version = "0.2.17" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" dependencies = [ "libc", ] @@ -876,18 +915,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -895,18 +934,40 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.13.0", + "crossterm_winapi", + "parking_lot", + "rustix 0.38.44", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] [[package]] name = "crunchy" @@ -955,7 +1016,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -969,7 +1030,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -980,7 +1041,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -991,23 +1052,23 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "dary_heap" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d2e3287df1c007e74221c49ca10a95d557349e54b3a75dc2fb14712c751f04" +checksum = "8b1e3a325bc115f096c8b77bbf027a7c2592230e70be2d985be950d3d5e60ebe" dependencies = [ "serde", ] [[package]] name = "der" -version = "0.7.10" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a69dedd701da44b0536442edf09c81a64b0ab97a7a4a5e3d1971f00027cbc63d" dependencies = [ "pem-rfc7468", "zeroize", @@ -1027,7 +1088,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -1048,7 +1109,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -1058,7 +1119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -1121,30 +1182,40 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", ] [[package]] name = "duckdb" -version = "1.4.3" +version = "1.10504.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7eeb487dde618b9f6ab26a451775ad5fac3fabe1ca2b64cbbe90b105f264ccd" +checksum = "0b9b997383221efd999a362448a0866c54b9a2cb7d4da8cd4903ead4df9f8eaa" dependencies = [ "arrow", "cast", + "comfy-table", "fallible-iterator", "fallible-streaming-iterator", "hashlink 0.10.0", "libduckdb-sys", "num-integer", "rust_decimal", - "strum 0.27.2", + "strum", ] [[package]] @@ -1155,15 +1226,15 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "ena" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" dependencies = [ "log", ] @@ -1206,7 +1277,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -1239,16 +1310,18 @@ checksum = "d817e038c30374a4bcb22f94d0a8a0e216958d4c3dcde369b1439fec4bdda6e6" [[package]] name = "exr" -version = "1.74.0" +version = "1.74.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be" +checksum = "711fe42c9964295e01ee3fba3f9fe0e1d24b98886950d68efe81b1c76e21adf3" dependencies = [ "bit_field", "half", "lebe", "miniz_oxide", + "num-complex", + "pulp", "rayon-core", - "smallvec 1.15.1", + "smallvec", "zune-inflate", ] @@ -1277,44 +1350,32 @@ dependencies = [ [[package]] name = "fastembed" -version = "5.4.0" +version = "5.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d719825156b62586040fd0e5653a4f7bc0ad9caf6c7ec38cb18f1a08ee0384" +checksum = "545e4fb17fc48768ff36c2a3854aa5b0b809d0ed595ab5530fa8ac94f31bd0ea" dependencies = [ "anyhow", "hf-hub", "image", "ndarray", "ort", + "safetensors", + "serde", "serde_json", "tokenizers", ] [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fax" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" -dependencies = [ - "fax_derive", -] - -[[package]] -name = "fax_derive" -version = "0.2.0" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" [[package]] name = "fd-lock" @@ -1323,7 +1384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", - "rustix", + "rustix 1.1.4", "windows-sys 0.59.0", ] @@ -1338,14 +1399,12 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", - "windows-sys 0.60.2", ] [[package]] @@ -1356,13 +1415,13 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", - "libz-rs-sys", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -1386,6 +1445,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -1427,9 +1492,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -1442,9 +1507,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -1452,15 +1517,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -1469,38 +1534,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -1510,7 +1575,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -1526,9 +1590,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -1544,18 +1608,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", "wasm-bindgen", ] [[package]] name = "gif" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" dependencies = [ "color_quant", "weezl", @@ -1576,9 +1652,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.12" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", "bytes", @@ -1602,7 +1678,7 @@ dependencies = [ "cfg-if", "crunchy", "num-traits", - "zerocopy 0.8.31", + "zerocopy 0.8.54", ] [[package]] @@ -1629,7 +1705,7 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -1637,6 +1713,19 @@ name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", + "serde", + "serde_core", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "hashlink" @@ -1664,9 +1753,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hf-hub" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629d8f3bbeda9d148036d6b0de0a3ab947abd08ce90626327fc3547a49d59d97" +checksum = "aef3982638978efa195ff11b305f51f1f22f4f0a6cabee7af79b383ebee6a213" dependencies = [ "dirs", "http", @@ -1674,15 +1763,21 @@ dependencies = [ "libc", "log", "native-tls", - "rand 0.9.2", + "rand 0.9.5", "reqwest", "serde", "serde_json", - "thiserror 2.0.17", - "ureq 2.12.1", - "windows-sys 0.60.2", + "thiserror 2.0.18", + "ureq", + "windows-sys 0.61.2", ] +[[package]] +name = "hmac-sha256" +version = "1.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec9d92d097f4749b64e8cc33d924d9f40a2d4eb91402b458014b781f5733d60f" + [[package]] name = "home" version = "0.5.12" @@ -1694,9 +1789,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -1733,9 +1828,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.8.1" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -1747,27 +1842,25 @@ dependencies = [ "httparse", "itoa", "pin-project-lite", - "pin-utils", - "smallvec 1.15.1", + "smallvec", "tokio", "want", ] [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", "hyper-util", "rustls", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.4", + "webpki-roots", ] [[package]] @@ -1788,14 +1881,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", - "futures-core", "futures-util", "http", "http-body", @@ -1814,9 +1906,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1838,12 +1930,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1851,9 +1944,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -1864,29 +1957,29 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", - "smallvec 1.15.1", + "smallvec", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -1898,15 +1991,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -1930,15 +2023,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", - "smallvec 1.15.1", + "smallvec", "utf8_iter", ] [[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", @@ -1946,9 +2039,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.25" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +checksum = "2adf14691c72bcfc1058740436a35bdd3ae9c07d1a941ef00b749e9ea16aefa7" dependencies = [ "crossbeam-deque", "globset", @@ -1962,9 +2055,9 @@ dependencies = [ [[package]] name = "image" -version = "0.25.9" +version = "0.25.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" dependencies = [ "bytemuck", "byteorder-lite", @@ -1980,8 +2073,8 @@ dependencies = [ "rayon", "rgb", "tiff", - "zune-core 0.5.0", - "zune-jpeg 0.5.7", + "zune-core", + "zune-jpeg", ] [[package]] @@ -1996,30 +2089,30 @@ dependencies = [ [[package]] name = "imgref" -version = "1.12.0" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" +checksum = "89194689a993ab15268672e99e7b0e19da2da3268ac682e8f02d29d4d1434cd7" [[package]] name = "indexmap" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", ] [[package]] name = "indicatif" -version = "0.17.11" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" dependencies = [ "console", - "number_prefix", "portable-atomic", "unicode-width", + "unit-prefix", "web-time", ] @@ -2036,9 +2129,9 @@ dependencies = [ [[package]] name = "inotify-sys" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +checksum = "c033f80b2c113cdf91ab7a33faa9cbc014726dcad99880c8609af2a370edf37d" dependencies = [ "libc", ] @@ -2051,24 +2144,14 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[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.9" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" -dependencies = [ - "memchr", - "serde", -] +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "is_terminal_polyfill" @@ -2105,35 +2188,36 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] [[package]] name = "kqueue" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +checksum = "273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5" dependencies = [ "kqueue-sys", "libc", @@ -2141,11 +2225,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.4" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.13.0", "libc", ] @@ -2250,15 +2334,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.178" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libduckdb-sys" -version = "1.4.3" +version = "1.10504.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8c60c2d269e63ae5197e4fe9075efffed35dfda0095a5ac8b41f3c765b18456" +checksum = "94e67523a40ee3da30411e00e243990b3760d91877202ab2f39c03ab34f8dbfc" dependencies = [ "cc", "flate2", @@ -2273,9 +2357,9 @@ dependencies = [ [[package]] name = "libfuzzer-sys" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2" dependencies = [ "arbitrary", "cc", @@ -2283,19 +2367,17 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.11" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" dependencies = [ - "bitflags 2.10.0", "libc", - "redox_syscall 0.6.0", ] [[package]] @@ -2310,25 +2392,28 @@ dependencies = [ ] [[package]] -name = "libz-rs-sys" -version = "0.5.4" +name = "linux-raw-sys" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15413ef615ad868d4d65dce091cb233b229419c7c0c4bcaa746c0901c49ff39c" -dependencies = [ - "zlib-rs", -] +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "litrs" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lock_api" @@ -2341,9 +2426,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "loop9" @@ -2360,6 +2445,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "lzma-rust2" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e20f57f9918e5bd7bc58c22cdd70a6afc7375d4dd9683af5f2b34bd3d2bba619" + [[package]] name = "macro_rules_attribute" version = "0.2.2" @@ -2398,9 +2489,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "mime" @@ -2438,9 +2529,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -2466,14 +2557,14 @@ checksum = "e4db6d5580af57bf992f59068d4ea26fd518574ff48d7639b255a36f9de6e7e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "moxcms" -version = "0.7.11" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" dependencies = [ "num-traits", "pxfm", @@ -2481,9 +2572,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ "libc", "log", @@ -2498,9 +2589,9 @@ dependencies = [ [[package]] name = "ndarray" -version = "0.16.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" +checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d" dependencies = [ "matrixmultiply", "num-complex", @@ -2523,7 +2614,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" dependencies = [ - "smallvec 1.15.1", + "smallvec", ] [[package]] @@ -2532,12 +2623,21 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "cfg-if", "cfg_aliases", "libc", ] +[[package]] +name = "no_std_io2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" +dependencies = [ + "memchr", +] + [[package]] name = "nom" version = "7.1.3" @@ -2575,7 +2675,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "crossbeam-channel", "filetime", "fsevent-sys", @@ -2599,25 +2699,11 @@ dependencies = [ "notify", ] -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -2629,6 +2715,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ + "bytemuck", "num-traits", ] @@ -2646,7 +2733,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -2658,17 +2745,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-rational" version = "0.4.2" @@ -2690,17 +2766,11 @@ dependencies = [ "libm", ] -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - [[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" @@ -2710,11 +2780,11 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "onig" -version = "6.5.1" +version = "6.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" +checksum = "0cc3cbf698f9438986c11a880c90a6d04b9de27575afd28bbf45b154b6c709e2" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "libc", "once_cell", "onig_sys", @@ -2722,9 +2792,9 @@ dependencies = [ [[package]] name = "onig_sys" -version = "69.9.1" +version = "69.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc" +checksum = "1e68317604e77e53b85896388e1a803c1d21b74c899ec9e5e1112db90735edd7" dependencies = [ "cc", "pkg-config", @@ -2732,15 +2802,14 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.75" +version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -2753,20 +2822,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "openssl-probe" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.111" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -2782,27 +2851,26 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ort" -version = "2.0.0-rc.10" +version = "2.0.0-rc.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa7e49bd669d32d7bc2a15ec540a527e7764aec722a45467814005725bcd721" +checksum = "d7de3af33d24a745ffb8fab904b13478438d1cd52868e6f17735ef6e1f8bf133" dependencies = [ "ndarray", "ort-sys", - "smallvec 2.0.0-alpha.10", + "smallvec", "tracing", + "ureq", ] [[package]] name = "ort-sys" -version = "2.0.0-rc.10" +version = "2.0.0-rc.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2aba9f5c7c479925205799216e7e5d07cc1d4fa76ea8058c60a9a30f6a4e890" +checksum = "d7b497d21a8b6fbb4b5a544f8fadb77e801a09ae0add9e411d31c6f89e3c1e90" dependencies = [ - "flate2", - "pkg-config", - "sha2", - "tar", - "ureq 3.1.4", + "hmac-sha256", + "lzma-rust2", + "ureq", ] [[package]] @@ -2823,8 +2891,8 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", - "smallvec 1.15.1", + "redox_syscall", + "smallvec", "windows-link", ] @@ -2842,15 +2910,15 @@ checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" [[package]] name = "pastey" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pem-rfc7468" -version = "0.7.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" dependencies = [ "base64ct", ] @@ -2888,7 +2956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand 0.8.5", + "rand 0.8.7", ] [[package]] @@ -2901,7 +2969,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -2915,29 +2983,23 @@ dependencies = [ [[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" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "png" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "crc32fast", "fdeflate", "flate2", @@ -2946,24 +3008,24 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.4" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -2980,7 +3042,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.31", + "zerocopy 0.8.54", ] [[package]] @@ -3021,39 +3083,39 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.23.9", + "toml_edit 0.25.12+spec-1.1.0", ] [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" dependencies = [ "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -3077,14 +3139,34 @@ dependencies = [ ] [[package]] -name = "pxfm" -version = "0.1.27" +name = "pulp" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8" +checksum = "046aa45b989642ec2e4717c8e72d677b13edd831a4d3b6cf37d9a3e54912496a" dependencies = [ - "num-traits", + "bytemuck", + "cfg-if", + "libm", + "num-complex", + "paste", + "pulp-wasm-simd-flag", + "raw-cpuid", + "reborrow", + "version_check", ] +[[package]] +name = "pulp-wasm-simd-flag" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8f70e07b9c3962945a74e59ca1c511bba65b6419468acc217c457d93f3c740" + +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + [[package]] name = "qoi" version = "0.4.1" @@ -3102,19 +3184,19 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash 2.1.3", "rustls", "socket2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -3122,20 +3204,21 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.13" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" dependencies = [ "bytes", - "getrandom 0.3.4", + "getrandom 0.4.3", "lru-slab", - "rand 0.9.2", + "rand 0.10.2", + "rand_pcg", "ring", - "rustc-hash 2.1.1", + "rustc-hash 2.1.3", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -3143,23 +3226,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" dependencies = [ "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "quote" -version = "1.0.42" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -3170,6 +3253,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -3188,9 +3277,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -3199,12 +3288,23 @@ 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.3", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] @@ -3224,7 +3324,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -3233,18 +3333,33 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +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 = "rav1e" version = "0.8.1" @@ -3272,19 +3387,19 @@ dependencies = [ "num-traits", "paste", "profiling", - "rand 0.9.2", + "rand 0.9.5", "rand_chacha 0.9.0", "simd_helpers", - "thiserror 2.0.17", + "thiserror 2.0.18", "v_frame", "wasm-bindgen", ] [[package]] name = "ravif" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285" +checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45" dependencies = [ "avif-serialize", "imgref", @@ -3295,6 +3410,15 @@ dependencies = [ "rgb", ] +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.13.0", +] + [[package]] name = "rawpointer" version = "0.2.1" @@ -3303,9 +3427,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -3333,21 +3457,18 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "reborrow" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags 2.10.0", -] +checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" [[package]] name = "redox_syscall" -version = "0.6.0" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", ] [[package]] @@ -3356,7 +3477,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", "thiserror 1.0.69", ] @@ -3367,9 +3488,9 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3389,14 +3510,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" dependencies = [ "aho-corasick", "memchr", @@ -3406,9 +3527,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" dependencies = [ "aho-corasick", "memchr", @@ -3417,9 +3538,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rend" @@ -3432,9 +3553,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.26" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", @@ -3475,14 +3596,14 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.4", + "webpki-roots", ] [[package]] name = "rgb" -version = "0.8.52" +version = "0.8.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" [[package]] name = "ring" @@ -3492,7 +3613,7 @@ checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -3500,9 +3621,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.45" +version = "0.7.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +checksum = "2297bf9c81a3f0dc96bc9521370b88f054168c29826a75e89c55ff196e7ed6a1" dependencies = [ "bitvec", "bytecheck", @@ -3518,9 +3639,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.45" +version = "0.7.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +checksum = "84d7b42d4b8d06048d3ac8db0eb31bcb942cbeb709f0b5f2b2ebde398d3038f5" dependencies = [ "proc-macro2", "quote", @@ -3537,13 +3658,13 @@ dependencies = [ "base64 0.22.1", "chrono", "futures", - "pastey 0.2.1", + "pastey 0.2.3", "pin-project-lite", "rmcp-macros", "schemars", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -3559,7 +3680,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -3568,28 +3689,29 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cdbe9230a57259b37f7257d0aff38b8c9dbda3513edba2105e59b130189d82f" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink 0.9.1", "libsqlite3-sys", - "smallvec 1.15.1", + "smallvec", ] [[package]] name = "rust_decimal" -version = "1.39.0" +version = "1.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35affe401787a9bd846712274d97654355d21b2a2c092a3139aabe31e9022282" +checksum = "be2a24f50780bc85f09cc6ac299bdf1424302742d77221106859c9d8b102126a" dependencies = [ "arrayvec", "borsh", "bytes", "num-traits", - "rand 0.8.5", + "rand 0.8.7", "rkyv", "serde", "serde_json", + "wasm-bindgen", ] [[package]] @@ -3600,28 +3722,41 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[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 = "rustix" -version = "1.1.2" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.13.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.12.1", "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "log", "once_cell", @@ -3634,9 +3769,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "web-time", "zeroize", @@ -3644,9 +3779,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "ring", "rustls-pki-types", @@ -3655,9 +3790,9 @@ dependencies = [ [[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 = "rustyline" @@ -3665,7 +3800,7 @@ version = "17.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e902948a25149d50edc1a8e0141aad50f54e22ba83ff988cf8f7c9ef07f50564" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", "cfg-if", "clipboard-win", "fd-lock", @@ -3683,9 +3818,22 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "safetensors" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b079b829cb27a1c3c374341345ed2e8b2c0c839034522cee576c140bd7f846" +dependencies = [ + "hashbrown 0.16.1", + "libc", + "serde", + "serde_json", + "tempfile", +] [[package]] name = "same-file" @@ -3698,18 +3846,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] [[package]] name = "schemars" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" dependencies = [ "chrono", "dyn-clone", @@ -3721,14 +3869,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301858a4023d78debd2353c7426dc486001bddc91ae31a76fb1f55132f7e2633" +checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -3745,12 +3893,12 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "security-framework" -version = "2.11.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.10.0", - "core-foundation", + "bitflags 2.13.0", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -3758,9 +3906,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -3799,7 +3947,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -3810,20 +3958,20 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -3854,15 +4002,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simd_helpers" @@ -3881,36 +4029,30 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "smallvec" -version = "1.15.1" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "2.0.0-alpha.10" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d44cfb396c3caf6fbfd0ab422af02631b69ddd96d2eff0b0f0724f9024051b" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3952,9 +4094,9 @@ dependencies = [ [[package]] name = "sqlite-vec" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec77b84fb8dd5f0f8def127226db83b5d1152c5bf367f09af03998b76ba554a" +checksum = "d0ba424237a9a5db2f6071f193319e2b6a32f7f3961debb2fbbfe67067abce3f" dependencies = [ "cc", ] @@ -3989,32 +4131,13 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" - [[package]] name = "strum" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.2", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.111", + "strum_macros", ] [[package]] @@ -4026,7 +4149,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -4048,9 +4171,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.111" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -4074,17 +4197,17 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "system-configuration" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.10.0", - "core-foundation", + "bitflags 2.13.0", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -4106,9 +4229,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", @@ -4117,14 +4240,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", - "rustix", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -4156,11 +4279,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -4171,32 +4294,32 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "tiff" -version = "0.10.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" dependencies = [ "fax", "flate2", "half", "quick-error", "weezl", - "zune-jpeg 0.4.21", + "zune-jpeg", ] [[package]] @@ -4255,9 +4378,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -4265,9 +4388,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -4297,7 +4420,7 @@ dependencies = [ "monostate", "onig", "paste", - "rand 0.9.2", + "rand 0.9.5", "rayon", "rayon-cond", "regex", @@ -4305,7 +4428,7 @@ dependencies = [ "serde", "serde_json", "spm_precompiled", - "thiserror 2.0.17", + "thiserror 2.0.18", "unicode-normalization-alignments", "unicode-segmentation", "unicode_categories", @@ -4313,13 +4436,13 @@ dependencies = [ [[package]] name = "tokio" -version = "1.48.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", - "mio 1.1.1", + "mio 1.2.1", "pin-project-lite", "socket2", "tokio-macros", @@ -4328,13 +4451,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -4359,9 +4482,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -4370,12 +4493,10 @@ dependencies = [ [[package]] name = "tokio-test" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7" +checksum = "3f6d24790a10a7af737693a3e8f1d03faef7e6ca0cc99aae5066f533766de545" dependencies = [ - "async-stream", - "bytes", "futures-core", "tokio", "tokio-stream", @@ -4383,9 +4504,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.17" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -4417,9 +4538,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] @@ -4435,28 +4556,28 @@ dependencies = [ "serde_spanned", "toml_datetime 0.6.11", "toml_write", - "winnow", + "winnow 0.7.15", ] [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", - "toml_datetime 0.7.3", + "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow", + "winnow 1.0.3", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.3", ] [[package]] @@ -4467,9 +4588,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -4482,20 +4603,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.0", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -4512,9 +4633,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -4529,14 +4650,14 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] @@ -4609,15 +4730,15 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[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 = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization-alignments" @@ -4625,14 +4746,14 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43f613e4fa046e69818dd287fdc4bc78175ff20331479dab6e1b0f98d57062de" dependencies = [ - "smallvec 1.15.1", + "smallvec", ] [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" @@ -4652,6 +4773,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +[[package]] +name = "unit-prefix" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" + [[package]] name = "untrusted" version = "0.9.0" @@ -4660,47 +4787,33 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" +checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ "base64 0.22.1", + "cookie_store", + "der", "flate2", "log", "native-tls", - "once_cell", + "percent-encoding", "rustls", "rustls-pki-types", "serde", "serde_json", "socks", - "url", - "webpki-roots 0.26.11", -] - -[[package]] -name = "ureq" -version = "3.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" -dependencies = [ - "base64 0.22.1", - "der", - "log", - "native-tls", - "percent-encoding", - "rustls-pki-types", - "socks", "ureq-proto", - "utf-8", + "utf8-zero", "webpki-root-certs", + "webpki-roots", ] [[package]] name = "ureq-proto" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f" +checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ "base64 0.22.1", "http", @@ -4710,9 +4823,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", @@ -4721,10 +4834,10 @@ dependencies = [ ] [[package]] -name = "utf-8" -version = "0.7.6" +name = "utf8-zero" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" [[package]] name = "utf8_iter" @@ -4740,9 +4853,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.23.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "ea5fab0d6c3c01ae70085a09cb03d4c7a1d6314e2b3e075392783396d724ca0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -4807,44 +4920,42 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", "rustversion", + "serde", "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4852,22 +4963,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] @@ -4887,9 +4998,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -4907,27 +5018,18 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3e3b5f5e80bc89f30ce8d0343bf4e5f12341c51f3e26cbeecbc7c85443e85b" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.4", -] - -[[package]] -name = "webpki-roots" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" dependencies = [ "rustls-pki-types", ] @@ -4990,7 +5092,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -5001,7 +5103,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -5272,24 +5374,33 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wyz" @@ -5307,7 +5418,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", - "rustix", + "rustix 1.1.4", ] [[package]] @@ -5318,9 +5429,9 @@ checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" [[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", @@ -5329,13 +5440,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", "synstructure", ] @@ -5351,11 +5462,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" dependencies = [ - "zerocopy-derive 0.8.31", + "zerocopy-derive 0.8.54", ] [[package]] @@ -5366,52 +5477,52 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[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.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -5420,9 +5531,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -5431,13 +5542,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.118", ] [[package]] @@ -5456,9 +5567,15 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.5.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f936044d677be1a1168fae1d03b583a285a5dd9d8cbf7b24c23aa1fc775235" +checksum = "b142a20ec14a91d5bc708c1dc21b080c550113d8aa77afa29635673a65dd02c5" + +[[package]] +name = "zmij" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2f034a4bebf216c9e4b7083603e024cf930873fd67830cfb083c9fa33129d9" [[package]] name = "zopfli" @@ -5474,15 +5591,9 @@ dependencies = [ [[package]] name = "zune-core" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" - -[[package]] -name = "zune-core" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111f7d9820f05fd715df3144e254d6fc02ee4088b0644c0ffd0efc9e6d9d2773" +checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" [[package]] name = "zune-inflate" @@ -5495,18 +5606,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" -dependencies = [ - "zune-core 0.4.12", -] - -[[package]] -name = "zune-jpeg" -version = "0.5.7" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d915729b0e7d5fe35c2f294c5dc10b30207cc637920e5b59077bfa3da63f28" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ - "zune-core 0.5.0", + "zune-core", ] diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..33cbf29 --- /dev/null +++ b/deny.toml @@ -0,0 +1,56 @@ +[graph] +all-features = true +exclude-dev = false + +[advisories] +version = 2 +yanked = "deny" +ignore = [ + # Transitive through fastembed/image; no maintained replacement is selectable. + # Reassess with the next fastembed update, no later than 2026-09-30. + "RUSTSEC-2024-0436", + # ring's affected QUIC/large single-buffer AES paths are not used by ctx. A + # fixed ring currently conflicts with the tree-sitter 0.20 cc constraint. + # Remove after the parser stack moves, no later than 2026-09-30. + "RUSTSEC-2025-0009", + # ctx enables rmcp's stdio transport only; the vulnerable Streamable HTTP + # server transport is neither enabled nor exposed. Upgrade rmcp by 2026-09-30. + "RUSTSEC-2026-0189", +] + +[licenses] +version = 2 +confidence-threshold = 0.66 +unused-allowed-license = "warn" +allow = [ + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "BSL-1.0", + "CC0-1.0", + "CDLA-Permissive-2.0", + "ISC", + "MIT", + "MIT-0", + "MPL-2.0", + "NCSA", + "OpenSSL", + "Unicode-3.0", + "Unlicense", + "Zlib", +] + +[bans] +multiple-versions = "warn" +wildcards = "deny" +highlight = "all" +deny = [] +skip = [] +skip-tree = [] + +[sources] +unknown-registry = "deny" +unknown-git = "deny" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] diff --git a/governance/agent-workflow.md b/governance/agent-workflow.md new file mode 100644 index 0000000..e5aa030 --- /dev/null +++ b/governance/agent-workflow.md @@ -0,0 +1,46 @@ +# AI and human contributor workflow + +## Before editing + +Read root `AGENTS.md`, `CLAUDE.md`, this file, `versioning.md`, and any policy +relevant to the task. Inspect the worktree and preserve unrelated changes. +Use a feature branch/worktree for release or governance changes. `docs/` is +public product documentation; internal policy belongs in `governance/`. + +Use ctx for discovery when its index is available, but verify generated or +security-sensitive conclusions against source. Do not edit generated harness +hooks, Cargo lockfiles, plugin manifests, checksums, release notes, or CLI +contract snapshots by hand when their generator exists. + +## While changing contracts + +- Add a categorized Unreleased changelog entry for product behavior. Internal + changes may use a maintainer-approved `skip-changelog` label. +- Treat CLI, JSON, config, schemas/indexes, library API, MCP/plugins, exits, + packaging/platforms, and self-update as compatibility surfaces. +- Run `scripts/check-contracts.py capture --binary target/release/ctx` only after + reviewing the change. Snapshot updates never make a breaking change safe by + themselves. +- Do not change the product version during ordinary feature/fix work. Release + preparation uses `scripts/version.py` and the `release-preparation` label. +- Never create/push tags, publish crates, create releases, or change repository + settings without explicit authorization. +- Never weaken/skip a gate to make CI green. Document sandbox/environment + limitations and run the closest deterministic subset instead. + +## Required validation + +Run the narrowest relevant tests while iterating, then `scripts/ci.sh` before +handoff when the environment supports it. At minimum run formatting, Clippy, +relevant tests, `scripts/check-agent-docs.sh`, version checks, and contract +checks for the touched surfaces. Report any check not run or not enforceable. + +Release changes additionally require `scripts/release-check.sh v`. +Review generated notes and artifact names. Scripts never authorize a publish. + +## Handoff + +State what changed, compatibility/version impact, changelog impact, tests, +remaining human review, and external settings not enforced from the repo. Do +not claim branch protection, signatures, semantic compatibility, or provenance +unless the corresponding external check actually succeeded. diff --git a/governance/contracts/cli.json b/governance/contracts/cli.json new file mode 100644 index 0000000..172bd86 --- /dev/null +++ b/governance/contracts/cli.json @@ -0,0 +1,794 @@ +{ + "commands": { + "ctx": { + "options": { + "--check": "--check", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--version": "With --version: also query GitHub for a newer release" + }, + "subcommands": [ + "audit", + "check", + "complexity", + "diff", + "duplicates", + "embed", + "explain", + "graph", + "harness", + "hotspots", + "index", + "map", + "query", + "review", + "score", + "search", + "self-update", + "semantic", + "shell", + "similar", + "smart", + "snapshot", + "source", + "sql" + ] + }, + "ctx audit": { + "options": { + "--categories": "--categories Categories to check (comma-separated: complexity,duplication,coverage,modularity,naming)", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--incremental": "--incremental Only audit changed files (not yet implemented)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--min-score": "--min-score Minimum score threshold (fails if below, 0.0-10.0)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--output": "-o, --output Output format (text, json, markdown) [default: text]", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx check": { + "options": { + "--against": "--against Only report violations where at least one endpoint's file changed since REF (for no_new_dependents: where the new dependent changed)", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--list": "--list Print the parsed rules and layer membership counts, then exit 0", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--rules": "--rules Path to the rules file (default: .ctx/rules.toml)", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx complexity": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--output": "--output Output format (table, json) [default: table]", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--threshold": "--threshold Fan-out threshold (default: 10, flag > 50 as critical) [default: 10]", + "--warnings-only": "-w, --warnings-only Only show functions exceeding threshold" + }, + "subcommands": [] + }, + "ctx diff": { + "options": { + "--changes-only": "--changes-only Only include changed files (no context expansion)", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "--depth Call graph context depth [default: 1]", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens in output [default: 8000]", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--staged": "--staged Include staged changes only", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--summary": "--summary Include change summary" + }, + "subcommands": [] + }, + "ctx duplicates": { + "options": { + "--against": "--against Only report pairs where at least one function is in a file changed relative to this git reference (e.g. `main`)", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--fail-on-found": "--fail-on-found Exit with code 1 when any near-duplicate pair is reported (default: informational, exit 0)", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--min-tokens": "--min-tokens Ignore functions with fewer than N normalized tokens [default: 50]", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--threshold": "--threshold Jaccard similarity threshold (0.0-1.0) over normalized token shingles. Breaking change from the old percent-based, line-oriented threshold: 0.85 means 85% of 5-token shingles are shared, not that 85% of lines match. Values below 0.5 are clamped to 0.5 [default: 0.85]" + }, + "subcommands": [] + }, + "ctx embed": { + "options": { + "--batch-size": "--batch-size Batch size for embedding generation [default: 50]", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--force": "--force Force re-embedding of all symbols", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--openai": "--openai", + "--provider": "Deprecated alias for `--provider openai` (requires OPENAI_API_KEY)", + "--serial": "--serial Disable parallel embedding (single-threaded)", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--verbose": "-v, --verbose Show verbose output", + "--watch": "-w, --watch Watch for index changes and auto-embed new symbols" + }, + "subcommands": [] + }, + "ctx explain": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--file": "-f, --file Filter by file path pattern (glob syntax: \"src/parser/*.rs\")", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--kind": "-k, --kind Filter by symbol kind (function, method, struct, etc.)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx graph": { + "options": { + "--by-file": "--by-file Group by file/module instead of individual symbols", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "--depth Maximum depth for symbol-level graphs [default: 3]", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--filter": "--filter Only show dependencies involving these files (comma-separated)", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--output": "--output Output format (dot, mermaid, json) [default: dot]", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx harness": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [ + "compat", + "doctor", + "init" + ] + }, + "ctx harness compat": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--require": "--require Required version: a bare version (\"0.2\" means \"at least 0.2.0\") or a semver requirement expression (\"^0.2\", \">=0.2, <0.4\")", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx harness doctor": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx harness init": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--force": "--force Overwrite user-modified generated files (except .ctx/rules.toml)", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--mode": "--mode What to scaffold: local hooks or a distributable plugin Possible values: - local: Project-local hooks plus target-specific settings or guidance - plugin: A distributable target plugin with hooks, skill, and marketplace [default: local]", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--target": "--target Harness to target (unknown values exit 2 listing supported targets) Possible values: - claude: Claude Code (hooks, settings, skills, plugin manifest) - codex: Codex (project hooks, AGENTS.md guidance, skills, plugin manifest) [default: claude]" + }, + "subcommands": [] + }, + "ctx hotspots": { + "options": { + "--against": "--against Only analyze files changed relative to this git ref (e.g. main)", + "--by": "--by Rank by file or by symbol (symbol churn is approximated by its file's churn) Possible values: - file: One row per indexed file - symbol: One row per function/method (churn approximated by the file's churn) [default: file]", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--limit": "--limit Maximum number of entries to show [default: 20]", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--min-churn": "--min-churn Minimum number of commits for a file to be analyzed [default: 2]", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--since": "How far back to count commits (git --since date spec) [default: \"6 months ago\"]", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx index": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--force": "--force Force full reindex (clears existing database)", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--pattern": "-p, --pattern File patterns or paths to include (glob syntax supported)", + "--serial": "--serial Disable parallel indexing (single-threaded)", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--verbose": "-v, --verbose Show verbose output", + "--watch": "-w, --watch Watch for changes and reindex automatically" + }, + "subcommands": [] + }, + "ctx map": { + "options": { + "--budget": "--budget Token budget for the map (tokens are estimated as ceil(chars / 4)) [default: 2000]", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--focus": "--focus Focus on a file path/glob or symbol name: boosts the matching symbols and their direct neighbors in the ranking", + "--format": "-f, --format Output format (text, markdown, json) Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: text]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx query": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [ + "callers", + "deps", + "files", + "find", + "graph", + "impact", + "stats" + ] + }, + "ctx query callers": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "-d, --depth Maximum depth to traverse [default: 3]", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--file": "-f, --file Filter by file path pattern (glob syntax: \"src/parser/*.rs\")", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx query deps": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "-d, --depth Maximum depth to traverse [default: 3]", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--file": "-f, --file Filter by file path pattern (glob syntax: \"src/parser/*.rs\")", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--kind": "-k, --kind Filter by symbol kind (function, method, struct, etc.)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx query files": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx query find": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--file": "-f, --file Filter by file path pattern (glob syntax: \"src/parser/*.rs\")", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--kind": "-k, --kind Filter by symbol kind (function, struct, etc.)", + "--limit": "-l, --limit Maximum number of results [default: 20]", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx query graph": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "-d, --depth Maximum depth [default: 5]", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--output": "--output Output format (text, json, dot) [default: text]", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx query impact": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "-d, --depth Maximum depth [default: 5]", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx query stats": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx review": { + "options": { + "--changes-only": "--changes-only Only include changed files (no context expansion)", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "--depth Call graph context depth [default: 1]", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--include-comments": "--include-comments Include PR comments in output", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens in output [default: 8000]", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--repo": "--repo Repository (owner/name, auto-detected if not specified)", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--summary": "--summary Include change summary" + }, + "subcommands": [] + }, + "ctx score": { + "options": { + "--against": "--against Git reference to compare against. The default (HEAD) scores uncommitted changes; use your default branch (main/master) to score a whole branch or PR [default: HEAD]", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--fail-on": "--fail-on Fail (exit 1) when any comma-separated condition `metric OP value` holds; OP is one of >=, <=, >, < (e.g. \"new_duplication>0\")", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx search": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--limit": "-l, --limit Maximum number of results [default: 20]", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--output": "--output Output format (table, json) [default: table]", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx self-update": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--version": "--version Install this exact release (allows downgrades) instead of the latest" + }, + "subcommands": [] + }, + "ctx semantic": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--limit": "-l, --limit Maximum number of results [default: 10]", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--openai": "--openai", + "--output": "--output Output format (table, json) [default: table]", + "--provider": "Deprecated alias for `--provider openai` (requires OPENAI_API_KEY)", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx shell": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--history": "--history History file location", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-history": "--no-history Disable command history", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--vi": "--vi Use vi editing mode (default: emacs)" + }, + "subcommands": [] + }, + "ctx similar": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--keyword": "--keyword Use FTS5 keyword search instead of embeddings (works with zero embeddings and no API key)", + "--limit": "-l, --limit Maximum number of results [default: 10]", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--openai": "--openai", + "--provider": "Deprecated alias for `--provider openai` (requires OPENAI_API_KEY)", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx smart": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--depth": "--depth Call graph expansion depth [default: 2]", + "--dry-run": "--dry-run Preview selection without generating context", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--explain": "--explain Show selection reasoning for each file", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens in output [default: 8000]", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--openai": "--openai", + "--provider": "Deprecated alias for `--provider openai` (requires OPENAI_API_KEY)", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--top": "--top Number of initial semantic matches to find [default: 10]" + }, + "subcommands": [] + }, + "ctx snapshot": { + "options": { + "--churn-window": "--churn-window ", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--force": "--force Overwrite an existing partition for HEAD", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--since": "How far back to count per-file churn (git --since date spec) [default: \"90 days ago\"]", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [ + "backfill" + ] + }, + "ctx snapshot backfill": { + "options": { + "--churn-window": "--churn-window ", + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--every": "--every Sample every Nth commit (the newest commit is always included) [default: 1]", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--since": "How far back to count per-file churn (git --since date spec); the upper bound is anchored to each commit's date [default: \"90 days ago\"]", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx source": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--file": "-f, --file Filter by file path pattern (glob syntax: \"src/parser/*.rs\")", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json Emit machine-readable JSON to stdout (see docs/json-output.md)", + "--kind": "-k, --kind Filter by symbol kind (function, method, struct, etc.)", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--stats": "--stats Print stats (file count, total size, time taken)" + }, + "subcommands": [] + }, + "ctx sql": { + "options": { + "--count-only": "--count-only Only count tokens, don't output file contents", + "--encoding": "--encoding Tokenizer encoding to use (cl100k_base, o200k_base, p50k_base) [default: cl100k_base]", + "--fail-on-rows": "--fail-on-rows Exit 1 if the query returns >= 1 row (for gate usage)", + "--file": "--file Read the query from a file (mutually exclusive with the QUERY arg)", + "--format": "-f, --format Output format Possible values: - xml - markdown - md - plain - text: Plain text (used by `ctx map`; alias for plain elsewhere) - json [default: xml]", + "--help": "-h, --help Print help (see a summary with '-h')", + "--ignore": "-i, --ignore Additional ignore patterns (can be repeated)", + "--json": "--json", + "--max-rows": "--max-rows Cap returned rows (0 = unlimited) [default: 1000]", + "--max-tokens": "--max-tokens Maximum tokens to include in output (omits files to fit budget, does not truncate file contents)", + "--no-default-ignores": "--no-default-ignores Disable built-in ignore patterns", + "--no-gitignore": "--no-gitignore Disable .gitignore pattern matching", + "--no-stream": "--no-stream Buffer all output before printing (instead of streaming)", + "--no-tree": "--no-tree Disable project tree in output", + "--output": "Alias for --output json", + "--schema": "--schema Print the public schema reference and exit", + "--show-sizes": "--show-sizes Show file sizes in project tree", + "--snapshots": "Load snapshot partitions from DIR (default .ctx/snapshots) as in-memory tables snap.files / snap.symbols / snap.dup_pairs / snap.meta for trend queries (see `ctx snapshot`). Pass a custom dir with `--snapshots=DIR`", + "--stats": "--stats Print stats (file count, total size, time taken)", + "--timeout": "--timeout Abort the query after N seconds [default: 10]" + }, + "subcommands": [] + } + }, + "schema": 1 +} diff --git a/governance/current-state.md b/governance/current-state.md new file mode 100644 index 0000000..1d285a8 --- /dev/null +++ b/governance/current-state.md @@ -0,0 +1,79 @@ +# Repository governance baseline + +This inventory records the repository state observed before the governance +system was introduced. It is an internal maintainer record, not product +documentation. + +## Versioning and packaging + +- The repository is not a Cargo workspace. The root is one publishable package, + `agentis-ctx`, which owns both the `ctx` binary and the `ctx` library. +- `perf/` is a separate, explicitly isolated Cargo package named `ctx-perf`. + It is versioned `0.0.0`, is not published, and depends on the root package by + path. +- `Cargo.toml` `[package].version` is the existing and most appropriate + authoritative version. `Cargo.lock` and `perf/Cargo.lock` repeat the resolved + local package version. Runtime version strings use `CARGO_PKG_VERSION`. +- `ctx --version`, JSON envelopes, MCP server metadata, snapshots, gate logs, + generated harness files, plugin manifests, and self-update HTTP headers all + embed the Cargo package version. +- There are no committed Homebrew, Scoop, Winget, Nix, or similar + package-manager manifests on `main`. Plugin manifests are generated during + release and checked against the tag version. +- Rust 1.91 is the declared minimum supported Rust version. The crate uses Rust + 2021 edition. + +## Release flow + +- Releases are triggered only by pushing a `v*` Git tag. +- The existing release workflow compares the tag with Cargo metadata, tests, + builds four target archives, packages Claude/Codex plugins, publishes the + crate, and creates a GitHub Release. +- Archives have per-file checksums and the GitHub Release contains an aggregate + `SHA256SUMS`, which `ctx self-update` verifies. +- GitHub-generated notes, rather than the reviewed `CHANGELOG.md` section, were + used as release notes. Crate publication and GitHub Release creation could + run independently, allowing inconsistent partial outcomes. +- `CHANGELOG.md` follows Keep a Changelog and has an Unreleased section, but no + deterministic tool validated headings, links, empty releases, or tag state. + +## Compatibility and quality surfaces + +- The published Rust library is a public API surface. No semantic-compatibility + comparison against `main` existed. +- CLI commands/flags/defaults, exit codes, configuration, JSON envelopes, + SQLite index schema, snapshot/SQL schemas, MCP tools, generated plugins, and + self-update artifact naming are compatibility-sensitive. +- CI ran formatting, Clippy, a three-platform test matrix, publish dry-runs, + and an advisory performance harness. It did not validate version/changelog + policy, dependency advisories, licenses, dependency sources, or release + provenance. +- Architecture checks and score gates exist in ctx itself, but this repository + currently commits only `.ctx/config.toml`, not `.ctx/rules.toml`; therefore + no repository architecture rules were enforced. +- Generated documentation build output and `.ctx` indexes are ignored. Cargo + lockfiles, the public website source, benchmark schema, and performance + baselines are committed. + +## Repository settings and documentation boundary + +- The GitHub API reported that `main` had no branch protection configured at + the time of this inventory. Repository files cannot enforce review counts, + force-push restrictions, or required-check selection; those remain explicit + administrator actions documented in `guardrails.md`. +- `docs/` is the public ctx manual and website source. No internal policy + directory existed. Internal policy is therefore introduced only under + `governance/`. +- Root `AGENTS.md` was auto-generated and contained malformed command guidance. + `CLAUDE.md` covered ctx/Linear usage but no release or compatibility workflow. + +## Minimal target architecture + +Keep `Cargo.toml` as the sole manually edited version source. Add one standard +library for version/changelog operations, a deterministic checker and release +note renderer, focused tests, a PR policy workflow, dependency/license/source +checks, Rust API compatibility checks, hardened tag release gates, checksummed +artifacts with GitHub provenance attestations, and concise contributor intent +in `AGENTS.md`/`CLAUDE.md`. Contracts that cannot be classified safely by a +machine are routed to explicit labelled human review rather than described as +automatically enforced. diff --git a/governance/guardrails.md b/governance/guardrails.md new file mode 100644 index 0000000..f9e9146 --- /dev/null +++ b/governance/guardrails.md @@ -0,0 +1,72 @@ +# Repository guardrails + +## Enforced in repository code and CI + +- `scripts/version.py check` validates SemVer, both lockfiles, Cargo metadata, + compiled `ctx --version`, tag naming, changelog state, and self-update/release + conventions. +- `scripts/check-contracts.py` makes the committed CLI surface reproducible. + Removed commands/flags require `breaking-change`, `contract-review`, the + correct SemVer increase, and a `BREAKING:` entry. +- `cargo-semver-checks` compares the published Rust library surface with the PR + base. Intentional exceptions require a reviewed baseline/version decision; + the check is not advisory. +- Compatibility-sensitive source paths require `contract-review`, even where + the CLI snapshot has no detectable removal. +- CI enforces rustfmt, Clippy warnings-as-errors, tests on Linux/macOS/Windows, + all/minimal feature combinations, version/governance tests, publish dry-runs, + changelog policy, dependency advisories/licenses/sources, and contract state. +- Release CI repeats stronger gates, validates generated plugins and artifacts, + publishes checksums, and creates GitHub artifact provenance attestations. +- Dependabot proposes weekly Cargo and GitHub Actions updates. `deny.toml` + permits only approved licenses, denies unknown registries/git sources, and + checks advisories and duplicate/wildcard dependency policy. +- CODEOWNERS routes workflows, governance, release scripts, Cargo metadata, + compatibility surfaces, and security policy to maintainers. + +No prose-only rule above is described as enforced unless a script/workflow +implements it. + +## Human-review requirements + +Automation cannot determine every semantic break. Maintainers must review +default behavior, human/JSON semantics, configuration precedence, migrations, +MCP/plugin behavior, exit codes, platform support, package installation, and +self-update behavior. Security disclosure timing and contributor attribution +also require judgment. Labels are acknowledgements, not proof of compatibility. + +Tag signature verification is recommended but not enforced because no durable +maintainer keyring is committed. Performance CI remains advisory until its +baseline policy is explicitly promoted. + +## GitHub repository settings + +At baseline, the GitHub API reported `main` was not protected. These settings +cannot be enforced by committed files. A repository administrator must create +a branch ruleset that: + +- requires pull requests and at least one approving review; +- requires CODEOWNERS review and dismissal after new commits; +- requires conversation resolution and linear history; +- blocks force pushes, deletion, and direct pushes (including administrators + except documented emergency bypass); +- requires the CI, Policy, docs, and ctx-analysis checks selected after these + workflows land; +- requires branches to be current before merge; +- restricts tag creation/deletion for `v*` to release maintainers. + +The `release` deployment environment must require release-maintainer approval +and limit deployments to protected `v*` tags. Label permissions must also be +limited to trusted contributors: CI validates required label names, but a +label alone cannot prove who acknowledged the risk. + +Administrators must audit those settings after workflow/check names change. +Until configured, repository-local CI can report failures but cannot prevent a +privileged direct push; this document deliberately does not claim otherwise. + +## Documentation boundary + +`docs/` is public product documentation and the user manual. Maintainer +procedure, CI policy, architecture governance, and agent operating rules live +only in `governance/`, root agent files, scripts, and workflows. The structural +governance check prevents the named policy files from being placed in `docs/`. diff --git a/governance/releasing.md b/governance/releasing.md new file mode 100644 index 0000000..f7bc51d --- /dev/null +++ b/governance/releasing.md @@ -0,0 +1,78 @@ +# Release procedure + +Releases are constructed entirely from repository state and require no hidden +local files. Archives are not claimed to be byte-for-byte reproducible across +runner images. The release source is a reviewed commit on `main`; the trigger +is an annotated `v` tag. CI requires the peeled tag commit to be in +`origin/main`. The workflow does not accept release branches or a manual +version input. + +## Prepare a release pull request + +1. Ensure every user-visible change has a categorized Unreleased changelog + entry. Allowed categories are Added, Changed, Deprecated, Removed, Fixed, + Security, Documentation, and Internal. Put `BREAKING:` first in every + incompatible entry and include migration instructions. +2. Keep embargoed vulnerability detail out of the public changelog until the + coordinated disclosure point. Use a neutral security entry if necessary. +3. Run `python3 scripts/version.py bump patch|minor|major`. The command moves + Unreleased notes into a dated release section and updates both lockfiles. +4. Apply the `release-preparation` label. Apply `breaking-change` and + `contract-review` when applicable. +5. Run `scripts/release-check.sh v$(python3 scripts/version.py show)` and review + the generated `release-notes.md` without committing that generated file. +6. Merge only after all required checks and CODEOWNERS review pass. + +Changelog bullets should link PRs and preserve contributor credit when +practical. An empty release is rejected unless `--allow-empty` is deliberately +used and justified in the release PR. + +## Tag and publish + +From the reviewed `main` commit: + +```bash +version="$(python3 scripts/version.py show)" +git tag -a "v$version" -m "ctx $version" +git push origin "v$version" +``` + +Signed tags are recommended and are a human-review requirement until the +repository has a maintained signing-key policy; CI currently enforces the +name/content relationship, not cryptographic tag signatures. + +The `publish` job targets the protected GitHub environment named `release`. +Administrators must configure required release-maintainer reviewers for that +environment. The repository currently uses a scoped crates.io token; migrate +to crates.io trusted publishing when it is configured and verified for this +repository. + +The tag workflow repeats governance, formatting, Clippy, all-feature and +minimal-feature tests, CLI/Rust compatibility checks, publish dry-runs, plugin +lockstep checks, and dependency policy before publishing. It derives reviewed +GitHub release notes from `CHANGELOG.md`, not commit-title heuristics. It builds +four target archives, creates per-archive and aggregate SHA-256 checksums, +publishes `agentis-ctx`, waits for that publication, then creates the GitHub +Release and provenance attestations. + +If crate publication succeeds but GitHub Release creation fails, rerun the +failed workflow jobs; do not create a second tag or bump the version. Cargo +publication is immutable. Never move or reuse a published tag. + +## Post-release verification + +- Verify crates.io shows the exact version and expected feature set. +- Verify every documented platform archive, both plugin archives, + `SHA256SUMS`, and provenance attestations exist. +- Download one archive, verify its checksum, and run `ctx --version`. +- Verify `ctx self-update --version ` on a supported platform. +- Confirm the GitHub notes match the reviewed changelog and no embargoed detail + was disclosed. +- Leave a fresh empty Unreleased heading; `version.py` already creates it. + +Package-manager manifests are not currently committed. If introduced, they +must be generated or added to `version.py check` before being described as +release-supported. + +This is maintainer policy under `governance/`; public usage documentation stays +under `docs/`. diff --git a/governance/versioning.md b/governance/versioning.md new file mode 100644 index 0000000..3d9a45a --- /dev/null +++ b/governance/versioning.md @@ -0,0 +1,92 @@ +# Versioning policy + +ctx follows [Semantic Versioning 2.0.0](https://semver.org/). The only manually +edited project version is `[package].version` in the root `Cargo.toml`. +`Cargo.lock`, `perf/Cargo.lock`, compiled binaries, generated plugins, release +archives, and release tags are derived from or checked against it. + +`perf/` is an independent, unpublished harness at `0.0.0`; it does not share +the product release number. + +## Release levels + +Patch releases contain backwards-compatible bug/correctness fixes, +performance improvements without intentional incompatibility, internal +refactors, documentation fixes, compatible dependency updates, and compatible +packaging fixes. + +Minor releases contain backwards-compatible functionality: new commands or +flags with compatible defaults, additive fields in explicitly extensible +formats, new analysis capabilities/integrations, and deprecations that retain +existing behavior. + +Major releases contain incompatible changes: command/flag removal or rename, +incompatible semantics/defaults/configuration/machine-output changes, an index +format change without migration, incompatible Rust library API changes, +exit-code changes, platform removal, an MSRV increase outside policy, or an +incompatible plugin/MCP/protocol/integration contract. + +## Pre-1.0 compatibility + +Until 1.0, `0.MINOR.0` may intentionally break compatibility. +`0.MINOR.PATCH` must remain compatible within that minor line. Every break +still needs maintainer acknowledgement (`breaking-change` and +`contract-review` labels), a prominent `BREAKING:` changelog entry, the +required version increase, migration guidance, and deprecation first when +reasonably possible. Pre-1.0 is not permission for accidental breakage. + +## Contract classification + +- Human-readable output is best-effort stable. Scripts must use documented + JSON. Deliberate structural/default/exit-status changes still require review. +- Documented JSON fields may be added when the object is documented as + extensible. Removing, renaming, changing types/meaning, or changing envelope + and exit semantics is breaking. +- SQLite index `PRAGMA user_version`, public SQL schema, snapshot Parquet + schema, gate-log schema, and benchmark schemas must be bumped for + incompatible persisted changes. Migration or a clear rebuild path is + required. +- Configuration additions with compatible defaults are minor. Removing keys, + changing meaning, or changing precedence/default behavior incompatibly is + breaking. +- MCP tool names, arguments, result schemas, protocol behavior, generated + plugin manifests/hooks, and compatibility floors are machine contracts. +- Shell completion text itself is not stable, but command/option availability + and accepted values are. Removing completion-visible surfaces is breaking. +- Package-manager names, archive names/contents, supported targets, checksums, + crates.io identity/features, and installation commands are contracts. +- `ctx self-update` tag parsing (`v`), artifact mapping, checksum + verification, target support, downgrade behavior, and exit codes are + contracts. +- Exit code 0/1/2/3 meanings are stable. Reassignment or command-specific + divergence is breaking. + +The CLI snapshot and Rust API compatibility job detect a useful subset of +breaks. Changes to sensitive paths require explicit contract review because +machines cannot reliably classify behavioral compatibility. See +`guardrails.md`; never claim that semantic behavior is fully automatic. + +## Version operations + +```bash +python3 scripts/version.py show +cargo build --locked --release --no-default-features +python3 scripts/version.py check --binary target/release/ctx +python3 scripts/version.py bump patch +python3 scripts/version.py bump minor +python3 scripts/version.py set 0.4.0 +``` + +Mutation commands refuse a dirty tree, invalid/regressing versions, and empty +Unreleased notes unless an explicit override is supplied. They update the +manifest, both lockfiles, release heading/date, and comparison links, print +every changed file, and never commit, tag, push, publish, or access the +network. Re-running the current version is a no-op. + +Raising `rust-version` is a compatibility decision. Before 1.0 it requires at +least a minor release and contract review; after 1.0 it requires a major +release unless the project has announced a time-based MSRV policy in this file. +No such exception currently exists. + +Internal policy belongs in `governance/`; `docs/` remains the public product +manual. diff --git a/perf/Cargo.lock b/perf/Cargo.lock index ec7bfc1..eaf1e08 100644 --- a/perf/Cargo.lock +++ b/perf/Cargo.lock @@ -348,9 +348,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "d6aedf8ae72766347502cf3cb4f41cf5e9cc37d28bee90f1fdaaae15f9cf9424" [[package]] name = "byteorder" @@ -953,9 +953,9 @@ checksum = "d817e038c30374a4bcb22f94d0a8a0e216958d4c3dcde369b1439fec4bdda6e6" [[package]] name = "exr" -version = "1.74.1" +version = "1.74.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6be87932f10230a4339ab394edd8e4611fcb72553d8295b4d52ea55249b3daa5" +checksum = "711fe42c9964295e01ee3fba3f9fe0e1d24b98886950d68efe81b1c76e21adf3" dependencies = [ "bit_field", "half", @@ -1331,7 +1331,7 @@ dependencies = [ "libc", "log", "native-tls", - "rand 0.9.4", + "rand 0.9.5", "reqwest", "serde", "serde_json", @@ -2426,7 +2426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand 0.8.6", + "rand 0.8.7", ] [[package]] @@ -2654,18 +2654,18 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha", "rand_core 0.9.5", @@ -2723,7 +2723,7 @@ dependencies = [ "num-traits", "paste", "profiling", - "rand 0.9.4", + "rand 0.9.5", "rand_chacha", "simd_helpers", "thiserror 2.0.18", @@ -3524,7 +3524,7 @@ dependencies = [ "monostate", "onig", "paste", - "rand 0.9.4", + "rand 0.9.5", "rayon", "rayon-cond", "regex", @@ -4540,9 +4540,9 @@ checksum = "b142a20ec14a91d5bc708c1dc21b080c550113d8aa77afa29635673a65dd02c5" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "bd2f034a4bebf216c9e4b7083603e024cf930873fd67830cfb083c9fa33129d9" [[package]] name = "zopfli" diff --git a/scripts/check-agent-docs.sh b/scripts/check-agent-docs.sh new file mode 100755 index 0000000..c7c641e --- /dev/null +++ b/scripts/check-agent-docs.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -euo pipefail +repo_root="$(cd "$(dirname "$0")/.." && pwd)" +exec python3 "$repo_root/scripts/check-governance.py" check diff --git a/scripts/check-contracts.py b/scripts/check-contracts.py new file mode 100755 index 0000000..7e874dd --- /dev/null +++ b/scripts/check-contracts.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python3 +"""Capture and compare the machine-checkable ctx CLI compatibility surface.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +import re +import subprocess +import sys +import tomllib + +ROOT = Path(__file__).resolve().parents[1] +CONTRACT = ROOT / "governance/contracts/cli.json" +SENSITIVE_PATHS = ( + "src/", "Cargo.toml", "docs/json-output.md", "docs/configuration.md", + "scripts/release-", ".github/workflows/release.yml", "perf/schemas/", +) + + +class ContractError(RuntimeError): + pass + + +def help_text(binary: Path, path: tuple[str, ...]) -> str: + result = subprocess.run( + [str(binary), *path, "--help"], cwd=ROOT, text=True, capture_output=True + ) + if result.returncode: + raise ContractError( + f"{' '.join((binary.name, *path, '--help'))} failed: {result.stderr.strip()}" + ) + return result.stdout + + +def section_lines(text: str, heading: str) -> list[str]: + lines = text.splitlines() + try: + start = lines.index(heading) + 1 + except ValueError: + return [] + output: list[str] = [] + for line in lines[start:]: + if line and not line.startswith(" "): + break + if line.strip(): + output.append(line.strip()) + return output + + +def command_names(text: str) -> list[str]: + names: list[str] = [] + for line in section_lines(text, "Commands:"): + name = line.split()[0] + if name != "help" and re.fullmatch(r"[a-z][a-z0-9-]*", name): + names.append(name) + return sorted(set(names)) + + +def options(text: str) -> dict[str, str]: + result: dict[str, str] = {} + lines = text.splitlines() + in_options = False + current: str | None = None + for raw in lines: + if raw == "Options:": + in_options = True + continue + if in_options and raw and not raw.startswith(" "): + break + if not in_options or not raw.strip(): + continue + longs = re.findall(r"--[a-z][a-z0-9-]*", raw) + if longs: + current = longs[-1] + result[current] = re.sub(r"\s+", " ", raw.strip()) + elif current and raw.startswith(" "): + result[current] += " " + re.sub(r"\s+", " ", raw.strip()) + return dict(sorted(result.items())) + + +def capture(binary: Path) -> dict: + binary = binary.resolve() + if not binary.is_file(): + raise ContractError(f"compiled ctx binary not found: {binary}") + pending: list[tuple[str, ...]] = [()] + commands: dict[str, dict] = {} + while pending: + path = pending.pop(0) + output = help_text(binary, path) + children = command_names(output) + key = "ctx" if not path else "ctx " + " ".join(path) + commands[key] = {"options": options(output), "subcommands": children} + for child in children: + pending.append((*path, child)) + return {"schema": 1, "commands": dict(sorted(commands.items()))} + + +def write_contract(binary: Path) -> None: + CONTRACT.parent.mkdir(parents=True, exist_ok=True) + CONTRACT.write_text( + json.dumps(capture(binary), indent=2, sort_keys=True) + "\n", encoding="utf-8" + ) + print(CONTRACT.relative_to(ROOT)) + + +def load_contract(path: Path = CONTRACT) -> dict: + try: + value = json.loads(path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError) as error: + raise ContractError(f"cannot read {path}: {error}") from error + if value.get("schema") != 1 or not isinstance(value.get("commands"), dict): + raise ContractError(f"{path} is not a CLI contract schema 1 document") + return value + + +def check_snapshot(binary: Path) -> None: + expected = load_contract() + actual = capture(binary) + if actual != expected: + raise ContractError( + "CLI contract snapshot is stale; review the compatibility impact and run " + f"scripts/check-contracts.py capture --binary {binary}" + ) + print("OK: compiled CLI matches governance/contracts/cli.json") + + +def git_output(*args: str) -> str: + result = subprocess.run( + ["git", *args], cwd=ROOT, text=True, capture_output=True + ) + if result.returncode: + raise ContractError(result.stderr.strip() or f"git {' '.join(args)} failed") + return result.stdout + + +def contract_from_ref(reference: str) -> dict | None: + result = subprocess.run( + ["git", "show", f"{reference}:governance/contracts/cli.json"], + cwd=ROOT, + text=True, + capture_output=True, + ) + if result.returncode: + return None + return json.loads(result.stdout) + + +def version_from_ref(reference: str) -> tuple[int, int, int]: + raw = git_output("show", f"{reference}:Cargo.toml") + data = tomllib.loads(raw) + value = data["package"]["version"] + match = re.fullmatch(r"(\d+)\.(\d+)\.(\d+)(?:[-+].*)?", value) + if not match: + raise ContractError(f"base Cargo.toml version is not SemVer: {value}") + return tuple(int(item) for item in match.groups()) + + +def current_version() -> tuple[int, int, int]: + with (ROOT / "Cargo.toml").open("rb") as handle: + value = tomllib.load(handle)["package"]["version"] + match = re.fullmatch(r"(\d+)\.(\d+)\.(\d+)(?:[-+].*)?", value) + if not match: + raise ContractError(f"Cargo.toml version is not SemVer: {value}") + return tuple(int(item) for item in match.groups()) + + +def breaking_notes_section(old: tuple[int, int, int], new: tuple[int, int, int]) -> str: + text = (ROOT / "CHANGELOG.md").read_text(encoding="utf-8") + heading = "Unreleased" if new == old else ".".join(str(item) for item in new) + marker = f"## [{heading}]" + start = text.find(marker) + if start < 0: + raise ContractError(f"CHANGELOG.md is missing {marker}") + end = text.find("\n## [", start + len(marker)) + return text[start : end if end >= 0 else len(text)] + + +def compare_contracts(base: dict, current: dict) -> tuple[list[str], list[str]]: + removed: list[str] = [] + changed: list[str] = [] + base_commands = base.get("commands", {}) + current_commands = current.get("commands", {}) + for command, old in base_commands.items(): + if command not in current_commands: + removed.append(f"command {command}") + continue + new = current_commands[command] + for option in old.get("options", {}): + if option not in new.get("options", {}): + removed.append(f"option {command} {option}") + for option, description in old.get("options", {}).items(): + if option in new.get("options", {}) and new["options"][option] != description: + changed.append(f"option contract {command} {option}") + return removed, changed + + +def pr_policy(base_ref: str, labels: set[str]) -> None: + current = load_contract() + base = contract_from_ref(base_ref) + changed_files = set( + git_output("diff", "--name-only", f"{base_ref}...HEAD").splitlines() + ) + sensitive = sorted( + path for path in changed_files if any(path == prefix or path.startswith(prefix) for prefix in SENSITIVE_PATHS) + ) + if base is None: + print("OK: bootstrapping compatibility contract; no prior snapshot") + return + removed, changed = compare_contracts(base, current) + if (sensitive or changed or removed) and "contract-review" not in labels: + details = ", ".join((sensitive + changed + removed)[:12]) + raise ContractError( + "compatibility-sensitive changes require maintainer label contract-review: " + + details + ) + if removed: + if "breaking-change" not in labels: + raise ContractError( + "removed CLI contracts require maintainer label breaking-change: " + + ", ".join(removed) + ) + old, new = version_from_ref(base_ref), current_version() + compatible_bump = new[0] > old[0] if old[0] > 0 else (new[0] > old[0] or new[1] > old[1]) + if not compatible_bump: + raise ContractError( + f"breaking CLI change requires a major bump (or pre-1.0 minor bump): {old} -> {new}" + ) + if "BREAKING:" not in breaking_notes_section(old, new): + raise ContractError( + "breaking change needs a prominent BREAKING: entry in Unreleased " + "or the release-preparation version section" + ) + print("OK: compatibility-sensitive changes have the required review acknowledgement") + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + for name in ("capture", "check"): + command = commands.add_parser(name) + command.add_argument("--binary", required=True, type=Path) + policy = commands.add_parser("pr-policy") + policy.add_argument("--base", required=True) + policy.add_argument("--labels", default="") + args = parser.parse_args() + try: + if args.command == "capture": + write_contract(args.binary) + elif args.command == "check": + check_snapshot(args.binary) + else: + pr_policy(args.base, {item.strip() for item in args.labels.split(",") if item.strip()}) + return 0 + except (ContractError, OSError, json.JSONDecodeError) as error: + print(f"ERROR: {error}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/check-governance.py b/scripts/check-governance.py new file mode 100755 index 0000000..ff8f5ec --- /dev/null +++ b/scripts/check-governance.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 +"""Repository policy checks that do not belong in the product test suite.""" + +from __future__ import annotations + +import argparse +import datetime as dt +from pathlib import Path +import re +import subprocess +import sys +import tomllib + +ROOT = Path(__file__).resolve().parents[1] +REQUIRED = ( + "governance/current-state.md", + "governance/versioning.md", + "governance/releasing.md", + "governance/guardrails.md", + "governance/agent-workflow.md", +) +FORBIDDEN_DOCS = ( + "docs/versioning.md", "docs/releasing.md", "docs/guardrails.md", + "docs/agent-workflow.md", +) +AGENT_MARKER = "" + + +class GovernanceError(RuntimeError): + pass + + +def git(*args: str) -> str: + result = subprocess.run( + ["git", *args], cwd=ROOT, text=True, capture_output=True + ) + if result.returncode: + raise GovernanceError(result.stderr.strip() or f"git {' '.join(args)} failed") + return result.stdout + + +def structural_check() -> None: + errors: list[str] = [] + for relative in REQUIRED: + if not (ROOT / relative).is_file(): + errors.append(f"missing internal policy file {relative}") + for relative in FORBIDDEN_DOCS: + if (ROOT / relative).exists(): + errors.append(f"internal policy must not be stored in product docs: {relative}") + for relative in ("AGENTS.md", "CLAUDE.md"): + text = (ROOT / relative).read_text(encoding="utf-8") + if AGENT_MARKER not in text: + errors.append(f"{relative} is missing {AGENT_MARKER}") + for required in ("governance/agent-workflow.md", "governance/versioning.md"): + if required not in text: + errors.append(f"{relative} must link to {required}") + if "docs/ is public product documentation" not in text: + errors.append(f"{relative} must state the docs/governance boundary") + for relative in REQUIRED[1:]: + text = (ROOT / relative).read_text(encoding="utf-8") + if "docs/" not in text and relative == "governance/guardrails.md": + errors.append("guardrails.md must state the documentation boundary") + action_files = list((ROOT / ".github/workflows").glob("*.yml")) + action_files += list((ROOT / ".github/workflows").glob("*.yaml")) + action_files += list((ROOT / ".github/actions").glob("**/action.yml")) + action_files += list((ROOT / ".github/actions").glob("**/action.yaml")) + for workflow in sorted(action_files): + for line_number, line in enumerate( + workflow.read_text(encoding="utf-8").splitlines(), 1 + ): + match = re.search(r"\buses:\s*([^\s#]+)", line) + if not match or match.group(1).startswith("./"): + continue + reference = match.group(1).rsplit("@", 1)[-1] + if not re.fullmatch(r"[0-9a-f]{40}", reference): + errors.append( + f"{workflow.relative_to(ROOT)}:{line_number} action must be pinned " + "to a full commit SHA" + ) + deny_lines = (ROOT / "deny.toml").read_text(encoding="utf-8").splitlines() + today = dt.datetime.now(dt.timezone.utc).date() + for line_number, line in enumerate(deny_lines): + if not re.search(r'"RUSTSEC-\d{4}-\d{4}"', line): + continue + window = "\n".join(deny_lines[max(0, line_number - 4) : line_number + 5]) + dates = re.findall(r"\b\d{4}-\d{2}-\d{2}\b", window) + if not dates: + errors.append( + f"deny.toml:{line_number + 1} advisory exception needs a review deadline" + ) + continue + try: + deadline = max(dt.date.fromisoformat(value) for value in dates) + except ValueError as error: + errors.append(f"deny.toml:{line_number + 1} has invalid deadline: {error}") + continue + if deadline < today: + errors.append( + f"deny.toml:{line_number + 1} advisory exception expired {deadline}" + ) + if errors: + raise GovernanceError("\n".join(errors)) + print("OK: governance files and agent instructions respect the docs boundary") + + +def unreleased_body(text: str) -> str: + start = text.find("## [Unreleased]") + if start < 0: + return "" + end = text.find("\n## [", start + 1) + return text[start : end if end >= 0 else len(text)] + + +def unreleased_entries(text: str) -> set[str]: + return { + line.strip() + for line in unreleased_body(text).splitlines() + if line.strip().startswith("- ") + } + + +def manifest_version(text: str) -> str: + try: + value = tomllib.loads(text)["package"]["version"] + except (tomllib.TOMLDecodeError, KeyError, TypeError) as error: + raise GovernanceError(f"cannot read [package].version: {error}") from error + if not isinstance(value, str): + raise GovernanceError("[package].version must be a string") + return value + + +def pr_check(base: str, labels: set[str]) -> None: + changed = set(git("diff", "--name-only", f"{base}...HEAD").splitlines()) + version_changed = False + if "Cargo.toml" in changed: + current_manifest = (ROOT / "Cargo.toml").read_text(encoding="utf-8") + base_manifest = git("show", f"{base}:Cargo.toml") + version_changed = manifest_version(current_manifest) != manifest_version(base_manifest) + product_change = any( + path == "Cargo.toml" + or path.startswith("src/") + or path.startswith(".ctx/") + or path.startswith("docs/") + or path in {"README.md", "install.sh"} + or path.startswith("scripts/release-") + or path == ".github/workflows/release.yml" + for path in changed + ) + if product_change and not version_changed and "skip-changelog" not in labels: + if "CHANGELOG.md" not in changed: + raise GovernanceError( + "user-visible/product changes require an Unreleased CHANGELOG.md entry; " + "a maintainer may apply skip-changelog only for genuinely internal changes" + ) + current_text = (ROOT / "CHANGELOG.md").read_text(encoding="utf-8") + base_text = git("show", f"{base}:CHANGELOG.md") + added = unreleased_entries(current_text) - unreleased_entries(base_text) + if not added: + raise GovernanceError( + "product changes require a newly added Unreleased changelog bullet" + ) + if version_changed and "release-preparation" not in labels: + raise GovernanceError( + "authoritative version changes require maintainer label release-preparation" + ) + print("OK: PR changelog and version-change policy satisfied") + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + commands.add_parser("check") + pr = commands.add_parser("pr") + pr.add_argument("--base", required=True) + pr.add_argument("--labels", default="") + args = parser.parse_args() + try: + structural_check() + if args.command == "pr": + pr_check( + args.base, + {item.strip() for item in args.labels.split(",") if item.strip()}, + ) + return 0 + except (GovernanceError, OSError) as error: + print(f"ERROR: {error}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/ci.sh b/scripts/ci.sh new file mode 100755 index 0000000..5ac2dd4 --- /dev/null +++ b/scripts/ci.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Local equivalent of the deterministic pull-request quality gates. +set -euo pipefail + +repo_root="$(cd "$(dirname "$0")/.." && pwd)" +cd "$repo_root" + +python3 scripts/check-governance.py check +python3 -m unittest discover -s tests/versioning -p 'test_*.py' +cargo fmt --all -- --check +cargo clippy --all-targets --all-features -- -D warnings +cargo test --locked --all-features +cargo test --locked --no-default-features +cargo build --locked --release --no-default-features +python3 scripts/version.py check --binary target/release/ctx +python3 scripts/check-contracts.py check --binary target/release/ctx +cargo publish --locked --dry-run +cargo publish --locked --dry-run --no-default-features diff --git a/scripts/release-check.sh b/scripts/release-check.sh new file mode 100755 index 0000000..714b88a --- /dev/null +++ b/scripts/release-check.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Complete, side-effect-free release gate. Does not tag, publish, or commit. +set -euo pipefail + +if [[ $# -ne 1 || ! "$1" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then + echo "usage: scripts/release-check.sh v" >&2 + exit 2 +fi + +repo_root="$(cd "$(dirname "$0")/.." && pwd)" +cd "$repo_root" +tag="$1" +version="${tag#v}" + +python3 scripts/check-governance.py check +python3 -m unittest discover -s tests/versioning -p 'test_*.py' +python3 scripts/version.py check --tag "$tag" --release --skip-binary +python3 scripts/version.py notes "$version" --output release-notes.md +cargo fmt --all -- --check +cargo clippy --all-targets --all-features -- -D warnings +cargo test --locked --all-features +cargo test --locked --no-default-features +cargo build --locked --release +python3 scripts/version.py check --tag "$tag" --release --binary target/release/ctx +python3 scripts/check-contracts.py check --binary target/release/ctx +cargo publish --locked --dry-run +cargo publish --locked --dry-run --no-default-features + +echo "OK: $tag passed all release gates; release-notes.md is ready for review" diff --git a/scripts/version.py b/scripts/version.py new file mode 100755 index 0000000..2d10b75 --- /dev/null +++ b/scripts/version.py @@ -0,0 +1,500 @@ +#!/usr/bin/env python3 +"""Authoritative ctx version, changelog, and release validation tooling.""" + +from __future__ import annotations + +import argparse +from collections.abc import Mapping +import dataclasses +import datetime as dt +import os +from pathlib import Path +import re +import subprocess +import sys +import tomllib + +ROOT = Path(__file__).resolve().parents[1] +MANIFEST = ROOT / "Cargo.toml" +CHANGELOG = ROOT / "CHANGELOG.md" +LOCKFILES = (ROOT / "Cargo.lock", ROOT / "perf" / "Cargo.lock") +PACKAGE = "agentis-ctx" +ALLOWED_CATEGORIES = { + "Added", "Changed", "Deprecated", "Removed", "Fixed", "Security", + "Documentation", "Internal", +} + + +class PolicyError(RuntimeError): + pass + + +@dataclasses.dataclass(frozen=True) +class SemVer: + major: int + minor: int + patch: int + prerelease: tuple[str, ...] = () + build: tuple[str, ...] = () + + _PATTERN = re.compile( + r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)" + r"(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?" + r"(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$" + ) + + @classmethod + def parse(cls, value: str) -> "SemVer": + match = cls._PATTERN.fullmatch(value) + if not match: + raise PolicyError(f"invalid Semantic Version: {value!r}") + prerelease = tuple(match.group(4).split(".")) if match.group(4) else () + build = tuple(match.group(5).split(".")) if match.group(5) else () + for identifier in prerelease: + if identifier.isdigit() and len(identifier) > 1 and identifier.startswith("0"): + raise PolicyError( + f"invalid Semantic Version {value!r}: numeric prerelease identifiers " + "must not contain leading zeroes" + ) + return cls(*(int(match.group(i)) for i in range(1, 4)), prerelease, build) + + def __str__(self) -> str: + value = f"{self.major}.{self.minor}.{self.patch}" + if self.prerelease: + value += "-" + ".".join(self.prerelease) + if self.build: + value += "+" + ".".join(self.build) + return value + + def precedence(self) -> tuple[object, ...]: + return self.major, self.minor, self.patch + + def compare(self, other: "SemVer") -> int: + if self.precedence() != other.precedence(): + return 1 if self.precedence() > other.precedence() else -1 + if not self.prerelease and not other.prerelease: + return 0 + if not self.prerelease: + return 1 + if not other.prerelease: + return -1 + for left, right in zip(self.prerelease, other.prerelease): + if left == right: + continue + if left.isdigit() and right.isdigit(): + return 1 if int(left) > int(right) else -1 + if left.isdigit() != right.isdigit(): + return -1 if left.isdigit() else 1 + return 1 if left > right else -1 + return (len(self.prerelease) > len(other.prerelease)) - ( + len(self.prerelease) < len(other.prerelease) + ) + + +def manifest_data() -> dict: + with MANIFEST.open("rb") as handle: + return tomllib.load(handle) + + +def current_version() -> SemVer: + package = manifest_data().get("package", {}) + if package.get("name") != PACKAGE: + raise PolicyError( + f"{MANIFEST.relative_to(ROOT)} [package].name must be {PACKAGE!r}" + ) + raw = package.get("version") + if not isinstance(raw, str): + raise PolicyError("Cargo.toml [package].version must be a string") + return SemVer.parse(raw) + + +def local_lock_version(path: Path) -> str: + text = path.read_text(encoding="utf-8") + for block in text.split("[[package]]")[1:]: + name = re.search(r'^name = "([^"]+)"$', block, re.MULTILINE) + if name and name.group(1) == PACKAGE: + version = re.search(r'^version = "([^"]+)"$', block, re.MULTILINE) + if not version: + break + return version.group(1) + raise PolicyError(f"{path.relative_to(ROOT)} has no local {PACKAGE} package entry") + + +def changelog_section(text: str, heading: str) -> str: + marker = f"## [{heading}]" + start = text.find(marker) + if start < 0: + raise PolicyError(f"CHANGELOG.md is missing {marker}") + body_start = text.find("\n", start) + next_heading = text.find("\n## [", body_start + 1) + return text[body_start + 1 : next_heading if next_heading >= 0 else len(text)].strip() + + +def has_release_content(section: str) -> bool: + return any( + line.startswith("- ") + for line in section.splitlines() + if not line.startswith("[Unreleased]:") + ) + + +def validate_changelog(version: SemVer, *, release: bool) -> list[str]: + errors: list[str] = [] + text = CHANGELOG.read_text(encoding="utf-8") + try: + released = changelog_section(text, str(version)) + except PolicyError as error: + errors.append(str(error)) + released = "" + if released and not has_release_content(released): + errors.append(f"CHANGELOG.md release {version} is empty") + expected_link = ( + f"[Unreleased]: https://github.com/agentis-tools/ctx/compare/v{version}...HEAD" + ) + if expected_link not in text: + errors.append( + "CHANGELOG.md Unreleased comparison must start at the authoritative " + f"version: expected {expected_link!r}" + ) + headings = re.findall(r"^## \[([^]]+)]", text, re.MULTILINE) + duplicates = sorted({item for item in headings if headings.count(item) > 1}) + if duplicates: + errors.append(f"CHANGELOG.md contains duplicate release headings: {duplicates}") + releases: list[tuple[SemVer, dt.date]] = [] + for heading, date_text in re.findall( + r"^## \[([^]]+)](?: - (\S+))?$", text, re.MULTILINE + ): + if heading == "Unreleased": + if date_text: + errors.append("CHANGELOG.md Unreleased heading must not have a date") + continue + try: + parsed_version = SemVer.parse(heading) + except PolicyError as error: + errors.append(f"CHANGELOG.md heading is invalid: {error}") + continue + try: + parsed_date = dt.date.fromisoformat(date_text) + except ValueError: + errors.append( + f"CHANGELOG.md release {heading} needs a real ISO date, got {date_text!r}" + ) + continue + releases.append((parsed_version, parsed_date)) + for (newer_version, newer_date), (older_version, older_date) in zip( + releases, releases[1:] + ): + if newer_version.compare(older_version) <= 0: + errors.append( + f"CHANGELOG.md releases are not newest-first: {newer_version}, {older_version}" + ) + if newer_date < older_date: + errors.append( + f"CHANGELOG.md dates are not newest-first: {newer_date}, {older_date}" + ) + categories = re.findall(r"^### (.+)$", text, re.MULTILINE) + unexpected = sorted(set(categories) - ALLOWED_CATEGORIES) + if unexpected: + errors.append( + "CHANGELOG.md contains unsupported categories " + f"{unexpected}; allowed: {sorted(ALLOWED_CATEGORIES)}" + ) + if release and not re.search( + rf"^## \[{re.escape(str(version))}] - \d{{4}}-\d{{2}}-\d{{2}}$", + text, + re.MULTILINE, + ): + errors.append(f"release {version} needs a dated CHANGELOG.md heading") + return errors + + +def run_metadata(manifest: Path) -> str | None: + command = [ + "cargo", "metadata", "--locked", "--offline", "--no-deps", + "--format-version", "1", "--manifest-path", str(manifest), + ] + result = subprocess.run(command, cwd=ROOT, text=True, capture_output=True) + if result.returncode: + return ( + f"cargo metadata failed for {manifest.relative_to(ROOT)}: " + f"{result.stderr.strip()}" + ) + return None + + +def tag_from_environment(environment: Mapping[str, str]) -> str | None: + """Return the Actions ref name only when the workflow runs for a tag.""" + if environment.get("GITHUB_REF_TYPE") == "tag": + return environment.get("GITHUB_REF_NAME") + return None + + +def check(args: argparse.Namespace) -> int: + errors: list[str] = [] + try: + version = current_version() + except PolicyError as error: + print(f"ERROR: {error}", file=sys.stderr) + return 1 + + package = manifest_data()["package"] + if package.get("rust-version") != "1.91": + errors.append("Cargo.toml rust-version must match the governed MSRV 1.91") + bins = manifest_data().get("bin", []) + if not any(item.get("name") == "ctx" for item in bins): + errors.append("Cargo.toml must declare the ctx binary") + + for lockfile in LOCKFILES: + try: + actual = local_lock_version(lockfile) + if actual != str(version): + errors.append( + f"{lockfile.relative_to(ROOT)} resolves {PACKAGE} {actual}, " + f"expected {version}; run scripts/version.py set {version}" + ) + except PolicyError as error: + errors.append(str(error)) + + for manifest in (MANIFEST, ROOT / "perf" / "Cargo.toml"): + metadata_error = run_metadata(manifest) + if metadata_error: + errors.append(metadata_error) + + # GITHUB_REF_NAME is also set to values such as `main` and `123/merge`. + # Treat it as a release tag only when GitHub identifies the ref as a tag; + # callers outside Actions should pass --tag explicitly. + tag = args.tag or tag_from_environment(os.environ) + if tag and tag != f"v{version}": + errors.append(f"release tag must be v{version}, got {tag!r}") + release = args.release or bool(tag) + errors.extend(validate_changelog(version, release=release)) + + update_source = (ROOT / "src" / "update.rs").read_text(encoding="utf-8") + for invariant in ( + 'format!("ctx-{tag}-{target}.{ext}")', + 'format!("{}/releases/tags/{tag}", base_url())', + 'env!("CARGO_PKG_VERSION")', + ): + if invariant not in update_source: + errors.append( + "src/update.rs no longer matches the governed v/artifact " + f"contract; missing {invariant!r}" + ) + + workflow = (ROOT / ".github" / "workflows" / "release.yml").read_text( + encoding="utf-8" + ) + if "scripts/release-check.sh" not in workflow: + errors.append("release.yml must delegate tag/version validation to release-check.sh") + stale = re.findall(r"ctx-v\d+\.\d+\.\d+", workflow) + if stale: + errors.append(f"release.yml contains hardcoded release artifacts: {stale}") + + if not args.skip_binary: + binary = Path(args.binary or os.environ.get("CTX_BINARY", ROOT / "target/debug/ctx")) + if not binary.is_absolute(): + binary = ROOT / binary + if not binary.is_file(): + errors.append( + f"compiled ctx binary not found at {binary}; build it or pass --binary" + ) + else: + result = subprocess.run( + [str(binary), "--version"], cwd=ROOT, text=True, capture_output=True + ) + expected = f"ctx {version}" + if result.returncode or result.stdout.strip() != expected: + errors.append( + f"{binary} --version returned {result.stdout.strip()!r}, " + f"expected {expected!r}" + ) + + if errors: + for error in errors: + print(f"ERROR: {error}", file=sys.stderr) + return 1 + print(f"OK: {PACKAGE} {version} version and release invariants are consistent") + return 0 + + +def replace_manifest_version(text: str, old: str, new: str) -> str: + package_at = text.find("[package]") + next_section = text.find("\n[", package_at + 1) + prefix, section, suffix = text[:package_at], text[package_at:next_section], text[next_section:] + replaced, count = re.subn( + rf'(?m)^version = "{re.escape(old)}"$', f'version = "{new}"', section + ) + if count != 1: + raise PolicyError("could not update exactly one [package].version in Cargo.toml") + return prefix + replaced + suffix + + +def replace_lock_version(text: str, old: str, new: str) -> str: + pattern = re.compile( + rf'(\[\[package]]\nname = "{re.escape(PACKAGE)}"\nversion = ")' + rf'{re.escape(old)}("\n)' + ) + updated, count = pattern.subn(rf"\g<1>{new}\2", text, count=1) + if count != 1: + raise PolicyError(f"could not update the {PACKAGE} lockfile entry") + return updated + + +def finalize_changelog(text: str, old: str, new: str, date: str, allow_empty: bool) -> str: + unreleased = changelog_section(text, "Unreleased") + if not has_release_content(unreleased) and not allow_empty: + raise PolicyError( + "CHANGELOG.md Unreleased section is empty; add reviewed release notes " + "or pass --allow-empty explicitly" + ) + marker = "## [Unreleased]" + text = text.replace(marker, f"{marker}\n\n## [{new}] - {date}", 1) + old_unreleased = ( + f"[Unreleased]: https://github.com/agentis-tools/ctx/compare/v{old}...HEAD" + ) + new_links = ( + f"[Unreleased]: https://github.com/agentis-tools/ctx/compare/v{new}...HEAD\n" + f"[{new}]: https://github.com/agentis-tools/ctx/compare/v{old}...v{new}" + ) + if old_unreleased not in text: + raise PolicyError(f"CHANGELOG.md is missing {old_unreleased!r}") + return text.replace(old_unreleased, new_links, 1) + + +def ensure_clean(allow_dirty: bool) -> None: + result = subprocess.run( + ["git", "status", "--porcelain", "--untracked-files=normal"], + cwd=ROOT, + text=True, + capture_output=True, + check=True, + ) + if result.stdout.strip() and not allow_dirty: + raise PolicyError( + "working tree is dirty; commit/stash changes or pass --allow-dirty explicitly" + ) + if result.stdout.strip(): + print("WARNING: changing version in a dirty working tree", file=sys.stderr) + + +def set_version(args: argparse.Namespace) -> int: + ensure_clean(args.allow_dirty) + old = current_version() + new = SemVer.parse(args.version) + comparison = new.compare(old) + if comparison < 0 and not args.allow_regression: + raise PolicyError( + f"version regression {old} -> {new} refused; pass --allow-regression explicitly" + ) + if comparison == 0 and str(new) == str(old): + print(f"{new}: already current; no files changed") + return 0 + date = args.date or dt.datetime.now(dt.timezone.utc).date().isoformat() + try: + dt.date.fromisoformat(date) + except ValueError as error: + raise PolicyError(f"invalid release date {date!r}: {error}") from error + + changed: list[Path] = [] + manifest_text = MANIFEST.read_text(encoding="utf-8") + changelog_text = CHANGELOG.read_text(encoding="utf-8") + updates: dict[Path, str] = { + MANIFEST: replace_manifest_version(manifest_text, str(old), str(new)), + CHANGELOG: finalize_changelog( + changelog_text, str(old), str(new), date, args.allow_empty + ), + } + for lockfile in LOCKFILES: + updates[lockfile] = replace_lock_version( + lockfile.read_text(encoding="utf-8"), str(old), str(new) + ) + for path, content in updates.items(): + if path.read_text(encoding="utf-8") != content: + path.write_text(content, encoding="utf-8") + changed.append(path) + print(f"Updated {old} -> {new}") + for path in changed: + print(path.relative_to(ROOT)) + return 0 + + +def bump(args: argparse.Namespace) -> int: + current = current_version() + if args.part == "patch": + target = SemVer(current.major, current.minor, current.patch + 1) + elif args.part == "minor": + target = SemVer(current.major, current.minor + 1, 0) + else: + target = SemVer(current.major + 1, 0, 0) + args.version = str(target) + return set_version(args) + + +def release_notes(args: argparse.Namespace) -> int: + version = SemVer.parse(args.version) + current = current_version() + if version.compare(current) != 0 or str(version) != str(current): + raise PolicyError( + f"release notes requested for {version}, authoritative version is {current}" + ) + section = changelog_section(CHANGELOG.read_text(encoding="utf-8"), str(version)) + if not has_release_content(section): + raise PolicyError(f"CHANGELOG.md release {version} is empty") + output = f"# ctx {version}\n\n{section.strip()}\n" + if args.output: + Path(args.output).write_text(output, encoding="utf-8") + else: + sys.stdout.write(output) + return 0 + + +def parser() -> argparse.ArgumentParser: + cli = argparse.ArgumentParser(description=__doc__) + commands = cli.add_subparsers(dest="command", required=True) + commands.add_parser("show", aliases=["current"], help="print the authoritative version") + + check_parser = commands.add_parser("check", help="validate version/release invariants") + check_parser.add_argument("--tag") + check_parser.add_argument("--release", action="store_true") + check_parser.add_argument("--binary") + check_parser.add_argument("--skip-binary", action="store_true") + + def mutation_options(command: argparse.ArgumentParser) -> None: + command.add_argument("--allow-dirty", action="store_true") + command.add_argument("--allow-regression", action="store_true") + command.add_argument("--allow-empty", action="store_true") + command.add_argument("--date") + + set_parser = commands.add_parser("set", help="set an explicit release version") + set_parser.add_argument("version") + mutation_options(set_parser) + bump_parser = commands.add_parser("bump", help="bump a SemVer component") + bump_parser.add_argument("part", choices=("patch", "minor", "major")) + mutation_options(bump_parser) + + notes = commands.add_parser("notes", help="render reviewed release notes") + notes.add_argument("version") + notes.add_argument("--output") + return cli + + +def main(argv: list[str] | None = None) -> int: + args = parser().parse_args(argv) + try: + if args.command in ("show", "current"): + print(current_version()) + return 0 + if args.command == "check": + return check(args) + if args.command == "set": + return set_version(args) + if args.command == "bump": + return bump(args) + return release_notes(args) + except (PolicyError, OSError, subprocess.CalledProcessError) as error: + print(f"ERROR: {error}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/versioning/test_governance.py b/tests/versioning/test_governance.py new file mode 100644 index 0000000..db26217 --- /dev/null +++ b/tests/versioning/test_governance.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +import importlib.util +from pathlib import Path +import sys +import unittest + +ROOT = Path(__file__).resolve().parents[2] + + +def load_script(name: str, filename: str): + spec = importlib.util.spec_from_file_location(name, ROOT / "scripts" / filename) + module = importlib.util.module_from_spec(spec) + assert spec.loader + sys.modules[spec.name] = module + spec.loader.exec_module(module) + return module + + +governance = load_script("ctx_governance", "check-governance.py") +contracts = load_script("ctx_contracts", "check-contracts.py") + + +class GovernancePolicyTests(unittest.TestCase): + def test_unreleased_entries_do_not_reuse_released_history(self): + text = """## [Unreleased] + +### Fixed +- New fix + +## [0.3.4] - 2026-07-12 +- Historical fix +""" + self.assertEqual(governance.unreleased_entries(text), {"- New fix"}) + + def test_manifest_version_reads_only_package_version(self): + text = """[package] +name = "agentis-ctx" +version = "0.3.4" + +[dependencies] +example = "9.9.9" +""" + self.assertEqual(governance.manifest_version(text), "0.3.4") + + +class ContractPolicyTests(unittest.TestCase): + def test_removed_commands_and_options_are_breaking(self): + base = { + "commands": { + "ctx": {"options": {"--json": "old"}, "subcommands": ["map"]}, + "ctx map": {"options": {"--budget": "old"}, "subcommands": []}, + } + } + current = { + "commands": { + "ctx": {"options": {"--json": "new"}, "subcommands": []}, + } + } + removed, changed = contracts.compare_contracts(base, current) + self.assertIn("command ctx map", removed) + self.assertIn("option contract ctx --json", changed) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/versioning/test_version.py b/tests/versioning/test_version.py new file mode 100644 index 0000000..643d86e --- /dev/null +++ b/tests/versioning/test_version.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +import importlib.util +from pathlib import Path +import sys +import unittest +from unittest import mock + +ROOT = Path(__file__).resolve().parents[2] +SPEC = importlib.util.spec_from_file_location("ctx_version", ROOT / "scripts/version.py") +version = importlib.util.module_from_spec(SPEC) +assert SPEC.loader +sys.modules[SPEC.name] = version +SPEC.loader.exec_module(version) + + +class SemVerTests(unittest.TestCase): + def test_accepts_full_semver(self): + parsed = version.SemVer.parse("1.2.3-rc.1+build.9") + self.assertEqual(str(parsed), "1.2.3-rc.1+build.9") + + def test_rejects_incomplete_and_leading_zero_versions(self): + for value in ("1.2", "v1.2.3", "01.2.3", "1.2.3-01"): + with self.subTest(value=value), self.assertRaises(version.PolicyError): + version.SemVer.parse(value) + + def test_semver_precedence(self): + ordered = ["0.4.0-alpha.1", "0.4.0-alpha.2", "0.4.0-rc.1", "0.4.0"] + parsed = [version.SemVer.parse(item) for item in ordered] + for left, right in zip(parsed, parsed[1:]): + self.assertLess(left.compare(right), 0) + self.assertEqual( + version.SemVer.parse("1.0.0+one").compare( + version.SemVer.parse("1.0.0+two") + ), + 0, + ) + + +class RewriteTests(unittest.TestCase): + def test_manifest_rewrite_touches_package_version_only(self): + source = '[package]\nname = "agentis-ctx"\nversion = "0.3.4"\n\n[dependencies]\nx = "0.3.4"\n' + updated = version.replace_manifest_version(source, "0.3.4", "0.4.0") + self.assertIn('version = "0.4.0"', updated) + self.assertIn('x = "0.3.4"', updated) + + def test_lock_rewrite_touches_named_local_package_only(self): + source = '[[package]]\nname = "agentis-ctx"\nversion = "0.3.4"\n\n[[package]]\nname = "other"\nversion = "0.3.4"\n' + updated = version.replace_lock_version(source, "0.3.4", "0.4.0") + self.assertIn('name = "agentis-ctx"\nversion = "0.4.0"', updated) + self.assertIn('name = "other"\nversion = "0.3.4"', updated) + + def test_finalize_changelog_moves_unreleased_notes_and_links(self): + source = """# Changelog + +## [Unreleased] + +### Added +- A reviewed feature (#1) + +## [0.3.4] - 2026-07-12 + +### Fixed +- Old fix + +[Unreleased]: https://github.com/agentis-tools/ctx/compare/v0.3.4...HEAD +[0.3.4]: https://github.com/agentis-tools/ctx/releases/tag/v0.3.4 +""" + updated = version.finalize_changelog( + source, "0.3.4", "0.4.0", "2026-07-13", False + ) + self.assertIn("## [Unreleased]\n\n## [0.4.0] - 2026-07-13", updated) + self.assertIn("compare/v0.4.0...HEAD", updated) + self.assertIn("compare/v0.3.4...v0.4.0", updated) + self.assertEqual(version.changelog_section(updated, "0.4.0").count("# Added"), 1) + + def test_empty_release_requires_explicit_override(self): + source = "## [Unreleased]\n\n## [0.3.4] - 2026-07-12\n\n- prior\n\n[Unreleased]: https://github.com/agentis-tools/ctx/compare/v0.3.4...HEAD\n" + with self.assertRaises(version.PolicyError): + version.finalize_changelog( + source, "0.3.4", "0.3.5", "2026-07-13", False + ) + + +class GitHubEnvironmentTests(unittest.TestCase): + def test_branch_ref_is_not_implicitly_a_release_tag(self): + with mock.patch.dict( + version.os.environ, + {"GITHUB_REF_NAME": "123/merge", "GITHUB_REF_TYPE": "branch"}, + clear=True, + ): + github_tag = version.tag_from_environment(version.os.environ) + self.assertIsNone(github_tag) + + def test_tag_ref_is_used_for_release_validation(self): + environment = {"GITHUB_REF_NAME": "v0.3.4", "GITHUB_REF_TYPE": "tag"} + self.assertEqual(version.tag_from_environment(environment), "v0.3.4") + + +if __name__ == "__main__": + unittest.main() From 6fb4d11594839648993b5951d2ef65b091b44721 Mon Sep 17 00:00:00 2001 From: johan Date: Mon, 13 Jul 2026 15:25:47 +0200 Subject: [PATCH 2/5] fix: make CI toolchains reproducible --- .github/workflows/ci.yml | 35 +++++++++++++++++++++++++--------- .github/workflows/snapshot.yml | 4 +++- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50845f0..6ba93d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,9 @@ on: env: CARGO_TERM_COLOR: always +permissions: + contents: read + jobs: test: runs-on: ${{ matrix.os }} @@ -37,9 +40,13 @@ jobs: steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Setup Rust uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" - name: Cache cargo uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 @@ -56,40 +63,47 @@ jobs: key: ${{ runner.os }}-${{ env.ImageVersion }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Build - run: cargo build --verbose ${{ matrix.features }} + run: cargo build --locked --verbose ${{ matrix.features }} - name: Run tests - run: cargo test --verbose ${{ matrix.features }} + run: cargo test --locked --verbose ${{ matrix.features }} lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Setup Rust uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with: + toolchain: "1.91" components: rustfmt, clippy - name: Check formatting run: cargo fmt --all -- --check - name: Clippy - run: cargo clippy -- -D warnings + run: cargo clippy --locked --all-targets --all-features -- -D warnings publish-dry-run: runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: Setup Rust uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" - name: Dry-run publish (with features) - run: cargo publish --dry-run + run: cargo publish --locked --dry-run - name: Dry-run publish (minimal) - run: cargo publish --dry-run --no-default-features + run: cargo publish --locked --dry-run --no-default-features perf: runs-on: ubuntu-latest @@ -99,9 +113,12 @@ jobs: # ctx score/check diff against git history; the harness also # records the commit SHA in its results. fetch-depth: 0 + persist-credentials: false - name: Setup Rust uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" - name: Cache cargo uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 @@ -119,15 +136,15 @@ jobs: key: ${{ runner.os }}-${{ env.ImageVersion }}-cargo-perf-${{ hashFiles('**/Cargo.lock') }} - name: Build ctx (perf profile, all features) - run: cargo build --profile perf --all-features + run: cargo build --locked --profile perf --all-features - name: Harness unit tests - run: cargo test --manifest-path perf/Cargo.toml + run: cargo test --locked --manifest-path perf/Cargo.toml - name: Harness smoke run env: CTX_PERF_BIN: ${{ github.workspace }}/target/perf/ctx - run: cargo run --release --manifest-path perf/Cargo.toml -- --smoke + run: cargo run --locked --release --manifest-path perf/Cargo.toml -- --smoke # Advisory period: continue-on-error until the ubuntu-latest baseline # lands in perf/baselines/ and run-to-run spread is confirmed <20%. @@ -144,7 +161,7 @@ jobs: { [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; }; then SUITE=full fi - cargo run --release --manifest-path perf/Cargo.toml -- \ + cargo run --locked --release --manifest-path perf/Cargo.toml -- \ --suite "$SUITE" \ --baseline perf/baselines/ubuntu-latest.json \ --json-out perf-results.json diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 48a2f25..3fbbe72 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -30,6 +30,8 @@ jobs: - name: Setup Rust uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 + with: + toolchain: "1.91" - name: Cache cargo uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 @@ -47,7 +49,7 @@ jobs: - name: Build # default features include duckdb, which `ctx snapshot` requires - run: cargo build --release + run: cargo build --locked --release - name: Capture snapshot run: | From 75566d31ca125ac5d8677a16cca10a72970d774b Mon Sep 17 00:00:00 2001 From: johan Date: Mon, 13 Jul 2026 15:34:09 +0200 Subject: [PATCH 3/5] fix: update cargo-deny for CVSS 4 advisories --- .github/workflows/policy.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/policy.yml b/.github/workflows/policy.yml index 504af11..e04013b 100644 --- a/.github/workflows/policy.yml +++ b/.github/workflows/policy.yml @@ -93,12 +93,12 @@ jobs: with: persist-credentials: false - name: Check root dependency graph - uses: EmbarkStudios/cargo-deny-action@43cf000bced7a828a6e01af0596dd7e99b5b4e13 # v2.0.12 + uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1 with: command: check arguments: --all-features - name: Check perf harness dependency graph - uses: EmbarkStudios/cargo-deny-action@43cf000bced7a828a6e01af0596dd7e99b5b4e13 # v2.0.12 + uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1 with: manifest-path: ./perf/Cargo.toml command: check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fed486a..db267f0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: run: scripts/release-check.sh "${GITHUB_REF_NAME}" - name: Check dependency, license, advisory, and source policy - uses: EmbarkStudios/cargo-deny-action@43cf000bced7a828a6e01af0596dd7e99b5b4e13 # v2.0.12 + uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1 with: command: check arguments: --all-features From 908afd50c5a125cd3628c7f195f6b26269a298e4 Mon Sep 17 00:00:00 2001 From: johan Date: Mon, 13 Jul 2026 15:40:34 +0200 Subject: [PATCH 4/5] fix: govern performance harness dependencies --- deny.toml | 3 +++ perf/Cargo.toml | 1 + 2 files changed, 4 insertions(+) diff --git a/deny.toml b/deny.toml index 33cbf29..5a63ae0 100644 --- a/deny.toml +++ b/deny.toml @@ -44,6 +44,9 @@ allow = [ [bans] multiple-versions = "warn" wildcards = "deny" +# Internal path dependencies are tied to the checked-out source tree. Keep +# registry wildcard versions denied without duplicating the ctx package version. +allow-wildcard-paths = true highlight = "all" deny = [] skip = [] diff --git a/perf/Cargo.toml b/perf/Cargo.toml index aa0a15e..113beba 100644 --- a/perf/Cargo.toml +++ b/perf/Cargo.toml @@ -6,6 +6,7 @@ name = "ctx-perf" version = "0.0.0" edition = "2021" +license = "MIT OR Apache-2.0" publish = false [workspace] From 528147e9630c257fe66a1dc9e0b46b2b4539d9e9 Mon Sep 17 00:00:00 2001 From: johan Date: Mon, 13 Jul 2026 15:50:52 +0200 Subject: [PATCH 5/5] chore: update cache action for Node 24 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/snapshot.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ba93d6..0d42fc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: toolchain: "1.91" - name: Cache cargo - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | ~/.cargo/bin/ @@ -121,7 +121,7 @@ jobs: toolchain: "1.91" - name: Cache cargo - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | ~/.cargo/bin/ diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 3fbbe72..59a3c6f 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -34,7 +34,7 @@ jobs: toolchain: "1.91" - name: Cache cargo - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: | ~/.cargo/bin/