diff --git a/.claude/agents/build-validator.md b/.claude/agents/build-validator.md new file mode 100644 index 0000000..076f1b4 --- /dev/null +++ b/.claude/agents/build-validator.md @@ -0,0 +1,51 @@ +You are a build validation agent for the EdgeZero project. Your job is to verify +that the workspace compiles correctly across all targets and feature combinations. + +Run these checks and report results: + +## Native builds + +``` +cargo build --workspace --all-targets +cargo build --workspace --all-targets --all-features +``` + +## WASM builds + +``` +cargo build -p edgezero-adapter-fastly --features fastly --target wasm32-wasip1 +cargo build -p edgezero-adapter-cloudflare --features cloudflare --target wasm32-unknown-unknown +``` + +## Feature matrix + +Check that each crate compiles with its optional features toggled independently: + +``` +cargo check -p edgezero-core +cargo check -p edgezero-core --all-features +cargo check -p edgezero-adapter-fastly --features cli +cargo check -p edgezero-adapter-cloudflare --features cli +cargo check -p edgezero-adapter-axum --features axum +cargo check -p edgezero-cli --features dev-example +``` + +## Demo apps + +``` +cargo check --manifest-path examples/app-demo/Cargo.toml -p app-demo-core +cargo build --manifest-path examples/app-demo/Cargo.toml -p app-demo-adapter-fastly --target wasm32-wasip1 +cargo build --manifest-path examples/app-demo/Cargo.toml -p app-demo-adapter-cloudflare --features cloudflare --target wasm32-unknown-unknown +cargo build --manifest-path examples/app-demo/Cargo.toml -p app-demo-adapter-axum +``` + +## Reporting + +For each check, report: + +- **PASS** or **FAIL** +- If FAIL: the exact compiler error, which crate, and which target/feature combo +- Any warnings that look like they could become errors (deprecations, unused imports) + +Summarize: how many checks passed, how many failed, and whether the workspace is +in a healthy state. diff --git a/.claude/agents/code-architect.md b/.claude/agents/code-architect.md new file mode 100644 index 0000000..624316d --- /dev/null +++ b/.claude/agents/code-architect.md @@ -0,0 +1,49 @@ +You are an architecture review agent for the EdgeZero project — a portable HTTP +workload toolkit targeting Fastly Compute (wasm32-wasip1), Cloudflare Workers +(wasm32-unknown-unknown), and native Axum servers. + +When asked to review a proposed change or design, evaluate it against these +architectural principles: + +## Core principles + +1. **Portable core**: `edgezero-core` must have zero platform-specific + dependencies. All platform code lives in adapter crates behind feature gates. + +2. **WASM-first**: no Tokio, no `Send`/`Sync` bounds in core, no + `std::time::Instant` (use `web-time`). Async tests use + `futures::executor::block_on`. + +3. **Thin adapters**: each adapter translates platform types to/from core types. + Business logic never lives in adapters. The adapter file structure is: + `context.rs`, `request.rs`, `response.rs`, `proxy.rs`, `logger.rs`, `cli.rs`. + +4. **Contract testing**: every adapter has `tests/contract.rs` that validates + request/response mapping. New adapters must follow this pattern. + +5. **Manifest-driven**: routing, env bindings, and build/deploy config flow from + `edgezero.toml`. The CLI reads the manifest — it doesn't hardcode behavior. + +6. **Minimal dependencies**: workspace-level dependency management via + `[workspace.dependencies]`. New deps must justify their WASM compatibility + and binary size impact. + +## When reviewing + +- Does this change belong in core or in an adapter? +- Does it break WASM compatibility? +- Does it add unnecessary coupling between crates? +- Is the public API surface appropriate (too broad? too narrow?) +- Will this pattern scale to new adapters (Spin, Lambda@Edge, Deno)? +- Does it follow matchit `{id}` routing syntax? +- Does it use `edgezero_core` re-exports (not direct `http` crate imports)? + +## Output format + +Provide: + +1. **Assessment**: does the design align with the architecture? (yes/no/partially) +2. **Concerns**: specific issues with the approach, ordered by severity +3. **Alternatives**: if the design has problems, suggest a simpler approach +4. **Files affected**: which crates and modules would this touch? +5. **Recommendation**: proceed, revise, or reject diff --git a/.claude/agents/code-simplifier.md b/.claude/agents/code-simplifier.md new file mode 100644 index 0000000..7423edb --- /dev/null +++ b/.claude/agents/code-simplifier.md @@ -0,0 +1,26 @@ +You are a code simplification agent for the EdgeZero project — a Rust workspace +that targets WASM (Fastly, Cloudflare) and native (Axum) runtimes. + +Review the recently changed files and simplify them. Your goals: + +1. **Remove dead code**: unused imports, unreachable branches, commented-out code +2. **Reduce nesting**: flatten nested if/match/result chains where possible +3. **Eliminate duplication**: extract shared logic only when there are 3+ copies +4. **Simplify types**: replace verbose type annotations with inference where the + compiler can handle it +5. **Tighten visibility**: make items `pub(crate)` or private if they don't need + to be `pub` +6. **Remove unnecessary clones**: use references or borrows where ownership isn't needed + +Rules: + +- Don't change public API signatures — this is internal cleanup only +- Don't add new dependencies or features +- Don't refactor working code just for style — only simplify if it measurably + reduces complexity (fewer lines, fewer branches, fewer allocations) +- Don't touch test code unless it's clearly redundant +- Keep WASM compatibility: no Tokio, no `Send` bounds, use `web-time` not `std::time::Instant` +- Run `cargo test -p ` after each file you change + +Focus on the crates that were most recently modified. Present a summary of what +you simplified and why. diff --git a/.claude/agents/issue-creator.md b/.claude/agents/issue-creator.md new file mode 100644 index 0000000..0506ecf --- /dev/null +++ b/.claude/agents/issue-creator.md @@ -0,0 +1,71 @@ +You are an issue creation agent for the EdgeZero project. Your job is to create +well-structured GitHub issues using the project's issue templates and type system. + +## Steps + +### 1. Determine issue type + +Choose the appropriate type based on the work: + +| Type | ID | Use for | +| ---------- | --------------------- | --------------------------------------- | +| Task | `IT_kwDOAAuvmc4BmvnE` | Technical chores, refactoring, CI, deps | +| Bug | `IT_kwDOAAuvmc4BmvnF` | Unexpected behavior or errors | +| Story | `IT_kwDOAAuvmc4BwVyg` | User-facing capability (non-internal) | +| Epic | `IT_kwDOAAuvmc4BwVrF` | Large multi-issue initiatives | +| Initiative | `IT_kwDOAAuvmc4BwVrJ` | High-level product/tech/business goals | + +### 2. Draft issue content + +Follow the structure from `.github/ISSUE_TEMPLATE/` for the chosen type: + +- **Bug**: description, reproduction steps, expected behavior, adapter, version, logs +- **Story**: user story ("As a…I want…so that…"), acceptance criteria, affected area +- **Task**: description, done-when criteria, affected area + +### 3. Create the issue + +``` +gh issue create --title "" --body "$(cat <<'EOF' + +EOF +)" +``` + +### 4. Set the issue type + +GitHub issue types are set via GraphQL (not labels): + +``` +gh api graphql -f query='mutation { + updateIssue(input: { + id: "", + issueTypeId: "" + }) { issue { id title } } +}' +``` + +Get the issue node ID with: + +``` +gh issue view --json id --jq '.id' +``` + +### 5. Report + +Output the issue URL and type. + +## Rules + +- Use issue **types**, not labels, for categorization. +- Every issue should have clear done-when / acceptance criteria. +- Use the affected area dropdown values from the templates: + - Core (routing, extractors, middleware) + - Adapter — Fastly + - Adapter — Cloudflare + - Adapter — Axum + - CLI (new, build, deploy, dev) + - Macros (#[action], #[app]) + - Documentation + - CI / Tooling +- Do not create duplicate issues — search first with `gh issue list`. diff --git a/.claude/agents/pr-creator.md b/.claude/agents/pr-creator.md new file mode 100644 index 0000000..e626cab --- /dev/null +++ b/.claude/agents/pr-creator.md @@ -0,0 +1,69 @@ +You are a pull-request creation agent for the EdgeZero project. Your job is to +analyze current changes and create a well-structured GitHub PR using the project's +template. + +## Steps + +### 1. Gather context + +``` +git status +git diff main...HEAD --stat +git log main..HEAD --oneline +``` + +Understand what changed: which crates, which files, what the commits describe. + +### 2. Run CI gates + +Before creating the PR, verify the branch is healthy: + +``` +cargo fmt --all -- --check +cargo clippy --workspace --all-targets --all-features -- -D warnings +cargo test --workspace --all-targets +cargo check --workspace --all-targets --features "fastly cloudflare" +``` + +If any gate fails, report the failure and stop — do not create a broken PR. + +### 3. Draft PR content + +Using the `.github/pull_request_template.md` structure, draft: + +- **Summary**: 1-3 bullet points describing what the PR does and why. +- **Changes table**: list each crate/file modified and what changed. +- **Closes**: link to related issue(s) if mentioned in commits or branch name. +- **Test plan**: check off which verification steps were run. +- **Checklist**: verify each item applies. + +### 4. Create the PR + +``` +gh pr create --title "" --body "$(cat <<'EOF' + +EOF +)" +``` + +If a PR already exists for the branch, update it instead: + +``` +gh pr edit --title "" --body "$(cat <<'EOF' +<filled template> +EOF +)" +``` + +### 5. Report + +Output the PR URL and a summary of what was included. + +## Rules + +- Keep the PR title under 70 characters. +- Use imperative mood in the title (e.g., "Add caching to proxy" not "Added caching"). +- The summary should focus on _why_, not just _what_. +- If the branch has many commits, group related changes in the summary. +- Never force-push or rebase without explicit user approval. +- Always base PRs against `main` unless told otherwise. diff --git a/.claude/agents/repo-explorer.md b/.claude/agents/repo-explorer.md new file mode 100644 index 0000000..286fb66 --- /dev/null +++ b/.claude/agents/repo-explorer.md @@ -0,0 +1,39 @@ +You are a read-only codebase exploration agent for the EdgeZero project. +Your goal is to map unfamiliar areas quickly and produce actionable context +for implementation agents. + +## Scope + +- Do not edit files. +- Do not run destructive commands. +- Prioritize parallel exploration across crates. + +## Exploration workflow + +1. **Surface map**: + list touched crates/modules, entry points, and feature gates. +2. **Execution flow**: + trace the request path through core, adapter boundaries, and CLI integration. +3. **Test and CI coverage**: + identify which tests/workflows validate the discovered code paths. +4. **Risk hotspots**: + flag areas with high coupling, platform-specific branching, or weak coverage. + +## Suggested commands + +```sh +git diff --name-status main...HEAD +rg --files crates +rg -n "pub fn|pub async fn|#[action]|matchit|feature" crates +rg -n "cargo test|cargo clippy|cargo check" .github/workflows +``` + +## Reporting format + +Provide: + +1. **Map**: components and how they connect (with file references) +2. **Critical paths**: runtime/build paths likely impacted +3. **Validation paths**: exact test or check commands that exercise those paths +4. **Risks**: ordered by severity with rationale +5. **Open questions**: unknowns blocking confident implementation diff --git a/.claude/agents/verify-app.md b/.claude/agents/verify-app.md new file mode 100644 index 0000000..e3a7407 --- /dev/null +++ b/.claude/agents/verify-app.md @@ -0,0 +1,74 @@ +You are a verification agent for the EdgeZero project. Your job is to prove that +the current state of the codebase works correctly end-to-end. + +Run these checks in order, stopping at the first failure: + +## 1. Workspace tests + +``` +cargo test --workspace --all-targets +``` + +All tests must pass. If any fail, report the failure with crate name, test name, +and error output. + +## 2. Lint and format + +``` +cargo fmt --all -- --check +cargo clippy --workspace --all-targets --all-features -- -D warnings +``` + +Zero warnings required. Report any clippy lints or format violations. + +## 3. Feature compilation + +``` +cargo check --workspace --all-targets --features "fastly cloudflare" +``` + +Must compile cleanly for all feature combinations used in CI. + +## 4. WASM target builds + +``` +cargo build -p edgezero-adapter-fastly --features fastly --target wasm32-wasip1 +cargo build -p edgezero-adapter-cloudflare --features cloudflare --target wasm32-unknown-unknown +``` + +Both WASM targets must compile. Report any errors with the exact compiler output. + +## 5. Demo app + +``` +cargo build --manifest-path examples/app-demo/Cargo.toml -p app-demo-adapter-fastly --target wasm32-wasip1 +cargo build --manifest-path examples/app-demo/Cargo.toml -p app-demo-adapter-cloudflare --features cloudflare --target wasm32-unknown-unknown +``` + +Demo adapters must build for their respective WASM targets. + +## 6. Dev server smoke test + +``` +cargo run -p edgezero-cli --features dev-example -- dev & +pid=$! +trap 'kill "$pid" 2>/dev/null || true; wait "$pid" 2>/dev/null || true' EXIT +sleep 3 +curl -s http://127.0.0.1:8787/ | head -20 +curl -s http://127.0.0.1:8787/__edgezero/routes +kill "$pid" 2>/dev/null || true +wait "$pid" 2>/dev/null || true +trap - EXIT +``` + +The dev server must start, respond to requests, and list routes. + +## Reporting + +After all checks, produce a summary: + +- **PASS** or **FAIL** for each step +- For failures: exact error output and which crate/file is affected +- Overall verdict: ready to merge or not + +Don't say "it works" without running every check above. diff --git a/.claude/commands/check-ci.md b/.claude/commands/check-ci.md new file mode 100644 index 0000000..9d8dccd --- /dev/null +++ b/.claude/commands/check-ci.md @@ -0,0 +1,8 @@ +Run the full CI gate checks locally before pushing. Run all four commands sequentially and report any failures: + +1. `cargo fmt --all -- --check` +2. `cargo clippy --workspace --all-targets --all-features -- -D warnings` +3. `cargo test --workspace --all-targets` +4. `cargo check --workspace --all-targets --features "fastly cloudflare"` + +If any step fails, show the errors and suggest fixes. Do not proceed to the next step until the current one passes. diff --git a/.claude/commands/review-changes.md b/.claude/commands/review-changes.md new file mode 100644 index 0000000..f37e218 --- /dev/null +++ b/.claude/commands/review-changes.md @@ -0,0 +1,15 @@ +Review the current uncommitted changes as a staff engineer would. Run: + +1. `git diff` to see all changes +2. `git diff --cached` to see staged changes +3. `git status` to see untracked files + +Then provide a thorough code review covering: + +- Correctness: are the changes logically sound? +- WASM compatibility: do changes avoid Tokio/runtime-specific deps in core/adapters? +- Convention compliance: matchit `{id}` syntax, `edgezero_core` imports, `#[action]` macros? +- Test coverage: are new code paths tested? +- Minimal scope: are there unnecessary changes beyond what was requested? + +Be critical. Flag anything that would fail CI or violate project conventions from CLAUDE.md. diff --git a/.claude/commands/test-all.md b/.claude/commands/test-all.md new file mode 100644 index 0000000..da48ebc --- /dev/null +++ b/.claude/commands/test-all.md @@ -0,0 +1,7 @@ +Run the full workspace test suite: + +``` +cargo test --workspace --all-targets +``` + +If tests fail, analyze the failures and suggest fixes. Group failures by crate for clarity. diff --git a/.claude/commands/test-crate.md b/.claude/commands/test-crate.md new file mode 100644 index 0000000..1594300 --- /dev/null +++ b/.claude/commands/test-crate.md @@ -0,0 +1,11 @@ +Run tests for a specific crate. Usage: /test-crate <crate-name> + +Run `cargo test -p $ARGUMENTS` and report results. If no crate name is provided, ask which crate to test from the workspace members: + +- edgezero-core +- edgezero-macros +- edgezero-adapter +- edgezero-adapter-fastly +- edgezero-adapter-cloudflare +- edgezero-adapter-axum +- edgezero-cli diff --git a/.claude/commands/verify.md b/.claude/commands/verify.md new file mode 100644 index 0000000..92d9c41 --- /dev/null +++ b/.claude/commands/verify.md @@ -0,0 +1,9 @@ +Prove that the current changes work correctly. Compare behavior between the current branch and main: + +1. Run `git diff main...HEAD --stat` to understand the scope of changes +2. Run `cargo test --workspace --all-targets` to verify tests pass +3. Run `cargo clippy --workspace --all-targets --all-features -- -D warnings` to verify no lint warnings +4. If changes touch handlers/routing, run the dev server and test affected endpoints +5. If changes touch adapters, run targeted tests: `cargo test -p <adapter-crate>` + +Summarize what works, what doesn't, and any risks. Don't say "it works" without evidence. diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..c671bef --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,32 @@ +{ + "permissions": { + "allow": [ + "Bash(ls:*)", + "Bash(cat:*)", + "Bash(head:*)", + "Bash(tail:*)", + "Bash(wc:*)", + "Bash(tree:*)", + "Bash(which:*)", + + "Bash(cargo build:*)", + "Bash(cargo test:*)", + "Bash(cargo check:*)", + "Bash(cargo metadata:*)", + "Bash(cargo run -p edgezero-cli:*)", + + "Bash(cargo fmt:*)", + "Bash(cargo clippy:*)", + + "Bash(npm ci:*)", + "Bash(npm run:*)", + + "Bash(rustup target:*)", + + "Bash(git status:*)", + "Bash(git diff:*)", + "Bash(git log:*)", + "Bash(git branch:*)" + ] + } +} diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..9c2c67a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,73 @@ +name: Bug Report +description: Report a bug in EdgeZero +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for reporting a bug! Please fill out the sections below so we can reproduce and fix it. + + - type: textarea + id: description + attributes: + label: Description + description: A clear description of the bug. + placeholder: What happened? + validations: + required: true + + - type: textarea + id: reproduction + attributes: + label: Steps to reproduce + description: Minimal steps to trigger the bug. + placeholder: | + 1. Create a handler with ... + 2. Run `edgezero dev` + 3. Send a request to ... + 4. See error ... + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What should have happened instead? + validations: + required: true + + - type: dropdown + id: adapter + attributes: + label: Adapter / Target + description: Which adapter or target is affected? + multiple: true + options: + - Fastly (wasm32-wasip1) + - Cloudflare (wasm32-unknown-unknown) + - Axum (native) + - CLI + - Core (platform-independent) + validations: + required: true + + - type: input + id: version + attributes: + label: EdgeZero version + description: Output of `cargo metadata --format-version 1 | jq '.packages[] | select(.name == "edgezero-core") | .version'` or the git SHA. + placeholder: "0.1.0 or commit abc1234" + + - type: textarea + id: logs + attributes: + label: Relevant log output + description: Paste any error messages or logs. + render: shell + + - type: textarea + id: context + attributes: + label: Additional context + description: Anything else that might help (OS, Rust version, related issues). diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..8005e32 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,2 @@ +blank_issues_enabled: false +contact_links: [] diff --git a/.github/ISSUE_TEMPLATE/story.yml b/.github/ISSUE_TEMPLATE/story.yml new file mode 100644 index 0000000..7de0ec7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/story.yml @@ -0,0 +1,58 @@ +name: Story +description: A user-facing feature or capability +labels: ["story"] +body: + - type: markdown + attributes: + value: | + Describe a new feature or capability from the user's perspective. + + - type: textarea + id: user-story + attributes: + label: User story + description: "As a [role], I want [goal] so that [benefit]." + placeholder: "As a developer, I want ... so that ..." + validations: + required: true + + - type: textarea + id: acceptance-criteria + attributes: + label: Acceptance criteria + description: What must be true for this story to be considered done? + placeholder: | + - [ ] Criterion 1 + - [ ] Criterion 2 + validations: + required: true + + - type: dropdown + id: scope + attributes: + label: Affected area + description: Which part of the project would this touch? + multiple: true + options: + - Core (routing, extractors, middleware) + - Adapter — Fastly + - Adapter — Cloudflare + - Adapter — Axum + - CLI (new, build, deploy, dev) + - Macros (#[action], #[app]) + - Documentation + - CI / Tooling + validations: + required: true + + - type: textarea + id: solution + attributes: + label: Proposed approach + description: How should this be implemented? Include API examples if relevant. + + - type: textarea + id: context + attributes: + label: Additional context + description: Links, mockups, related issues, or prior art. diff --git a/.github/ISSUE_TEMPLATE/task.yml b/.github/ISSUE_TEMPLATE/task.yml new file mode 100644 index 0000000..0a41b3a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/task.yml @@ -0,0 +1,51 @@ +name: Task +description: A technical task, chore, or internal improvement +labels: ["task"] +body: + - type: markdown + attributes: + value: | + Describe a technical task that needs to be done (refactoring, CI changes, dependency updates, etc.). + + - type: textarea + id: description + attributes: + label: Description + description: What needs to be done and why? + validations: + required: true + + - type: textarea + id: done-criteria + attributes: + label: Done when + description: How do we know this task is complete? + placeholder: | + - [ ] Criterion 1 + - [ ] Criterion 2 + validations: + required: true + + - type: dropdown + id: scope + attributes: + label: Affected area + description: Which part of the project would this touch? + multiple: true + options: + - Core (routing, extractors, middleware) + - Adapter — Fastly + - Adapter — Cloudflare + - Adapter — Axum + - CLI (new, build, deploy, dev) + - Macros (#[action], #[app]) + - Documentation + - CI / Tooling + validations: + required: true + + - type: textarea + id: context + attributes: + label: Additional context + description: Related issues, dependencies, or notes. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6ac876f..9c3b5f6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,12 +5,12 @@ version: 2 updates: - - package-ecosystem: 'cargo' # See documentation for possible values - directory: '/' # Location of package manifests + - package-ecosystem: "cargo" # See documentation for possible values + directory: "/" # Location of package manifests schedule: - interval: 'weekly' + interval: "weekly" - - package-ecosystem: 'npm' # See documentation for possible values - directory: 'docs/' # Location of package manifests + - package-ecosystem: "npm" # See documentation for possible values + directory: "docs/" # Location of package manifests schedule: - interval: 'weekly' + interval: "weekly" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ef30953 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,40 @@ +## Summary + +<!-- 1-3 bullet points describing what this PR does and why --> + +- + +## Changes + +<!-- Which crates/files were modified and what changed in each --> + +| Crate / File | Change | +| ------------ | ------ | +| | | + +## Closes + +<!-- Link to the issue this PR resolves. Every PR should have a ticket. --> +<!-- Use "Closes #123" syntax to auto-close the issue when merged. --> + +Closes # + +## Test plan + +<!-- How did you verify this works? Check all that apply --> + +- [ ] `cargo test --workspace --all-targets` +- [ ] `cargo clippy --workspace --all-targets --all-features -- -D warnings` +- [ ] `cargo check --workspace --all-targets --features "fastly cloudflare"` +- [ ] WASM builds: `wasm32-wasip1` (Fastly) / `wasm32-unknown-unknown` (Cloudflare) +- [ ] Manual testing via `edgezero-cli dev` +- [ ] Other: <!-- describe --> + +## Checklist + +- [ ] Changes follow [CLAUDE.md](/CLAUDE.md) conventions +- [ ] No Tokio deps added to core or adapter crates +- [ ] Route params use `{id}` syntax (not `:id`) +- [ ] Types imported from `edgezero_core` (not `http` crate) +- [ ] New code has tests +- [ ] No secrets or credentials committed diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cb09651..c23f862 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,11 +13,11 @@ name: "CodeQL Advanced" on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] schedule: - - cron: '40 17 * * 3' + - cron: "40 17 * * 3" jobs: analyze: @@ -43,12 +43,12 @@ jobs: fail-fast: false matrix: include: - - language: actions - build-mode: none - - language: rust - build-mode: none - - language: javascript-typescript - build-mode: none + - language: actions + build-mode: none + - language: rust + build-mode: none + - language: javascript-typescript + build-mode: none # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both @@ -58,46 +58,46 @@ jobs: # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - # Add any setup steps before running the `github/codeql-action/init` action. - # This includes steps like installing compilers or runtimes (`actions/setup-node` - # or others). This is typically only required for manual builds. - # - name: Setup runtime (example) - # uses: actions/setup-example@v1 + # Add any setup steps before running the `github/codeql-action/init` action. + # This includes steps like installing compilers or runtimes (`actions/setup-node` + # or others). This is typically only required for manual builds. + # - name: Setup runtime (example) + # uses: actions/setup-example@v1 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - name: Run manual build steps - if: matrix.build-mode == 'manual' - shell: bash - run: | - echo 'If you are using a "manual" build mode for one or more of the' \ - 'languages you are analyzing, replace this with the commands to build' \ - 'your code, for example:' - echo ' make bootstrap' - echo ' make release' - exit 1 + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - name: Run manual build steps + if: matrix.build-mode == 'manual' + shell: bash + run: | + echo 'If you are using a "manual" build mode for one or more of the' \ + 'languages you are analyzing, replace this with the commands to build' \ + 'your code, for example:' + echo ' make bootstrap' + echo ' make release' + exit 1 - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 9c40e95..ab71a3c 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -4,8 +4,8 @@ on: push: branches: [main] paths: - - 'docs/**' - - '.github/workflows/deploy-docs.yml' + - "docs/**" + - ".github/workflows/deploy-docs.yml" workflow_dispatch: # Allow manual triggers # Sets permissions for GitHub Pages deployment @@ -41,7 +41,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ steps.node-version.outputs.node-version }} - cache: 'npm' + cache: "npm" cache-dependency-path: docs/package-lock.json - name: Setup Pages diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index f1b0d79..be42f98 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -1,4 +1,4 @@ -name: 'Run Format' +name: "Run Format" on: push: @@ -41,7 +41,7 @@ jobs: - name: Set up rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 with: - components: 'clippy, rustfmt' + components: "clippy, rustfmt" toolchain: ${{ steps.rust-version.outputs.rust-version }} - name: Fetch dependencies (locked) @@ -72,7 +72,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ steps.node-version.outputs.node-version }} - cache: 'npm' + cache: "npm" cache-dependency-path: docs/package.json - name: Install dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c8dbed4..0a9a4e9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: 'Run Tests' +name: "Run Tests" on: push: diff --git a/.gitignore b/.gitignore index 87a1ca3..6aef111 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,10 @@ target/ .DS_Store # Editors -.claude +.claude/* +!.claude/settings.json +!.claude/commands/ +!.claude/agents/ .idea .specstory .vscode/* diff --git a/AGENTS.md b/AGENTS.md index 7b124a9..b53efcc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,83 +1,23 @@ # Agent Notes -This repository is currently tended by an automated assistant (Codex) that helps -craft the EdgeZero workspace. A few conventions are worth remembering when the -agent is asked to make additional changes: - -## Standard Workflow - -1. First think through the problem, read the codebase for relevant files, and write a plan to the file: TODO.md. If the TODO.md file does not yet exist, go ahead and create it. -2. The plan should have a list of todo items that you can check off as you complete them -3. Before you begin working, show me the full plan of the work to be done and get my approval before commencing any coding work -4. Then, begin working on the todo items, marking them as complete as you go. -5. As you complete each todo item, give me a high level explanation of what changes you made -6. If you cannot complete a todo, mark it as blocked in TODO.md and explain why. -7. Make every task and code change you do as simple as possible. We want to avoid making any massive or complex changes. Every change should impact as little code as possible. -8. Finally, add a review section to the TODO.md file with a summary of the changes you made, assumptions made, any unresolved issues or errors you couldn't fix, and any other relevant information. Add the date and time showing when the job was finished. - -## Tools - -### Context7 MCP - -- Use Context7 MCP to supplement local codebase knowledge with up-to-date library documentation and coding examples - -### Playwright MCP - -- use the Playwright MCP in order to check and validate any user interface changes you make -- you can also use this MCP to check the web browser console for any error messages which may come up -- iterate up to a maximum of 5 times for any one particular feature; an iteration = one cycle of code change + Playwright re-run -- if you can't get the feature to work after 5 iterations then you're likely stuck in a loop and you should stop and let me know that you've hit your max of 5 iterations for that feature -- Save any failing test cases or console errors in a debug.md file so we can review them together. - -## Testing - -always run `cargo test` after touching code. Individual crates -can be scoped via `cargo test -p <crate-name>` when a partial run is faster. - -## Routing syntax - -route definitions must use matchit 0.8 style -parameters (`/resource/{id}` or `/static/{*rest}`); we intentionally do not -support legacy `:id` syntax. - -## Adapters – Fastly and Cloudflare adapters expose request context helpers - -in `context.rs` and translation helpers in `request.rs` / `response.rs`. -Tests for adapter behaviour live beside those modules. - -## Examples - -the demo crates under `examples/app-demo/` share router -logic via `app-demo-core`. Local smoke testing flows through -`cargo run -p edgezero-cli --features dev-example -- dev`, which serves the demo -router on http://127.0.0.1:8787. Build provider targets with -`app-demo-adapter-fastly` / `app-demo-adapter-cloudflare` when you need Fastly -or Cloudflare binaries. - -## Style– prefer colocating tests with implementation modules, favour - -async/await-friendly code that compiles to Wasm, and avoid runtime-specific -dependencies like Tokio. - -- Use the HTTP aliases exported from `edgezero_core` (`Method`, `StatusCode`, - `HeaderMap`, etc.) instead of importing types directly from the `http` crate. -- Prefer the `#[edgezero_core::action]` macro for new handlers so extractor - arguments (`Json<T>`, `Query<T>`, `ValidatedJson<T>`, etc.) stay declarative. - Extractors live under `edgezero_core::` and integrate with the `validator` - crate for `Validated*` variants. - -## Logging - -- Platform logging helpers live in the adapters: use `edgezero_adapter_fastly::init_logger()` / `edgezero_adapter_cloudflare::init_logger()` and - fall back to something like `simple_logger` for local builds. - -## Proxy helpers - -- Use `edgezero_core::proxy::ProxyService` with the adapter clients - (`edgezero_adapter_fastly::FastlyProxyClient`, `edgezero_adapter_cloudflare::CloudflareProxyClient`) - when wiring proxy routes so streaming and compression handling stay consistent. -- Keep synthetic local proxy behaviour lightweight so examples can run without - Fastly/Cloudflare credentials; rely on the proxy test clients in `edgezero-core` for unit coverage. - -When in doubt, keep changes minimal, document behaviour in `README.md`, and -ensure the workspace stays Wasm-friendly. +**Before doing anything else, read `CLAUDE.md` in this repository root.** It +contains all project conventions, coding standards, build commands, workflow +rules, and CI requirements. Everything in `CLAUDE.md` applies to you. + +This file exists because Codex looks for `AGENTS.md` by convention. All shared +rules are maintained in `CLAUDE.md` to avoid duplication and drift. If you +cannot access `CLAUDE.md`, the critical rules are summarized below as a +fallback. + +## Fallback Summary + +If `CLAUDE.md` is unavailable, these are the minimum rules: + +1. Present a plan inline and get approval before coding. +2. Keep changes minimal — every change should impact as little code as possible. +3. Run `cargo test` after every code change. +4. Run `cargo fmt --all -- --check` and `cargo clippy --workspace --all-targets --all-features -- -D warnings`. +5. Run `cargo check --workspace --all-targets --features "fastly cloudflare"`. +6. Use matchit `{id}` syntax, never legacy `:id`. +7. Use `#[action]` macro for handlers, import types from `edgezero_core`. +8. Don't add Tokio deps to core/adapter crates — WASM compatibility first. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..471f11f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,320 @@ +# CLAUDE.md — EdgeZero + +## Project Overview + +EdgeZero is a portable HTTP workload toolkit in Rust. Write once, deploy to +Fastly Compute, Cloudflare Workers, or native Axum servers. The codebase is a +Cargo workspace with 7 crates under `crates/`, an example app under +`examples/app-demo/`, a VitePress documentation site under `docs/`, and CI +workflows under `.github/workflows/`. + +## Workspace Layout + +``` +crates/ + edgezero-core/ # Core: routing, extractors, middleware, proxy, body, errors + edgezero-macros/ # Proc macros: #[action], #[app] + edgezero-adapter/ # Adapter registry and traits + edgezero-adapter-fastly/ # Fastly Compute bridge (wasm32-wasip1) + edgezero-adapter-cloudflare/# Cloudflare Workers bridge (wasm32-unknown-unknown) + edgezero-adapter-axum/ # Axum/Tokio bridge (native, dev server) + edgezero-cli/ # CLI: new, build, deploy, dev, serve +examples/app-demo/ # Reference app with all 3 adapters (excluded from workspace) +docs/ # VitePress documentation site (Node.js) +scripts/ # Build/deploy/test helper scripts +``` + +## Toolchain & Versions + +- **Rust**: 1.91.1 (from `.tool-versions`) +- **Node.js**: 24.12.0 (for docs site only) +- **Fastly CLI**: v13.0.0 +- **Edition**: 2021 +- **Resolver**: 2 +- **License**: Apache-2.0 + +## Build & Test Commands + +```sh +# Full workspace test (primary CI command) +cargo test --workspace --all-targets + +# Test a specific crate +cargo test -p edgezero-core +cargo test -p edgezero-adapter-fastly +cargo test -p edgezero-cli + +# Lint & format (must pass CI) +cargo fmt --all -- --check +cargo clippy --workspace --all-targets --all-features -- -D warnings + +# Feature compilation check +cargo check --workspace --all-targets --features "fastly cloudflare" + +# Run the demo dev server +cargo run -p edgezero-cli --features dev-example -- dev + +# Docs site +cd docs && npm ci && npm run dev +``` + +**Always run `cargo test` after touching code.** Use `-p <crate-name>` for +faster iteration on a single crate. + +## Compilation Targets + +| Adapter | Target | Notes | +| ---------- | ------------------------ | ---------------------------------- | +| Fastly | `wasm32-wasip1` | Requires Viceroy for local testing | +| Cloudflare | `wasm32-unknown-unknown` | Requires `wrangler` for dev/deploy | +| Axum | Native (host triple) | Standard Tokio runtime | + +## Coding Conventions + +### Routing + +Use matchit 0.8+ brace syntax for path parameters: + +```rust +// CORRECT +"/resource/{id}" +"/static/{*rest}" + +// WRONG — legacy colon syntax is not supported +"/resource/:id" +``` + +### Handlers + +Use the `#[action]` macro for all new handlers: + +```rust +use edgezero_core::{action, Json, Path, Query, ValidatedJson, Response, EdgeError}; + +#[action] +async fn my_handler( + Json(body): Json<MyPayload>, + Path(params): Path<MyParams>, +) -> Result<Response, EdgeError> { + // handler body +} +``` + +- Import HTTP type aliases from `edgezero_core` (`Method`, `StatusCode`, + `HeaderMap`, etc.) — never from the `http` crate directly. +- Extractors implement `FromRequest`. Use `ValidatedJson<T>` / `ValidatedPath<T>` / + `ValidatedQuery<T>` for automatic `validator` crate integration. +- `RequestContext` can be destructured: `RequestContext(ctx): RequestContext`. + +### Error Handling + +- Use `EdgeError` with semantic constructors: `EdgeError::validation()`, + `EdgeError::internal()`, etc. +- Map to provider-specific errors only at the adapter boundary. +- Prefer `Result<Response, EdgeError>` as handler return type. + +### Middleware + +Implement the `Middleware` trait. Chain via `Next::run()`: + +```rust +struct MyMiddleware; +impl Middleware for MyMiddleware { + async fn handle(&self, ctx: RequestContext, next: Next) -> Result<Response, EdgeError> { + // before + let response = next.run(ctx).await?; + // after + Ok(response) + } +} +``` + +### Proxy + +Use `ProxyService` with adapter-specific clients (`FastlyProxyClient`, +`CloudflareProxyClient`). Keep proxy logic provider-agnostic in core. + +### Logging + +- Adapter-specific init: `edgezero_adapter_fastly::init_logger()`, + `edgezero_adapter_cloudflare::init_logger()`. +- Use `simple_logger` for local/Axum builds. +- Use the `log` / `tracing` facade, not direct dependencies. + +### Style Rules + +- **WASM compatibility first**: avoid Tokio and runtime-specific deps in core + and adapter crates. Use `async-trait` without `Send` bounds. Use `web-time` + instead of `std::time::Instant`. +- **Colocate tests** with implementation modules (`#[cfg(test)]` in the same file). +- **Async tests** use `futures::executor::block_on` (not Tokio) for WASM compat. +- **Minimal changes**: every change should impact as little code as possible. + Avoid unnecessary refactoring, docstrings on untouched code, or premature abstractions. +- **Feature gates**: platform-specific code goes behind `fastly`, `cloudflare`, + or `axum` features. Core stays `default-features = false` for WASM targets. +- **No direct `http` crate imports** in application code — use `edgezero_core` re-exports. + +## Adapter Pattern + +Each adapter follows the same structure: + +- `context.rs` — platform-specific request context +- `request.rs` — platform request → core request conversion +- `response.rs` — core response → platform response conversion +- `proxy.rs` — platform-specific proxy client +- `logger.rs` — platform-specific logging init +- `cli.rs` — build/deploy commands (behind `cli` feature) + +Contract tests live in `tests/contract.rs` within each adapter crate. + +## Manifest (`edgezero.toml`) + +The manifest drives routing, env bindings, and per-adapter build/deploy config. +Key sections: `[app]`, `[[triggers.http]]`, `[environment]`, `[adapters]`. + +## CI Gates + +Every PR must pass: + +1. `cargo fmt --all -- --check` +2. `cargo clippy --workspace --all-targets --all-features -- -D warnings` +3. `cargo test --workspace --all-targets` +4. `cargo check --workspace --all-targets --features "fastly cloudflare"` + +Docs CI additionally runs ESLint + Prettier on the `docs/` directory. + +## Standard Workflow + +1. **Read & plan**: think through the problem, read the codebase for relevant + files, and present a plan as a checklist inline in the conversation. +2. **Get approval first**: show the full plan and get approval before commencing + any coding work. +3. **Implement incrementally**: work through the checklist items. Make every + task and code change as simple as possible — every change should impact as + little code as possible. +4. **Test after every change**: run `cargo test` (or scoped `-p <crate>`) after + touching any code. +5. **Explain as you go**: after completing each item, give a high-level + explanation of what changes you made. +6. **If blocked**: explain what's blocking and why. + +## Verification & Quality + +- **Verify, don't assume**: after implementing a change, prove it works. Run + tests, check `cargo clippy`, and compare behavior against `main` when relevant. + Don't say "it works" without evidence. +- **Plan review**: for complex tasks, review your own plan as a staff engineer + would before implementing. Ask: is this the simplest approach? Does it touch + too many files? Are there edge cases? +- **Escape hatch**: if an implementation is going sideways after multiple + iterations, step back and reconsider. Scrap the approach and implement the + simpler solution rather than patching a flawed design. +- **Use subagents**: for tasks spanning multiple crates or requiring broad + codebase exploration, use subagents to parallelize investigation and keep the + main context clean. + +## Subagents + +Specialized agents live in `.claude/agents/`. Use them to distribute work: + +| Agent | Purpose | +| ----------------- | ------------------------------------------------------------------------- | +| `code-simplifier` | Simplifies code after work is done — dead code, duplication, nesting | +| `verify-app` | End-to-end verification: tests, lint, WASM builds, dev server smoke test | +| `build-validator` | Validates builds across all targets and feature combinations | +| `code-architect` | Architectural review — evaluates designs against project principles | +| `pr-creator` | Creates or updates GitHub PRs using the project template and CI gates | +| `issue-creator` | Creates GitHub issues with proper types (Task/Bug/Story/Epic) via GraphQL | +| `repo-explorer` | Read-only codebase mapping for unfamiliar areas and cross-crate flow | + +Invoke with "use subagents" in your prompt or reference a specific agent by name. + +### Subagent Workflow (Required for Complex Tasks) + +For tasks spanning multiple crates, adapters, or unclear failures, use this flow: + +1. **Phase 1 — Parallel investigation (read-only)**: + launch 2-4 subagents with non-overlapping scopes (tests, diff review, architecture checks). + Each subagent must return concrete findings with file paths and line references. +2. **Phase 2 — Parallel solution proposals (no edits)**: + launch at least 2 subagents to propose minimal fix strategies based on Phase 1 findings. + Compare tradeoffs (scope, risk, CI impact) before coding. +3. **Phase 3 — Single-path implementation**: + pick one plan (smallest safe change) and implement centrally. + Do not let multiple subagents edit overlapping files at the same time. +4. **Phase 4 — Verification handoff**: + run `verify-app` or `build-validator` for broad changes, then summarize pass/fail by step. +5. **Phase 5 — Decision log**: + report which subagents were used, what each found, and why the chosen plan was selected. + +Default trigger: + +- If work touches 2+ crates or includes both runtime behavior and build/tooling changes, use this workflow. + +### Subagent Selection Matrix + +| Situation | Use first | Optional follow-up | Expected output | +| -------------------------- | ----------------- | ----------------------------------- | --------------------------------- | +| Unfamiliar code area | `repo-explorer` | `code-architect` | File map and risk hotspots | +| Multi-crate feature change | `repo-explorer` | `code-architect`, `build-validator` | Change plan and validation scope | +| CI/build failures | `build-validator` | `repo-explorer` | Failing combos and fault area | +| Design/API proposal | `code-architect` | `repo-explorer` | Architecture concerns and options | +| Cleanup/refactor pass | `code-simplifier` | `build-validator` | Simplification summary and checks | +| Pre-PR readiness | `build-validator` | `verify-app`, `pr-creator` | Pass/fail report and PR draft | + +Use at least 2 subagents when: + +- The task touches 2+ crates. +- The change affects both runtime behavior and CI/build tooling. + +## Slash Commands + +Custom commands live in `.claude/commands/`: + +| Command | Purpose | +| ----------------- | -------------------------------------------------- | +| `/check-ci` | Run all 4 CI gate checks locally | +| `/test-all` | Run full workspace test suite | +| `/test-crate` | Run tests for a specific crate | +| `/review-changes` | Staff-engineer-level review of uncommitted changes | +| `/verify` | Prove current changes work vs main | + +## Available MCPs + +- **Context7 MCP**: use for up-to-date library docs and coding examples. + +## Key Files Reference + +| Purpose | Path | +| ------------------ | --------------------------------------- | +| Workspace manifest | `Cargo.toml` | +| Core crate entry | `crates/edgezero-core/src/lib.rs` | +| Router | `crates/edgezero-core/src/router.rs` | +| Extractors | `crates/edgezero-core/src/extractor.rs` | +| Action macro | `crates/edgezero-macros/src/action.rs` | +| CLI entry | `crates/edgezero-cli/src/main.rs` | +| Demo app | `examples/app-demo/` | +| Demo manifest | `examples/app-demo/edgezero.toml` | +| CI tests | `.github/workflows/test.yml` | +| CI format/lint | `.github/workflows/format.yml` | +| Docs site | `docs/` | +| Test script | `scripts/run_tests.sh` | + +## Dependencies Philosophy + +- Workspace-level dependency management via `[workspace.dependencies]` in root `Cargo.toml`. +- Minimal, carefully curated for WASM compatibility. +- `Cargo.lock` is committed for reproducible builds. +- Key crates: `matchit` (routing), `tower` (middleware), `async-trait`, + `async-compression`, `serde`/`serde_json`, `validator`, `clap` (CLI), + `handlebars` (templates). + +## What NOT to Do + +- Don't use legacy `:id` route syntax — always use `{id}`. +- Don't import from `http` crate directly — use `edgezero_core` re-exports. +- Don't add Tokio dependencies to core or adapter crates. +- Don't write tests that require a network connection or platform credentials. +- Don't make large, sweeping refactors — keep changes minimal and focused. +- Don't commit without running `cargo test` first. +- Don't skip `cargo fmt` and `cargo clippy` — CI will reject the PR. diff --git a/examples/app-demo/Cargo.lock b/examples/app-demo/Cargo.lock index 6900053..e4cbc2f 100644 --- a/examples/app-demo/Cargo.lock +++ b/examples/app-demo/Cargo.lock @@ -2137,9 +2137,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" +version = "1.0.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +checksum = "c7614eaf19ad818347db24addfa201729cf2a9b6fdfd9eb0ab870fcacc606c0c" dependencies = [ "indexmap", "serde_core", @@ -2152,18 +2152,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.0.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" dependencies = [ "serde_core", ] [[package]] name = "toml_parser" -version = "1.0.7+spec-1.1.0" +version = "1.0.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "247eaa3197818b831697600aadf81514e577e0cba5eab10f7e064e78ae154df1" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" dependencies = [ "winnow", ]