diff --git a/.codex/skills/clawbot-feishu-debug/SKILL.md b/.codex/skills/clawbot-feishu-debug/SKILL.md
new file mode 100644
index 000000000..4b699282b
--- /dev/null
+++ b/.codex/skills/clawbot-feishu-debug/SKILL.md
@@ -0,0 +1,32 @@
+---
+name: clawbot-feishu-debug
+description: Use when debugging Codex clawbot and Feishu integration problems such as missing sessions, missing inbound messages, reaction failures, websocket health, session binding, or reply forwarding.
+---
+
+Debug clawbot in this order:
+
+1. Check workspace-local state under `.codex/clawbot/`:
+ - `config.toml`
+ - `runtime.json`
+ - `sessions.json`
+ - `bindings.json`
+ - `unread_messages.jsonl`
+ - `inbound_receipts.json`
+2. Distinguish these cases clearly:
+ - REST send path works
+ - runtime says `connected`
+ - websocket inbound events are actually arriving
+ These are not the same thing.
+3. Verify the bot identity and app credentials match the intended Feishu app.
+4. For session issues, check whether the session is auto-discovered, manually bound, reachable by the current bot, and still visible through Feishu APIs.
+5. For repeated messages, check dedupe state in `inbound_receipts.json`.
+6. For reaction failures, use exact official Feishu `emoji_type` names only.
+
+Useful checks:
+
+- `runtime.json` proving `connected` is not enough; confirm new inbound state is landing in unread / receipt files.
+- If a session is bound but no inbound message lands in local state, suspect websocket delivery before suspecting thread routing.
+- If send fails with “Bot/User can NOT be out of the chat”, the bound `chat_id` is invalid for the current bot.
+
+Prefer concrete file evidence over speculation, and end with the smallest next verification command.
+
diff --git a/.codex/skills/codex-loop-debug/SKILL.md b/.codex/skills/codex-loop-debug/SKILL.md
new file mode 100644
index 000000000..af32642e9
--- /dev/null
+++ b/.codex/skills/codex-loop-debug/SKILL.md
@@ -0,0 +1,31 @@
+---
+name: codex-loop-debug
+description: Use when debugging Codex loop behavior such as before-turn or after-turn ordering, queue semantics, until_no_followup behavior, /stop handling, or stale running background loop UI in TUI.
+---
+
+Treat loop issues as scheduler problems first, UI problems second.
+
+Debug in this order:
+
+1. Confirm the active workspace and inspect:
+ - `.codex/loop_timers.json`
+ - `.codex/loop_trigger_queues.json`
+2. Separate these failure classes:
+ - trigger configuration is empty or wrong
+ - scheduler queue / round semantics are wrong
+ - follow-up submission keeps the chain alive
+ - `/stop` is not interrupting the active loop task
+ - TUI background loop indicator is stale
+3. For `after-turn`, reason in rounds:
+ - all handlers in trigger order
+ - each follow-up drained serially
+ - next round only after the current follow-up queue is done
+4. For “it keeps running forever”, check whether the loop keeps generating follow-up user turns. If yes, `until_no_followup` will never stop.
+5. For UI banner bugs, verify whether scheduler state is really empty before blaming `chatwidget`.
+
+Useful principles:
+
+- One thread should have one serial after-turn runner.
+- Queue state is a better source of truth than a single boolean gate.
+- If the user asks for fail-fast behavior, do not preserve legacy loop semantics just to smooth migration.
+
diff --git a/.codex/skills/deep-discovery/SKILL.md b/.codex/skills/deep-discovery/SKILL.md
new file mode 100644
index 000000000..d03717bb6
--- /dev/null
+++ b/.codex/skills/deep-discovery/SKILL.md
@@ -0,0 +1,31 @@
+---
+name: deep-discovery
+description: "Use when the user wants a design-first workflow: read local docs like AGENTS.md and proposal/design files, ask detailed follow-up questions, use question tool where helpful, and only produce proposal/design/todos after high-confidence understanding."
+---
+
+This skill is for design and discovery work before implementation.
+
+Default flow:
+
+1. Read local context first:
+ - `AGENTS.md`
+ - `README.md`
+ - `design.md`
+ - `proposal.md`
+ - other nearby docs the task explicitly references
+2. Build understanding before proposing a solution.
+3. Ask complete follow-up questions. When many answers are needed, prefer the `question` tool.
+4. Keep asking until the user's real goal, constraints, and success criteria are clear enough to design against.
+5. Then summarize using STAR:
+ - Situation
+ - Task
+ - Action
+ - Result
+6. Use first-principles reasoning. If the requested path is not the best path, say so and explain why.
+
+Guardrails:
+
+- Do not rush into code when the user asked for proposal or design first.
+- Do not assume the user already knows the best solution shape.
+- If motivation or constraints are unclear, pause and ask instead of inventing certainty.
+- Once the goal is clear, keep the proposal concrete: data model, state model, file touch points, and validation commands.
diff --git a/.codex/skills/enhanced-release/SKILL.md b/.codex/skills/enhanced-release/SKILL.md
new file mode 100644
index 000000000..45f67c2a4
--- /dev/null
+++ b/.codex/skills/enhanced-release/SKILL.md
@@ -0,0 +1,24 @@
+---
+name: enhanced-release
+description: Use when the user asks to cut, push, or monitor a release tag on the enhanced Codex fork, especially when they mention enhanced-release, new tag, GitHub release workflow, or release run status.
+---
+
+For this fork, the standard release path is the `enhanced-release` GitHub workflow on `Piping/codex-enhanced`.
+
+Default workflow:
+
+1. Inspect `git status --short`, `git tag --sort=-version:refname`, and recent commits.
+2. Determine the next patch version instead of reusing the current workspace version.
+3. Update the workspace version before tagging.
+4. Keep the release commit narrow. Do not pull in unrelated untracked files.
+5. Create a release commit like `chore: release x.y.z`.
+6. Create tag `vx.y.z`.
+7. Push `main` and the tag to remote `enhanced`.
+8. Query the `enhanced-release` workflow run and report the run id and status.
+
+Guardrails:
+
+- Do not assume `HEAD` already has the right version number.
+- Do not include scratch files, local scripts, `.drawio` sources, or other unrelated untracked files unless the user explicitly asks.
+- If the user asks for the workflow by name, make sure the response explicitly references `enhanced-release`.
+
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index bbd2df27c..ca26d3551 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,11 +36,12 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
- # Use a rust-release version that includes all native binaries.
- CODEX_VERSION=0.115.0
+ CODEX_VERSION="$(grep -m1 '^version' codex-rs/Cargo.toml | sed -E 's/version *= *"([^"]+)".*/\1/')"
OUTPUT_DIR="${RUNNER_TEMP}"
python3 ./scripts/stage_npm_packages.py \
--release-version "$CODEX_VERSION" \
+ --github-repo "$GITHUB_REPOSITORY" \
+ --workflow-name ".github/workflows/enhanced-release.yml" \
--package codex \
--output-dir "$OUTPUT_DIR"
PACK_OUTPUT="${OUTPUT_DIR}/codex-npm-${CODEX_VERSION}.tgz"
diff --git a/.github/workflows/enhanced-release.yml b/.github/workflows/enhanced-release.yml
new file mode 100644
index 000000000..ca65d3609
--- /dev/null
+++ b/.github/workflows/enhanced-release.yml
@@ -0,0 +1,234 @@
+name: enhanced-release
+
+on:
+ push:
+ tags:
+ - "v*.*.*"
+ workflow_dispatch:
+ inputs:
+ release_tag:
+ description: Existing tag to build and publish, for example v0.1.1
+ required: true
+ type: string
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref_name || inputs.release_tag }}
+ cancel-in-progress: true
+
+jobs:
+ prepare:
+ runs-on: ubuntu-latest
+ outputs:
+ release_tag: ${{ steps.meta.outputs.release_tag }}
+ release_version: ${{ steps.meta.outputs.release_version }}
+ checkout_ref: ${{ steps.meta.outputs.checkout_ref }}
+ steps:
+ - name: Resolve release metadata
+ id: meta
+ shell: bash
+ run: |
+ set -euo pipefail
+
+ if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
+ release_tag="${{ inputs.release_tag }}"
+ checkout_ref="refs/tags/${release_tag}"
+ else
+ release_tag="${GITHUB_REF_NAME}"
+ checkout_ref="${GITHUB_REF}"
+ fi
+
+ [[ "${release_tag}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta)(\.[0-9]+)?)?$ ]] \
+ || { echo "Release tag ${release_tag} is not in the expected format."; exit 1; }
+
+ echo "release_tag=${release_tag}" >> "$GITHUB_OUTPUT"
+ echo "release_version=${release_tag#v}" >> "$GITHUB_OUTPUT"
+ echo "checkout_ref=${checkout_ref}" >> "$GITHUB_OUTPUT"
+
+ - name: Checkout release ref
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ steps.meta.outputs.checkout_ref }}
+
+ - uses: dtolnay/rust-toolchain@1.100
+
+ - name: Validate tag matches Cargo version
+ shell: bash
+ run: |
+ set -euo pipefail
+ cargo_ver="$(grep -m1 '^version' codex-rs/Cargo.toml | sed -E 's/version *= *"([^"]+)".*/\1/')"
+ tag_ver="${{ steps.meta.outputs.release_version }}"
+ [[ "${tag_ver}" == "${cargo_ver}" ]] \
+ || { echo "Tag version ${tag_ver} does not match Cargo.toml ${cargo_ver}."; exit 1; }
+
+ build:
+ needs: prepare
+ name: build-${{ matrix.target }}
+ runs-on: ${{ matrix.runner }}
+ permissions:
+ contents: read
+ defaults:
+ run:
+ working-directory: codex-rs
+ env:
+ CARGO_INCREMENTAL: "0"
+ CARGO_PROFILE_RELEASE_LTO: fat
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - runner: macos-14
+ target: aarch64-apple-darwin
+ archive_ext: tar.gz
+ archive_kind: tar
+ - runner: macos-15-intel
+ target: x86_64-apple-darwin
+ archive_ext: tar.gz
+ archive_kind: tar
+ - runner: ubuntu-24.04
+ target: x86_64-unknown-linux-gnu
+ archive_ext: tar.gz
+ archive_kind: tar
+ - runner: windows-2022
+ target: x86_64-pc-windows-msvc
+ archive_ext: zip
+ archive_kind: zip
+ steps:
+ - name: Checkout release ref
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ needs.prepare.outputs.checkout_ref }}
+
+ - uses: dtolnay/rust-toolchain@1.100
+ with:
+ targets: ${{ matrix.target }}
+
+ - name: Install sccache
+ uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2
+ with:
+ tool: sccache
+
+ - name: Enable sccache wrapper
+ shell: bash
+ run: echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV"
+
+ - name: Clear workspace build rustflags for CI release builds
+ shell: bash
+ run: |
+ set -euo pipefail
+ echo "RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
+
+ - name: Use default macOS linker
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ echo "RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS=" >> "$GITHUB_ENV"
+
+ - name: Install Linux build dependencies
+ if: ${{ runner.os == 'Linux' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ sudo apt-get update
+ sudo apt-get install -y libcap-dev pkg-config protobuf-compiler
+
+ - name: Install macOS build dependencies
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ if ! command -v protoc >/dev/null 2>&1; then
+ brew install protobuf
+ fi
+
+ - name: Install Windows build dependencies
+ if: ${{ runner.os == 'Windows' }}
+ shell: pwsh
+ run: |
+ if (-not (Get-Command protoc -ErrorAction SilentlyContinue)) {
+ choco install protoc -y --no-progress
+ }
+
+ - name: Build release binaries
+ shell: bash
+ run: |
+ set -euo pipefail
+ cargo build --locked --release --target "${{ matrix.target }}" --bin codex --bin codex-responses-api-proxy
+
+ - name: Package unix artifacts
+ if: ${{ matrix.archive_kind == 'tar' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ stage_dir="dist/${{ matrix.target }}"
+ archive_name="codex-enhanced-${{ needs.prepare.outputs.release_version }}-${{ matrix.target }}.${{ matrix.archive_ext }}"
+
+ mkdir -p "${stage_dir}"
+ cp "target/${{ matrix.target }}/release/codex" "${stage_dir}/codex"
+ cp "target/${{ matrix.target }}/release/codex-responses-api-proxy" "${stage_dir}/codex-responses-api-proxy"
+
+ tar -C "${stage_dir}" -czf "${archive_name}" codex codex-responses-api-proxy
+
+ - name: Package windows artifacts
+ if: ${{ matrix.archive_kind == 'zip' }}
+ shell: pwsh
+ run: |
+ $stageDir = "dist/${{ matrix.target }}"
+ $archiveName = "codex-enhanced-${{ needs.prepare.outputs.release_version }}-${{ matrix.target }}.${{ matrix.archive_ext }}"
+
+ New-Item -ItemType Directory -Force -Path $stageDir | Out-Null
+ Copy-Item "target/${{ matrix.target }}/release/codex.exe" "$stageDir/codex.exe"
+ Copy-Item "target/${{ matrix.target }}/release/codex-responses-api-proxy.exe" "$stageDir/codex-responses-api-proxy.exe"
+
+ Compress-Archive -Path "$stageDir/codex.exe", "$stageDir/codex-responses-api-proxy.exe" -DestinationPath $archiveName -Force
+
+ - name: Upload packaged artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: release-${{ matrix.target }}
+ path: codex-rs/codex-enhanced-${{ needs.prepare.outputs.release_version }}-${{ matrix.target }}.${{ matrix.archive_ext }}
+ if-no-files-found: error
+
+ release:
+ needs:
+ - prepare
+ - build
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Checkout release ref
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ needs.prepare.outputs.checkout_ref }}
+
+ - name: Download packaged artifacts
+ uses: actions/download-artifact@v4
+ with:
+ pattern: release-*
+ path: release-artifacts
+ merge-multiple: true
+
+ - name: Write release notes from tag commit message
+ shell: bash
+ run: |
+ set -euo pipefail
+ commit="$(git rev-parse "${{ needs.prepare.outputs.checkout_ref }}^{commit}")"
+ git log -1 --format=%B "${commit}" > release-notes.md
+ echo >> release-notes.md
+
+ - name: Publish GitHub Release assets
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: ${{ needs.prepare.outputs.release_tag }}
+ name: Codex Enhanced ${{ needs.prepare.outputs.release_version }}
+ body_path: release-notes.md
+ files: release-artifacts/*
+ fail_on_unmatched_files: true
+ prerelease: ${{ contains(needs.prepare.outputs.release_version, '-') }}
diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml
new file mode 100644
index 000000000..977194781
--- /dev/null
+++ b/.github/workflows/pypi-release.yml
@@ -0,0 +1,198 @@
+name: pypi-release
+
+on:
+ push:
+ tags:
+ - "v*.*.*"
+ workflow_dispatch:
+ inputs:
+ release_tag:
+ description: Existing tag to build and publish, for example v0.1.12
+ required: true
+ type: string
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref_name || inputs.release_tag }}
+ cancel-in-progress: true
+
+jobs:
+ prepare:
+ runs-on: ubuntu-latest
+ outputs:
+ release_tag: ${{ steps.meta.outputs.release_tag }}
+ release_version: ${{ steps.meta.outputs.release_version }}
+ checkout_ref: ${{ steps.meta.outputs.checkout_ref }}
+ steps:
+ - name: Resolve release metadata
+ id: meta
+ shell: bash
+ run: |
+ set -euo pipefail
+
+ if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
+ release_tag="${{ inputs.release_tag }}"
+ checkout_ref="refs/tags/${release_tag}"
+ else
+ release_tag="${GITHUB_REF_NAME}"
+ checkout_ref="${GITHUB_REF}"
+ fi
+
+ [[ "${release_tag}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta)(\.[0-9]+)?)?$ ]] \
+ || { echo "Release tag ${release_tag} is not in the expected format."; exit 1; }
+
+ echo "release_tag=${release_tag}" >> "$GITHUB_OUTPUT"
+ echo "release_version=${release_tag#v}" >> "$GITHUB_OUTPUT"
+ echo "checkout_ref=${checkout_ref}" >> "$GITHUB_OUTPUT"
+
+ - name: Checkout release ref
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ steps.meta.outputs.checkout_ref }}
+
+ - name: Validate tag matches Cargo version
+ shell: bash
+ run: |
+ set -euo pipefail
+ cargo_ver="$(grep -m1 '^version' codex-rs/Cargo.toml | sed -E 's/version *= *"([^"]+)".*/\1/')"
+ tag_ver="${{ steps.meta.outputs.release_version }}"
+ [[ "${tag_ver}" == "${cargo_ver}" ]] \
+ || { echo "Tag version ${tag_ver} does not match Cargo.toml ${cargo_ver}."; exit 1; }
+
+ build:
+ needs: prepare
+ name: build-wheel-${{ matrix.target }}
+ runs-on: ${{ matrix.runner }}
+ permissions:
+ contents: read
+ env:
+ CARGO_INCREMENTAL: "0"
+ RUSTC_WRAPPER: ""
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - runner: macos-14
+ target: aarch64-apple-darwin
+ binary_name: codex
+ - runner: macos-15-intel
+ target: x86_64-apple-darwin
+ binary_name: codex
+ - runner: ubuntu-24.04
+ target: x86_64-unknown-linux-gnu
+ binary_name: codex
+ - runner: windows-2022
+ target: x86_64-pc-windows-msvc
+ binary_name: codex.exe
+ steps:
+ - name: Checkout release ref
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ needs.prepare.outputs.checkout_ref }}
+
+ - uses: dtolnay/rust-toolchain@1.100
+ with:
+ targets: ${{ matrix.target }}
+
+ - uses: actions/setup-python@v5
+ with:
+ python-version: "3.13"
+
+ - name: Install Python build dependencies
+ shell: bash
+ run: python -m pip install --upgrade build hatchling
+
+ - name: Clear workspace build rustflags for CI release builds
+ shell: bash
+ run: |
+ set -euo pipefail
+ echo "RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
+
+ - name: Use default macOS linker
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ echo "RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS=" >> "$GITHUB_ENV"
+
+ - name: Install Linux build dependencies
+ if: ${{ runner.os == 'Linux' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ sudo apt-get update
+ sudo apt-get install -y libcap-dev pkg-config protobuf-compiler
+
+ - name: Install macOS build dependencies
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ if ! command -v protoc >/dev/null 2>&1; then
+ brew install protobuf
+ fi
+
+ - name: Install Windows build dependencies
+ if: ${{ runner.os == 'Windows' }}
+ shell: pwsh
+ run: |
+ if (-not (Get-Command protoc -ErrorAction SilentlyContinue)) {
+ choco install protoc -y --no-progress
+ }
+
+ - name: Build release codex binary
+ shell: bash
+ working-directory: codex-rs
+ run: |
+ set -euo pipefail
+ cargo build --locked --release --target "${{ matrix.target }}" --bin codex
+
+ - name: Stage codex-enhanced runtime package
+ shell: bash
+ run: |
+ set -euo pipefail
+ python sdk/python/scripts/update_sdk_artifacts.py \
+ stage-runtime \
+ "${RUNNER_TEMP}/codex-enhanced" \
+ "${GITHUB_WORKSPACE}/codex-rs/target/${{ matrix.target }}/release/${{ matrix.binary_name }}" \
+ --runtime-version "${{ needs.prepare.outputs.release_version }}" \
+ --runtime-package enhanced
+
+ - name: Build wheel
+ shell: bash
+ run: python -m build --wheel "${RUNNER_TEMP}/codex-enhanced"
+
+ - name: Upload wheel artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: pypi-wheel-${{ matrix.target }}
+ path: ${{ runner.temp }}/codex-enhanced/dist/*
+ if-no-files-found: error
+
+ publish:
+ needs:
+ - prepare
+ - build
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ id-token: write
+ steps:
+ - name: Download wheel artifacts
+ uses: actions/download-artifact@v4
+ with:
+ pattern: pypi-wheel-*
+ path: dist
+ merge-multiple: true
+
+ - name: Publish codex-enhanced wheels to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
+ with:
+ packages-dir: dist
+ skip-existing: true
+ verbose: true
diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml
index c203e2b74..19bc0b20b 100644
--- a/.github/workflows/rust-ci.yml
+++ b/.github/workflows/rust-ci.yml
@@ -67,7 +67,7 @@ jobs:
working-directory: codex-rs
steps:
- uses: actions/checkout@v6
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
components: rustfmt
- name: cargo fmt
@@ -83,7 +83,7 @@ jobs:
working-directory: codex-rs
steps:
- uses: actions/checkout@v6
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2
with:
tool: cargo-shear
@@ -98,7 +98,7 @@ jobs:
if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' || github.event_name == 'push' }}
steps:
- uses: actions/checkout@v6
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
toolchain: nightly-2025-09-18
components: llvm-tools-preview, rustc-dev, rust-src
@@ -124,7 +124,7 @@ jobs:
argument_comment_lint_prebuilt:
name: Argument comment lint - ${{ matrix.name }}
- runs-on: ${{ matrix.runs_on || matrix.runner }}
+ runs-on: ${{ fromJSON(github.repository_owner == 'openai' && matrix.runs_on || format('"{0}"', matrix.runner)) }}
needs: changed
if: ${{ needs.changed.outputs.argument_comment_lint == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }}
strategy:
@@ -137,9 +137,7 @@ jobs:
runner: macos-15-xlarge
- name: Windows
runner: windows-x64
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
steps:
- uses: actions/checkout@v6
- name: Install Linux sandbox build dependencies
@@ -148,7 +146,7 @@ jobs:
run: |
sudo DEBIAN_FRONTEND=noninteractive apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
toolchain: nightly-2025-09-18
components: llvm-tools-preview, rustc-dev, rust-src
@@ -191,39 +189,27 @@ jobs:
- runner: ubuntu-24.04
target: x86_64-unknown-linux-musl
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-linux-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-x64"}'
- runner: ubuntu-24.04
target: x86_64-unknown-linux-gnu
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-linux-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-x64"}'
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-linux-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-arm64"}'
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-linux-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-arm64"}'
- runner: windows-x64
target: x86_64-pc-windows-msvc
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
- runner: windows-arm64
target: aarch64-pc-windows-msvc
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-windows-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-arm64"}'
# Also run representative release builds on Mac and Linux because
# there could be release-only build errors we want to catch.
@@ -235,27 +221,19 @@ jobs:
- runner: ubuntu-24.04
target: x86_64-unknown-linux-musl
profile: release
- runs_on:
- group: codex-runners
- labels: codex-linux-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-x64"}'
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-musl
profile: release
- runs_on:
- group: codex-runners
- labels: codex-linux-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-arm64"}'
- runner: windows-x64
target: x86_64-pc-windows-msvc
profile: release
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
- runner: windows-arm64
target: aarch64-pc-windows-msvc
profile: release
- runs_on:
- group: codex-runners
- labels: codex-windows-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-arm64"}'
steps:
- uses: actions/checkout@v6
@@ -272,7 +250,7 @@ jobs:
fi
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "${packages[@]}"
fi
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
targets: ${{ matrix.target }}
components: clippy
@@ -546,7 +524,7 @@ jobs:
tests:
name: Tests — ${{ matrix.runner }} - ${{ matrix.target }}${{ matrix.remote_env == 'true' && ' (remote)' || '' }}
- runs-on: ${{ matrix.runs_on || matrix.runner }}
+ runs-on: ${{ fromJSON(github.repository_owner == 'openai' && matrix.runs_on || format('"{0}"', matrix.runner)) }}
timeout-minutes: ${{ matrix.runner == 'windows-arm64' && 35 || 30 }}
needs: changed
if: ${{ needs.changed.outputs.codex == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }}
@@ -572,27 +550,19 @@ jobs:
target: x86_64-unknown-linux-gnu
profile: dev
remote_env: "true"
- runs_on:
- group: codex-runners
- labels: codex-linux-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-x64"}'
- runner: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-linux-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-linux-arm64"}'
- runner: windows-x64
target: x86_64-pc-windows-msvc
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
- runner: windows-arm64
target: aarch64-pc-windows-msvc
profile: dev
- runs_on:
- group: codex-runners
- labels: codex-windows-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-arm64"}'
steps:
- uses: actions/checkout@v6
@@ -615,7 +585,7 @@ jobs:
- name: Install DotSlash
uses: facebook/install-dotslash@v2
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
targets: ${{ matrix.target }}
diff --git a/.github/workflows/rust-release-argument-comment-lint.yml b/.github/workflows/rust-release-argument-comment-lint.yml
index a0d12d6db..8340076a5 100644
--- a/.github/workflows/rust-release-argument-comment-lint.yml
+++ b/.github/workflows/rust-release-argument-comment-lint.yml
@@ -17,7 +17,7 @@ jobs:
build:
if: ${{ inputs.publish }}
name: Build - ${{ matrix.runner }} - ${{ matrix.target }}
- runs-on: ${{ matrix.runs_on || matrix.runner }}
+ runs-on: ${{ fromJSON(github.repository_owner == 'openai' && matrix.runs_on || format('"{0}"', matrix.runner)) }}
timeout-minutes: 60
strategy:
@@ -48,14 +48,12 @@ jobs:
lib_name: argument_comment_lint@nightly-2025-09-18-x86_64-pc-windows-msvc.dll
runner_binary: argument-comment-lint.exe
cargo_dylint_binary: cargo-dylint.exe
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
steps:
- uses: actions/checkout@v6
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
toolchain: nightly-2025-09-18
targets: ${{ matrix.target }}
diff --git a/.github/workflows/rust-release-windows.yml b/.github/workflows/rust-release-windows.yml
index f762fbc4b..62e77190a 100644
--- a/.github/workflows/rust-release-windows.yml
+++ b/.github/workflows/rust-release-windows.yml
@@ -23,7 +23,7 @@ on:
jobs:
build-windows-binaries:
name: Build Windows binaries - ${{ matrix.runner }} - ${{ matrix.target }} - ${{ matrix.bundle }}
- runs-on: ${{ matrix.runs_on }}
+ runs-on: ${{ fromJSON(github.repository_owner == 'openai' && matrix.runs_on || format('"{0}"', matrix.runner)) }}
timeout-minutes: 60
permissions:
contents: read
@@ -41,30 +41,22 @@ jobs:
target: x86_64-pc-windows-msvc
bundle: primary
build_args: --bin codex --bin codex-responses-api-proxy
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
- runner: windows-arm64
target: aarch64-pc-windows-msvc
bundle: primary
build_args: --bin codex --bin codex-responses-api-proxy
- runs_on:
- group: codex-runners
- labels: codex-windows-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-arm64"}'
- runner: windows-x64
target: x86_64-pc-windows-msvc
bundle: helpers
build_args: --bin codex-windows-sandbox-setup --bin codex-command-runner
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
- runner: windows-arm64
target: aarch64-pc-windows-msvc
bundle: helpers
build_args: --bin codex-windows-sandbox-setup --bin codex-command-runner
- runs_on:
- group: codex-runners
- labels: codex-windows-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-arm64"}'
steps:
- uses: actions/checkout@v6
@@ -82,10 +74,17 @@ jobs:
Write-Host "Total RAM: $ramGiB GiB"
Write-Host "Disk usage:"
Get-PSDrive -PSProvider FileSystem | Format-Table -AutoSize Name, @{Name='Size(GB)';Expression={[math]::Round(($_.Used + $_.Free) / 1GB, 1)}}, @{Name='Free(GB)';Expression={[math]::Round($_.Free / 1GB, 1)}}
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
targets: ${{ matrix.target }}
+ - name: Install Windows build dependencies
+ shell: powershell
+ run: |
+ if (-not (Get-Command protoc -ErrorAction SilentlyContinue)) {
+ choco install protoc -y --no-progress
+ }
+
- name: Cargo build (Windows binaries)
shell: bash
run: |
@@ -122,7 +121,7 @@ jobs:
needs:
- build-windows-binaries
name: Build - ${{ matrix.runner }} - ${{ matrix.target }}
- runs-on: ${{ matrix.runs_on }}
+ runs-on: ${{ fromJSON(github.repository_owner == 'openai' && matrix.runs_on || format('"{0}"', matrix.runner)) }}
timeout-minutes: 60
permissions:
contents: read
@@ -137,14 +136,10 @@ jobs:
include:
- runner: windows-x64
target: x86_64-pc-windows-msvc
- runs_on:
- group: codex-runners
- labels: codex-windows-x64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-x64"}'
- runner: windows-arm64
target: aarch64-pc-windows-msvc
- runs_on:
- group: codex-runners
- labels: codex-windows-arm64
+ runs_on: '{"group":"codex-runners","labels":"codex-windows-arm64"}'
steps:
- uses: actions/checkout@v6
diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml
index 1ec9bd28b..1691fcceb 100644
--- a/.github/workflows/rust-release.yml
+++ b/.github/workflows/rust-release.yml
@@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- - uses: dtolnay/rust-toolchain@1.92
+ - uses: dtolnay/rust-toolchain@1.100
- name: Validate tag matches Cargo.toml version
shell: bash
run: |
@@ -57,9 +57,7 @@ jobs:
run:
working-directory: codex-rs
env:
- # 2026-03-04: temporarily change releases to use thin LTO because
- # Ubuntu ARM is timing out at 60 minutes.
- CARGO_PROFILE_RELEASE_LTO: ${{ contains(github.ref_name, '-alpha') && 'thin' || 'thin' }}
+ CARGO_PROFILE_RELEASE_LTO: fat
strategy:
fail-fast: false
@@ -115,7 +113,16 @@ jobs:
run: |
set -euo pipefail
sudo apt-get update -y
- sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
+ sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev protobuf-compiler
+
+ - name: Install macOS build dependencies
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ if ! command -v protoc >/dev/null 2>&1; then
+ brew install protobuf
+ fi
- name: Install UBSan runtime (musl)
if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl' }}
shell: bash
@@ -125,10 +132,21 @@ jobs:
sudo apt-get update -y
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libubsan1
fi
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
with:
targets: ${{ matrix.target }}
+ - name: Use default macOS linker
+ if: ${{ runner.os == 'macOS' }}
+ shell: bash
+ run: |
+ set -euo pipefail
+ echo "RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS=" >> "$GITHUB_ENV"
+
- if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
name: Use hermetic Cargo home (musl)
shell: bash
@@ -386,7 +404,7 @@ jobs:
needs: tag-check
uses: ./.github/workflows/rust-release-windows.yml
with:
- release-lto: ${{ contains(github.ref_name, '-alpha') && 'thin' || 'fat' }}
+ release-lto: fat
secrets: inherit
argument-comment-lint-release-assets:
diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml
index c5026fe8c..e82489ca0 100644
--- a/.github/workflows/sdk.yml
+++ b/.github/workflows/sdk.yml
@@ -7,10 +7,10 @@ on:
jobs:
sdks:
- runs-on:
- group: codex-runners
- labels: codex-linux-x64
+ runs-on: ${{ fromJSON(github.repository_owner == 'openai' && '{"group":"codex-runners","labels":"codex-linux-x64"}' || '"ubuntu-latest"') }}
timeout-minutes: 10
+ env:
+ RUSTC_WRAPPER: ""
steps:
- name: Checkout repository
uses: actions/checkout@v6
@@ -20,7 +20,7 @@ jobs:
run: |
set -euo pipefail
sudo apt-get update -y
- sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
+ sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev protobuf-compiler
- name: Setup pnpm
uses: pnpm/action-setup@v5
@@ -33,7 +33,15 @@ jobs:
node-version: 22
cache: pnpm
- - uses: dtolnay/rust-toolchain@1.93.0
+ - uses: dtolnay/rust-toolchain@1.100
+
+ - name: Clear workspace build rustflags for SDK builds
+ shell: bash
+ run: |
+ set -euo pipefail
+ echo "RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
+ echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
- name: build codex
run: cargo build --bin codex
diff --git a/.gitignore b/.gitignore
index 8f39b7b1c..17d49db39 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,3 +91,8 @@ CHANGELOG.ignore.md
__pycache__/
*.pyc
+# codex local runtime data
+!.codex/
+.codex/*
+!.codex/skills/
+!.codex/skills/**
diff --git a/AGENTS.md b/AGENTS.md
index 3a287a599..459acf2ef 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -2,6 +2,11 @@
In the codex-rs folder where the rust code lives:
+- This fork has a few project-specific overrides:
+ - During active development, if the user explicitly narrows validation to `cargo check` and `cargo build`, treat that as an override for the default test / clippy / lint flow in this file. Do not expand validation unless the user later asks for it.
+ - Prefer KISS. Solve the current concrete problem with the smallest clear design that works.
+ - When requirements change, fail fast. Remove superseded paths instead of preserving fallback compatibility, dual behavior, or migration shims unless the user explicitly asks for backward compatibility.
+ - Do not add speculative extension points for imagined future needs. Extract an abstraction only after the variation is already real or the extension boundary is clearly required.
- Crate names are prefixed with `codex-`. For example, the `core` folder's crate is named `codex-core`
- When using format! and you can inline variables into {}, always do that.
- Install any commands the repo relies on (for example `just`, `rg`, or `cargo-insta`) if they aren't already available before running instructions here.
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index ee89f6243..47c3151f0 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -733,6 +733,7 @@
"crc32fast_1.5.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1\"},{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"default\":[\"std\"],\"nightly\":[],\"std\":[]}}",
"crc_3.4.0": "{\"dependencies\":[{\"name\":\"crc-catalog\",\"req\":\"^2.4.0\"}],\"features\":{}}",
"critical-section_1.2.0": "{\"dependencies\":[],\"features\":{\"restore-state-bool\":[],\"restore-state-none\":[],\"restore-state-u16\":[],\"restore-state-u32\":[],\"restore-state-u64\":[],\"restore-state-u8\":[],\"restore-state-usize\":[],\"std\":[\"restore-state-bool\"]}}",
+ "cron_0.16.0": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"clock\"],\"name\":\"chrono\",\"req\":\"~0.4\"},{\"kind\":\"dev\",\"name\":\"chrono-tz\",\"req\":\"~0.6\"},{\"name\":\"once_cell\",\"req\":\"^1.10\"},{\"features\":[\"macros\"],\"name\":\"phf\",\"req\":\"^0.11\"},{\"default_features\":false,\"features\":[\"use-std\"],\"kind\":\"dev\",\"name\":\"postcard\",\"req\":\"^1.0.10\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.164\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1.0.164\"},{\"name\":\"winnow\",\"req\":\"^0.7.0\"}],\"features\":{\"serde\":[\"dep:serde\"]}}",
"crossbeam-channel_0.5.15": "{\"dependencies\":[{\"default_features\":false,\"name\":\"crossbeam-utils\",\"req\":\"^0.8.18\"},{\"kind\":\"dev\",\"name\":\"num_cpus\",\"req\":\"^1.13.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"signal-hook\",\"req\":\"^0.3\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"crossbeam-utils/std\"]}}",
"crossbeam-deque_0.8.6": "{\"dependencies\":[{\"default_features\":false,\"name\":\"crossbeam-epoch\",\"req\":\"^0.9.17\"},{\"default_features\":false,\"name\":\"crossbeam-utils\",\"req\":\"^0.8.18\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"crossbeam-epoch/std\",\"crossbeam-utils/std\"]}}",
"crossbeam-epoch_0.9.18": "{\"dependencies\":[{\"default_features\":false,\"name\":\"crossbeam-utils\",\"req\":\"^0.8.18\"},{\"name\":\"loom-crate\",\"optional\":true,\"package\":\"loom\",\"req\":\"^0.7.1\",\"target\":\"cfg(crossbeam_loom)\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"loom\":[\"loom-crate\",\"crossbeam-utils/loom\"],\"nightly\":[\"crossbeam-utils/nightly\"],\"std\":[\"alloc\",\"crossbeam-utils/std\"]}}",
@@ -979,6 +980,7 @@
"lalrpop_0.19.12": "{\"dependencies\":[{\"default_features\":false,\"name\":\"ascii-canvas\",\"req\":\"^3.0\"},{\"default_features\":false,\"name\":\"bit-set\",\"req\":\"^0.5.2\"},{\"default_features\":false,\"name\":\"diff\",\"req\":\"^0.1.12\"},{\"default_features\":false,\"name\":\"ena\",\"req\":\"^0.14\"},{\"name\":\"is-terminal\",\"req\":\"^0.4.2\"},{\"default_features\":false,\"features\":[\"use_std\"],\"name\":\"itertools\",\"req\":\"^0.10\"},{\"name\":\"lalrpop-util\",\"req\":\"^0.19.12\"},{\"default_features\":false,\"name\":\"petgraph\",\"req\":\"^0.6\"},{\"default_features\":false,\"name\":\"pico-args\",\"optional\":true,\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"regex\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"std\",\"unicode-case\",\"unicode-perl\"],\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"unicode\"],\"name\":\"regex-syntax\",\"req\":\"^0.6\"},{\"default_features\":false,\"features\":[\"unicode-case\",\"unicode-perl\"],\"kind\":\"dev\",\"name\":\"regex-syntax\",\"req\":\"^0.6\"},{\"default_features\":false,\"name\":\"string_cache\",\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"term\",\"req\":\"^0.7\"},{\"features\":[\"sha3\"],\"name\":\"tiny-keccak\",\"req\":\"^2.0.2\"},{\"default_features\":false,\"name\":\"unicode-xid\",\"req\":\"^0.2\"}],\"features\":{\"default\":[\"lexer\"],\"lexer\":[\"lalrpop-util/lexer\"],\"test\":[]}}",
"landlock_0.4.4": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0\"},{\"name\":\"enumflags2\",\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"libc\",\"req\":\"^0.2.175\"},{\"kind\":\"dev\",\"name\":\"strum\",\"req\":\"^0.26\"},{\"kind\":\"dev\",\"name\":\"strum_macros\",\"req\":\"^0.26\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"}],\"features\":{}}",
"language-tags_0.3.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"}],\"features\":{}}",
+ "lark-websocket-protobuf_0.1.1": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1.6.0\"},{\"name\":\"prost\",\"req\":\"^0.13.1\"},{\"kind\":\"build\",\"name\":\"prost-build\",\"req\":\"^0.12.6\"}],\"features\":{}}",
"lazy_static_1.5.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3.1\"},{\"default_features\":false,\"features\":[\"once\"],\"name\":\"spin\",\"optional\":true,\"req\":\"^0.9.8\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1\"}],\"features\":{\"spin_no_std\":[\"spin\"]}}",
"libc_0.2.182": "{\"dependencies\":[{\"name\":\"rustc-std-workspace-core\",\"optional\":true,\"req\":\"^1.0.1\"}],\"features\":{\"align\":[],\"const-extern-fn\":[],\"default\":[\"std\"],\"extra_traits\":[],\"rustc-dep-of-std\":[\"align\",\"rustc-std-workspace-core\"],\"std\":[],\"use_std\":[\"std\"]}}",
"libdbus-sys_0.2.7": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"cc\",\"optional\":true,\"req\":\"^1.0.78\"},{\"kind\":\"build\",\"name\":\"pkg-config\",\"optional\":true,\"req\":\"^0.3\"}],\"features\":{\"default\":[\"pkg-config\"],\"vendored\":[\"cc\"]}}",
@@ -1076,6 +1078,26 @@
"onig_6.5.1": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.4.0\"},{\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(windows)\"},{\"name\":\"once_cell\",\"req\":\"^1.12\"},{\"default_features\":false,\"name\":\"onig_sys\",\"req\":\"^69.9.1\"}],\"features\":{\"default\":[\"generate\"],\"generate\":[\"onig_sys/generate\"],\"posix-api\":[\"onig_sys/posix-api\"],\"print-debug\":[\"onig_sys/print-debug\"],\"std-pattern\":[]}}",
"onig_sys_69.9.1": "{\"dependencies\":[{\"features\":[\"runtime\"],\"kind\":\"build\",\"name\":\"bindgen\",\"optional\":true,\"req\":\"^0.71\"},{\"kind\":\"build\",\"name\":\"cc\",\"req\":\"^1.0\"},{\"kind\":\"build\",\"name\":\"pkg-config\",\"req\":\"^0.3.16\"}],\"features\":{\"default\":[\"generate\"],\"generate\":[\"bindgen\"],\"posix-api\":[],\"print-debug\":[]}}",
"opaque-debug_0.3.1": "{\"dependencies\":[],\"features\":{}}",
+ "openlark-ai_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"}],\"features\":{\"default\":[\"v1\"],\"full\":[\"v1\"],\"v1\":[]}}",
+ "openlark-analytics_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"name\":\"futures\",\"req\":\"^0.3.30\"},{\"name\":\"log\",\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"once_cell\",\"req\":\"^1.19\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"regex\",\"req\":\"^1.10\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_repr\",\"req\":\"^0.1.19\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"features\":[\"serde\"],\"name\":\"url\",\"req\":\"^2.5.0\"},{\"features\":[\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"all-analytics\":[\"full\"],\"analytics\":[\"search\",\"report\"],\"core\":[],\"default\":[\"search\",\"report\"],\"full\":[\"search\",\"report\",\"v4\"],\"report\":[\"report-core\",\"core\"],\"report-core\":[],\"search\":[\"search-core\",\"core\"],\"search-core\":[],\"v1\":[\"core\"],\"v2\":[\"v1\"],\"v3\":[\"v2\"],\"v4\":[\"v3\"]}}",
+ "openlark-application_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.38\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\",\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"name\":\"tracing\",\"req\":\"^0.1\"}],\"features\":{\"async\":[\"tokio\"],\"default\":[\"v1\",\"async\"],\"full\":[\"v1\",\"async\"],\"v1\":[]}}",
+ "openlark-auth_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"base64\",\"req\":\"^0.22\"},{\"features\":[\"serde\",\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"features\":[\"html_reports\"],\"name\":\"criterion\",\"optional\":true,\"req\":\"^0.5\"},{\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"hmac\",\"optional\":true,\"req\":\"^0.12\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"pbkdf2\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"regex\",\"req\":\"^1.10\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"optional\":true,\"req\":\"^0.12.7\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.18\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\",\"full\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tracing\",\"req\":\"^0.1\"},{\"features\":[\"serde\"],\"name\":\"url\",\"optional\":true,\"req\":\"^2.5.0\"},{\"name\":\"urlencoding\",\"req\":\"^2.1\"},{\"features\":[\"v4\",\"serde\",\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"advanced-cache\":[\"cache\",\"encryption\"],\"benchmarks\":[\"performance\"],\"cache\":[\"token-management\"],\"default\":[\"token-management\",\"cache\",\"encryption\",\"oauth\"],\"dev\":[\"token-management\",\"cache\",\"oauth\",\"encryption\"],\"encryption\":[\"ring\",\"sha2\",\"hmac\",\"pbkdf2\"],\"monitoring\":[],\"oauth\":[\"reqwest\",\"url\"],\"performance\":[\"criterion\"],\"token-management\":[]}}",
+ "openlark-cardkit_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"kind\":\"dev\",\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"name\":\"tracing\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"default\":[\"v1\"],\"full\":[\"v1\"],\"v1\":[]}}",
+ "openlark-client_0.15.0-rc.1": "{\"dependencies\":[{\"features\":[\"serde\",\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"default_features\":false,\"features\":[\"sink\",\"std\"],\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.30\"},{\"name\":\"lark-websocket-protobuf\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"openlark-ai\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-auth\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-cardkit\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-communication\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-docs\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-hr\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-meeting\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-security\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"prost\",\"optional\":true,\"req\":\"^0.13\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"optional\":true,\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"features\":[\"rustls-tls-native-roots\"],\"name\":\"tokio-tungstenite\",\"optional\":true,\"req\":\"^0.23\"},{\"name\":\"tracing\",\"req\":\"^0.1\"},{\"features\":[\"serde\"],\"name\":\"url\",\"optional\":true,\"req\":\"^2.5.0\"},{\"features\":[\"v4\",\"serde\",\"v4\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"ai\":[\"openlark-ai\"],\"auth\":[\"openlark-auth\"],\"cardkit\":[\"auth\",\"openlark-cardkit\"],\"client\":[],\"client-communication\":[\"client\",\"communication\"],\"client-docs\":[\"client\",\"docs\"],\"client-p0\":[\"client\",\"p0-services\"],\"client-security\":[\"client\",\"security\"],\"communication\":[\"auth\",\"openlark-communication\"],\"core-layer\":[\"communication\",\"docs\",\"security\"],\"default\":[\"auth\",\"communication\"],\"docs\":[\"auth\",\"openlark-docs\"],\"hr\":[\"openlark-hr\"],\"meeting\":[\"auth\",\"openlark-meeting\"],\"p0-services\":[\"communication\",\"docs\",\"security\"],\"security\":[\"auth\",\"openlark-security\"],\"websocket\":[\"tokio-tungstenite\",\"futures-util\",\"lark-websocket-protobuf\",\"url\",\"prost\",\"reqwest\",\"log\"]}}",
+ "openlark-communication_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"name\":\"tracing\",\"req\":\"^0.1\"}],\"features\":{\"aily\":[],\"contact\":[],\"default\":[\"im\",\"contact\",\"moments\"],\"full\":[\"im\",\"contact\",\"moments\",\"aily\"],\"im\":[],\"moments\":[]}}",
+ "openlark-core_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"base64\",\"req\":\"^0.22.1\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"default_features\":false,\"features\":[\"sink\",\"std\"],\"name\":\"futures-util\",\"req\":\"^0.3.30\"},{\"name\":\"hmac\",\"req\":\"^0.12.1\"},{\"name\":\"http\",\"req\":\"^1.0\"},{\"name\":\"lark-websocket-protobuf\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"num_cpus\",\"req\":\"^1.16\"},{\"name\":\"openlark-protocol\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"opentelemetry\",\"optional\":true,\"req\":\"^0.24\"},{\"name\":\"opentelemetry-otlp\",\"optional\":true,\"req\":\"^0.17\"},{\"features\":[\"rt-tokio\"],\"name\":\"opentelemetry_sdk\",\"optional\":true,\"req\":\"^0.24\"},{\"name\":\"prost\",\"optional\":true,\"req\":\"^0.13\"},{\"name\":\"quick_cache\",\"req\":\"^0.6.3\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"regex\",\"req\":\"^1.10\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_with\",\"req\":\"^3\"},{\"name\":\"sha2\",\"req\":\"^0.10.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"features\":[\"rustls-tls-native-roots\"],\"name\":\"tokio-tungstenite\",\"optional\":true,\"req\":\"^0.23\"},{\"name\":\"tracing\",\"req\":\"^0.1\"},{\"name\":\"tracing-opentelemetry\",\"optional\":true,\"req\":\"^0.25\"},{\"features\":[\"env-filter\",\"json\"],\"name\":\"tracing-subscriber\",\"optional\":true,\"req\":\"^0.3\"},{\"features\":[\"env-filter\",\"json\"],\"kind\":\"dev\",\"name\":\"tracing-subscriber\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"tracing-test\",\"req\":\"^0.2\"},{\"features\":[\"serde\"],\"name\":\"url\",\"req\":\"^2.5.0\"},{\"name\":\"urlencoding\",\"req\":\"^2.1\"},{\"features\":[\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"default\":[\"testing\"],\"otel\":[\"tracing-init\",\"opentelemetry\",\"opentelemetry_sdk\",\"opentelemetry-otlp\",\"tracing-opentelemetry\"],\"testing\":[\"tracing-init\"],\"tracing-init\":[\"tracing-subscriber\"],\"websocket\":[\"tokio-tungstenite\",\"prost\",\"openlark-protocol\",\"lark-websocket-protobuf\"]}}",
+ "openlark-docs_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"name\":\"base64\",\"req\":\"^0.22.1\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"name\":\"futures\",\"req\":\"^0.3.30\"},{\"name\":\"futures-util\",\"req\":\"^0.3\"},{\"name\":\"log\",\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"once_cell\",\"req\":\"^1.19\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"regex\",\"req\":\"^1.10\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_repr\",\"req\":\"^0.1.19\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"features\":[\"serde\"],\"name\":\"url\",\"req\":\"^2.5.0\"},{\"name\":\"urlencoding\",\"req\":\"^2.1\"},{\"features\":[\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"all-cloud-docs\":[\"full\"],\"baike\":[],\"base\":[\"core\"],\"bitable\":[\"core\"],\"ccm\":[\"ccm-core\",\"ccm-doc\",\"ccm-docx\",\"ccm-drive\",\"ccm-sheets\",\"ccm-wiki\"],\"ccm-core\":[],\"ccm-doc\":[\"ccm-core\"],\"ccm-docx\":[\"ccm-core\"],\"ccm-drive\":[\"ccm-core\"],\"ccm-sheets\":[\"ccm-sheets-v3\"],\"ccm-sheets-v3\":[\"ccm-core\"],\"ccm-wiki\":[\"ccm-core\"],\"cloud-docs\":[\"ccm\",\"bitable\",\"base\"],\"core\":[],\"default\":[],\"docs\":[\"ccm-doc\"],\"docx\":[\"ccm-docx\"],\"full\":[\"ccm\",\"bitable\",\"base\",\"baike\",\"minutes\",\"v3\"],\"lingo\":[],\"minutes\":[\"core\"],\"v1\":[\"core\"],\"v2\":[\"v1\"],\"v3\":[\"v2\"],\"wiki\":[\"ccm-wiki\"]}}",
+ "openlark-helpdesk_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.38\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\",\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"name\":\"tracing\",\"req\":\"^0.1\"}],\"features\":{\"async\":[\"tokio\"],\"default\":[\"v1\",\"async\"],\"full\":[\"v1\",\"async\"],\"v1\":[]}}",
+ "openlark-hr_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"name\":\"log\",\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serial_test\",\"req\":\"^3.2\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"attendance\":[],\"compensation\":[],\"corehr\":[],\"default\":[\"attendance\",\"corehr\",\"compensation\",\"payroll\",\"performance\",\"okr\",\"hire\",\"ehr\"],\"ehr\":[],\"hire\":[],\"hr-full\":[\"attendance\",\"corehr\",\"compensation\",\"payroll\",\"performance\",\"okr\",\"hire\",\"ehr\"],\"okr\":[],\"payroll\":[],\"performance\":[]}}",
+ "openlark-mail_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.38\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\",\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"name\":\"tracing\",\"req\":\"^0.1\"}],\"features\":{\"async\":[\"tokio\"],\"default\":[\"v1\",\"async\"],\"full\":[\"v1\",\"async\"],\"v1\":[]}}",
+ "openlark-meeting_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"features\":[\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1\"}],\"features\":{\"calendar\":[\"calendar-v4\"],\"calendar-v4\":[],\"default\":[\"vc\",\"calendar\"],\"full\":[\"vc\",\"calendar\",\"meeting-room\"],\"meeting-room\":[\"meeting-room-v1\"],\"meeting-room-v1\":[],\"vc\":[\"vc-v1\"],\"vc-v1\":[]}}",
+ "openlark-platform_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"name\":\"futures\",\"req\":\"^0.3.30\"},{\"name\":\"log\",\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"once_cell\",\"req\":\"^1.19\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"regex\",\"req\":\"^1.10\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_repr\",\"req\":\"^0.1.19\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"features\":[\"serde\"],\"name\":\"url\",\"req\":\"^2.5.0\"},{\"name\":\"urlencoding\",\"req\":\"^2.1\"},{\"features\":[\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"admin\":[\"admin-core\",\"core\"],\"admin-core\":[],\"all-platform\":[\"full\"],\"app-engine\":[\"app-engine-core\",\"core\"],\"app-engine-core\":[],\"core\":[],\"default\":[\"app-engine\",\"directory\",\"admin\",\"mdm\",\"tenant\",\"trust_party\"],\"directory\":[\"directory-core\",\"core\"],\"directory-core\":[],\"full\":[\"app-engine\",\"directory\",\"admin\",\"mdm\",\"tenant\",\"trust_party\",\"v4\"],\"mdm\":[\"mdm-core\",\"core\"],\"mdm-core\":[],\"platform\":[\"app-engine\",\"directory\",\"admin\"],\"tenant\":[\"tenant-core\",\"core\"],\"tenant-core\":[],\"trust_party\":[\"trust_party-core\",\"core\"],\"trust_party-core\":[],\"v1\":[\"core\"],\"v2\":[\"v1\"],\"v3\":[\"v2\"],\"v4\":[\"v3\"]}}",
+ "openlark-protocol_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1.6.0\"},{\"name\":\"prost\",\"req\":\"^0.13.1\"},{\"kind\":\"build\",\"name\":\"prost-build\",\"req\":\"^0.12.6\"}],\"features\":{}}",
+ "openlark-security_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"name\":\"base64\",\"req\":\"^0.22.1\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"name\":\"hmac\",\"req\":\"^0.12.1\"},{\"name\":\"log\",\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_repr\",\"req\":\"^0.1.19\"},{\"name\":\"sha2\",\"req\":\"^0.10.8\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tracing\",\"req\":\"^0.1\"},{\"features\":[\"serde\"],\"name\":\"url\",\"req\":\"^2.5.0\"},{\"name\":\"urlencoding\",\"req\":\"^2.1\"},{\"features\":[\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"acs\":[\"auth\"],\"audit\":[\"core\"],\"auth\":[\"core\"],\"compliance\":[\"auth\"],\"core\":[],\"default\":[\"auth\",\"acs\"],\"full\":[\"auth\",\"acs\",\"audit\",\"token\",\"compliance\",\"v3\"],\"security\":[\"full\"],\"token\":[\"auth\"],\"v1\":[\"core\"],\"v2\":[\"v1\"],\"v3\":[\"v2\"]}}",
+ "openlark-user_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"name\":\"async-trait\",\"req\":\"^0.1.83\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"name\":\"futures\",\"req\":\"^0.3.30\"},{\"name\":\"log\",\"req\":\"^0.4.21\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"name\":\"once_cell\",\"req\":\"^1.19\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"regex\",\"req\":\"^1.10\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_repr\",\"req\":\"^0.1.19\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"features\":[\"serde\"],\"name\":\"url\",\"req\":\"^2.5.0\"},{\"features\":[\"v4\",\"serde\"],\"name\":\"uuid\",\"req\":\"^1.6\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"all-user\":[\"full\"],\"core\":[],\"default\":[\"settings\",\"preferences\"],\"full\":[\"settings\",\"preferences\",\"v4\"],\"preferences\":[\"preferences-core\",\"core\"],\"preferences-core\":[],\"settings\":[\"settings-core\",\"core\"],\"settings-core\":[],\"user\":[\"settings\",\"preferences\"],\"v1\":[\"core\"],\"v2\":[\"v1\"],\"v3\":[\"v2\"],\"v4\":[\"v3\"]}}",
+ "openlark-webhook_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"base64\",\"optional\":true,\"req\":\"^0.22.1\"},{\"name\":\"hmac\",\"optional\":true,\"req\":\"^0.12.1\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10.8\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"card\":[],\"default\":[\"robot\"],\"robot\":[],\"signature\":[\"hmac\",\"sha2\",\"base64\"]}}",
+ "openlark-workflow_0.15.0-rc.1": "{\"dependencies\":[{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.38\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\",\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"name\":\"tracing\",\"req\":\"^0.1\"}],\"features\":{\"async\":[\"tokio\"],\"board\":[],\"default\":[\"v1\",\"v2\",\"async\",\"board\"],\"full\":[\"v1\",\"v2\",\"async\",\"board\"],\"v1\":[],\"v2\":[]}}",
+ "openlark_0.15.0-rc.1": "{\"dependencies\":[{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^4.4\"},{\"kind\":\"dev\",\"name\":\"colored\",\"req\":\"^2.1\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"dotenvy\",\"req\":\"^0.15\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.12\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1.19\"},{\"name\":\"openlark-ai\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-analytics\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-application\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-auth\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-cardkit\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-client\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-communication\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-core\",\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-docs\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-helpdesk\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-hr\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-mail\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-meeting\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-platform\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-protocol\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-security\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-user\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-webhook\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"name\":\"openlark-workflow\",\"optional\":true,\"req\":\"^0.15.0-rc.1\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"json\",\"multipart\",\"rustls-tls\"],\"kind\":\"dev\",\"name\":\"reqwest\",\"req\":\"^0.12.7\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.19\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_repr\",\"req\":\"^0.1.19\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.8\"},{\"kind\":\"dev\",\"name\":\"test-log\",\"req\":\"^0.2\"},{\"features\":[\"rt\",\"rt-multi-thread\",\"macros\",\"rt-multi-thread\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38\"},{\"kind\":\"dev\",\"name\":\"tracing-test\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"wiremock\",\"req\":\"^0.6\"}],\"features\":{\"ai\":[\"client\",\"openlark-ai\"],\"analytics\":[\"client\",\"openlark-analytics\"],\"application\":[\"client\",\"openlark-application\"],\"auth\":[\"client\",\"openlark-auth\"],\"base\":[\"client\",\"openlark-docs\"],\"bitable\":[\"client\",\"openlark-docs\"],\"cardkit\":[\"client\",\"openlark-cardkit\"],\"client\":[\"openlark-client\"],\"communication\":[\"client\",\"openlark-communication\"],\"core-services\":[\"auth\",\"communication\",\"docs\",\"workflow\"],\"default\":[\"core-services\"],\"dev-tools\":[],\"docs\":[\"client\",\"openlark-docs\"],\"helpdesk\":[\"client\",\"openlark-helpdesk\"],\"hr\":[\"client\",\"openlark-hr\"],\"mail\":[\"client\",\"openlark-mail\"],\"meeting\":[\"client\",\"openlark-meeting\"],\"platform\":[\"client\",\"openlark-platform\"],\"protocol\":[\"openlark-protocol\"],\"security\":[\"client\",\"openlark-security\"],\"user\":[\"client\",\"openlark-user\"],\"webhook\":[\"client\",\"openlark-webhook\"],\"websocket\":[\"protocol\",\"openlark-client/websocket\"],\"workflow\":[\"client\",\"openlark-workflow\"]}}",
"openssl-macros_0.1.1": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}",
"openssl-probe_0.1.6": "{\"dependencies\":[],\"features\":{}}",
"openssl-probe_0.2.1": "{\"dependencies\":[],\"features\":{}}",
@@ -1108,6 +1130,9 @@
"percent-encoding_2.3.2": "{\"dependencies\":[],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[\"alloc\"]}}",
"petgraph_0.6.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"ahash\",\"req\":\"^0.7.2\"},{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.3.3\"},{\"kind\":\"dev\",\"name\":\"defmac\",\"req\":\"^0.2.1\"},{\"default_features\":false,\"name\":\"fixedbitset\",\"req\":\"^0.4.0\"},{\"kind\":\"dev\",\"name\":\"fxhash\",\"req\":\"^0.2.1\"},{\"name\":\"indexmap\",\"req\":\"^2.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"itertools\",\"req\":\"^0.12.1\"},{\"kind\":\"dev\",\"name\":\"odds\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"name\":\"quickcheck\",\"optional\":true,\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.5.5\"},{\"name\":\"rayon\",\"optional\":true,\"req\":\"^1.5.3\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"serde_derive\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"all\":[\"unstable\",\"quickcheck\",\"matrix_graph\",\"stable_graph\",\"graphmap\",\"rayon\"],\"default\":[\"graphmap\",\"stable_graph\",\"matrix_graph\"],\"generate\":[],\"graphmap\":[],\"matrix_graph\":[],\"rayon\":[\"dep:rayon\",\"indexmap/rayon\"],\"serde-1\":[\"serde\",\"serde_derive\"],\"stable_graph\":[],\"unstable\":[\"generate\"]}}",
"petgraph_0.8.3": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"ahash\",\"req\":\"^0.7.2\"},{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.3.3\"},{\"kind\":\"dev\",\"name\":\"defmac\",\"req\":\"^0.2.1\"},{\"name\":\"dot-parser\",\"optional\":true,\"req\":\"^0.5.1\"},{\"name\":\"dot-parser-macros\",\"optional\":true,\"req\":\"^0.5.1\"},{\"default_features\":false,\"name\":\"fixedbitset\",\"req\":\"^0.5.7\"},{\"kind\":\"dev\",\"name\":\"fxhash\",\"req\":\"^0.2.1\"},{\"default_features\":false,\"features\":[\"default-hasher\",\"inline-more\"],\"name\":\"hashbrown\",\"req\":\"^0.15.0\"},{\"default_features\":false,\"name\":\"indexmap\",\"req\":\"^2.5.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"itertools\",\"req\":\"^0.12.1\"},{\"kind\":\"dev\",\"name\":\"odds\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"name\":\"quickcheck\",\"optional\":true,\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.5.5\"},{\"name\":\"rayon\",\"optional\":true,\"req\":\"^1.5.3\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"serde_derive\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"all\":[\"unstable\",\"quickcheck\",\"matrix_graph\",\"stable_graph\",\"graphmap\",\"rayon\",\"dot_parser\"],\"default\":[\"std\",\"graphmap\",\"stable_graph\",\"matrix_graph\"],\"dot_parser\":[\"std\",\"dep:dot-parser\",\"dep:dot-parser-macros\"],\"generate\":[],\"graphmap\":[],\"matrix_graph\":[],\"quickcheck\":[\"std\",\"dep:quickcheck\",\"graphmap\",\"stable_graph\"],\"rayon\":[\"std\",\"dep:rayon\",\"indexmap/rayon\",\"hashbrown/rayon\"],\"serde-1\":[\"serde\",\"serde_derive\"],\"stable_graph\":[\"serde?/alloc\"],\"std\":[\"indexmap/std\"],\"unstable\":[\"generate\"]}}",
+ "phf_0.11.3": "{\"dependencies\":[{\"name\":\"phf_macros\",\"optional\":true,\"req\":\"^0.11.3\"},{\"default_features\":false,\"name\":\"phf_shared\",\"req\":\"^0.11.3\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"default\":[\"std\"],\"macros\":[\"phf_macros\"],\"std\":[\"phf_shared/std\"],\"uncased\":[\"phf_shared/uncased\"],\"unicase\":[\"phf_macros?/unicase\",\"phf_shared/unicase\"]}}",
+ "phf_generator_0.11.3": "{\"dependencies\":[{\"name\":\"criterion\",\"optional\":true,\"req\":\"^0.3.6\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3.6\"},{\"default_features\":false,\"name\":\"phf_shared\",\"req\":\"^0.11.2\"},{\"default_features\":false,\"features\":[\"small_rng\"],\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{}}",
+ "phf_macros_0.11.3": "{\"dependencies\":[{\"name\":\"phf_generator\",\"req\":\"^0.11.1\"},{\"default_features\":false,\"name\":\"phf_shared\",\"req\":\"^0.11.2\"},{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2\"},{\"name\":\"unicase_\",\"optional\":true,\"package\":\"unicase\",\"req\":\"^2.4.0\"}],\"features\":{\"unicase\":[\"unicase_\",\"phf_shared/unicase\"]}}",
"phf_shared_0.11.3": "{\"dependencies\":[{\"name\":\"siphasher\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"uncased\",\"optional\":true,\"req\":\"^0.9.9\"},{\"name\":\"unicase\",\"optional\":true,\"req\":\"^2.4.0\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}",
"pin-project-internal_1.1.10": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0.60\"},{\"name\":\"quote\",\"req\":\"^1.0.25\"},{\"default_features\":false,\"features\":[\"parsing\",\"printing\",\"clone-impls\",\"proc-macro\",\"full\",\"visit-mut\"],\"name\":\"syn\",\"req\":\"^2.0.1\"}],\"features\":{}}",
"pin-project-lite_0.2.16": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1\"}],\"features\":{}}",
@@ -1139,7 +1164,13 @@
"proc-macro2_1.0.106": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"flate2\",\"req\":\"^1.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quote\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rayon\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tar\",\"req\":\"^0.4\"},{\"name\":\"unicode-ident\",\"req\":\"^1.0\"}],\"features\":{\"default\":[\"proc-macro\"],\"nightly\":[],\"proc-macro\":[],\"span-locations\":[]}}",
"process-wrap_9.0.1": "{\"dependencies\":[{\"name\":\"futures\",\"optional\":true,\"req\":\"^0.3.30\"},{\"name\":\"indexmap\",\"req\":\"^2.9.0\"},{\"default_features\":false,\"features\":[\"fs\",\"poll\",\"signal\"],\"name\":\"nix\",\"optional\":true,\"req\":\"^0.30.1\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"remoteprocess\",\"req\":\"^0.5.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.20.0\"},{\"features\":[\"io-util\",\"macros\",\"process\",\"rt\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.38.2\"},{\"features\":[\"io-util\",\"macros\",\"process\",\"rt\",\"rt-multi-thread\",\"time\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38.2\"},{\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.40\"},{\"name\":\"windows\",\"optional\":true,\"req\":\"^0.62.2\",\"target\":\"cfg(windows)\"}],\"features\":{\"creation-flags\":[\"dep:windows\",\"windows/Win32_System_Threading\"],\"default\":[\"creation-flags\",\"job-object\",\"kill-on-drop\",\"process-group\",\"process-session\",\"tracing\"],\"job-object\":[\"dep:windows\",\"windows/Win32_Security\",\"windows/Win32_System_Diagnostics_ToolHelp\",\"windows/Win32_System_IO\",\"windows/Win32_System_JobObjects\",\"windows/Win32_System_Threading\"],\"kill-on-drop\":[],\"process-group\":[],\"process-session\":[\"process-group\"],\"reset-sigmask\":[],\"std\":[\"dep:nix\"],\"tokio1\":[\"dep:nix\",\"dep:futures\",\"dep:tokio\"],\"tracing\":[\"dep:tracing\"]}}",
"proptest_1.9.0": "{\"dependencies\":[{\"name\":\"bit-set\",\"optional\":true,\"req\":\"^0.8.0\"},{\"name\":\"bit-vec\",\"optional\":true,\"req\":\"^0.8.0\"},{\"name\":\"bitflags\",\"req\":\"^2.9\"},{\"default_features\":false,\"name\":\"num-traits\",\"req\":\"^0.2.15\"},{\"name\":\"proptest-macro\",\"optional\":true,\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"rand\",\"req\":\"^0.9\"},{\"default_features\":false,\"name\":\"rand_chacha\",\"req\":\"^0.9\"},{\"name\":\"rand_xorshift\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1.0\"},{\"name\":\"regex-syntax\",\"optional\":true,\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"rusty-fork\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"tempfile\",\"optional\":true,\"req\":\"^3.0\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"=1.0.112\"},{\"name\":\"unarray\",\"req\":\"^0.1.4\"},{\"name\":\"x86\",\"optional\":true,\"req\":\"^0.52.0\"}],\"features\":{\"alloc\":[],\"atomic64bit\":[],\"attr-macro\":[\"proptest-macro\"],\"bit-set\":[\"dep:bit-set\",\"dep:bit-vec\"],\"default\":[\"std\",\"fork\",\"timeout\",\"bit-set\"],\"default-code-coverage\":[\"std\",\"fork\",\"timeout\",\"bit-set\"],\"fork\":[\"std\",\"rusty-fork\",\"tempfile\"],\"handle-panics\":[\"std\"],\"hardware-rng\":[\"x86\"],\"no_std\":[\"num-traits/libm\"],\"std\":[\"rand/std\",\"rand/os_rng\",\"regex-syntax\",\"num-traits/std\"],\"timeout\":[\"fork\",\"rusty-fork/timeout\"],\"unstable\":[]}}",
+ "prost-build_0.12.6": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10\"},{\"name\":\"heck\",\"req\":\">=0.4, <=0.5\"},{\"default_features\":false,\"features\":[\"use_alloc\"],\"name\":\"itertools\",\"req\":\">=0.10, <=0.12\"},{\"name\":\"log\",\"req\":\"^0.4.4\"},{\"default_features\":false,\"name\":\"multimap\",\"req\":\">=0.8, <=0.10\"},{\"name\":\"once_cell\",\"req\":\"^1.17.1\"},{\"default_features\":false,\"name\":\"petgraph\",\"req\":\"^0.6\"},{\"name\":\"prettyplease\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"prost\",\"req\":\"^0.12.6\"},{\"default_features\":false,\"name\":\"prost-types\",\"req\":\"^0.12.6\"},{\"default_features\":false,\"name\":\"pulldown-cmark\",\"optional\":true,\"req\":\"^0.9.1\"},{\"name\":\"pulldown-cmark-to-cmark\",\"optional\":true,\"req\":\"^10.0.1\"},{\"default_features\":false,\"features\":[\"std\",\"unicode-bool\"],\"name\":\"regex\",\"req\":\"^1.8.1\"},{\"features\":[\"full\"],\"name\":\"syn\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"tempfile\",\"req\":\"^3\"}],\"features\":{\"cleanup-markdown\":[\"dep:pulldown-cmark\",\"dep:pulldown-cmark-to-cmark\"],\"default\":[\"format\"],\"format\":[\"dep:prettyplease\",\"dep:syn\"]}}",
+ "prost-derive_0.12.6": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.1\"},{\"default_features\":false,\"features\":[\"use_alloc\"],\"name\":\"itertools\",\"req\":\">=0.10, <=0.12\"},{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}",
+ "prost-derive_0.13.5": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.1\"},{\"name\":\"itertools\",\"req\":\">=0.10.1, <=0.14\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0.60\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}",
"prost-derive_0.14.3": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.1\"},{\"name\":\"itertools\",\"req\":\">=0.10.1, <=0.14\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0.60\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}",
+ "prost-types_0.12.6": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"prost-derive\"],\"name\":\"prost\",\"req\":\"^0.12.6\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"prost/std\"]}}",
+ "prost_0.12.6": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"prost-derive\",\"optional\":true,\"req\":\"^0.12.6\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"default\":[\"derive\",\"std\"],\"derive\":[\"dep:prost-derive\"],\"no-recursion-limit\":[],\"prost-derive\":[\"derive\"],\"std\":[]}}",
+ "prost_0.13.5": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"prost-derive\",\"optional\":true,\"req\":\"^0.13.5\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"}],\"features\":{\"default\":[\"derive\",\"std\"],\"derive\":[\"dep:prost-derive\"],\"no-recursion-limit\":[],\"prost-derive\":[\"derive\"],\"std\":[]}}",
"prost_0.14.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"prost-derive\",\"optional\":true,\"req\":\"^0.14.3\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"}],\"features\":{\"default\":[\"derive\",\"std\"],\"derive\":[\"dep:prost-derive\"],\"no-recursion-limit\":[],\"std\":[]}}",
"psl-types_2.0.11": "{\"dependencies\":[],\"features\":{}}",
"psl_2.1.184": "{\"dependencies\":[{\"name\":\"psl-types\",\"req\":\"^2.0.11\"},{\"kind\":\"dev\",\"name\":\"rspec\",\"req\":\"^1.0.0\"}],\"features\":{\"default\":[\"helpers\"],\"helpers\":[]}}",
@@ -1148,6 +1179,7 @@
"pxfm_0.1.27": "{\"dependencies\":[{\"name\":\"num-traits\",\"req\":\"^0.2.3\"}],\"features\":{}}",
"quick-error_2.0.1": "{\"dependencies\":[],\"features\":{}}",
"quick-xml_0.38.4": "{\"dependencies\":[{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\">=0.4, <0.8\"},{\"name\":\"document-features\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"encoding_rs\",\"optional\":true,\"req\":\"^0.8\"},{\"name\":\"memchr\",\"req\":\"^2.1\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^1.4\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1\"},{\"name\":\"serde\",\"optional\":true,\"req\":\">=1.0.139\"},{\"kind\":\"dev\",\"name\":\"serde-value\",\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0.206\"},{\"default_features\":false,\"features\":[\"io-util\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.10\"},{\"default_features\":false,\"features\":[\"macros\",\"rt\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.21\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"}],\"features\":{\"async-tokio\":[\"tokio\"],\"default\":[],\"encoding\":[\"encoding_rs\"],\"escape-html\":[],\"overlapped-lists\":[],\"serde-types\":[\"serde/derive\"],\"serialize\":[\"serde\"]}}",
+ "quick_cache_0.6.21": "{\"dependencies\":[{\"name\":\"ahash\",\"optional\":true,\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7\"},{\"name\":\"crossbeam-utils\",\"optional\":true,\"req\":\"^0.8\"},{\"name\":\"equivalent\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"inline-more\"],\"name\":\"hashbrown\",\"req\":\"^0.16\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12\"},{\"features\":[\"small_rng\"],\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"rand_distr\",\"req\":\"^0.5\"},{\"name\":\"shuttle\",\"optional\":true,\"req\":\"^0.8\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"}],\"features\":{\"default\":[\"ahash\",\"parking_lot\"],\"sharded-lock\":[\"dep:crossbeam-utils\"],\"shuttle\":[\"dep:shuttle\"],\"stats\":[]}}",
"quinn-proto_0.11.13": "{\"dependencies\":[{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.0.1\"},{\"kind\":\"dev\",\"name\":\"assert_matches\",\"req\":\"^1.1\"},{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.9\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"fastbloom\",\"optional\":true,\"req\":\"^0.14\"},{\"default_features\":false,\"features\":[\"wasm_js\"],\"name\":\"getrandom\",\"req\":\"^0.3\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"lru-slab\",\"req\":\"^0.1.2\"},{\"name\":\"qlog\",\"optional\":true,\"req\":\"^0.15.2\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"rand_pcg\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14\"},{\"features\":[\"wasm32_unknown_unknown_js\"],\"name\":\"ring\",\"req\":\"^0.17\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"name\":\"rustc-hash\",\"req\":\"^2\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"optional\":true,\"req\":\"^0.23.5\"},{\"features\":[\"web\"],\"name\":\"rustls-pki-types\",\"req\":\"^1.7\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"rustls-platform-verifier\",\"optional\":true,\"req\":\"^0.6\"},{\"name\":\"slab\",\"req\":\"^0.4.6\"},{\"name\":\"thiserror\",\"req\":\"^2.0.3\"},{\"features\":[\"alloc\",\"alloc\"],\"name\":\"tinyvec\",\"req\":\"^1.1\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"req\":\"^0.1.10\"},{\"default_features\":false,\"features\":[\"env-filter\",\"fmt\",\"ansi\",\"time\",\"local-time\"],\"kind\":\"dev\",\"name\":\"tracing-subscriber\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3.45\"},{\"name\":\"web-time\",\"req\":\"^1\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"}],\"features\":{\"aws-lc-rs\":[\"dep:aws-lc-rs\",\"aws-lc-rs?/aws-lc-sys\",\"aws-lc-rs?/prebuilt-nasm\"],\"aws-lc-rs-fips\":[\"aws-lc-rs\",\"aws-lc-rs?/fips\"],\"bloom\":[\"dep:fastbloom\"],\"default\":[\"rustls-ring\",\"log\",\"bloom\"],\"log\":[\"tracing/log\"],\"platform-verifier\":[\"dep:rustls-platform-verifier\"],\"qlog\":[\"dep:qlog\"],\"ring\":[\"dep:ring\"],\"rustls\":[\"rustls-ring\"],\"rustls-aws-lc-rs\":[\"dep:rustls\",\"rustls?/aws-lc-rs\",\"aws-lc-rs\"],\"rustls-aws-lc-rs-fips\":[\"rustls-aws-lc-rs\",\"aws-lc-rs-fips\"],\"rustls-log\":[\"rustls?/logging\"],\"rustls-ring\":[\"dep:rustls\",\"rustls?/ring\",\"ring\"]}}",
"quinn-udp_0.5.14": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"cfg_aliases\",\"req\":\"^0.2\"},{\"default_features\":false,\"features\":[\"async_tokio\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7\"},{\"name\":\"libc\",\"req\":\"^0.2.158\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"once_cell\",\"req\":\"^1.19\",\"target\":\"cfg(windows)\"},{\"name\":\"socket2\",\"req\":\">=0.5, <0.7\",\"target\":\"cfg(not(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\")))\"},{\"features\":[\"sync\",\"rt\",\"rt-multi-thread\",\"net\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.28.1\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.10\"},{\"features\":[\"Win32_Foundation\",\"Win32_System_IO\",\"Win32_Networking_WinSock\"],\"name\":\"windows-sys\",\"req\":\">=0.52, <=0.60\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[\"tracing\",\"log\"],\"direct-log\":[\"dep:log\"],\"fast-apple-datapath\":[],\"log\":[\"tracing/log\"]}}",
"quinn_0.11.9": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0.22\"},{\"name\":\"async-io\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"async-std\",\"optional\":true,\"req\":\"^1.11\"},{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"kind\":\"build\",\"name\":\"cfg_aliases\",\"req\":\"^0.2\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^4\"},{\"kind\":\"dev\",\"name\":\"crc\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"directories-next\",\"req\":\"^2\"},{\"name\":\"futures-io\",\"optional\":true,\"req\":\"^0.3.19\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"proto\",\"package\":\"quinn-proto\",\"req\":\"^0.11.12\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14\"},{\"name\":\"rustc-hash\",\"req\":\"^2\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"optional\":true,\"req\":\"^0.23.5\"},{\"kind\":\"dev\",\"name\":\"rustls-pemfile\",\"req\":\"^2\"},{\"name\":\"smol\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"socket2\",\"req\":\">=0.5, <0.7\",\"target\":\"cfg(not(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\")))\"},{\"name\":\"thiserror\",\"req\":\"^2.0.3\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1.28.1\"},{\"features\":[\"sync\",\"rt\",\"rt-multi-thread\",\"time\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.28.1\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"req\":\"^0.1.10\"},{\"default_features\":false,\"features\":[\"std-future\"],\"kind\":\"dev\",\"name\":\"tracing-futures\",\"req\":\"^0.2.0\"},{\"default_features\":false,\"features\":[\"env-filter\",\"fmt\",\"ansi\",\"time\",\"local-time\"],\"kind\":\"dev\",\"name\":\"tracing-subscriber\",\"req\":\"^0.3.0\"},{\"default_features\":false,\"features\":[\"tracing\"],\"name\":\"udp\",\"package\":\"quinn-udp\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"url\",\"req\":\"^2\"},{\"name\":\"web-time\",\"req\":\"^1\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"}],\"features\":{\"aws-lc-rs\":[\"proto/aws-lc-rs\"],\"aws-lc-rs-fips\":[\"proto/aws-lc-rs-fips\"],\"bloom\":[\"proto/bloom\"],\"default\":[\"log\",\"platform-verifier\",\"runtime-tokio\",\"rustls-ring\",\"bloom\"],\"lock_tracking\":[],\"log\":[\"tracing/log\",\"proto/log\",\"udp/log\"],\"platform-verifier\":[\"proto/platform-verifier\"],\"qlog\":[\"proto/qlog\"],\"ring\":[\"proto/ring\"],\"runtime-async-std\":[\"async-io\",\"async-std\"],\"runtime-smol\":[\"async-io\",\"smol\"],\"runtime-tokio\":[\"tokio/time\",\"tokio/rt\",\"tokio/net\"],\"rustls\":[\"rustls-ring\"],\"rustls-aws-lc-rs\":[\"dep:rustls\",\"aws-lc-rs\",\"proto/rustls-aws-lc-rs\",\"proto/aws-lc-rs\"],\"rustls-aws-lc-rs-fips\":[\"dep:rustls\",\"aws-lc-rs-fips\",\"proto/rustls-aws-lc-rs-fips\",\"proto/aws-lc-rs-fips\"],\"rustls-log\":[\"rustls?/logging\"],\"rustls-ring\":[\"dep:rustls\",\"ring\",\"proto/rustls-ring\",\"proto/ring\"]}}",
@@ -1211,7 +1243,9 @@
"rusticata-macros_4.1.0": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"std\"],\"name\":\"nom\",\"req\":\"^7.0\"}],\"features\":{}}",
"rustix_0.38.44": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bitflags\",\"req\":\"^2.4.0\"},{\"name\":\"compiler_builtins\",\"optional\":true,\"req\":\"^0.1.49\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.4\",\"target\":\"cfg(all(criterion, not(any(target_os = \\\"emscripten\\\", target_os = \\\"wasi\\\"))))\"},{\"kind\":\"dev\",\"name\":\"flate2\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"itoa\",\"optional\":true,\"req\":\"^1.0.13\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.161\",\"target\":\"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\"},{\"default_features\":false,\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.161\",\"target\":\"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2.161\"},{\"default_features\":false,\"name\":\"libc_errno\",\"package\":\"errno\",\"req\":\"^0.3.10\",\"target\":\"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\"},{\"default_features\":false,\"name\":\"libc_errno\",\"package\":\"errno\",\"req\":\"^0.3.10\",\"target\":\"cfg(windows)\"},{\"default_features\":false,\"name\":\"libc_errno\",\"optional\":true,\"package\":\"errno\",\"req\":\"^0.3.10\",\"target\":\"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"libc_errno\",\"package\":\"errno\",\"req\":\"^0.3.10\"},{\"default_features\":false,\"features\":[\"general\",\"ioctl\",\"no_std\"],\"name\":\"linux-raw-sys\",\"req\":\"^0.4.14\",\"target\":\"cfg(all(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\"},{\"default_features\":false,\"features\":[\"general\",\"errno\",\"ioctl\",\"no_std\",\"elf\"],\"name\":\"linux-raw-sys\",\"req\":\"^0.4.14\",\"target\":\"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\"},{\"kind\":\"dev\",\"name\":\"memoffset\",\"req\":\"^0.9.0\"},{\"name\":\"once_cell\",\"optional\":true,\"req\":\"^1.5.2\",\"target\":\"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"))\"},{\"name\":\"rustc-std-workspace-alloc\",\"optional\":true,\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"serial_test\",\"req\":\"^2.0.0\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1.1.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.5.0\"},{\"features\":[\"Win32_Foundation\",\"Win32_Networking_WinSock\",\"Win32_NetworkManagement_IpHelper\",\"Win32_System_Threading\"],\"name\":\"windows-sys\",\"req\":\">=0.52, <=0.59\",\"target\":\"cfg(windows)\"}],\"features\":{\"all-apis\":[\"event\",\"fs\",\"io_uring\",\"mm\",\"mount\",\"net\",\"param\",\"pipe\",\"process\",\"procfs\",\"pty\",\"rand\",\"runtime\",\"shm\",\"stdio\",\"system\",\"termios\",\"thread\",\"time\"],\"alloc\":[],\"cc\":[],\"default\":[\"std\",\"use-libc-auxv\"],\"event\":[],\"fs\":[],\"io_uring\":[\"event\",\"fs\",\"net\",\"linux-raw-sys/io_uring\"],\"libc-extra-traits\":[\"libc?/extra_traits\"],\"linux_4_11\":[],\"linux_latest\":[\"linux_4_11\"],\"mm\":[],\"mount\":[],\"net\":[\"linux-raw-sys/net\",\"linux-raw-sys/netlink\",\"linux-raw-sys/if_ether\",\"linux-raw-sys/xdp\"],\"param\":[\"fs\"],\"pipe\":[],\"process\":[\"linux-raw-sys/prctl\"],\"procfs\":[\"once_cell\",\"itoa\",\"fs\"],\"pty\":[\"itoa\",\"fs\"],\"rand\":[],\"runtime\":[\"linux-raw-sys/prctl\"],\"rustc-dep-of-std\":[\"core\",\"rustc-std-workspace-alloc\",\"compiler_builtins\",\"linux-raw-sys/rustc-dep-of-std\",\"bitflags/rustc-dep-of-std\",\"compiler_builtins?/rustc-dep-of-std\"],\"shm\":[\"fs\"],\"std\":[\"bitflags/std\",\"alloc\",\"libc?/std\",\"libc_errno?/std\",\"libc-extra-traits\"],\"stdio\":[],\"system\":[\"linux-raw-sys/system\"],\"termios\":[],\"thread\":[\"linux-raw-sys/prctl\"],\"time\":[],\"try_close\":[],\"use-explicitly-provided-auxv\":[],\"use-libc\":[\"libc_errno\",\"libc\",\"libc-extra-traits\"],\"use-libc-auxv\":[]}}",
"rustix_1.1.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bitflags\",\"req\":\"^2.4.0\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.4\",\"target\":\"cfg(all(criterion, not(any(target_os = \\\"emscripten\\\", target_os = \\\"wasi\\\"))))\"},{\"kind\":\"dev\",\"name\":\"flate2\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.177\",\"target\":\"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\"},{\"default_features\":false,\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.177\",\"target\":\"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2.171\"},{\"default_features\":false,\"name\":\"libc_errno\",\"package\":\"errno\",\"req\":\"^0.3.10\",\"target\":\"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\"},{\"default_features\":false,\"name\":\"libc_errno\",\"package\":\"errno\",\"req\":\"^0.3.10\",\"target\":\"cfg(windows)\"},{\"default_features\":false,\"name\":\"libc_errno\",\"optional\":true,\"package\":\"errno\",\"req\":\"^0.3.10\",\"target\":\"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"libc_errno\",\"package\":\"errno\",\"req\":\"^0.3.10\"},{\"default_features\":false,\"features\":[\"general\",\"ioctl\",\"no_std\"],\"name\":\"linux-raw-sys\",\"req\":\"^0.11.0\",\"target\":\"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\"},{\"default_features\":false,\"features\":[\"auxvec\",\"general\",\"errno\",\"ioctl\",\"no_std\",\"elf\"],\"name\":\"linux-raw-sys\",\"req\":\"^0.11.0\",\"target\":\"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\"},{\"kind\":\"dev\",\"name\":\"memoffset\",\"req\":\"^0.9.0\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1.20.3\",\"target\":\"cfg(windows)\"},{\"name\":\"rustc-std-workspace-alloc\",\"optional\":true,\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"serial_test\",\"req\":\"^2.0.0\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1.1.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.5.0\"},{\"features\":[\"Win32_Foundation\",\"Win32_Networking_WinSock\"],\"name\":\"windows-sys\",\"req\":\">=0.52, <0.62\",\"target\":\"cfg(windows)\"}],\"features\":{\"all-apis\":[\"event\",\"fs\",\"io_uring\",\"mm\",\"mount\",\"net\",\"param\",\"pipe\",\"process\",\"pty\",\"rand\",\"runtime\",\"shm\",\"stdio\",\"system\",\"termios\",\"thread\",\"time\"],\"alloc\":[],\"default\":[\"std\"],\"event\":[],\"fs\":[],\"io_uring\":[\"event\",\"fs\",\"net\",\"thread\",\"linux-raw-sys/io_uring\"],\"linux_4_11\":[],\"linux_5_1\":[\"linux_4_11\"],\"linux_5_11\":[\"linux_5_1\"],\"linux_latest\":[\"linux_5_11\"],\"mm\":[],\"mount\":[],\"net\":[\"linux-raw-sys/net\",\"linux-raw-sys/netlink\",\"linux-raw-sys/if_ether\",\"linux-raw-sys/xdp\"],\"param\":[],\"pipe\":[],\"process\":[\"linux-raw-sys/prctl\"],\"pty\":[\"fs\"],\"rand\":[],\"runtime\":[\"linux-raw-sys/prctl\"],\"rustc-dep-of-std\":[\"core\",\"rustc-std-workspace-alloc\",\"linux-raw-sys/rustc-dep-of-std\",\"bitflags/rustc-dep-of-std\"],\"shm\":[\"fs\"],\"std\":[\"bitflags/std\",\"alloc\",\"libc?/std\",\"libc_errno?/std\"],\"stdio\":[],\"system\":[\"linux-raw-sys/system\"],\"termios\":[],\"thread\":[\"linux-raw-sys/prctl\"],\"time\":[],\"try_close\":[],\"use-explicitly-provided-auxv\":[],\"use-libc\":[\"libc_errno\",\"libc\"],\"use-libc-auxv\":[]}}",
+ "rustls-native-certs_0.7.3": "{\"dependencies\":[{\"name\":\"openssl-probe\",\"req\":\"^0.1.2\",\"target\":\"cfg(all(unix, not(target_os = \\\"macos\\\")))\"},{\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"ring\",\"req\":\"^0.17\"},{\"kind\":\"dev\",\"name\":\"rustls\",\"req\":\"^0.23\"},{\"name\":\"rustls-pemfile\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"rustls-webpki\",\"req\":\"^0.102\"},{\"name\":\"schannel\",\"req\":\"^0.1\",\"target\":\"cfg(windows)\"},{\"name\":\"security-framework\",\"req\":\"^2\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"kind\":\"dev\",\"name\":\"serial_test\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.5\"},{\"kind\":\"dev\",\"name\":\"untrusted\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^0.26\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.16\"}],\"features\":{}}",
"rustls-native-certs_0.8.3": "{\"dependencies\":[{\"name\":\"openssl-probe\",\"req\":\"^0.2\",\"target\":\"cfg(all(unix, not(target_os = \\\"macos\\\")))\"},{\"features\":[\"std\"],\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.10\"},{\"kind\":\"dev\",\"name\":\"ring\",\"req\":\"^0.17\"},{\"kind\":\"dev\",\"name\":\"rustls\",\"req\":\"^0.23\"},{\"kind\":\"dev\",\"name\":\"rustls-webpki\",\"req\":\"^0.103\"},{\"name\":\"schannel\",\"req\":\"^0.1\",\"target\":\"cfg(windows)\"},{\"name\":\"security-framework\",\"req\":\"^3\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"kind\":\"dev\",\"name\":\"serial_test\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.5\"},{\"kind\":\"dev\",\"name\":\"untrusted\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.18\"}],\"features\":{}}",
+ "rustls-pemfile_2.2.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.9\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"pki-types/std\"]}}",
"rustls-pki-types_1.14.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"crabgrind\",\"req\":\"=0.1.9\",\"target\":\"cfg(all(target_os = \\\"linux\\\", target_arch = \\\"x86_64\\\"))\"},{\"name\":\"web-time\",\"optional\":true,\"req\":\"^1\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"dep:zeroize\"],\"default\":[\"alloc\"],\"std\":[\"alloc\"],\"web\":[\"web-time\"]}}",
"rustls-webpki_0.103.10": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.14\"},{\"kind\":\"dev\",\"name\":\"base64\",\"req\":\"^0.22\"},{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"kind\":\"dev\",\"name\":\"bzip2\",\"req\":\"^0.6\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1.17.2\"},{\"default_features\":false,\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.12\"},{\"default_features\":false,\"features\":[\"aws_lc_rs\"],\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14.2\"},{\"default_features\":false,\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"untrusted\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.18.1\"}],\"features\":{\"alloc\":[\"ring?/alloc\",\"pki-types/alloc\"],\"aws-lc-rs\":[\"dep:aws-lc-rs\",\"aws-lc-rs/aws-lc-sys\",\"aws-lc-rs/prebuilt-nasm\"],\"aws-lc-rs-fips\":[\"dep:aws-lc-rs\",\"aws-lc-rs/fips\"],\"aws-lc-rs-unstable\":[\"aws-lc-rs\",\"aws-lc-rs/unstable\"],\"default\":[\"std\"],\"ring\":[\"dep:ring\"],\"std\":[\"alloc\",\"pki-types/std\"]}}",
"rustls_0.23.36": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.14\"},{\"kind\":\"dev\",\"name\":\"base64\",\"req\":\"^0.22\"},{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.5\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"brotli\",\"optional\":true,\"req\":\"^8\"},{\"name\":\"brotli-decompressor\",\"optional\":true,\"req\":\"^5.0.0\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11\"},{\"default_features\":false,\"features\":[\"default-hasher\",\"inline-more\"],\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.15\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.8\"},{\"kind\":\"dev\",\"name\":\"log\",\"req\":\"^0.4.8\"},{\"kind\":\"dev\",\"name\":\"macro_rules_attribute\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"num-bigint\",\"req\":\"^0.4.4\"},{\"default_features\":false,\"features\":[\"alloc\",\"race\"],\"name\":\"once_cell\",\"req\":\"^1.16\"},{\"features\":[\"alloc\"],\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.12\"},{\"default_features\":false,\"features\":[\"pem\",\"aws_lc_rs\"],\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"kind\":\"build\",\"name\":\"rustversion\",\"optional\":true,\"req\":\"^1.0.6\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2.5.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.6\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103.5\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.17\"},{\"name\":\"zeroize\",\"req\":\"^1.8\"},{\"name\":\"zlib-rs\",\"optional\":true,\"req\":\"^0.5\"}],\"features\":{\"aws-lc-rs\":[\"aws_lc_rs\"],\"aws_lc_rs\":[\"dep:aws-lc-rs\",\"webpki/aws-lc-rs\",\"aws-lc-rs/aws-lc-sys\",\"aws-lc-rs/prebuilt-nasm\"],\"brotli\":[\"dep:brotli\",\"dep:brotli-decompressor\",\"std\"],\"custom-provider\":[],\"default\":[\"aws_lc_rs\",\"logging\",\"prefer-post-quantum\",\"std\",\"tls12\"],\"fips\":[\"aws_lc_rs\",\"aws-lc-rs?/fips\",\"webpki/aws-lc-rs-fips\"],\"logging\":[\"log\"],\"prefer-post-quantum\":[\"aws_lc_rs\"],\"read_buf\":[\"rustversion\",\"std\"],\"ring\":[\"dep:ring\",\"webpki/ring\"],\"std\":[\"webpki/std\",\"pki-types/std\",\"once_cell/std\"],\"tls12\":[],\"zlib\":[\"dep:zlib-rs\"]}}",
@@ -1366,6 +1400,7 @@
"tokio-rustls_0.26.4": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"argh\",\"req\":\"^0.1.1\"},{\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.1\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1.1\"},{\"features\":[\"pem\"],\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"req\":\"^0.23.27\"},{\"name\":\"tokio\",\"req\":\"^1.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^1\"}],\"features\":{\"aws-lc-rs\":[\"aws_lc_rs\"],\"aws_lc_rs\":[\"rustls/aws_lc_rs\"],\"brotli\":[\"rustls/brotli\"],\"default\":[\"logging\",\"tls12\",\"aws_lc_rs\"],\"early-data\":[],\"fips\":[\"rustls/fips\"],\"logging\":[\"rustls/logging\"],\"ring\":[\"rustls/ring\"],\"tls12\":[\"rustls/tls12\"],\"zlib\":[\"rustls/zlib\"]}}",
"tokio-stream_0.1.18": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1.15.0\"},{\"features\":[\"full\",\"test-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tokio-util\",\"optional\":true,\"req\":\"^0.7.0\"}],\"features\":{\"default\":[\"time\"],\"fs\":[\"tokio/fs\"],\"full\":[\"time\",\"net\",\"io-util\",\"fs\",\"sync\",\"signal\"],\"io-util\":[\"tokio/io-util\"],\"net\":[\"tokio/net\"],\"signal\":[\"tokio/signal\"],\"sync\":[\"tokio/sync\",\"tokio-util\"],\"time\":[\"tokio/time\"]}}",
"tokio-test_0.4.5": "{\"dependencies\":[{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.0\"},{\"features\":[\"rt\",\"sync\",\"time\",\"test-util\"],\"name\":\"tokio\",\"req\":\"^1.2.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.2.0\"},{\"name\":\"tokio-stream\",\"req\":\"^0.1.1\"}],\"features\":{}}",
+ "tokio-tungstenite_0.23.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10.0\"},{\"kind\":\"dev\",\"name\":\"futures-channel\",\"req\":\"^0.3.28\"},{\"default_features\":false,\"features\":[\"sink\",\"std\"],\"name\":\"futures-util\",\"req\":\"^0.3.28\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1\"},{\"default_features\":false,\"features\":[\"http1\",\"server\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.0\"},{\"features\":[\"tokio\"],\"kind\":\"dev\",\"name\":\"hyper-util\",\"req\":\"^0.1\"},{\"name\":\"log\",\"req\":\"^0.4.17\"},{\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\",\"req\":\"^0.2.11\"},{\"default_features\":false,\"name\":\"rustls\",\"optional\":true,\"req\":\"^0.23.0\"},{\"name\":\"rustls-native-certs\",\"optional\":true,\"req\":\"^0.7.0\"},{\"name\":\"rustls-pki-types\",\"optional\":true,\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"io-util\"],\"name\":\"tokio\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"features\":[\"io-std\",\"macros\",\"net\",\"rt-multi-thread\",\"time\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.27.0\"},{\"name\":\"tokio-native-tls\",\"optional\":true,\"req\":\"^0.3.1\"},{\"default_features\":false,\"name\":\"tokio-rustls\",\"optional\":true,\"req\":\"^0.26.0\"},{\"default_features\":false,\"name\":\"tungstenite\",\"req\":\"^0.23.0\"},{\"name\":\"webpki-roots\",\"optional\":true,\"req\":\"^0.26.0\"}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\",\"tokio-rustls\",\"stream\",\"tungstenite/__rustls-tls\",\"handshake\"],\"connect\":[\"stream\",\"tokio/net\",\"handshake\"],\"default\":[\"connect\",\"handshake\"],\"handshake\":[\"tungstenite/handshake\"],\"native-tls\":[\"native-tls-crate\",\"tokio-native-tls\",\"stream\",\"tungstenite/native-tls\",\"handshake\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate/vendored\",\"tungstenite/native-tls-vendored\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"],\"stream\":[],\"url\":[\"tungstenite/url\"]}}",
"tokio-util_0.7.18": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3.0\"},{\"name\":\"bytes\",\"req\":\"^1.5.0\"},{\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3.0\"},{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"name\":\"futures-io\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"futures-sink\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-test\",\"req\":\"^0.3.5\"},{\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.0\"},{\"default_features\":false,\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.15.0\"},{\"features\":[\"futures\",\"checkpoint\"],\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"name\":\"slab\",\"optional\":true,\"req\":\"^0.4.4\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.1.0\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1.44.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.29\"}],\"features\":{\"__docs_rs\":[\"futures-util\"],\"codec\":[],\"compat\":[\"futures-io\"],\"default\":[],\"full\":[\"codec\",\"compat\",\"io-util\",\"time\",\"net\",\"rt\",\"join-map\"],\"io\":[],\"io-util\":[\"io\",\"tokio/rt\",\"tokio/io-util\"],\"join-map\":[\"rt\",\"hashbrown\"],\"net\":[\"tokio/net\"],\"rt\":[\"tokio/rt\",\"tokio/sync\",\"futures-util\"],\"time\":[\"tokio/time\",\"slab\"]}}",
"tokio_1.49.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3\"},{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3.58\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1.2.1\"},{\"features\":[\"async-await\"],\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-concurrency\",\"req\":\"^7.6.3\"},{\"kind\":\"dev\",\"name\":\"futures-test\",\"req\":\"^0.3.31\"},{\"default_features\":false,\"name\":\"io-uring\",\"optional\":true,\"req\":\"^0.7.6\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.168\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.168\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2.168\",\"target\":\"cfg(unix)\"},{\"features\":[\"futures\",\"checkpoint\"],\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"},{\"default_features\":false,\"name\":\"mio\",\"optional\":true,\"req\":\"^1.0.1\"},{\"default_features\":false,\"features\":[\"os-poll\",\"os-ext\"],\"name\":\"mio\",\"optional\":true,\"req\":\"^1.0.1\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"features\":[\"tokio\"],\"kind\":\"dev\",\"name\":\"mio-aio\",\"req\":\"^1\",\"target\":\"cfg(target_os = \\\"freebsd\\\")\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.13.0\"},{\"default_features\":false,\"features\":[\"aio\",\"fs\",\"socket\"],\"kind\":\"dev\",\"name\":\"nix\",\"req\":\"^0.29.0\",\"target\":\"cfg(unix)\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\",\"target\":\"cfg(not(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\")))\"},{\"name\":\"signal-hook-registry\",\"optional\":true,\"req\":\"^1.1.1\",\"target\":\"cfg(unix)\"},{\"name\":\"slab\",\"optional\":true,\"req\":\"^0.4.9\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"features\":[\"all\"],\"name\":\"socket2\",\"optional\":true,\"req\":\"^0.6.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"socket2\",\"req\":\"^0.6.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.1.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"name\":\"tokio-macros\",\"optional\":true,\"req\":\"~2.6.0\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4.0\"},{\"features\":[\"rt\"],\"kind\":\"dev\",\"name\":\"tokio-util\",\"req\":\"^0.7\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.29\",\"target\":\"cfg(tokio_unstable)\"},{\"kind\":\"dev\",\"name\":\"tracing-mock\",\"req\":\"=0.1.0-beta.1\",\"target\":\"cfg(all(tokio_unstable, target_has_atomic = \\\"64\\\"))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3.0\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", not(target_os = \\\"wasi\\\")))\"},{\"name\":\"windows-sys\",\"optional\":true,\"req\":\"^0.61\",\"target\":\"cfg(windows)\"},{\"features\":[\"Win32_Foundation\",\"Win32_Security_Authorization\"],\"kind\":\"dev\",\"name\":\"windows-sys\",\"req\":\"^0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[],\"fs\":[],\"full\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"process\",\"rt\",\"rt-multi-thread\",\"signal\",\"sync\",\"time\"],\"io-std\":[],\"io-uring\":[\"dep:io-uring\",\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"dep:slab\"],\"io-util\":[\"bytes\"],\"macros\":[\"tokio-macros\"],\"net\":[\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"mio/net\",\"socket2\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_Security\",\"windows-sys/Win32_Storage_FileSystem\",\"windows-sys/Win32_System_Pipes\",\"windows-sys/Win32_System_SystemServices\"],\"process\":[\"bytes\",\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"mio/net\",\"signal-hook-registry\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_System_Threading\",\"windows-sys/Win32_System_WindowsProgramming\"],\"rt\":[],\"rt-multi-thread\":[\"rt\"],\"signal\":[\"libc\",\"mio/os-poll\",\"mio/net\",\"mio/os-ext\",\"signal-hook-registry\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_System_Console\"],\"sync\":[],\"taskdump\":[\"dep:backtrace\"],\"test-util\":[\"rt\",\"sync\",\"time\"],\"time\":[]}}",
"toml_0.5.11": "{\"dependencies\":[{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"serde\",\"req\":\"^1.0.97\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"}],\"features\":{\"default\":[],\"preserve_order\":[\"indexmap\"]}}",
@@ -1399,6 +1434,7 @@
"try-lock_0.2.5": "{\"dependencies\":[],\"features\":{}}",
"ts-rs-macros_11.1.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"full\",\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2.0.28\"},{\"name\":\"termcolor\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"no-serde-warnings\":[],\"serde-compat\":[\"termcolor\"]}}",
"ts-rs_11.1.0": "{\"dependencies\":[{\"features\":[\"serde\"],\"name\":\"bigdecimal\",\"optional\":true,\"req\":\">=0.0.13, <0.5\"},{\"name\":\"bson\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"chrono\",\"optional\":true,\"req\":\"^0.4\"},{\"features\":[\"serde\"],\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4\"},{\"name\":\"dprint-plugin-typescript\",\"optional\":true,\"req\":\"=0.95\"},{\"name\":\"heapless\",\"optional\":true,\"req\":\">=0.7, <0.9\"},{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"ordered-float\",\"optional\":true,\"req\":\">=3, <6\"},{\"name\":\"semver\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"},{\"name\":\"smol_str\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"thiserror\",\"req\":\"^2\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"sync\",\"rt\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.40\"},{\"name\":\"ts-rs-macros\",\"req\":\"=11.1.0\"},{\"name\":\"url\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"uuid\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"bigdecimal-impl\":[\"bigdecimal\"],\"bson-uuid-impl\":[\"bson\"],\"bytes-impl\":[\"bytes\"],\"chrono-impl\":[\"chrono\"],\"default\":[\"serde-compat\"],\"format\":[\"dprint-plugin-typescript\"],\"heapless-impl\":[\"heapless\"],\"import-esm\":[],\"indexmap-impl\":[\"indexmap\"],\"no-serde-warnings\":[\"ts-rs-macros/no-serde-warnings\"],\"ordered-float-impl\":[\"ordered-float\"],\"semver-impl\":[\"semver\"],\"serde-compat\":[\"ts-rs-macros/serde-compat\"],\"serde-json-impl\":[\"serde_json\"],\"smol_str-impl\":[\"smol_str\"],\"tokio-impl\":[\"tokio\"],\"url-impl\":[\"url\"],\"uuid-impl\":[\"uuid\"]}}",
+ "tungstenite_0.23.0": "{\"dependencies\":[{\"name\":\"byteorder\",\"req\":\"^1.3.2\"},{\"name\":\"bytes\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5.0\"},{\"name\":\"data-encoding\",\"optional\":true,\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10.0\"},{\"name\":\"http\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"httparse\",\"optional\":true,\"req\":\"^1.3.4\"},{\"kind\":\"dev\",\"name\":\"input_buffer\",\"req\":\"^0.5.0\"},{\"name\":\"log\",\"req\":\"^0.4.8\"},{\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\",\"req\":\"^0.2.3\"},{\"name\":\"rand\",\"req\":\"^0.8.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.4\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"optional\":true,\"req\":\"^0.23.0\"},{\"name\":\"rustls-native-certs\",\"optional\":true,\"req\":\"^0.7.0\"},{\"name\":\"rustls-pki-types\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"sha1\",\"optional\":true,\"req\":\"^0.10\"},{\"kind\":\"dev\",\"name\":\"socket2\",\"req\":\"^0.5.5\"},{\"name\":\"thiserror\",\"req\":\"^1.0.23\"},{\"name\":\"url\",\"optional\":true,\"req\":\"^2.1.0\"},{\"name\":\"utf-8\",\"req\":\"^0.7.5\"},{\"name\":\"webpki-roots\",\"optional\":true,\"req\":\"^0.26\"}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\"],\"default\":[\"handshake\"],\"handshake\":[\"data-encoding\",\"http\",\"httparse\",\"sha1\"],\"native-tls\":[\"native-tls-crate\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate/vendored\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"],\"url\":[\"dep:url\"]}}",
"two-face_0.5.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"cargo-lock\",\"req\":\"^10.1.0\"},{\"kind\":\"dev\",\"name\":\"insta\",\"req\":\"^1.44.3\"},{\"default_features\":false,\"features\":[\"read\"],\"kind\":\"dev\",\"name\":\"object\",\"req\":\"^0.36.7\"},{\"name\":\"serde\",\"req\":\"^1.0.228\"},{\"name\":\"serde_derive\",\"req\":\"^1.0.228\"},{\"kind\":\"dev\",\"name\":\"similar\",\"req\":\"^2.7.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"strum\",\"req\":\"^0.26.3\"},{\"default_features\":false,\"features\":[\"dump-load\",\"parsing\"],\"name\":\"syntect\",\"req\":\"^5.3.0\"},{\"default_features\":false,\"features\":[\"html\"],\"kind\":\"dev\",\"name\":\"syntect\",\"req\":\"^5.3.0\"},{\"kind\":\"dev\",\"name\":\"toml\",\"req\":\"^0.8.23\"},{\"default_features\":false,\"features\":[\"std\",\"xxhash64\"],\"kind\":\"dev\",\"name\":\"twox-hash\",\"req\":\"^2.1.2\"}],\"features\":{\"default\":[\"syntect-onig\"],\"syntect-default-fancy\":[\"syntect-fancy\",\"syntect/default-fancy\"],\"syntect-default-onig\":[\"syntect-onig\",\"syntect/default-onig\"],\"syntect-fancy\":[\"syntect/regex-fancy\"],\"syntect-onig\":[\"syntect/regex-onig\"]}}",
"type-map_0.5.1": "{\"dependencies\":[{\"name\":\"rustc-hash\",\"req\":\"^2\"}],\"features\":{}}",
"typenum_1.19.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"scale-info\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"const-generics\":[],\"force_unix_path_separator\":[],\"i128\":[],\"no_std\":[],\"scale_info\":[\"scale-info/derive\"],\"strict\":[]}}",
diff --git a/README.md b/README.md
index 1e44875f2..32f730009 100644
--- a/README.md
+++ b/README.md
@@ -1,60 +1,166 @@
-
npm i -g @openai/codex
or brew install --cask codex
-Codex CLI is a coding agent from OpenAI that runs locally on your computer.
-
-
-
-
-If you want Codex in your code editor (VS Code, Cursor, Windsurf), install in your IDE.
-If you want the desktop app experience, run codex app or visit the Codex App page.
-If you are looking for the cloud-based agent from OpenAI, Codex Web, go to chatgpt.com/codex.
+# Codex Enhanced
----
+Codex Enhanced is an operator-first Codex distribution for people who want a
+local coding agent with better session operations, loop-driven automation, and
+workspace-backed Feishu clawbot workflows.
-## Quickstart
+It stays close to upstream Codex where practical, but focuses fork effort on
+the places that matter in daily operations: account switching, visible control
+surfaces, repeatable release milestones, and automation that can be managed
+from inside the TUI instead of bolted on from the outside.
-### Installing and running Codex CLI
+
-Install globally with your preferred package manager:
+
-```shell
-# Install using npm
-npm install -g @openai/codex
+## Why This Fork Exists
+
+Upstream Codex already provides a strong local coding agent. This fork is about
+operability:
+
+- switching between multiple ChatGPT accounts should not require manual auth
+ file juggling
+- loop automation should be visible, interruptible, and predictable from the
+ TUI
+- external chat entry points should bind to real Codex threads instead of
+ living in a separate bot stack
+- fork-owned behavior should move toward explicit extension boundaries instead
+ of spreading through core runtime code
+
+## What You Get
+
+| Area | What is implemented now |
+| --- | --- |
+| Managed accounts | Named account slots under `~/.codex/accounts`, login-time registration, stable aliases, and operator-facing switching |
+| TUI control surface | `Ctrl-P` control panel for sessions, accounts, clawbot management, and current-session workflows |
+| Loop runtime | Before-turn and after-turn loop runners with queued scheduling, per-loop progress, `/stop` cancellation, and info cells in the chat stream |
+| Clawbot | Workspace-backed `codex-clawbot` runtime, Feishu session discovery, manual bind, cached unread flush, and final answer forwarding |
+| Fork boundary | Dedicated fork-owned crates and a release flow that keeps the fork delta reviewable |
+
+## Operator Surface
+
+| Overview | Release train |
+| --- | --- |
+|  |  |
+
+## Recent Releases
+
+### `v0.1.11`
+
+- fixed the empty `after-turn` path so the TUI does not leave a stale
+ `Running background loop` banner behind
+- hardened background loop state cleanup for the latest scheduler flow
+
+### `v0.1.10`
+
+- added the `codex-clawbot` crate for workspace-backed Feishu session bridging
+- added clawbot control-panel flows for session list, manual bind, retry, scan,
+ clear, flush, and configuration
+- made after-turn loop rounds responsive, surfaced per-loop queue progress, and
+ restored `/stop` cancellation for hidden loop runs
+
+### `v0.1.9`
+
+- shipped loop v2 runtime updates and aligned release artifacts around the new
+ scheduler flow
+- refreshed TUI and `tui_app_server` snapshots for the newer account and status
+ surfaces
+- aligned stop-cleanup and app-server widget behavior with the current TUI
+
+## Clawbot And Loop Workflow
+
+Recent releases moved this fork beyond simple account management:
+
+- Feishu sessions can be discovered, scanned, or manually bound to the current
+ Codex thread from `Ctrl-P -> Clawbot -> Sessions`
+- unread Feishu messages can be cached before binding, flushed into the bound
+ thread in order, and tagged in the TUI as `Feishu message`
+- loop-generated activity now shows explicit progress and emits `Loop agent
+ reply` info cells so operators can see where automation output came from
+- bound threads can forward their final assistant answer back into the linked
+ Feishu session
+
+## Repository Layout
+
+- [codex-rs/ext](./codex-rs/ext)
+ Fork-owned extension crate for account pool state, auth snapshots, and future
+ plugin host compatibility.
+- [codex-rs/clawbot](./codex-rs/clawbot)
+ Workspace-backed clawbot runtime for Feishu session persistence, binding, and
+ provider integration.
+- [codex-rs/tui](./codex-rs/tui)
+ Fullscreen local TUI implementation.
+- [codex-rs/tui_app_server](./codex-rs/tui_app_server)
+ App-server-backed TUI implementation that mirrors relevant UX changes.
+- [docs/fork-extension-mvp.md](./docs/fork-extension-mvp.md)
+ Fork proposal, MVP design, and phased roadmap.
+
+## Build And Run
+
+Build the Rust CLI locally:
+
+```bash
+cd codex-rs
+cargo build -p codex-cli
+./target/debug/codex
```
-```shell
-# Install using Homebrew
-brew install --cask codex
+Install it into your shell path:
+
+```bash
+cd codex-rs
+cargo build --release -p codex-cli
+sudo ln -sf "$(pwd)/target/release/codex" /usr/local/bin/codex
+codex --help
```
-Then simply run `codex` to get started.
+## Managed Account Quick Start
+
+Register multiple ChatGPT logins into the managed account pool:
-
-You can also go to the latest GitHub Release and download the appropriate binary for your platform.
+```bash
+codex login --auth primary
+codex login --auth backup
+codex login status
+```
-Each GitHub Release contains many executables, but in practice, you likely want one of these:
+Start Codex, then use:
-- macOS
- - Apple Silicon/arm64: `codex-aarch64-apple-darwin.tar.gz`
- - x86_64 (older Mac hardware): `codex-x86_64-apple-darwin.tar.gz`
-- Linux
- - x86_64: `codex-x86_64-unknown-linux-musl.tar.gz`
- - arm64: `codex-aarch64-unknown-linux-musl.tar.gz`
+- `Ctrl-P -> Sessions` to open the global session picker
+- `Ctrl-P -> Accounts` to switch the active managed account
+- `Ctrl-P -> Accounts -> Rename` to rename account aliases
+- `Ctrl-P -> Clawbot -> Sessions` to manage Feishu sessions and bind one to the
+ current thread
-Each archive contains a single entry with the platform baked into the name (e.g., `codex-x86_64-unknown-linux-musl`), so you likely want to rename it to `codex` after extracting it.
+Managed account state is stored under:
-
+```text
+~/.codex/accounts/
+├── account-pool.json
+└── /
+ └── auth.json
+```
-### Using Codex with your ChatGPT plan
+Workspace-backed clawbot state is stored under:
-Run `codex` and select **Sign in with ChatGPT**. We recommend signing into your ChatGPT account to use Codex as part of your Plus, Pro, Team, Edu, or Enterprise plan. [Learn more about what's included in your ChatGPT plan](https://help.openai.com/en/articles/11369540-codex-in-chatgpt).
+```text
+/.codex/clawbot/
+├── bindings.json
+├── config.toml
+├── inbound_receipts.json
+├── runtime.json
+├── sessions.json
+└── unread_messages.jsonl
+```
-You can also use Codex with an API key, but this requires [additional setup](https://developers.openai.com/codex/auth#sign-in-with-an-api-key).
+## Upstream Relationship
-## Docs
+This project is based on OpenAI Codex and keeps upstream history so changes can
+be rebased and audited cleanly. The maintenance goal is to keep the fork-owned
+delta small, explicit, and increasingly isolated behind `codex-ext`,
+`codex-clawbot`, and other dedicated extension layers instead of broad runtime
+patches.
-- [**Codex Documentation**](https://developers.openai.com/codex)
-- [**Contributing**](./docs/contributing.md)
-- [**Installing & building**](./docs/install.md)
-- [**Open source fund**](./docs/open-source-fund.md)
+## License
-This repository is licensed under the [Apache-2.0 License](LICENSE).
+This repository remains licensed under the [Apache-2.0 License](LICENSE).
diff --git a/codex-cli/scripts/install_native_deps.py b/codex-cli/scripts/install_native_deps.py
index 58fbd370f..66cc12d85 100755
--- a/codex-cli/scripts/install_native_deps.py
+++ b/codex-cli/scripts/install_native_deps.py
@@ -169,13 +169,13 @@ def main() -> int:
if not workflow_url:
workflow_url = DEFAULT_WORKFLOW_URL
- workflow_id = workflow_url.rstrip("/").split("/")[-1]
+ workflow_repo, workflow_id = _parse_workflow_url(workflow_url)
print(f"Downloading native artifacts from workflow {workflow_id}...")
with _gha_group(f"Download native artifacts from workflow {workflow_id}"):
with tempfile.TemporaryDirectory(prefix="codex-native-artifacts-") as artifacts_dir_str:
artifacts_dir = Path(artifacts_dir_str)
- _download_artifacts(workflow_id, artifacts_dir)
+ _download_artifacts(workflow_repo, workflow_id, artifacts_dir)
install_binary_components(
artifacts_dir,
vendor_dir,
@@ -259,7 +259,15 @@ def fetch_rg(
return [results[target] for target in targets]
-def _download_artifacts(workflow_id: str, dest_dir: Path) -> None:
+def _parse_workflow_url(workflow_url: str) -> tuple[str, str]:
+ parsed = urlparse(workflow_url)
+ path_parts = [part for part in parsed.path.split("/") if part]
+ if len(path_parts) < 5 or path_parts[2] != "actions" or path_parts[3] != "runs":
+ raise ValueError(f"Unsupported workflow URL: {workflow_url}")
+ return f"{path_parts[0]}/{path_parts[1]}", path_parts[4]
+
+
+def _download_artifacts(workflow_repo: str, workflow_id: str, dest_dir: Path) -> None:
cmd = [
"gh",
"run",
@@ -267,7 +275,7 @@ def _download_artifacts(workflow_id: str, dest_dir: Path) -> None:
"--dir",
str(dest_dir),
"--repo",
- "openai/codex",
+ workflow_repo,
workflow_id,
]
subprocess.check_call(cmd)
diff --git a/codex-rs/.cargo/config.toml b/codex-rs/.cargo/config.toml
index 5d5eb8fd6..f5d347bd9 100644
--- a/codex-rs/.cargo/config.toml
+++ b/codex-rs/.cargo/config.toml
@@ -1,3 +1,16 @@
+[build]
+jobs = 8
+rustc-wrapper = "sccache"
+rustflags = ["-Z", "threads=8"]
+
+[env]
+SCCACHE_CACHE_SIZE = "10G"
+
+[target.'cfg(target_os = "macos")']
+# Stable Cargo can't select a linker by profile, so use ld64.lld for macOS
+# target builds, which includes local `cargo test` runs.
+rustflags = ["-C", "link-arg=-fuse-ld=/opt/homebrew/opt/lld/bin/ld64.lld"]
+
[target.'cfg(all(windows, target_env = "msvc"))']
rustflags = ["-C", "link-arg=/STACK:8388608"]
diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock
index 9fc695795..6c11a384f 100644
--- a/codex-rs/Cargo.lock
+++ b/codex-rs/Cargo.lock
@@ -380,7 +380,7 @@ version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
- "windows-sys 0.61.2",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -391,7 +391,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
- "windows-sys 0.61.2",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -402,7 +402,7 @@ checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
[[package]]
name = "app_test_support"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"base64 0.22.1",
@@ -850,7 +850,7 @@ dependencies = [
"sha1",
"sync_wrapper",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"tower",
"tower-layer",
"tower-service",
@@ -1384,9 +1384,22 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9b18233253483ce2f65329a24072ec414db782531bdbb7d0bbc4bd2ce6b7e21"
+[[package]]
+name = "codex-accounts"
+version = "0.1.13"
+dependencies = [
+ "base64 0.22.1",
+ "codex-app-server-protocol",
+ "codex-core",
+ "pretty_assertions",
+ "serde",
+ "serde_json",
+ "tempfile",
+]
+
[[package]]
name = "codex-analytics"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-git-utils",
"codex-login",
@@ -1402,7 +1415,7 @@ dependencies = [
[[package]]
name = "codex-ansi-escape"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"ansi-to-tui",
"ratatui",
@@ -1411,7 +1424,7 @@ dependencies = [
[[package]]
name = "codex-api"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"assert_matches",
@@ -1431,17 +1444,17 @@ dependencies = [
"thiserror 2.0.18",
"tokio",
"tokio-test",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"tokio-util",
"tracing",
- "tungstenite",
+ "tungstenite 0.27.0",
"url",
"wiremock",
]
[[package]]
name = "codex-app-server"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"app_test_support",
@@ -1492,7 +1505,7 @@ dependencies = [
"tempfile",
"time",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"tokio-util",
"toml 0.9.11+spec-1.1.0",
"tracing",
@@ -1504,7 +1517,7 @@ dependencies = [
[[package]]
name = "codex-app-server-client"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-app-server",
"codex-app-server-protocol",
@@ -1517,7 +1530,7 @@ dependencies = [
"serde",
"serde_json",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"toml 0.9.11+spec-1.1.0",
"tracing",
"url",
@@ -1525,7 +1538,7 @@ dependencies = [
[[package]]
name = "codex-app-server-protocol"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"clap",
@@ -1553,7 +1566,7 @@ dependencies = [
[[package]]
name = "codex-app-server-test-client"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"clap",
@@ -1567,14 +1580,14 @@ dependencies = [
"tokio",
"tracing",
"tracing-subscriber",
- "tungstenite",
+ "tungstenite 0.27.0",
"url",
"uuid",
]
[[package]]
name = "codex-apply-patch"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"assert_cmd",
@@ -1590,7 +1603,7 @@ dependencies = [
[[package]]
name = "codex-arg0"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-apply-patch",
@@ -1605,7 +1618,7 @@ dependencies = [
[[package]]
name = "codex-artifacts"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-package-manager",
"flate2",
@@ -1626,7 +1639,7 @@ dependencies = [
[[package]]
name = "codex-async-utils"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"async-trait",
"pretty_assertions",
@@ -1636,7 +1649,7 @@ dependencies = [
[[package]]
name = "codex-backend-client"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-backend-openapi-models",
@@ -1651,16 +1664,24 @@ dependencies = [
[[package]]
name = "codex-backend-openapi-models"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"serde",
"serde_json",
"serde_with",
]
+[[package]]
+name = "codex-btw"
+version = "0.1.13"
+dependencies = [
+ "pretty_assertions",
+ "serde",
+]
+
[[package]]
name = "codex-chatgpt"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"clap",
@@ -1676,15 +1697,32 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "codex-clawbot"
+version = "0.1.13"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "openlark",
+ "pretty_assertions",
+ "serde",
+ "serde_json",
+ "tempfile",
+ "tokio",
+ "toml 0.9.11+spec-1.1.0",
+]
+
[[package]]
name = "codex-cli"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"assert_cmd",
"assert_matches",
+ "base64 0.22.1",
"clap",
"clap_complete",
+ "codex-accounts",
"codex-app-server",
"codex-app-server-protocol",
"codex-app-server-test-client",
@@ -1695,6 +1733,7 @@ dependencies = [
"codex-core",
"codex-exec",
"codex-execpolicy",
+ "codex-ext",
"codex-features",
"codex-login",
"codex-mcp-server",
@@ -1728,7 +1767,7 @@ dependencies = [
[[package]]
name = "codex-client"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"async-trait",
"bytes",
@@ -1743,7 +1782,7 @@ dependencies = [
"rand 0.9.2",
"reqwest",
"rustls",
- "rustls-native-certs",
+ "rustls-native-certs 0.8.3",
"rustls-pki-types",
"serde",
"serde_json",
@@ -1758,7 +1797,7 @@ dependencies = [
[[package]]
name = "codex-cloud-requirements"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"async-trait",
"base64 0.22.1",
@@ -1781,7 +1820,7 @@ dependencies = [
[[package]]
name = "codex-cloud-tasks"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"async-trait",
@@ -1812,7 +1851,7 @@ dependencies = [
[[package]]
name = "codex-cloud-tasks-client"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"async-trait",
@@ -1827,7 +1866,7 @@ dependencies = [
[[package]]
name = "codex-code-mode"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"async-trait",
"pretty_assertions",
@@ -1841,7 +1880,7 @@ dependencies = [
[[package]]
name = "codex-config"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-app-server-protocol",
@@ -1865,7 +1904,7 @@ dependencies = [
[[package]]
name = "codex-connectors"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-app-server-protocol",
@@ -1877,7 +1916,7 @@ dependencies = [
[[package]]
name = "codex-core"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"arc-swap",
@@ -1909,6 +1948,8 @@ dependencies = [
"codex-hooks",
"codex-instructions",
"codex-login",
+ "codex-loop",
+ "codex-loop-runtime",
"codex-network-proxy",
"codex-otel",
"codex-plugin",
@@ -1977,7 +2018,7 @@ dependencies = [
"test-log",
"thiserror 2.0.18",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"tokio-util",
"toml 0.9.11+spec-1.1.0",
"toml_edit 0.24.0+spec-1.1.0",
@@ -1998,7 +2039,7 @@ dependencies = [
[[package]]
name = "codex-core-skills"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-analytics",
@@ -2027,7 +2068,7 @@ dependencies = [
[[package]]
name = "codex-debug-client"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"clap",
@@ -2039,7 +2080,7 @@ dependencies = [
[[package]]
name = "codex-exec"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"assert_cmd",
@@ -2081,7 +2122,7 @@ dependencies = [
[[package]]
name = "codex-exec-server"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"async-trait",
@@ -2099,13 +2140,13 @@ dependencies = [
"test-case",
"thiserror 2.0.18",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"tracing",
]
[[package]]
name = "codex-execpolicy"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"clap",
@@ -2122,7 +2163,7 @@ dependencies = [
[[package]]
name = "codex-execpolicy-legacy"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"allocative",
"anyhow",
@@ -2142,16 +2183,32 @@ dependencies = [
[[package]]
name = "codex-experimental-api-macros"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.114",
]
+[[package]]
+name = "codex-ext"
+version = "0.1.13"
+dependencies = [
+ "base64 0.22.1",
+ "codex-accounts",
+ "codex-app-server-protocol",
+ "codex-btw",
+ "codex-core",
+ "codex-threadmessages",
+ "pretty_assertions",
+ "serde",
+ "serde_json",
+ "tempfile",
+]
+
[[package]]
name = "codex-features"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-login",
"codex-otel",
@@ -2165,7 +2222,7 @@ dependencies = [
[[package]]
name = "codex-feedback"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-protocol",
@@ -2177,7 +2234,7 @@ dependencies = [
[[package]]
name = "codex-file-search"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"clap",
@@ -2193,7 +2250,7 @@ dependencies = [
[[package]]
name = "codex-git-utils"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"assert_matches",
"codex-utils-absolute-path",
@@ -2212,7 +2269,7 @@ dependencies = [
[[package]]
name = "codex-hooks"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"chrono",
@@ -2230,7 +2287,7 @@ dependencies = [
[[package]]
name = "codex-instructions"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-protocol",
"pretty_assertions",
@@ -2239,7 +2296,7 @@ dependencies = [
[[package]]
name = "codex-keyring-store"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"keyring",
"tracing",
@@ -2247,7 +2304,7 @@ dependencies = [
[[package]]
name = "codex-linux-sandbox"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"cc",
"clap",
@@ -2269,7 +2326,7 @@ dependencies = [
[[package]]
name = "codex-lmstudio"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-core",
"reqwest",
@@ -2282,7 +2339,7 @@ dependencies = [
[[package]]
name = "codex-login"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"async-trait",
@@ -2318,9 +2375,37 @@ dependencies = [
"wiremock",
]
+[[package]]
+name = "codex-loop"
+version = "0.1.13"
+dependencies = [
+ "chrono",
+ "codex-utils-absolute-path",
+ "cron",
+ "pretty_assertions",
+ "serde",
+ "serde_json",
+ "tempfile",
+]
+
+[[package]]
+name = "codex-loop-runtime"
+version = "0.1.13"
+dependencies = [
+ "chrono",
+ "codex-loop",
+ "codex-protocol",
+ "codex-utils-absolute-path",
+ "pretty_assertions",
+ "serde",
+ "serde_json",
+ "tempfile",
+ "uuid",
+]
+
[[package]]
name = "codex-mcp-server"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-arg0",
@@ -2349,7 +2434,7 @@ dependencies = [
[[package]]
name = "codex-network-proxy"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"async-trait",
@@ -2380,7 +2465,7 @@ dependencies = [
[[package]]
name = "codex-ollama"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"assert_matches",
"async-stream",
@@ -2398,7 +2483,7 @@ dependencies = [
[[package]]
name = "codex-otel"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"chrono",
"codex-api",
@@ -2422,7 +2507,7 @@ dependencies = [
"strum_macros 0.28.0",
"thiserror 2.0.18",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"tracing",
"tracing-opentelemetry",
"tracing-subscriber",
@@ -2430,7 +2515,7 @@ dependencies = [
[[package]]
name = "codex-package-manager"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"fd-lock",
"flate2",
@@ -2450,7 +2535,7 @@ dependencies = [
[[package]]
name = "codex-plugin"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-utils-absolute-path",
"codex-utils-plugins",
@@ -2459,7 +2544,7 @@ dependencies = [
[[package]]
name = "codex-process-hardening"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"libc",
"pretty_assertions",
@@ -2467,7 +2552,7 @@ dependencies = [
[[package]]
name = "codex-protocol"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-execpolicy",
@@ -2495,7 +2580,7 @@ dependencies = [
[[package]]
name = "codex-responses-api-proxy"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"clap",
@@ -2511,7 +2596,7 @@ dependencies = [
[[package]]
name = "codex-rmcp-client"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"axum",
@@ -2545,7 +2630,7 @@ dependencies = [
[[package]]
name = "codex-rollout"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"async-trait",
@@ -2570,7 +2655,7 @@ dependencies = [
[[package]]
name = "codex-sandboxing"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-network-proxy",
"codex-protocol",
@@ -2587,7 +2672,7 @@ dependencies = [
[[package]]
name = "codex-secrets"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"age",
"anyhow",
@@ -2608,7 +2693,7 @@ dependencies = [
[[package]]
name = "codex-shell-command"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"base64 0.22.1",
@@ -2628,7 +2713,7 @@ dependencies = [
[[package]]
name = "codex-shell-escalation"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"async-trait",
@@ -2649,7 +2734,7 @@ dependencies = [
[[package]]
name = "codex-skills"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-utils-absolute-path",
"include_dir",
@@ -2658,7 +2743,7 @@ dependencies = [
[[package]]
name = "codex-state"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"chrono",
@@ -2681,7 +2766,7 @@ dependencies = [
[[package]]
name = "codex-stdio-to-uds"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-utils-cargo-bin",
@@ -2692,7 +2777,7 @@ dependencies = [
[[package]]
name = "codex-terminal-detection"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"pretty_assertions",
"tracing",
@@ -2700,16 +2785,24 @@ dependencies = [
[[package]]
name = "codex-test-macros"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.114",
]
+[[package]]
+name = "codex-threadmessages"
+version = "0.1.13"
+dependencies = [
+ "pretty_assertions",
+ "serde",
+]
+
[[package]]
name = "codex-tui"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"arboard",
@@ -2717,27 +2810,34 @@ dependencies = [
"base64 0.22.1",
"chrono",
"clap",
+ "codex-accounts",
"codex-ansi-escape",
"codex-app-server-client",
"codex-app-server-protocol",
"codex-arg0",
"codex-backend-client",
+ "codex-btw",
"codex-chatgpt",
+ "codex-clawbot",
"codex-cli",
"codex-client",
"codex-cloud-requirements",
"codex-core",
"codex-exec-server",
+ "codex-ext",
"codex-features",
"codex-feedback",
"codex-file-search",
"codex-git-utils",
"codex-login",
+ "codex-loop",
+ "codex-loop-runtime",
"codex-otel",
"codex-protocol",
"codex-shell-command",
"codex-state",
"codex-terminal-detection",
+ "codex-threadmessages",
"codex-tui-app-server",
"codex-utils-absolute-path",
"codex-utils-approval-presets",
@@ -2753,6 +2853,7 @@ dependencies = [
"codex-windows-sandbox",
"color-eyre",
"cpal",
+ "cron",
"crossterm",
"derive_more 2.1.1",
"diffy",
@@ -2805,7 +2906,7 @@ dependencies = [
[[package]]
name = "codex-tui-app-server"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"arboard",
@@ -2813,25 +2914,31 @@ dependencies = [
"base64 0.22.1",
"chrono",
"clap",
+ "codex-accounts",
"codex-ansi-escape",
"codex-app-server-client",
"codex-app-server-protocol",
"codex-arg0",
+ "codex-backend-client",
+ "codex-btw",
"codex-chatgpt",
"codex-cli",
"codex-client",
"codex-cloud-requirements",
"codex-core",
+ "codex-ext",
"codex-features",
"codex-feedback",
"codex-file-search",
"codex-git-utils",
"codex-login",
+ "codex-loop",
"codex-otel",
"codex-protocol",
"codex-shell-command",
"codex-state",
"codex-terminal-detection",
+ "codex-threadmessages",
"codex-utils-absolute-path",
"codex-utils-approval-presets",
"codex-utils-cargo-bin",
@@ -2898,7 +3005,7 @@ dependencies = [
[[package]]
name = "codex-utils-absolute-path"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"dirs",
"path-absolutize",
@@ -2912,14 +3019,14 @@ dependencies = [
[[package]]
name = "codex-utils-approval-presets"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-protocol",
]
[[package]]
name = "codex-utils-cache"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"lru 0.16.3",
"sha1",
@@ -2928,7 +3035,7 @@ dependencies = [
[[package]]
name = "codex-utils-cargo-bin"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"assert_cmd",
"runfiles",
@@ -2937,7 +3044,7 @@ dependencies = [
[[package]]
name = "codex-utils-cli"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"clap",
"codex-protocol",
@@ -2948,15 +3055,15 @@ dependencies = [
[[package]]
name = "codex-utils-elapsed"
-version = "0.0.0"
+version = "0.1.13"
[[package]]
name = "codex-utils-fuzzy-match"
-version = "0.0.0"
+version = "0.1.13"
[[package]]
name = "codex-utils-home-dir"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"dirs",
"pretty_assertions",
@@ -2965,7 +3072,7 @@ dependencies = [
[[package]]
name = "codex-utils-image"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"base64 0.22.1",
"codex-utils-cache",
@@ -2977,7 +3084,7 @@ dependencies = [
[[package]]
name = "codex-utils-json-to-toml"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"pretty_assertions",
"serde_json",
@@ -2986,7 +3093,7 @@ dependencies = [
[[package]]
name = "codex-utils-oss"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-core",
"codex-lmstudio",
@@ -2995,7 +3102,7 @@ dependencies = [
[[package]]
name = "codex-utils-output-truncation"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-protocol",
"codex-utils-string",
@@ -3004,7 +3111,7 @@ dependencies = [
[[package]]
name = "codex-utils-path"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-utils-absolute-path",
"dunce",
@@ -3014,7 +3121,7 @@ dependencies = [
[[package]]
name = "codex-utils-plugins"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"serde",
"serde_json",
@@ -3023,7 +3130,7 @@ dependencies = [
[[package]]
name = "codex-utils-pty"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"filedescriptor",
@@ -3039,7 +3146,7 @@ dependencies = [
[[package]]
name = "codex-utils-readiness"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"assert_matches",
"async-trait",
@@ -3050,14 +3157,14 @@ dependencies = [
[[package]]
name = "codex-utils-rustls-provider"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"rustls",
]
[[package]]
name = "codex-utils-sandbox-summary"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"codex-core",
"codex-protocol",
@@ -3067,7 +3174,7 @@ dependencies = [
[[package]]
name = "codex-utils-sleep-inhibitor"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"core-foundation 0.9.4",
"libc",
@@ -3077,14 +3184,14 @@ dependencies = [
[[package]]
name = "codex-utils-stream-parser"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"pretty_assertions",
]
[[package]]
name = "codex-utils-string"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"pretty_assertions",
"regex-lite",
@@ -3092,14 +3199,14 @@ dependencies = [
[[package]]
name = "codex-utils-template"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"pretty_assertions",
]
[[package]]
name = "codex-v8-poc"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"pretty_assertions",
"v8",
@@ -3107,7 +3214,7 @@ dependencies = [
[[package]]
name = "codex-windows-sandbox"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"base64 0.22.1",
@@ -3321,7 +3428,7 @@ dependencies = [
[[package]]
name = "core_test_support"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"assert_cmd",
@@ -3345,7 +3452,7 @@ dependencies = [
"shlex",
"tempfile",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.28.0",
"tracing",
"tracing-opentelemetry",
"tracing-subscriber",
@@ -3436,6 +3543,18 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+[[package]]
+name = "cron"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "089df96cf6a25253b4b6b6744d86f91150a3d4df546f31a95def47976b8cba97"
+dependencies = [
+ "chrono",
+ "once_cell",
+ "phf",
+ "winnow",
+]
+
[[package]]
name = "crossbeam-channel"
version = "0.5.15"
@@ -3984,7 +4103,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users 0.5.2",
- "windows-sys 0.61.2",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -4229,7 +4348,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
- "windows-sys 0.61.2",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -5113,7 +5232,7 @@ dependencies = [
"hyper",
"hyper-util",
"rustls",
- "rustls-native-certs",
+ "rustls-native-certs 0.8.3",
"rustls-pki-types",
"tokio",
"tokio-rustls",
@@ -5674,7 +5793,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
dependencies = [
"hermit-abi",
"libc",
- "windows-sys 0.61.2",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -5895,6 +6014,17 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
+[[package]]
+name = "lark-websocket-protobuf"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79d4b1f8c37d37efd353c1b116df0f98ff21c8bcb216f67ab026dd2fd2b9ab81"
+dependencies = [
+ "bytes",
+ "prost 0.13.5",
+ "prost-build",
+]
+
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -6158,7 +6288,7 @@ checksum = "b3eede3bdf92f3b4f9dc04072a9ce5ab557d5ec9038773bf9ffcd5588b3cc05b"
[[package]]
name = "mcp_test_support"
-version = "0.0.0"
+version = "0.1.13"
dependencies = [
"anyhow",
"codex-core",
@@ -6452,7 +6582,7 @@ version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
- "windows-sys 0.61.2",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -6899,54 +7029,453 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
-name = "openssl"
-version = "0.10.75"
+name = "openlark"
+version = "0.15.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
+checksum = "fe508c03b5517af1605c03235638f9be5736d89c2c921c73b5e0c24c97014541"
dependencies = [
- "bitflags 2.10.0",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
+ "chrono",
+ "openlark-ai",
+ "openlark-analytics",
+ "openlark-application",
+ "openlark-auth",
+ "openlark-cardkit",
+ "openlark-client",
+ "openlark-communication",
+ "openlark-core",
+ "openlark-docs",
+ "openlark-helpdesk",
+ "openlark-hr",
+ "openlark-mail",
+ "openlark-meeting",
+ "openlark-platform",
+ "openlark-protocol",
+ "openlark-security",
+ "openlark-user",
+ "openlark-webhook",
+ "openlark-workflow",
+ "serde",
+ "serde_json",
+ "serde_repr",
]
[[package]]
-name = "openssl-macros"
-version = "0.1.1"
+name = "openlark-ai"
+version = "0.15.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+checksum = "a2ef35f179540072bbd2a02aa3544cff96d5778855d3afad1c65fc8033b51dbf"
dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.114",
+ "anyhow",
+ "async-trait",
+ "openlark-core",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tokio",
]
[[package]]
-name = "openssl-probe"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
-
-[[package]]
-name = "openssl-probe"
-version = "0.2.1"
+name = "openlark-analytics"
+version = "0.15.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
+checksum = "28a78e778d66d90aa095e79a5db95531dd64b5965bdedd7fc51bc35aa8011bce"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "chrono",
+ "futures",
+ "log",
+ "once_cell",
+ "openlark-core",
+ "rand 0.8.5",
+ "regex",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "thiserror 2.0.18",
+ "tokio",
+ "url",
+ "uuid",
+]
[[package]]
-name = "openssl-src"
-version = "300.5.5+3.5.5"
+name = "openlark-application"
+version = "0.15.0-rc.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709"
+checksum = "a86364afdd947e5ace28671c88001d08120297ceb398d5a14e7dd35ee298c888"
dependencies = [
- "cc",
+ "openlark-core",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "tokio",
+ "tracing",
]
[[package]]
-name = "openssl-sys"
+name = "openlark-auth"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1eede42dc5d35250b179399ce58e67a324a792b8f1ace20eabb35e99ff1d097"
+dependencies = [
+ "anyhow",
+ "base64 0.22.1",
+ "chrono",
+ "hex",
+ "hmac",
+ "openlark-core",
+ "pbkdf2",
+ "rand 0.8.5",
+ "regex",
+ "reqwest",
+ "ring",
+ "serde",
+ "serde_json",
+ "sha2",
+ "thiserror 2.0.18",
+ "tokio",
+ "tracing",
+ "url",
+ "urlencoding",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-cardkit"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "841785e4863a2215703ff02016314aec7b5fb1f743db567bf901f66bb766023c"
+dependencies = [
+ "openlark-core",
+ "serde",
+ "serde_json",
+ "tracing",
+]
+
+[[package]]
+name = "openlark-client"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b9e7edbe53e8bf26941a2ea645d4e888cc3883839f0508c77b98a61e8c9b2f7"
+dependencies = [
+ "chrono",
+ "futures-util",
+ "lark-websocket-protobuf",
+ "log",
+ "openlark-auth",
+ "openlark-communication",
+ "openlark-core",
+ "prost 0.13.5",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tokio",
+ "tokio-tungstenite 0.23.1",
+ "tracing",
+ "url",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-communication"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ffdd6c935c748ec5dabc0991a0414eb11d62a75b593b20c7be791d473a8568d"
+dependencies = [
+ "openlark-core",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "tracing",
+]
+
+[[package]]
+name = "openlark-core"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "054315773d07ab248f4744747ad4dc9193cb16faa6f96c2ce5998f8f7a7a7725"
+dependencies = [
+ "base64 0.22.1",
+ "chrono",
+ "futures-util",
+ "hmac",
+ "http 1.4.0",
+ "num_cpus",
+ "quick_cache",
+ "rand 0.8.5",
+ "regex",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_with",
+ "sha2",
+ "thiserror 2.0.18",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+ "url",
+ "urlencoding",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-docs"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08a78a86061a0919140cf036345ea8d885f72cbce6fef363ef9a231a6e69031a"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "base64 0.22.1",
+ "chrono",
+ "futures",
+ "futures-util",
+ "log",
+ "once_cell",
+ "openlark-core",
+ "rand 0.8.5",
+ "regex",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "thiserror 2.0.18",
+ "tokio",
+ "url",
+ "urlencoding",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-helpdesk"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff66d9b1474d0e4bdfa8fb0f65103e6eab63777a981f45cb1148806c13fdc08b"
+dependencies = [
+ "openlark-core",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "openlark-hr"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca9f1610210a0beab4e7c82e735e2b1c8357a3ccc985e83aec36373f93ab03ef"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "log",
+ "openlark-core",
+ "rand 0.8.5",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tokio",
+]
+
+[[package]]
+name = "openlark-mail"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3d13227c79031ebb5fccbacd7291c4130259955185f142a41b840a8e6ca7236"
+dependencies = [
+ "openlark-core",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "openlark-meeting"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d855705ea24d7221b4fccb98b6dd4bcf75567cfccbb38e463d881e36f36414e8"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "chrono",
+ "openlark-core",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tokio",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-platform"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c02a1c0b0bf7386e61aafe1c534536f3ec9bbbd9ed477d686421248c446e76a1"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "chrono",
+ "futures",
+ "log",
+ "once_cell",
+ "openlark-core",
+ "rand 0.8.5",
+ "regex",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "thiserror 2.0.18",
+ "tokio",
+ "url",
+ "urlencoding",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-protocol"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce999beb07b5c710564dc06b1483adec8afd767b02da775fff120fdaf010f489"
+dependencies = [
+ "bytes",
+ "prost 0.13.5",
+ "prost-build",
+]
+
+[[package]]
+name = "openlark-security"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "103d1a0eba2b41cfdd12d3d21298c74603baeeb3b6852303fd375b0b47958b77"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "base64 0.22.1",
+ "chrono",
+ "hmac",
+ "log",
+ "openlark-core",
+ "rand 0.8.5",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "sha2",
+ "thiserror 2.0.18",
+ "tokio",
+ "tracing",
+ "url",
+ "urlencoding",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-user"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "128243c92b485beeb5adf7801dbf22788e90b9cac141e0d280c3fdde3bbcbd98"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "chrono",
+ "futures",
+ "log",
+ "once_cell",
+ "openlark-core",
+ "rand 0.8.5",
+ "regex",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "thiserror 2.0.18",
+ "tokio",
+ "url",
+ "uuid",
+]
+
+[[package]]
+name = "openlark-webhook"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c996281cadb1d5acfc868b7dde4ccc1680afdd75b0d4c64b9c6aeea689854207"
+dependencies = [
+ "openlark-core",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "openlark-workflow"
+version = "0.15.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8573cba2aa1a1a363473c2cde620253d4c531f38ed3e6f6798228a698abd1a8"
+dependencies = [
+ "openlark-core",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "openssl"
+version = "0.10.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
+dependencies = [
+ "bitflags 2.10.0",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
+
+[[package]]
+name = "openssl-probe"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
+
+[[package]]
+name = "openssl-src"
+version = "300.5.5+3.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "openssl-sys"
version = "0.9.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
@@ -7008,7 +7537,7 @@ dependencies = [
"opentelemetry-http",
"opentelemetry-proto",
"opentelemetry_sdk",
- "prost",
+ "prost 0.14.3",
"reqwest",
"serde_json",
"thiserror 2.0.18",
@@ -7027,7 +7556,7 @@ dependencies = [
"const-hex",
"opentelemetry",
"opentelemetry_sdk",
- "prost",
+ "prost 0.14.3",
"serde",
"serde_json",
"tonic",
@@ -7096,7 +7625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
dependencies = [
"libc",
- "windows-sys 0.61.2",
+ "windows-sys 0.45.0",
]
[[package]]
@@ -7230,6 +7759,39 @@ dependencies = [
"indexmap 2.13.0",
]
+[[package]]
+name = "phf"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+dependencies = [
+ "phf_macros",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+dependencies = [
+ "phf_shared",
+ "rand 0.8.5",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
[[package]]
name = "phf_shared"
version = "0.11.3"
@@ -7547,6 +8109,26 @@ dependencies = [
"unarray",
]
+[[package]]
+name = "prost"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
+dependencies = [
+ "bytes",
+ "prost-derive 0.12.6",
+]
+
+[[package]]
+name = "prost"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
+dependencies = [
+ "bytes",
+ "prost-derive 0.13.5",
+]
+
[[package]]
name = "prost"
version = "0.14.3"
@@ -7554,7 +8136,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
dependencies = [
"bytes",
- "prost-derive",
+ "prost-derive 0.14.3",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4"
+dependencies = [
+ "bytes",
+ "heck",
+ "itertools 0.10.5",
+ "log",
+ "multimap",
+ "once_cell",
+ "petgraph 0.6.5",
+ "prettyplease",
+ "prost 0.12.6",
+ "prost-types",
+ "regex",
+ "syn 2.0.114",
+ "tempfile",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
+dependencies = [
+ "anyhow",
+ "itertools 0.10.5",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
+dependencies = [
+ "anyhow",
+ "itertools 0.14.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
]
[[package]]
@@ -7570,6 +8199,15 @@ dependencies = [
"syn 2.0.114",
]
+[[package]]
+name = "prost-types"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
+dependencies = [
+ "prost 0.12.6",
+]
+
[[package]]
name = "psl"
version = "2.1.184"
@@ -7629,6 +8267,18 @@ dependencies = [
"serde",
]
+[[package]]
+name = "quick_cache"
+version = "0.6.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a70b1b8b47e31d0498ecbc3c5470bb931399a8bfed1fd79d1717a61ce7f96e3"
+dependencies = [
+ "ahash",
+ "equivalent",
+ "hashbrown 0.16.1",
+ "parking_lot",
+]
+
[[package]]
name = "quinn"
version = "0.11.9"
@@ -7979,7 +8629,7 @@ dependencies = [
"rama-utils",
"rcgen",
"rustls",
- "rustls-native-certs",
+ "rustls-native-certs 0.8.3",
"rustls-pki-types",
"tokio",
"tokio-rustls",
@@ -8290,7 +8940,7 @@ dependencies = [
"pin-project-lite",
"quinn",
"rustls",
- "rustls-native-certs",
+ "rustls-native-certs 0.8.3",
"rustls-pki-types",
"serde",
"serde_json",
@@ -8518,7 +9168,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.11.0",
- "windows-sys 0.61.2",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -8537,6 +9187,19 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "rustls-native-certs"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
+dependencies = [
+ "openssl-probe 0.1.6",
+ "rustls-pemfile",
+ "rustls-pki-types",
+ "schannel",
+ "security-framework 2.11.1",
+]
+
[[package]]
name = "rustls-native-certs"
version = "0.8.3"
@@ -8549,6 +9212,15 @@ dependencies = [
"security-framework 3.5.1",
]
+[[package]]
+name = "rustls-pemfile"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
[[package]]
name = "rustls-pki-types"
version = "1.14.0"
@@ -9963,7 +10635,7 @@ dependencies = [
"getrandom 0.3.4",
"once_cell",
"rustix 1.1.3",
- "windows-sys 0.61.2",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -10349,6 +11021,22 @@ dependencies = [
"tokio-stream",
]
+[[package]]
+name = "tokio-tungstenite"
+version = "0.23.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd"
+dependencies = [
+ "futures-util",
+ "log",
+ "rustls",
+ "rustls-native-certs 0.7.3",
+ "rustls-pki-types",
+ "tokio",
+ "tokio-rustls",
+ "tungstenite 0.23.0",
+]
+
[[package]]
name = "tokio-tungstenite"
version = "0.28.0"
@@ -10357,11 +11045,11 @@ dependencies = [
"futures-util",
"log",
"rustls",
- "rustls-native-certs",
+ "rustls-native-certs 0.8.3",
"rustls-pki-types",
"tokio",
"tokio-rustls",
- "tungstenite",
+ "tungstenite 0.27.0",
]
[[package]]
@@ -10469,7 +11157,7 @@ dependencies = [
"hyper-util",
"percent-encoding",
"pin-project",
- "rustls-native-certs",
+ "rustls-native-certs 0.8.3",
"sync_wrapper",
"tokio",
"tokio-rustls",
@@ -10487,7 +11175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6c55a2d6a14174563de34409c9f92ff981d006f56da9c6ecd40d9d4a31500b0"
dependencies = [
"bytes",
- "prost",
+ "prost 0.14.3",
"tonic",
]
@@ -10745,6 +11433,26 @@ dependencies = [
"termcolor",
]
+[[package]]
+name = "tungstenite"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8"
+dependencies = [
+ "byteorder",
+ "bytes",
+ "data-encoding",
+ "http 1.4.0",
+ "httparse",
+ "log",
+ "rand 0.8.5",
+ "rustls",
+ "rustls-pki-types",
+ "sha1",
+ "thiserror 1.0.69",
+ "utf-8",
+]
+
[[package]]
name = "tungstenite"
version = "0.27.0"
@@ -11409,7 +12117,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
- "windows-sys 0.61.2",
+ "windows-sys 0.48.0",
]
[[package]]
diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml
index f19fb650f..2bc3f3791 100644
--- a/codex-rs/Cargo.toml
+++ b/codex-rs/Cargo.toml
@@ -1,6 +1,7 @@
[workspace]
members = [
"analytics",
+ "accounts",
"backend-client",
"ansi-escape",
"async-utils",
@@ -19,6 +20,7 @@ members = [
"cloud-tasks",
"cloud-tasks-client",
"cli",
+ "clawbot",
"connectors",
"config",
"shell-command",
@@ -30,6 +32,7 @@ members = [
"instructions",
"secrets",
"exec",
+ "ext",
"exec-server",
"execpolicy",
"execpolicy-legacy",
@@ -84,11 +87,15 @@ members = [
"package-manager",
"plugin",
"artifacts",
+ "btw",
+ "loop",
+ "loop-runtime",
+ "threadmessages",
]
resolver = "2"
[workspace.package]
-version = "0.0.0"
+version = "0.1.13"
# Track the edition for all workspace crates in one place. Individual
# crates can still override this value, but keeping it here means new
# crates created with `cargo new -w ...` automatically inherit the 2024
@@ -99,10 +106,12 @@ license = "Apache-2.0"
[workspace.dependencies]
# Internal
app_test_support = { path = "app-server/tests/common" }
+codex-accounts = { path = "accounts" }
codex-ansi-escape = { path = "ansi-escape" }
codex-analytics = { path = "analytics" }
codex-api = { path = "codex-api" }
codex-artifacts = { path = "artifacts" }
+codex-btw = { path = "btw" }
codex-code-mode = { path = "code-mode" }
codex-package-manager = { path = "package-manager" }
codex-app-server = { path = "app-server" }
@@ -115,6 +124,7 @@ codex-async-utils = { path = "async-utils" }
codex-backend-client = { path = "backend-client" }
codex-chatgpt = { path = "chatgpt" }
codex-cli = { path = "cli" }
+codex-clawbot = { path = "clawbot" }
codex-client = { path = "codex-client" }
codex-cloud-requirements = { path = "cloud-requirements" }
codex-connectors = { path = "connectors" }
@@ -122,6 +132,7 @@ codex-config = { path = "config" }
codex-core = { path = "core" }
codex-core-skills = { path = "core-skills" }
codex-exec = { path = "exec" }
+codex-ext = { path = "ext" }
codex-exec-server = { path = "exec-server" }
codex-execpolicy = { path = "execpolicy" }
codex-experimental-api-macros = { path = "codex-experimental-api-macros" }
@@ -135,6 +146,8 @@ codex-keyring-store = { path = "keyring-store" }
codex-linux-sandbox = { path = "linux-sandbox" }
codex-lmstudio = { path = "lmstudio" }
codex-login = { path = "login" }
+codex-loop = { path = "loop" }
+codex-loop-runtime = { path = "loop-runtime" }
codex-mcp-server = { path = "mcp-server" }
codex-network-proxy = { path = "network-proxy" }
codex-ollama = { path = "ollama" }
@@ -154,6 +167,7 @@ codex-state = { path = "state" }
codex-stdio-to-uds = { path = "stdio-to-uds" }
codex-test-macros = { path = "test-macros" }
codex-terminal-detection = { path = "terminal-detection" }
+codex-threadmessages = { path = "threadmessages" }
codex-tui = { path = "tui" }
codex-tui-app-server = { path = "tui_app_server" }
codex-v8-poc = { path = "v8-poc" }
@@ -402,15 +416,41 @@ ignored = [
"codex-v8-poc",
]
+[profile.dev]
+# CI disables incremental compilation for better cache reuse, but local
+# edit-build-test loops are much faster when dev builds can reuse artifacts.
+debug = 0
+incremental = false
+lto = false
+codegen-units = 12
+
+[profile.dev.package."*"]
+incremental = false
+
+[profile.dev.build-override]
+debug = 0
+incremental = false
+
+[profile.test]
+debug = 0
+incremental = false
+
+[profile.test.package."*"]
+incremental = false
+
+[profile.test.build-override]
+debug = 0
+incremental = false
+
[profile.release]
-lto = "fat"
+lto = false
split-debuginfo = "off"
# Because we bundle some of these executables with the TypeScript CLI, we
# remove everything to make the binary as small as possible.
strip = "symbols"
-# See https://github.com/openai/codex/issues/1411 for details.
-codegen-units = 1
+# Match local parallelism better to reduce release build time.
+codegen-units = 12
[profile.ci-test]
debug = 1 # Reduce debug symbol size
diff --git a/codex-rs/README.md b/codex-rs/README.md
index ad8a0506f..a9c030843 100644
--- a/codex-rs/README.md
+++ b/codex-rs/README.md
@@ -17,6 +17,7 @@ You can also install via Homebrew (`brew install --cask codex`) or download a pl
- First run with Codex? Start with [`docs/getting-started.md`](../docs/getting-started.md) (links to the walkthrough for prompts, keyboard shortcuts, and session management).
- Want deeper control? See [`docs/config.md`](../docs/config.md) and [`docs/install.md`](../docs/install.md).
+- Looking for Rust-workspace design notes? See [`docs/codex_mcp_interface.md`](./docs/codex_mcp_interface.md), [`docs/codex_tool_design_principles.md`](./docs/codex_tool_design_principles.md), and the component evolution diagram in [`docs/codex_component_evolution.drawio`](./docs/codex_component_evolution.drawio).
## What's new in the Rust CLI
@@ -100,3 +101,21 @@ This folder is the root of a Cargo workspace. It contains quite a bit of experim
- [`cli/`](./cli) CLI multitool that provides the aforementioned CLIs via subcommands.
If you want to contribute or inspect behavior in detail, start by reading the module-level `README.md` files under each crate and run the project workspace from the top-level `codex-rs` directory so shared config, features, and build scripts stay aligned.
+
+## Faster Local Rust Iteration
+
+The workspace is tuned for faster local edit-build-test loops:
+
+- `profile.dev` and `profile.test` keep incremental compilation enabled.
+- Local dev/test builds drop debug info to reduce compile and link time.
+- The workspace forces `sccache` as the default Rust compiler wrapper.
+- The recommended inner loop is `cargo check` plus a debug `cargo build`; tests,
+ clippy, and other heavier checks are deferred to later validation.
+
+Install `sccache` before running direct Cargo commands in this workspace:
+
+```shell
+cargo check -p codex-cli
+cargo build -p codex-cli
+sccache --show-stats
+```
diff --git a/codex-rs/accounts/Cargo.toml b/codex-rs/accounts/Cargo.toml
new file mode 100644
index 000000000..4faf3c8a5
--- /dev/null
+++ b/codex-rs/accounts/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "codex-accounts"
+version.workspace = true
+edition.workspace = true
+license.workspace = true
+
+[lib]
+name = "codex_accounts"
+path = "src/lib.rs"
+
+[lints]
+workspace = true
+
+[dependencies]
+codex-core = { workspace = true }
+serde = { workspace = true, features = ["derive"] }
+serde_json = { workspace = true }
+
+[dev-dependencies]
+base64 = { workspace = true }
+codex-app-server-protocol = { workspace = true }
+pretty_assertions = { workspace = true }
+tempfile = { workspace = true }
diff --git a/codex-rs/accounts/src/account_pool.rs b/codex-rs/accounts/src/account_pool.rs
new file mode 100644
index 000000000..ee666c9b7
--- /dev/null
+++ b/codex-rs/accounts/src/account_pool.rs
@@ -0,0 +1,539 @@
+use serde::Deserialize;
+use serde::Serialize;
+use std::fs;
+use std::io;
+use std::path::PathBuf;
+
+use crate::account_signal::AccountLimitSignal;
+use crate::account_signal::AccountRateLimitSnapshot;
+
+pub const ACCOUNT_POOL_STATE_RELATIVE_PATH: &str = "accounts/account-pool.json";
+const ACCOUNT_POOL_STATE_VERSION: u32 = 2;
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum AccountUsageWindowKind {
+ FiveHour,
+ Weekly,
+ Custom,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum UsageEstimateSource {
+ Manual,
+ ResponseErrorInference,
+ LocalHeuristic,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AccountUsageWindow {
+ pub kind: AccountUsageWindowKind,
+ pub label: String,
+ pub estimated_used_units: u32,
+ pub estimated_limit_units: Option,
+ pub reset_at: Option,
+ pub source: UsageEstimateSource,
+}
+
+impl AccountUsageWindow {
+ pub fn pressure_permille(&self) -> Option {
+ let limit = self.estimated_limit_units?;
+ if limit == 0 {
+ return None;
+ }
+
+ let used = self.estimated_used_units.min(limit);
+ let permille = (u64::from(used) * 1000) / u64::from(limit);
+ u16::try_from(permille).ok()
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AccountRecord {
+ pub id: String,
+ pub alias: String,
+ pub masked_email: Option,
+ pub plan_label: Option,
+ pub priority: u32,
+ pub enabled: bool,
+ pub cooldown_until: Option,
+ pub last_limit_error_at: Option,
+ pub last_selected_at: Option,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub invalid_reason: Option,
+ pub usage_windows: Vec,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct AccountManagementProfile {
+ pub id: String,
+ pub alias: Option,
+ pub masked_email: Option,
+ pub plan_label: Option,
+ pub priority: Option,
+}
+
+impl AccountRecord {
+ pub fn display_name(&self) -> &str {
+ if self.alias.trim().is_empty() {
+ &self.id
+ } else {
+ &self.alias
+ }
+ }
+
+ pub fn is_invalid(&self) -> bool {
+ self.invalid_reason.is_some()
+ }
+
+ pub fn is_available_at(&self, now_ts: i64) -> bool {
+ if !self.enabled {
+ return false;
+ }
+
+ match self.cooldown_until {
+ Some(cooldown_until) => cooldown_until <= now_ts,
+ None => true,
+ }
+ }
+
+ pub fn highest_pressure_permille(&self) -> Option {
+ self.usage_windows
+ .iter()
+ .filter_map(AccountUsageWindow::pressure_permille)
+ .max()
+ }
+
+ pub fn usage_summary(&self) -> Option {
+ usage_summary_from_windows(&self.usage_windows)
+ }
+}
+
+pub fn usage_summary_from_rate_limit_snapshot(
+ snapshot: &AccountRateLimitSnapshot,
+) -> Option {
+ let windows = rate_limit_windows(snapshot);
+ usage_summary_from_windows(&windows)
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AccountPoolState {
+ pub version: u32,
+ pub active_account_id: Option,
+ pub accounts: Vec,
+}
+
+impl Default for AccountPoolState {
+ fn default() -> Self {
+ Self {
+ version: ACCOUNT_POOL_STATE_VERSION,
+ active_account_id: None,
+ accounts: Vec::new(),
+ }
+ }
+}
+
+impl AccountPoolState {
+ pub fn upsert_account(&mut self, profile: AccountManagementProfile) -> bool {
+ if let Some(account) = self
+ .accounts
+ .iter_mut()
+ .find(|account| account.id == profile.id)
+ {
+ let mut changed = false;
+ let next_alias = profile.alias.unwrap_or_else(|| account.alias.clone());
+ if account.alias != next_alias {
+ account.alias = next_alias;
+ changed = true;
+ }
+ if account.masked_email != profile.masked_email {
+ account.masked_email = profile.masked_email;
+ changed = true;
+ }
+ if account.plan_label != profile.plan_label {
+ account.plan_label = profile.plan_label;
+ changed = true;
+ }
+ if let Some(priority) = profile.priority
+ && account.priority != priority
+ {
+ account.priority = priority;
+ changed = true;
+ }
+ return changed;
+ }
+
+ self.accounts.push(AccountRecord {
+ id: profile.id.clone(),
+ alias: profile.alias.unwrap_or(profile.id.clone()),
+ masked_email: profile.masked_email,
+ plan_label: profile.plan_label,
+ priority: profile.priority.unwrap_or_else(|| {
+ u32::try_from(self.accounts.len()).unwrap_or(u32::MAX.saturating_sub(1))
+ }),
+ enabled: true,
+ cooldown_until: None,
+ last_limit_error_at: None,
+ last_selected_at: None,
+ invalid_reason: None,
+ usage_windows: Vec::new(),
+ });
+ if self.active_account_id.is_none() {
+ self.active_account_id = Some(profile.id);
+ }
+ true
+ }
+
+ pub fn set_active_account(&mut self, account_id: &str, now_ts: i64) -> bool {
+ let Some(account) = self
+ .accounts
+ .iter_mut()
+ .find(|account| account.id == account_id)
+ else {
+ return false;
+ };
+ account.last_selected_at = Some(now_ts);
+ let should_change = self.active_account_id.as_deref() != Some(account_id);
+ self.active_account_id = Some(account_id.to_string());
+ should_change || account.last_selected_at == Some(now_ts)
+ }
+
+ pub fn rename_account_alias(&mut self, account_id: &str, alias: String) -> bool {
+ let normalized = alias.trim();
+ let Some(account) = self
+ .accounts
+ .iter_mut()
+ .find(|account| account.id == account_id)
+ else {
+ return false;
+ };
+ let next_alias = if normalized.is_empty() {
+ account.id.clone()
+ } else {
+ normalized.to_string()
+ };
+ if account.alias == next_alias {
+ false
+ } else {
+ account.alias = next_alias;
+ true
+ }
+ }
+
+ pub fn remove_account(&mut self, account_id: &str) -> bool {
+ let original_len = self.accounts.len();
+ self.accounts.retain(|account| account.id != account_id);
+ if self.accounts.len() == original_len {
+ return false;
+ }
+
+ if self.active_account_id.as_deref() == Some(account_id) {
+ self.active_account_id = self.accounts.first().map(|account| account.id.clone());
+ }
+
+ true
+ }
+
+ pub fn apply_rate_limit_snapshot(
+ &mut self,
+ account_id: &str,
+ snapshot: &AccountRateLimitSnapshot,
+ ) -> bool {
+ let Some(account) = self
+ .accounts
+ .iter_mut()
+ .find(|account| account.id == account_id)
+ else {
+ return false;
+ };
+ let previous = account.usage_windows.clone();
+ account.usage_windows = rate_limit_windows(snapshot);
+ let usage_changed = previous != account.usage_windows;
+ let invalid_changed = account.invalid_reason.take().is_some();
+ usage_changed || invalid_changed
+ }
+
+ pub fn set_invalid_reason(&mut self, account_id: &str, invalid_reason: Option) -> bool {
+ let Some(account) = self
+ .accounts
+ .iter_mut()
+ .find(|account| account.id == account_id)
+ else {
+ return false;
+ };
+
+ let next_invalid_reason = invalid_reason
+ .map(|reason| reason.trim().to_string())
+ .filter(|reason| !reason.is_empty());
+ let changed = account.invalid_reason != next_invalid_reason;
+ if changed {
+ account.invalid_reason = next_invalid_reason;
+ }
+ if account.invalid_reason.is_some() && !account.usage_windows.is_empty() {
+ account.usage_windows.clear();
+ return true;
+ }
+ changed
+ }
+
+ pub fn set_plan_label(&mut self, account_id: &str, plan_label: Option) -> bool {
+ let Some(account) = self
+ .accounts
+ .iter_mut()
+ .find(|account| account.id == account_id)
+ else {
+ return false;
+ };
+
+ if account.plan_label == plan_label {
+ false
+ } else {
+ account.plan_label = plan_label;
+ true
+ }
+ }
+
+ pub fn apply_limit_signal(&mut self, account_id: &str, signal: &AccountLimitSignal) -> bool {
+ let Some(account) = self
+ .accounts
+ .iter_mut()
+ .find(|account| account.id == account_id)
+ else {
+ return false;
+ };
+
+ let mut changed = false;
+ if account.last_limit_error_at != Some(signal.recorded_at) {
+ account.last_limit_error_at = Some(signal.recorded_at);
+ changed = true;
+ }
+ if account.cooldown_until != signal.cooldown_until {
+ account.cooldown_until = signal.cooldown_until;
+ changed = true;
+ }
+ changed
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct AccountPoolStore {
+ codex_home: PathBuf,
+}
+
+impl AccountPoolStore {
+ pub fn new(codex_home: PathBuf) -> Self {
+ Self { codex_home }
+ }
+
+ pub fn path(&self) -> PathBuf {
+ self.codex_home.join(ACCOUNT_POOL_STATE_RELATIVE_PATH)
+ }
+
+ pub fn load(&self) -> io::Result {
+ let path = self.path();
+ match fs::read_to_string(path) {
+ Ok(contents) => serde_json::from_str(&contents).map_err(io::Error::other),
+ Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(AccountPoolState::default()),
+ Err(err) => Err(err),
+ }
+ }
+
+ pub fn save(&self, state: &AccountPoolState) -> io::Result<()> {
+ let path = self.path();
+ if let Some(parent) = path.parent() {
+ fs::create_dir_all(parent)?;
+ }
+ let contents = serde_json::to_string_pretty(state).map_err(io::Error::other)?;
+ fs::write(path, contents)
+ }
+
+ pub fn update(&self, updater: F) -> io::Result
+ where
+ F: FnOnce(&mut AccountPoolState),
+ {
+ let mut state = self.load()?;
+ updater(&mut state);
+ self.save(&state)?;
+ Ok(state)
+ }
+}
+
+fn rate_limit_windows(snapshot: &AccountRateLimitSnapshot) -> Vec {
+ let mut windows = Vec::new();
+ for (kind, label, window) in [
+ (
+ AccountUsageWindowKind::FiveHour,
+ "5h",
+ snapshot.primary.as_ref(),
+ ),
+ (
+ AccountUsageWindowKind::Weekly,
+ "week",
+ snapshot.secondary.as_ref(),
+ ),
+ ] {
+ let Some(window) = window else {
+ continue;
+ };
+ windows.push(AccountUsageWindow {
+ kind,
+ label: label.to_string(),
+ estimated_used_units: window.used_percent.round() as u32,
+ estimated_limit_units: Some(100),
+ reset_at: window.resets_at,
+ source: UsageEstimateSource::ResponseErrorInference,
+ });
+ }
+ windows
+}
+
+fn usage_summary_from_windows(windows: &[AccountUsageWindow]) -> Option {
+ let windows = windows
+ .iter()
+ .map(|window| {
+ let prefix = match window.kind {
+ AccountUsageWindowKind::FiveHour => "5h",
+ AccountUsageWindowKind::Weekly => "week",
+ AccountUsageWindowKind::Custom => window.label.as_str(),
+ };
+ match window.estimated_limit_units {
+ Some(limit) => format!("{prefix} {}/{}", window.estimated_used_units, limit),
+ None => format!("{prefix} {}", window.estimated_used_units),
+ }
+ })
+ .collect::>();
+ if windows.is_empty() {
+ None
+ } else {
+ Some(windows.join(" · "))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::AccountManagementProfile;
+ use super::AccountPoolState;
+ use super::AccountPoolStore;
+ use super::AccountRateLimitSnapshot;
+ use super::AccountRateLimitWindow;
+ use super::AccountRecord;
+ use super::AccountUsageWindow;
+ use super::AccountUsageWindowKind;
+ use super::UsageEstimateSource;
+ use pretty_assertions::assert_eq;
+ use tempfile::tempdir;
+
+ #[test]
+ fn missing_account_pool_file_returns_default_state() {
+ let tempdir = tempdir().expect("tempdir");
+ let store = AccountPoolStore::new(tempdir.path().to_path_buf());
+
+ assert_eq!(store.load().expect("load"), AccountPoolState::default());
+ }
+
+ #[test]
+ fn save_round_trips_account_pool_state() {
+ let tempdir = tempdir().expect("tempdir");
+ let store = AccountPoolStore::new(tempdir.path().to_path_buf());
+ let state = AccountPoolState {
+ version: 1,
+ active_account_id: Some("account-1".to_string()),
+ accounts: vec![AccountRecord {
+ id: "account-1".to_string(),
+ alias: "Primary".to_string(),
+ masked_email: Some("pri***@example.com".to_string()),
+ plan_label: Some("pro".to_string()),
+ priority: 0,
+ enabled: true,
+ cooldown_until: None,
+ last_limit_error_at: None,
+ last_selected_at: Some(12),
+ invalid_reason: None,
+ usage_windows: vec![AccountUsageWindow {
+ kind: AccountUsageWindowKind::FiveHour,
+ label: "5h".to_string(),
+ estimated_used_units: 10,
+ estimated_limit_units: Some(20),
+ reset_at: Some(100),
+ source: UsageEstimateSource::Manual,
+ }],
+ }],
+ };
+
+ store.save(&state).expect("save");
+
+ assert_eq!(store.load().expect("load"), state);
+ }
+
+ #[test]
+ fn upsert_account_preserves_existing_alias_when_profile_has_none() {
+ let mut state = AccountPoolState {
+ version: 1,
+ active_account_id: Some("account-1".to_string()),
+ accounts: vec![AccountRecord {
+ id: "account-1".to_string(),
+ alias: "Primary".to_string(),
+ masked_email: None,
+ plan_label: None,
+ priority: 0,
+ enabled: true,
+ cooldown_until: None,
+ last_limit_error_at: None,
+ last_selected_at: None,
+ invalid_reason: None,
+ usage_windows: Vec::new(),
+ }],
+ };
+
+ assert!(state.upsert_account(AccountManagementProfile {
+ id: "account-1".to_string(),
+ alias: None,
+ masked_email: Some("pri***@example.com".to_string()),
+ plan_label: Some("pro".to_string()),
+ priority: None,
+ }));
+ assert_eq!(state.accounts[0].alias, "Primary");
+ }
+
+ #[test]
+ fn apply_rate_limit_snapshot_rewrites_usage_windows() {
+ let mut state = AccountPoolState::default();
+ state.upsert_account(AccountManagementProfile {
+ id: "account-1".to_string(),
+ alias: Some("Primary".to_string()),
+ masked_email: None,
+ plan_label: None,
+ priority: Some(0),
+ });
+
+ let changed = state.apply_rate_limit_snapshot(
+ "account-1",
+ &AccountRateLimitSnapshot {
+ limit_name: Some("codex".to_string()),
+ primary: Some(AccountRateLimitWindow {
+ used_percent: 45.0,
+ window_minutes: Some(300),
+ resets_at: Some(123),
+ }),
+ secondary: None,
+ },
+ );
+
+ assert!(changed);
+ assert_eq!(
+ state.accounts[0].usage_windows,
+ vec![AccountUsageWindow {
+ kind: AccountUsageWindowKind::FiveHour,
+ label: "5h".to_string(),
+ estimated_used_units: 45,
+ estimated_limit_units: Some(100),
+ reset_at: Some(123),
+ source: UsageEstimateSource::ResponseErrorInference,
+ }]
+ );
+ }
+}
diff --git a/codex-rs/accounts/src/account_signal.rs b/codex-rs/accounts/src/account_signal.rs
new file mode 100644
index 000000000..a62a09a3e
--- /dev/null
+++ b/codex-rs/accounts/src/account_signal.rs
@@ -0,0 +1,136 @@
+use serde::Deserialize;
+use serde::Serialize;
+
+const DEFAULT_GENERIC_LIMIT_COOLDOWN_SECS: i64 = 15 * 60;
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AccountRateLimitWindow {
+ pub used_percent: f64,
+ pub window_minutes: Option,
+ pub resets_at: Option,
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AccountRateLimitSnapshot {
+ pub limit_name: Option,
+ pub primary: Option,
+ pub secondary: Option,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum LimitSignalKind {
+ UsageLimit,
+ RateLimit,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AccountLimitSignal {
+ pub kind: LimitSignalKind,
+ pub recorded_at: i64,
+ pub cooldown_until: Option,
+}
+
+pub fn infer_limit_signal(
+ kind: LimitSignalKind,
+ recorded_at: i64,
+ snapshot: Option<&AccountRateLimitSnapshot>,
+) -> AccountLimitSignal {
+ let cooldown_until = snapshot
+ .and_then(|snapshot| blocking_resets_at(snapshot, recorded_at))
+ .or_else(|| match kind {
+ LimitSignalKind::UsageLimit => None,
+ LimitSignalKind::RateLimit => Some(recorded_at + DEFAULT_GENERIC_LIMIT_COOLDOWN_SECS),
+ });
+
+ AccountLimitSignal {
+ kind,
+ recorded_at,
+ cooldown_until,
+ }
+}
+
+fn blocking_resets_at(snapshot: &AccountRateLimitSnapshot, recorded_at: i64) -> Option {
+ let mut saturated = Vec::new();
+ let mut any_future = Vec::new();
+
+ for window in [snapshot.primary.as_ref(), snapshot.secondary.as_ref()]
+ .into_iter()
+ .flatten()
+ {
+ let Some(resets_at) = window
+ .resets_at
+ .filter(|resets_at| *resets_at > recorded_at)
+ else {
+ continue;
+ };
+
+ any_future.push(resets_at);
+ if window.used_percent >= 99.5 {
+ saturated.push(resets_at);
+ }
+ }
+
+ saturated
+ .into_iter()
+ .min()
+ .or_else(|| any_future.into_iter().min())
+}
+
+#[cfg(test)]
+mod tests {
+ use pretty_assertions::assert_eq;
+
+ use super::AccountLimitSignal;
+ use super::AccountRateLimitSnapshot;
+ use super::AccountRateLimitWindow;
+ use super::LimitSignalKind;
+ use super::infer_limit_signal;
+
+ #[test]
+ fn usage_limit_prefers_saturated_window_reset() {
+ let signal = infer_limit_signal(
+ LimitSignalKind::UsageLimit,
+ 100,
+ Some(&AccountRateLimitSnapshot {
+ limit_name: Some("codex".to_string()),
+ primary: Some(AccountRateLimitWindow {
+ used_percent: 92.0,
+ window_minutes: Some(300),
+ resets_at: Some(500),
+ }),
+ secondary: Some(AccountRateLimitWindow {
+ used_percent: 100.0,
+ window_minutes: Some(10080),
+ resets_at: Some(900),
+ }),
+ }),
+ );
+
+ assert_eq!(
+ signal,
+ AccountLimitSignal {
+ kind: LimitSignalKind::UsageLimit,
+ recorded_at: 100,
+ cooldown_until: Some(900),
+ }
+ );
+ }
+
+ #[test]
+ fn rate_limit_falls_back_to_short_cooldown_without_snapshot() {
+ let signal = infer_limit_signal(LimitSignalKind::RateLimit, 100, None);
+
+ assert_eq!(
+ signal,
+ AccountLimitSignal {
+ kind: LimitSignalKind::RateLimit,
+ recorded_at: 100,
+ cooldown_until: Some(1000),
+ }
+ );
+ }
+}
diff --git a/codex-rs/accounts/src/lib.rs b/codex-rs/accounts/src/lib.rs
new file mode 100644
index 000000000..1f42ae1f2
--- /dev/null
+++ b/codex-rs/accounts/src/lib.rs
@@ -0,0 +1,31 @@
+mod account_pool;
+mod account_signal;
+mod managed_account_auth;
+mod router;
+
+pub use account_pool::ACCOUNT_POOL_STATE_RELATIVE_PATH;
+pub use account_pool::AccountManagementProfile;
+pub use account_pool::AccountPoolState;
+pub use account_pool::AccountPoolStore;
+pub use account_pool::AccountRecord;
+pub use account_pool::AccountUsageWindow;
+pub use account_pool::AccountUsageWindowKind;
+pub use account_pool::UsageEstimateSource;
+pub use account_pool::usage_summary_from_rate_limit_snapshot;
+pub use account_signal::AccountLimitSignal;
+pub use account_signal::AccountRateLimitSnapshot;
+pub use account_signal::AccountRateLimitWindow;
+pub use account_signal::LimitSignalKind;
+pub use account_signal::infer_limit_signal;
+pub use managed_account_auth::MANAGED_ACCOUNTS_RELATIVE_DIR;
+pub use managed_account_auth::ManagedAccountAuthStore;
+pub use managed_account_auth::ManagedAccountSnapshot;
+pub use managed_account_auth::activate_managed_account;
+pub use managed_account_auth::load_current_managed_account_snapshot;
+pub use managed_account_auth::persist_current_managed_account_snapshot;
+pub use managed_account_auth::persist_managed_account_auth_snapshot;
+pub use router::AccountRouterDecision;
+pub use router::AccountRouterDecisionReason;
+pub use router::DefaultAccountRouter;
+pub use router::RouteTurnRequest;
+pub use router::RoutingTrigger;
diff --git a/codex-rs/accounts/src/managed_account_auth.rs b/codex-rs/accounts/src/managed_account_auth.rs
new file mode 100644
index 000000000..8ca78fb8a
--- /dev/null
+++ b/codex-rs/accounts/src/managed_account_auth.rs
@@ -0,0 +1,271 @@
+use codex_core::auth::AuthCredentialsStoreMode;
+use codex_core::auth::AuthDotJson;
+use codex_core::auth::load_auth_dot_json;
+use codex_core::auth::save_auth;
+use std::fs;
+use std::fs::OpenOptions;
+use std::io;
+use std::io::Write;
+#[cfg(unix)]
+use std::os::unix::fs::OpenOptionsExt;
+use std::path::Path;
+use std::path::PathBuf;
+
+use crate::account_pool::AccountManagementProfile;
+
+pub const MANAGED_ACCOUNTS_RELATIVE_DIR: &str = "accounts";
+const ACCOUNT_AUTH_FILE_NAME: &str = "auth.json";
+
+#[derive(Debug, Clone, PartialEq)]
+pub struct ManagedAccountSnapshot {
+ pub profile: AccountManagementProfile,
+ pub auth: AuthDotJson,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ManagedAccountAuthStore {
+ codex_home: PathBuf,
+}
+
+impl ManagedAccountAuthStore {
+ pub fn new(codex_home: PathBuf) -> Self {
+ Self { codex_home }
+ }
+
+ pub fn directory(&self) -> PathBuf {
+ self.codex_home.join(MANAGED_ACCOUNTS_RELATIVE_DIR)
+ }
+
+ pub fn account_dir(&self, account_id: &str) -> PathBuf {
+ self.directory().join(account_id)
+ }
+
+ pub fn account_auth_path(&self, account_id: &str) -> PathBuf {
+ self.account_dir(account_id).join(ACCOUNT_AUTH_FILE_NAME)
+ }
+
+ pub fn load_account_auth(&self, account_id: &str) -> io::Result {
+ let path = self.account_auth_path(account_id);
+ let contents = fs::read_to_string(path)?;
+ serde_json::from_str(&contents).map_err(io::Error::other)
+ }
+
+ pub fn save_account_auth(&self, account_id: &str, auth: &AuthDotJson) -> io::Result<()> {
+ let path = self.account_auth_path(account_id);
+ if let Some(parent) = path.parent() {
+ fs::create_dir_all(parent)?;
+ }
+
+ let contents = serde_json::to_string_pretty(auth).map_err(io::Error::other)?;
+ let mut options = OpenOptions::new();
+ options.create(true).truncate(true).write(true);
+ #[cfg(unix)]
+ {
+ options.mode(0o600);
+ }
+ let mut file = options.open(path)?;
+ file.write_all(contents.as_bytes())?;
+ file.flush()
+ }
+
+ pub fn delete_account_auth(&self, account_id: &str) -> io::Result<()> {
+ let account_dir = self.account_dir(account_id);
+ match fs::remove_dir_all(account_dir) {
+ Ok(()) => Ok(()),
+ Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()),
+ Err(err) => Err(err),
+ }
+ }
+}
+
+pub fn activate_managed_account(
+ codex_home: &Path,
+ auth_credentials_store_mode: AuthCredentialsStoreMode,
+ account_id: &str,
+) -> io::Result<()> {
+ let store = ManagedAccountAuthStore::new(codex_home.to_path_buf());
+ let auth = store.load_account_auth(account_id)?;
+ save_auth(codex_home, &auth, auth_credentials_store_mode)
+}
+
+pub fn persist_current_managed_account_snapshot(
+ codex_home: &Path,
+ auth_credentials_store_mode: AuthCredentialsStoreMode,
+) -> io::Result