diff --git a/.github/workflows/gemini-dispatch.yml b/.github/workflows/gemini-dispatch.yml index 22d0b27a..ebe773b6 100644 --- a/.github/workflows/gemini-dispatch.yml +++ b/.github/workflows/gemini-dispatch.yml @@ -83,7 +83,7 @@ jobs: - name: 'Extract command' id: 'extract_command' - uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7 + uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 env: EVENT_TYPE: '${{ github.event_name }}.${{ github.event.action }}' REQUEST: '${{ github.event.comment.body || github.event.review.body || github.event.issue.body }}' @@ -135,7 +135,10 @@ jobs: pull-requests: 'write' with: additional_context: '${{ needs.dispatch.outputs.additional_context }}' - secrets: 'inherit' + secrets: + APP_PRIVATE_KEY: '${{ secrets.APP_PRIVATE_KEY }}' + GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}' + GOOGLE_API_KEY: '${{ secrets.GOOGLE_API_KEY }}' triage: needs: 'dispatch' @@ -149,7 +152,10 @@ jobs: pull-requests: 'write' with: additional_context: '${{ needs.dispatch.outputs.additional_context }}' - secrets: 'inherit' + secrets: + APP_PRIVATE_KEY: '${{ secrets.APP_PRIVATE_KEY }}' + GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}' + GOOGLE_API_KEY: '${{ secrets.GOOGLE_API_KEY }}' invoke: needs: 'dispatch' @@ -163,7 +169,10 @@ jobs: pull-requests: 'write' with: additional_context: '${{ needs.dispatch.outputs.additional_context }}' - secrets: 'inherit' + secrets: + APP_PRIVATE_KEY: '${{ secrets.APP_PRIVATE_KEY }}' + GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}' + GOOGLE_API_KEY: '${{ secrets.GOOGLE_API_KEY }}' fallthrough: needs: diff --git a/.github/workflows/gemini-invoke.yml b/.github/workflows/gemini-invoke.yml index e59e55de..461be377 100644 --- a/.github/workflows/gemini-invoke.yml +++ b/.github/workflows/gemini-invoke.yml @@ -2,6 +2,13 @@ name: '▶️ Gemini Invoke' on: workflow_call: + secrets: + APP_PRIVATE_KEY: + required: false + GEMINI_API_KEY: + required: false + GOOGLE_API_KEY: + required: false inputs: additional_context: type: 'string' @@ -37,9 +44,26 @@ jobs: permission-issues: 'write' permission-pull-requests: 'write' + - name: 'Check authentication configuration' + id: 'check_auth' + env: + HAS_GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY != '' }} + HAS_GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY != '' }} + HAS_WIF_PROVIDER: ${{ vars.GCP_WIF_PROVIDER != '' }} + HAS_USE_VERTEXAI: ${{ vars.GOOGLE_GENAI_USE_VERTEXAI != '' }} + HAS_USE_GCA: ${{ vars.GOOGLE_GENAI_USE_GCA != '' }} + run: |- + if [[ "${HAS_GEMINI_API_KEY}" == "true" || "${HAS_GOOGLE_API_KEY}" == "true" || "${HAS_WIF_PROVIDER}" == "true" || "${HAS_USE_VERTEXAI}" == "true" || "${HAS_USE_GCA}" == "true" ]]; then + echo "configured=true" >> "${GITHUB_OUTPUT}" + else + echo "configured=false" >> "${GITHUB_OUTPUT}" + echo "::warning::No Gemini authentication configured. Set one of: GEMINI_API_KEY secret, GOOGLE_API_KEY secret, or configure the GCP_WIF_PROVIDER, GOOGLE_GENAI_USE_VERTEXAI, or GOOGLE_GENAI_USE_GCA variables." + fi + - name: 'Run Gemini CLI' id: 'run_gemini' - uses: 'google-github-actions/run-gemini-cli@v0' # ratchet:exclude + if: '${{ steps.check_auth.outputs.configured == ''true'' }}' + uses: 'google-github-actions/run-gemini-cli@f77273f4c914e4bf38440cf36a0369cb64a37489' # ratchet:exclude env: TITLE: '${{ github.event.pull_request.title || github.event.issue.title }}' DESCRIPTION: '${{ github.event.pull_request.body || github.event.issue.body }}' @@ -49,6 +73,7 @@ jobs: ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}' REPOSITORY: '${{ github.repository }}' ADDITIONAL_CONTEXT: '${{ inputs.additional_context }}' + GEMINI_CLI_TRUST_WORKSPACE: 'true' with: gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}' gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}' diff --git a/.github/workflows/gemini-review.yml b/.github/workflows/gemini-review.yml index d3b43a15..72a88941 100644 --- a/.github/workflows/gemini-review.yml +++ b/.github/workflows/gemini-review.yml @@ -2,6 +2,13 @@ name: '🔎 Gemini Review' on: workflow_call: + secrets: + APP_PRIVATE_KEY: + required: false + GEMINI_API_KEY: + required: false + GOOGLE_API_KEY: + required: false inputs: additional_context: type: 'string' @@ -41,8 +48,25 @@ jobs: - name: 'Checkout repository' uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5 + - name: 'Check authentication configuration' + id: 'check_auth' + env: + HAS_GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY != '' }} + HAS_GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY != '' }} + HAS_WIF_PROVIDER: ${{ vars.GCP_WIF_PROVIDER != '' }} + HAS_USE_VERTEXAI: ${{ vars.GOOGLE_GENAI_USE_VERTEXAI != '' }} + HAS_USE_GCA: ${{ vars.GOOGLE_GENAI_USE_GCA != '' }} + run: |- + if [[ "${HAS_GEMINI_API_KEY}" == "true" || "${HAS_GOOGLE_API_KEY}" == "true" || "${HAS_WIF_PROVIDER}" == "true" || "${HAS_USE_VERTEXAI}" == "true" || "${HAS_USE_GCA}" == "true" ]]; then + echo "configured=true" >> "${GITHUB_OUTPUT}" + else + echo "configured=false" >> "${GITHUB_OUTPUT}" + echo "::warning::No Gemini authentication configured. Set one of: GEMINI_API_KEY secret, GOOGLE_API_KEY secret, or configure the GCP_WIF_PROVIDER, GOOGLE_GENAI_USE_VERTEXAI, or GOOGLE_GENAI_USE_GCA variables." + fi + - name: 'Run Gemini pull request review' - uses: 'google-github-actions/run-gemini-cli@v0' # ratchet:exclude + if: '${{ steps.check_auth.outputs.configured == ''true'' }}' + uses: 'google-github-actions/run-gemini-cli@f77273f4c914e4bf38440cf36a0369cb64a37489' # ratchet:exclude id: 'gemini_pr_review' env: GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}' @@ -51,6 +75,7 @@ jobs: PULL_REQUEST_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}' REPOSITORY: '${{ github.repository }}' ADDITIONAL_CONTEXT: '${{ inputs.additional_context }}' + GEMINI_CLI_TRUST_WORKSPACE: 'true' with: gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}' gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}' @@ -65,6 +90,7 @@ jobs: use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}' upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}' workflow_name: 'gemini-review' + github_pr_number: '${{ github.event.pull_request.number || github.event.issue.number }}' settings: |- { "model": { @@ -84,13 +110,12 @@ jobs: "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", - "ghcr.io/github/github-mcp-server:v0.18.0" + "ghcr.io/github/github-mcp-server:v0.27.0" ], "includeTools": [ "add_comment_to_pending_review", - "create_pending_pull_request_review", "pull_request_read", - "submit_pending_pull_request_review" + "pull_request_review_write" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" diff --git a/.github/workflows/gemini-scheduled-triage.yml b/.github/workflows/gemini-scheduled-triage.yml index 46bb71f2..235e5b10 100644 --- a/.github/workflows/gemini-scheduled-triage.yml +++ b/.github/workflows/gemini-scheduled-triage.yml @@ -40,7 +40,7 @@ jobs: steps: - name: 'Get repository labels' id: 'get_labels' - uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7.0.1 + uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.0.1 with: # NOTE: we intentionally do not use the minted token. The default # GITHUB_TOKEN provided by the action has enough permissions to read @@ -85,16 +85,33 @@ jobs: ISSUE_COUNT="$(echo "${ISSUES}" | jq 'length')" echo "✅ Found ${ISSUE_COUNT} issue(s) to triage! 🎯" + - name: 'Check authentication configuration' + id: 'check_auth' + env: + HAS_GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY != '' }} + HAS_GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY != '' }} + HAS_WIF_PROVIDER: ${{ vars.GCP_WIF_PROVIDER != '' }} + HAS_USE_VERTEXAI: ${{ vars.GOOGLE_GENAI_USE_VERTEXAI != '' }} + HAS_USE_GCA: ${{ vars.GOOGLE_GENAI_USE_GCA != '' }} + run: |- + if [[ "${HAS_GEMINI_API_KEY}" == "true" || "${HAS_GOOGLE_API_KEY}" == "true" || "${HAS_WIF_PROVIDER}" == "true" || "${HAS_USE_VERTEXAI}" == "true" || "${HAS_USE_GCA}" == "true" ]]; then + echo "configured=true" >> "${GITHUB_OUTPUT}" + else + echo "configured=false" >> "${GITHUB_OUTPUT}" + echo "::warning::No Gemini authentication configured. Set one of: GEMINI_API_KEY secret, GOOGLE_API_KEY secret, or configure the GCP_WIF_PROVIDER, GOOGLE_GENAI_USE_VERTEXAI, or GOOGLE_GENAI_USE_GCA variables." + fi + - name: 'Run Gemini Issue Analysis' id: 'gemini_issue_analysis' if: |- - ${{ steps.find_issues.outputs.issues_to_triage != '[]' }} - uses: 'google-github-actions/run-gemini-cli@v0' # ratchet:exclude + ${{ steps.find_issues.outputs.issues_to_triage != '[]' && steps.check_auth.outputs.configured == 'true' }} + uses: 'google-github-actions/run-gemini-cli@f77273f4c914e4bf38440cf36a0369cb64a37489' # ratchet:exclude env: GITHUB_TOKEN: '' # Do not pass any auth token here since this runs on untrusted inputs ISSUES_TO_TRIAGE: '${{ steps.find_issues.outputs.issues_to_triage }}' REPOSITORY: '${{ github.repository }}' AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}' + GEMINI_CLI_TRUST_WORKSPACE: 'true' with: gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}' gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}' @@ -159,7 +176,7 @@ jobs: env: AVAILABLE_LABELS: '${{ needs.triage.outputs.available_labels }}' TRIAGED_ISSUES: '${{ needs.triage.outputs.triaged_issues }}' - uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7.0.1 + uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.0.1 with: # Use the provided token so that the "gemini-cli" is the actor in the # log for what changed the labels. diff --git a/.github/workflows/gemini-triage.yml b/.github/workflows/gemini-triage.yml index 581acbbf..407b78c4 100644 --- a/.github/workflows/gemini-triage.yml +++ b/.github/workflows/gemini-triage.yml @@ -2,6 +2,13 @@ name: '🔀 Gemini Triage' on: workflow_call: + secrets: + APP_PRIVATE_KEY: + required: false + GEMINI_API_KEY: + required: false + GOOGLE_API_KEY: + required: false inputs: additional_context: type: 'string' @@ -31,7 +38,7 @@ jobs: steps: - name: 'Get repository labels' id: 'get_labels' - uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7.0.1 + uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.0.1 with: # NOTE: we intentionally do not use the given token. The default # GITHUB_TOKEN provided by the action has enough permissions to read @@ -55,16 +62,33 @@ jobs: core.info(`Found ${labelNames.length} labels: ${labelNames.join(', ')}`); return labelNames; + - name: 'Check authentication configuration' + id: 'check_auth' + env: + HAS_GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY != '' }} + HAS_GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY != '' }} + HAS_WIF_PROVIDER: ${{ vars.GCP_WIF_PROVIDER != '' }} + HAS_USE_VERTEXAI: ${{ vars.GOOGLE_GENAI_USE_VERTEXAI != '' }} + HAS_USE_GCA: ${{ vars.GOOGLE_GENAI_USE_GCA != '' }} + run: |- + if [[ "${HAS_GEMINI_API_KEY}" == "true" || "${HAS_GOOGLE_API_KEY}" == "true" || "${HAS_WIF_PROVIDER}" == "true" || "${HAS_USE_VERTEXAI}" == "true" || "${HAS_USE_GCA}" == "true" ]]; then + echo "configured=true" >> "${GITHUB_OUTPUT}" + else + echo "configured=false" >> "${GITHUB_OUTPUT}" + echo "::warning::No Gemini authentication configured. Set one of: GEMINI_API_KEY secret, GOOGLE_API_KEY secret, or configure the GCP_WIF_PROVIDER, GOOGLE_GENAI_USE_VERTEXAI, or GOOGLE_GENAI_USE_GCA variables." + fi + - name: 'Run Gemini issue analysis' id: 'gemini_analysis' if: |- - ${{ steps.get_labels.outputs.available_labels != '' }} - uses: 'google-github-actions/run-gemini-cli@v0' # ratchet:exclude + ${{ steps.get_labels.outputs.available_labels != '' && steps.check_auth.outputs.configured == 'true' }} + uses: 'google-github-actions/run-gemini-cli@f77273f4c914e4bf38440cf36a0369cb64a37489' # ratchet:exclude env: GITHUB_TOKEN: '' # Do NOT pass any auth tokens here since this runs on untrusted inputs ISSUE_TITLE: '${{ github.event.issue.title }}' ISSUE_BODY: '${{ github.event.issue.body }}' AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}' + GEMINI_CLI_TRUST_WORKSPACE: 'true' with: gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}' gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}' @@ -125,7 +149,7 @@ jobs: ISSUE_NUMBER: '${{ github.event.issue.number }}' AVAILABLE_LABELS: '${{ needs.triage.outputs.available_labels }}' SELECTED_LABELS: '${{ needs.triage.outputs.selected_labels }}' - uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7.0.1 + uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.0.1 with: # Use the provided token so that the "gemini-cli" is the actor in the # log for what changed the labels. diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8eb47229..00000000 --- a/.gitignore +++ /dev/null @@ -1,92 +0,0 @@ -/loctree_rs/target -/.codex -*.pyc -/.fastembed_cache -tarpaulin-report.json -tarpaulin-report.html -*.profraw -loctree_rs/tarpaulin-report.json -/.ai-agents -/.ai-suite -# loctree: keep repo-local config files, ignore cache artifacts -/.loctree/* -!/.loctree/config.toml -!/.loctree/suppressions.toml -/.benchmarks -/agents -/loctree_rs/logs -/loctree_rs/.loctree -*.log -/.claude - -# Root Markdown policy: ignore root .md files except core docs that are tracked -/*.md -!/README.md -!/CHANGELOG.md -!/CONTRIBUTING.md -!/SECURITY.md - -# Local patch/diff artifacts -*.patch -*.diff - -# Python cache -__pycache__/ -.mypy_cache/ -.ruff_cache/ -*.pyc -/.env -/.env.* -!/.env.example -!/.env.sample -/reports/target -*.zip -# Test fixtures - generated .loctree snapshots -/loctree_rs/tests/fixtures/**/.loctree - -# Generated loctree output assets (JS libraries written alongside reports) -loctree-*.js -loctree-*.min.js -/reports/loctree-*.js -/reports/reports/ -/reports/wasm/target -/loctree_rs/.fastembed_cache -*.txt -!tools/fixtures/**/*.txt -/assets/Icon Exports -.replit -/.tools - -.gemini/ -gha-creds-*.json -GEMINI.md -gemini.md -**/.loctree/**/report.html -/loctree_memex/target -/loctree_server/target -/target -brave-mcp-servers-report.md -reports/report.html -/loctree_rs/src/.loctree - -# npm package - downloaded binaries (keep placeholders) -/bin/*.tar.gz -/bin/*.zip -# Keep placeholder scripts but ignore actual binaries that overwrite them -# (they have no extension on Unix, .exe on Windows) - -# macOS -**/.DS_Store -/.idea -SeniorDev/ -/reports/.loctree -/.vibecrafted/* -!/.vibecrafted/GUIDELINES.md - -# Orphan workspace member Cargo.lock files -# Root Cargo.lock is the single source of truth for the workspace. -# Members must not carry their own lockfiles (regenerated by partial cargo runs / IDEs). -loctree_rs/Cargo.lock -loctree-mcp/Cargo.lock -reports/Cargo.lock -reports/wasm/Cargo.lock diff --git a/.loctignore b/.loctignore deleted file mode 100644 index 06c86c67..00000000 --- a/.loctignore +++ /dev/null @@ -1,16 +0,0 @@ -# Loctree ignore patterns for loctree-suite monorepo -# Created by M&K ⓒ 2025-2026 The LibraxisAI Team -# Note: Only literal paths supported, no globs - -# Test fixtures - intentional patterns (cycles, dead code, etc) -loctree_rs/tests/fixtures/ - -# Build outputs - not source code -reports/wasm/assets/ - -# External API declarations (used by npm consumers, not internally) -distribution/npm/index.d.ts - -# Tools fixtures and test files -tools/fixtures/ -tools/test_ts/ diff --git a/.semgrep.yaml b/.semgrep.yaml deleted file mode 100644 index 13fd7ef5..00000000 --- a/.semgrep.yaml +++ /dev/null @@ -1,99 +0,0 @@ -rules: - # Secrets and credential patterns - - id: local.secrets.generic - languages: [generic] - message: Possible secret/credential detected - severity: ERROR - paths: - include: ["**"] - exclude: ["**/.semgrep.yaml"] - patterns: - - pattern-either: - - pattern: /AIza[0-9A-Za-z\-_]{35}/ - - pattern: /ghp_[0-9A-Za-z]{36}/ - - pattern: /sk-[A-Za-z0-9]{32,}/ - - pattern: /(?i)AWS_SECRET_ACCESS_KEY\s*=\s*[A-Za-z0-9\/\+=]{40}/ - - pattern: /(?i)AWS_ACCESS_KEY_ID\s*=\s*AKIA[0-9A-Z]{16}/ - - pattern: /(?i)PASSWORD\s*=\s*[^\\s]+/ - - pattern: /(?i)SECRET\s*=\s*[^\\s]+/ - - # CI hygiene: disallow sleep in tests - - id: local.ci.no-sleep-in-tests - languages: [javascript, typescript, python, rust] - message: Avoid sleep in tests (flaky/slow CI) - severity: WARNING - paths: - include: ["**/*test*.*", "**/tests/**"] - patterns: - - pattern-either: - - pattern: sleep(...) - - pattern: asyncio.sleep(...) - - pattern: setTimeout(...) - metadata: - category: ci - - # Enforce safe fs open in Rust (no unwrap on File::open) - - id: local.rust.no-file-open-unwrap - languages: [rust] - message: Avoid unwrap() on File::open to prevent crashes - severity: WARNING - patterns: - - pattern: File::open(...).unwrap() - - # JS/TS: forbid dynamic import with template literal without prefix (semgrep-friendly) - - id: local.js.dynamic-import-template - languages: [javascript, typescript] - message: Dynamic import with template literal can bypass graph analysis - severity: WARNING - patterns: - - pattern: import(`...`) - - pattern-not: import(`./${...}`) - - # JS/TS: block eval/new Function - - id: local.js.no-eval - languages: [javascript, typescript] - message: Avoid eval/new Function for safety and analyzability - severity: ERROR - patterns: - - pattern-either: - - pattern: eval(...) - - pattern: new Function(...) - - # Python: forbid __import__ without literal - - id: local.py.dynamic-import-literal - languages: [python] - message: __import__ without literal makes graph incomplete - severity: WARNING - patterns: - - pattern: __import__($X) - - pattern-not: __import__("...") - - # Python: discourage shell=True in subprocess - - id: local.py.subprocess-shell - languages: [python] - message: Avoid subprocess with shell=True (command injection risk) - severity: WARNING - pattern-either: - - patterns: - - pattern: subprocess.$FUNC(..., shell=True, ...) - - metavariable-regex: - metavariable: $FUNC - regex: "(run|Popen|call|check_call|check_output)" - - # Rust: avoid unwrap in command handlers (generic guard) - - id: local.rust.no-unwrap - languages: [rust] - message: Avoid unwrap(); use ? or expect with context - severity: WARNING - patterns: - - pattern: $X.unwrap() - - # Bash: disallow curl|bash style installers - - id: local.bash.no-curl-pipe-sh - languages: [bash] - message: Avoid piping curl/wget output to shell - severity: ERROR - patterns: - - pattern-either: - - pattern: curl ... | sh - - pattern: wget ... | sh diff --git a/.semgrepignore b/.semgrepignore deleted file mode 100644 index 178b14ca..00000000 --- a/.semgrepignore +++ /dev/null @@ -1,55 +0,0 @@ -# Semgrep ignore patterns -# ⓒ 2025-2026 Loctree Team - -# ============================================================================ -# STATIC HTML TEMPLATES -# These files use innerHTML with static HTML strings only (no user input). -# Converting to DOM API would make code unreadable without security benefit. -# ============================================================================ - -# Graph visualization - static UI templates for toolbar, panels -reports/src/graph_bootstrap.js - -# ============================================================================ -# CLI ENTRY POINTS -# args()/args_os() is required pattern for any CLI tool. -# Not used for security-sensitive decisions, only CLI flag parsing. -# ============================================================================ - -# Main binary entry points -loctree_rs/src/bin/loct.rs -loctree_rs/src/bin/loctree.rs -loctree_rs/src/args.rs - -# ============================================================================ -# TEST FILES -# Test code uses controlled fixture paths, not user input. -# Path traversal rules don't apply to test infrastructure. -# ============================================================================ - -loctree_rs/tests/ - -# ============================================================================ -# STATIC LANDING PAGE -# is SEO metadata, not a resource loader. -# Semgrep missing-integrity rule is a false positive on non-script tags. -# ============================================================================ - -public_dist/index.html - -# ============================================================================ -# VENDORED MINIFIED LIBRARIES -# Third-party code we don't control. Findings are upstream responsibility. -# ============================================================================ - -loctree_rs/src/analyzer/assets/cytoscape.min.js -loctree_rs/src/analyzer/assets/dagre.min.js - -# ============================================================================ -# DEMO / FIXTURE HTML -# External script tags here are for local examples and parser fixtures, not -# production pages. Semgrep's missing-integrity rule is noise on these files. -# ============================================================================ - -reports/src/twins_graph_example.html -tools/fixtures/html-scripts/vue-style.html diff --git a/.vibecrafted/GUIDELINES.md b/.vibecrafted/GUIDELINES.md deleted file mode 100644 index f15bb7f4..00000000 --- a/.vibecrafted/GUIDELINES.md +++ /dev/null @@ -1,10 +0,0 @@ -## VibeCrafted Guidelines - -This repository keeps the canonical project contract in `AGENTS.md`. -Read that first, then use these repo-specific defaults: - -- Map before you edit: `repo-view -> focus -> slice -> impact -> find -> follow`. -- Rust quality gate: `make precheck` for a fast pass, `make check` for the full repo gate, and `make test` before release-facing changes. -- Treat `loctree_rs/src/types.rs`, `loctree_rs/src/snapshot.rs`, and `reports/src/types.rs` as blast-radius hubs. -- Distribution truth lives under `distribution/`; do not invent release notes or install paths outside that spine. -- `loct` is the canonical CLI. `loctree` remains a compatibility alias and should stay quiet unless behavior truly changes. diff --git a/Cargo.lock b/Cargo.lock index cb1cf1cd..9f9d04bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,8046 +3,3031 @@ version = 4 [[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "adobe-cmap-parser" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8abfa9a4688de8fc9f42b3f013b6fffec18ed8a554f5f113577e0b9b3212a3" -dependencies = [ - "pom", -] - -[[package]] -name = "aes" -version = "0.8.4" +name = "aho-corasick" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", + "memchr", ] [[package]] -name = "ahash" -version = "0.8.12" +name = "allocator-api2" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "const-random", - "getrandom 0.3.4", - "once_cell", - "version_check", - "zerocopy", -] +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] -name = "aho-corasick" -version = "1.1.4" +name = "android_system_properties" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "memchr", + "libc", ] [[package]] -name = "alloc-no-stdlib" -version = "2.0.4" +name = "anstyle" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] -name = "alloc-stdlib" -version = "0.2.2" +name = "any_spawner" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "1384d3fe1eecb464229fcf6eebb72306591c56bf27b373561489458a7c73027d" dependencies = [ - "alloc-no-stdlib", + "futures", + "thiserror 2.0.18", + "wasm-bindgen-futures", ] [[package]] -name = "allocator-api2" -version = "0.2.21" +name = "anyhow" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] -name = "android_system_properties" -version = "0.1.5" +name = "assert_cmd" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "2aa3a22042e45de04255c7bf3626e239f450200fd0493c1e382263544b20aea6" dependencies = [ + "anstyle", + "bstr", "libc", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", ] [[package]] -name = "anstream" -version = "0.6.21" +name = "async-lock" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", + "event-listener", + "event-listener-strategy", + "pin-project-lite", ] [[package]] -name = "anstyle" -version = "1.0.13" +name = "async-once-cell" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" [[package]] -name = "anstyle-parse" -version = "0.2.7" +name = "async-trait" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ - "utf8parse", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "anstyle-query" -version = "1.1.5" +name = "attribute-derive" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +checksum = "05832cdddc8f2650cc2cc187cc2e952b8c133a48eb055f35211f61ee81502d77" dependencies = [ - "windows-sys 0.61.2", + "attribute-derive-macro", + "derive-where", + "manyhow", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "anstyle-wincon" -version = "3.0.11" +name = "attribute-derive-macro" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +checksum = "0a7cdbbd4bd005c5d3e2e9c885e6fa575db4f4a3572335b974d8db853b6beb61" dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.61.2", + "collection_literals", + "interpolator", + "manyhow", + "proc-macro-utils", + "proc-macro2", + "quote", + "quote-use", + "syn", ] [[package]] -name = "any_spawner" -version = "0.3.0" +name = "autocfg" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1384d3fe1eecb464229fcf6eebb72306591c56bf27b373561489458a7c73027d" -dependencies = [ - "futures", - "thiserror 2.0.18", - "wasm-bindgen-futures", -] +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] -name = "anyhow" -version = "1.0.101" +name = "base16" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" [[package]] -name = "arc-swap" -version = "1.8.1" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ded5f9a03ac8f24d1b8a25101ee812cd32cdc8c50a4c50237de2c4915850e73" -dependencies = [ - "rustversion", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "arrayref" -version = "0.3.9" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "arrayvec" -version = "0.7.6" +name = "bitflags" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] -name = "arrow" -version = "56.2.0" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e833808ff2d94ed40d9379848a950d995043c7fb3e81a30b383f4c6033821cc" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "arrow-arith", - "arrow-array", - "arrow-buffer", - "arrow-cast", - "arrow-csv", - "arrow-data", - "arrow-ipc", - "arrow-json", - "arrow-ord", - "arrow-row", - "arrow-schema", - "arrow-select", - "arrow-string", + "generic-array", ] [[package]] -name = "arrow-arith" -version = "56.2.0" +name = "block-buffer" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad08897b81588f60ba983e3ca39bda2b179bdd84dced378e7df81a5313802ef8" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "chrono", - "num", + "hybrid-array", ] [[package]] -name = "arrow-array" -version = "56.2.0" +name = "bstr" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8548ca7c070d8db9ce7aa43f37393e4bfcf3f2d3681df278490772fd1673d08d" +checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" dependencies = [ - "ahash", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "chrono", - "chrono-tz", - "half", - "hashbrown 0.16.1", - "num", + "memchr", + "regex-automata", + "serde_core", ] [[package]] -name = "arrow-buffer" -version = "56.2.0" +name = "bumpalo" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e003216336f70446457e280807a73899dd822feaf02087d31febca1363e2fccc" -dependencies = [ - "bytes", - "half", - "num", -] +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] -name = "arrow-cast" -version = "56.2.0" +name = "bytes" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919418a0681298d3a77d1a315f625916cb5678ad0d74b9c60108eb15fd083023" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", - "atoi", - "base64", - "chrono", - "comfy-table", - "half", - "lexical-core", - "num", - "ryu", -] +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] -name = "arrow-csv" -version = "56.2.0" +name = "camino" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa9bf02705b5cf762b6f764c65f04ae9082c7cfc4e96e0c33548ee3f67012eb" -dependencies = [ - "arrow-array", - "arrow-cast", - "arrow-schema", - "chrono", - "csv", - "csv-core", - "regex", -] +checksum = "5f2d30e4173c4026932d51d31d6b0613b1fd3014bf3f9f8943d4ba139c437ba0" [[package]] -name = "arrow-data" -version = "56.2.0" +name = "castaway" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5c64fff1d142f833d78897a772f2e5b55b36cb3e6320376f0961ab0db7bd6d0" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" dependencies = [ - "arrow-buffer", - "arrow-schema", - "half", - "num", + "rustversion", ] [[package]] -name = "arrow-ipc" -version = "56.2.0" +name = "cc" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3594dcddccc7f20fd069bc8e9828ce37220372680ff638c5e00dea427d88f5" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", - "flatbuffers", - "lz4_flex", - "zstd", + "find-msvc-tools", + "jobserver", + "libc", + "shlex", ] [[package]] -name = "arrow-json" -version = "56.2.0" +name = "cfg-if" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88cf36502b64a127dc659e3b305f1d993a544eab0d48cce704424e62074dc04b" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-cast", - "arrow-data", - "arrow-schema", - "chrono", - "half", - "indexmap 2.13.0", - "lexical-core", - "memchr", - "num", - "serde", - "serde_json", - "simdutf8", -] +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] -name = "arrow-ord" -version = "56.2.0" +name = "cfg_aliases" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8f82583eb4f8d84d4ee55fd1cb306720cddead7596edce95b50ee418edf66f" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", -] +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] -name = "arrow-row" -version = "56.2.0" +name = "chrono" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d07ba24522229d9085031df6b94605e0f4b26e099fb7cdeec37abd941a73753" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "half", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", ] [[package]] -name = "arrow-schema" -version = "56.2.0" +name = "codee" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3aa9e59c611ebc291c28582077ef25c97f1975383f1479b12f3b9ffee2ffabe" +checksum = "a9dbbdc4b4d349732bc6690de10a9de952bd39ba6a065c586e26600b6b0b91f5" dependencies = [ - "bitflags 2.10.0", "serde", "serde_json", + "thiserror 2.0.18", ] [[package]] -name = "arrow-select" -version = "56.2.0" +name = "collection_literals" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c41dbbd1e97bfcaee4fcb30e29105fb2c75e4d82ae4de70b792a5d3f66b2e7a" -dependencies = [ - "ahash", - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "num", -] +checksum = "2550f75b8cfac212855f6b1885455df8eaee8fe8e246b647d69146142e016084" [[package]] -name = "arrow-string" -version = "56.2.0" +name = "colored" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f5183c150fbc619eede22b861ea7c0eebed8eaac0333eaa7f6da5205fd504d" +checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", - "memchr", - "num", - "regex", - "regex-syntax", + "windows-sys 0.61.2", ] [[package]] -name = "assert_cmd" -version = "2.1.2" +name = "compact_str" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c5bcfa8749ac45dd12cb11055aeeb6b27a3895560d60d71e3c23bf979e60514" +checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab" dependencies = [ - "anstyle", - "bstr", - "libc", - "predicates", - "predicates-core", - "predicates-tree", - "wait-timeout", + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", ] [[package]] -name = "async-channel" +name = "concurrent-queue" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", + "crossbeam-utils", ] [[package]] -name = "async-compression" -version = "0.4.39" +name = "config" +version = "0.15.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68650b7df54f0293fd061972a0fb05aaf4fc0879d3b3d21a638a182c5c543b9f" +checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139" dependencies = [ - "compression-codecs", - "compression-core", - "pin-project-lite", - "tokio", + "convert_case 0.6.0", + "pathdiff", + "serde_core", + "toml", + "winnow", ] [[package]] -name = "async-lock" -version = "3.4.2" +name = "console" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", + "encode_unicode", + "libc", + "unicode-width", + "windows-sys 0.61.2", ] [[package]] -name = "async-once-cell" -version = "0.5.4" +name = "const-oid" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] -name = "async-recursion" -version = "1.1.1" +name = "const-str" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] +checksum = "18f12cc9948ed9604230cdddc7c86e270f9401ccbe3c2e98a4378c5e7632212f" [[package]] -name = "async-stream" -version = "0.3.6" +name = "const_format" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", + "const_format_proc_macros", + "konst", ] [[package]] -name = "async-stream-impl" -version = "0.3.6" +name = "const_format_proc_macros" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "unicode-xid", ] [[package]] -name = "async-trait" -version = "0.1.89" +name = "const_str_slice_concat" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", + "unicode-segmentation", ] [[package]] -name = "async_cell" -version = "0.2.3" +name = "convert_case" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447ab28afbb345f5408b120702a44e5529ebf90b1796ec76e9528df8e288e6c2" +checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" dependencies = [ - "loom", + "unicode-segmentation", ] [[package]] -name = "atoi" -version = "2.0.0" +name = "convert_case_extras" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +checksum = "589c70f0faf8aa9d17787557d5eae854d7755cac50f5c3d12c81d3d57661cebb" dependencies = [ - "num-traits", + "convert_case 0.11.0", ] [[package]] -name = "atomic-waker" -version = "1.1.2" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "attribute-derive" -version = "0.10.5" +name = "cow-utils" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05832cdddc8f2650cc2cc187cc2e952b8c133a48eb055f35211f61ee81502d77" +checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ - "attribute-derive-macro", - "derive-where", - "manyhow", - "proc-macro2", - "quote", - "syn 2.0.114", + "libc", ] [[package]] -name = "attribute-derive-macro" -version = "0.10.5" +name = "cpufeatures" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a7cdbbd4bd005c5d3e2e9c885e6fa575db4f4a3572335b974d8db853b6beb61" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" dependencies = [ - "collection_literals", - "interpolator", - "manyhow", - "proc-macro-utils", - "proc-macro2", - "quote", - "quote-use", - "syn 2.0.114", + "libc", ] [[package]] -name = "autocfg" -version = "1.5.0" +name = "crossbeam-utils" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] -name = "aws-config" -version = "1.8.14" +name = "crypto-common" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a8fc176d53d6fe85017f230405e3255cedb4a02221cb55ed6d76dccbbb099b2" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ - "aws-credential-types", - "aws-runtime", - "aws-sdk-sso", - "aws-sdk-ssooidc", - "aws-sdk-sts", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "hex", - "http 1.4.0", - "ring", - "time", - "tokio", - "tracing", - "url", - "zeroize", + "generic-array", + "typenum", ] [[package]] -name = "aws-credential-types" -version = "1.2.12" +name = "crypto-common" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e26bbf46abc608f2dc61fd6cb3b7b0665497cc259a21520151ed98f8b37d2c79" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "aws-smithy-async", - "aws-smithy-runtime-api", - "aws-smithy-types", - "zeroize", + "hybrid-array", ] [[package]] -name = "aws-lc-rs" -version = "1.16.3" +name = "darling" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "aws-lc-sys", - "zeroize", + "darling_core", + "darling_macro", ] [[package]] -name = "aws-lc-sys" -version = "0.40.0" +name = "darling_core" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", ] [[package]] -name = "aws-runtime" -version = "1.7.0" +name = "darling_macro" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f92058d22a46adf53ec57a6a96f34447daf02bff52e8fb956c66bcd5c6ac12" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "aws-credential-types", - "aws-sigv4", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "bytes-utils", - "fastrand", - "http 1.4.0", - "http-body 1.0.1", - "percent-encoding", - "pin-project-lite", - "tracing", - "uuid", + "darling_core", + "quote", + "syn", ] [[package]] -name = "aws-sdk-sso" -version = "1.94.0" +name = "defmt" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "699da1961a289b23842d88fe2984c6ff68735fdf9bdcbc69ceaeb2491c9bf434" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" dependencies = [ - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.0", - "regex-lite", - "tracing", + "bitflags 1.3.2", + "defmt-macros", ] [[package]] -name = "aws-sdk-ssooidc" -version = "1.96.0" +name = "defmt-macros" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e3a4cb3b124833eafea9afd1a6cc5f8ddf3efefffc6651ef76a03cbc6b4981" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" dependencies = [ - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.0", - "regex-lite", - "tracing", + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "aws-sdk-sts" -version = "1.98.0" +name = "defmt-parser" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89c4f19655ab0856375e169865c91264de965bd74c407c7f1e403184b1049409" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ - "aws-credential-types", - "aws-runtime", - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-json", - "aws-smithy-observability", - "aws-smithy-query", - "aws-smithy-runtime", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-smithy-xml", - "aws-types", - "fastrand", - "http 0.2.12", - "http 1.4.0", - "regex-lite", - "tracing", + "thiserror 2.0.18", ] [[package]] -name = "aws-sigv4" -version = "1.4.0" +name = "deranged" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f6ae9b71597dc5fd115d52849d7a5556ad9265885ad3492ea8d73b93bbc46e" -dependencies = [ - "aws-credential-types", - "aws-smithy-http", - "aws-smithy-runtime-api", - "aws-smithy-types", - "bytes", - "form_urlencoded", - "hex", - "hmac", - "http 0.2.12", - "http 1.4.0", - "percent-encoding", - "sha2", - "time", - "tracing", -] +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" [[package]] -name = "aws-smithy-async" -version = "1.2.12" +name = "derive-where" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cba48474f1d6807384d06fec085b909f5807e16653c5af5c45dfe89539f0b70" +checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" dependencies = [ - "futures-util", - "pin-project-lite", - "tokio", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "aws-smithy-http" -version = "0.63.4" +name = "diff" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4a8a5fe3e4ac7ee871237c340bbce13e982d37543b65700f4419e039f5d78e" -dependencies = [ - "aws-smithy-runtime-api", - "aws-smithy-types", - "bytes", - "bytes-utils", - "futures-core", - "futures-util", - "http 1.4.0", - "http-body 1.0.1", - "http-body-util", - "percent-encoding", - "pin-project-lite", - "pin-utils", - "tracing", -] +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] -name = "aws-smithy-http-client" -version = "1.1.10" +name = "difflib" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0709f0083aa19b704132684bc26d3c868e06bd428ccc4373b0b55c3e8748a58b" -dependencies = [ - "aws-smithy-async", - "aws-smithy-runtime-api", - "aws-smithy-types", - "h2", - "http 1.4.0", - "hyper", - "hyper-rustls", - "hyper-util", - "pin-project-lite", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower", - "tracing", -] +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] -name = "aws-smithy-json" -version = "0.62.4" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b3a779093e18cad88bbae08dc4261e1d95018c4c5b9356a52bcae7c0b6e9bb" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "aws-smithy-types", + "block-buffer 0.10.4", + "crypto-common 0.1.7", ] [[package]] -name = "aws-smithy-observability" -version = "0.2.5" +name = "digest" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3f39d5bb871aaf461d59144557f16d5927a5248a983a40654d9cf3b9ba183b" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "aws-smithy-runtime-api", + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", ] [[package]] -name = "aws-smithy-query" -version = "0.60.14" +name = "dirs" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f76a580e3d8f8961e5d48763214025a2af65c2fa4cd1fb7f270a0e107a71b0" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "aws-smithy-types", - "urlencoding", + "dirs-sys", ] [[package]] -name = "aws-smithy-runtime" -version = "1.10.1" +name = "dirs-sys" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd3dfc18c1ce097cf81fced7192731e63809829c6cbf933c1ec47452d08e1aa" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ - "aws-smithy-async", - "aws-smithy-http", - "aws-smithy-http-client", - "aws-smithy-observability", - "aws-smithy-runtime-api", - "aws-smithy-types", - "bytes", - "fastrand", - "http 0.2.12", - "http 1.4.0", - "http-body 0.4.6", - "http-body 1.0.1", - "http-body-util", - "pin-project-lite", - "pin-utils", - "tokio", - "tracing", + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", ] [[package]] -name = "aws-smithy-runtime-api" -version = "1.11.4" +name = "displaydoc" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c55e0837e9b8526f49e0b9bfa9ee18ddee70e853f5bc09c5d11ebceddcb0fec" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ - "aws-smithy-async", - "aws-smithy-types", - "bytes", - "http 0.2.12", - "http 1.4.0", - "pin-project-lite", - "tokio", - "tracing", - "zeroize", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "aws-smithy-types" -version = "1.4.4" +name = "dragonbox_ecma" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576b0d6991c9c32bc14fc340582ef148311f924d41815f641a308b5d11e8e7cd" -dependencies = [ - "base64-simd", - "bytes", - "bytes-utils", - "http 0.2.12", - "http 1.4.0", - "http-body 0.4.6", - "http-body 1.0.1", - "http-body-util", - "itoa", - "num-integer", - "pin-project-lite", - "pin-utils", - "ryu", - "serde", - "time", -] +checksum = "fd8e701084c37e7ef62d3f9e453b618130cbc0ef3573847785952a3ac3f746bf" [[package]] -name = "aws-smithy-xml" -version = "0.60.14" +name = "drain_filter_polyfill" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53543b4b86ed43f051644f704a98c7291b3618b67adf057ee77a366fa52fcaa" -dependencies = [ - "xmlparser", -] +checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" [[package]] -name = "aws-types" -version = "1.3.12" +name = "dyn-clone" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c50f3cdf47caa8d01f2be4a6663ea02418e892f9bbfd82c7b9a3a37eaccdd3a" -dependencies = [ - "aws-credential-types", - "aws-smithy-async", - "aws-smithy-runtime-api", - "aws-smithy-types", - "rustc_version", - "tracing", -] +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] -name = "axum" -version = "0.8.8" +name = "either" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" -dependencies = [ - "axum-core", - "bytes", - "form_urlencoded", - "futures-util", - "http 1.4.0", - "http-body 1.0.1", - "http-body-util", - "hyper", - "hyper-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "serde_core", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-layer", - "tower-service", - "tracing", -] +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] -name = "axum-core" -version = "0.5.6" +name = "either_of" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +checksum = "5060e0a4cbf26a87550792688ade88e6b8aec9208613631a7a363bda7bc2d4cd" dependencies = [ - "bytes", - "futures-core", - "http 1.4.0", - "http-body 1.0.1", - "http-body-util", - "mime", + "paste", "pin-project-lite", - "sync_wrapper", - "tower-layer", - "tower-service", - "tracing", ] [[package]] -name = "backon" -version = "1.6.0" +name = "encode_unicode" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" -dependencies = [ - "fastrand", - "gloo-timers", - "tokio", -] +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] -name = "base16" -version = "0.2.1" +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "base64" -version = "0.22.1" +name = "erased" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "a1731451909bde27714eacba19c2566362a7f35224f52b153d3f42cf60f72472" [[package]] -name = "base64-simd" -version = "0.8.0" +name = "errno" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ - "outref", - "vsimd", + "libc", + "windows-sys 0.61.2", ] [[package]] -name = "base64ct" -version = "1.8.3" +name = "event-listener" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] [[package]] -name = "bigdecimal" -version = "0.4.10" +name = "event-listener-strategy" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "autocfg", - "libm", - "num-bigint", - "num-integer", - "num-traits", + "event-listener", + "pin-project-lite", ] [[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.10.0" +name = "fastrand" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] -name = "bitpacking" -version = "0.9.3" +name = "file-id" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a7139abd3d9cebf8cd6f920a389cf3dc9576172e32f4563f188cae3c3eb019" +checksum = "e1fc6a637b6dc58414714eddd9170ff187ecb0933d4c7024d1abbd23a3cc26e9" dependencies = [ - "crunchy", + "windows-sys 0.60.2", ] [[package]] -name = "bitvec" -version = "1.0.1" +name = "find-msvc-tools" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] -name = "blake2" -version = "0.10.6" +name = "float-cmp" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" dependencies = [ - "digest", + "num-traits", ] [[package]] -name = "blake3" -version = "1.8.3" +name = "foldhash" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "cpufeatures", -] +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "block-buffer" -version = "0.10.4" +name = "form_urlencoded" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ - "generic-array", + "percent-encoding", ] [[package]] -name = "block-padding" -version = "0.3.3" +name = "fs4" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +checksum = "8640e34b88f7652208ce9e88b1a37a2ae95227d84abec377ccd3c5cfeb141ed4" dependencies = [ - "generic-array", + "rustix", + "windows-sys 0.59.0", ] [[package]] -name = "bon" -version = "3.8.2" +name = "fsevent-sys" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234655ec178edd82b891e262ea7cf71f6584bcd09eff94db786be23f1821825c" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" dependencies = [ - "bon-macros", - "rustversion", + "libc", ] [[package]] -name = "bon-macros" -version = "3.8.2" +name = "futures" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ec27229c38ed0eb3c0feee3d2c1d6a4379ae44f418a29a658890e062d8f365" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ - "darling 0.23.0", - "ident_case", - "prettyplease", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.114", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "brotli" -version = "8.0.2" +name = "futures-channel" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", + "futures-core", + "futures-sink", ] [[package]] -name = "brotli-decompressor" -version = "5.0.0" +name = "futures-core" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] -name = "bstr" -version = "1.12.1" +name = "futures-executor" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ - "memchr", - "regex-automata", - "serde", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "bumpalo" -version = "3.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" - -[[package]] -name = "bytecount" -version = "0.6.9" +name = "futures-io" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] -name = "bytemuck" -version = "1.25.0" +name = "futures-macro" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "byteorder" -version = "1.5.0" +name = "futures-sink" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] -name = "bytes" -version = "1.11.1" +name = "futures-task" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] -name = "bytes-utils" -version = "0.1.4" +name = "futures-util" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ - "bytes", - "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", ] [[package]] -name = "camino" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "castaway" -version = "0.2.4" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "rustversion", + "typenum", + "version_check", ] [[package]] -name = "cbc" -version = "0.1.2" +name = "getrandom" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ - "cipher", + "cfg-if", + "libc", + "wasi", ] [[package]] -name = "cc" -version = "1.2.55" +name = "getrandom" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ - "find-msvc-tools", - "jobserver", + "cfg-if", "libc", - "shlex", + "r-efi 5.3.0", + "wasip2", ] [[package]] -name = "census" -version = "0.4.2" +name = "getrandom" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] [[package]] -name = "cff-parser" -version = "0.1.0" +name = "git2" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f5b6e9141c036f3ff4ce7b2f7e432b0f00dee416ddcd4f17741d189ddc2e9d" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +dependencies = [ + "bitflags 2.13.0", + "libc", + "libgit2-sys", + "log", + "url", +] [[package]] -name = "cfg-if" -version = "1.0.4" +name = "globset" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] [[package]] -name = "cfg_aliases" -version = "0.2.1" +name = "gloo-net" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] [[package]] -name = "chrono" -version = "0.4.43" +name = "gloo-utils" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" dependencies = [ - "iana-time-zone", "js-sys", - "num-traits", "serde", + "serde_json", "wasm-bindgen", - "windows-link", + "web-sys", ] [[package]] -name = "chrono-tz" -version = "0.10.4" +name = "guardian" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" -dependencies = [ - "chrono", - "phf 0.12.1", -] +checksum = "17e2ac29387b1aa07a1e448f7bb4f35b500787971e965b02842b900afa5c8f6f" [[package]] -name = "cipher" -version = "0.4.4" +name = "hashbrown" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ - "crypto-common", - "inout", + "allocator-api2", ] [[package]] -name = "clap" -version = "4.5.58" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806" -dependencies = [ - "clap_builder", - "clap_derive", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "clap_builder" -version = "4.5.58" +name = "hifijson" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] +checksum = "242402749acf71e6f32f5857598b7002c4058a4e3c3b22b4c7d51cab9aea754e" [[package]] -name = "clap_derive" -version = "4.5.55" +name = "html-escape" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.114", + "utf8-width", ] [[package]] -name = "clap_lex" -version = "1.0.0" +name = "http" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] [[package]] -name = "cmake" -version = "0.1.57" +name = "hybrid-array" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" dependencies = [ - "cc", + "typenum", ] [[package]] -name = "codee" -version = "0.3.5" +name = "hydration_context" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dbbdc4b4d349732bc6690de10a9de952bd39ba6a065c586e26600b6b0b91f5" +checksum = "7bbbeb23ee808258cef2c5585ff0dc8e41da21a8dde943f6b290da153a042a96" dependencies = [ + "futures", + "js-sys", + "or_poisoned", + "pin-project-lite", "serde", - "serde_json", - "thiserror 2.0.18", + "throw_error", + "wasm-bindgen", ] [[package]] -name = "collection_literals" -version = "1.0.3" +name = "iana-time-zone" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2550f75b8cfac212855f6b1885455df8eaee8fe8e246b647d69146142e016084" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] [[package]] -name = "colorchoice" -version = "1.0.4" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] [[package]] -name = "colored" -version = "3.1.1" +name = "icu_collections" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ - "windows-sys 0.61.2", + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "comfy-table" -version = "7.1.2" +name = "icu_locale_core" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d05af1e006a2407bedef5af410552494ce5be9090444dbbcb57258c1af3d56" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ - "strum", - "strum_macros", - "unicode-width", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "compact_str" -version = "0.9.0" +name = "icu_normalizer" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", ] [[package]] -name = "compression-codecs" -version = "0.4.36" +name = "icu_normalizer_data" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" + +[[package]] +name = "icu_properties" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ - "compression-core", - "flate2", - "memchr", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", ] [[package]] -name = "compression-core" -version = "0.4.31" +name = "icu_properties_data" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] -name = "concurrent-queue" -version = "2.5.0" +name = "icu_provider" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ - "crossbeam-utils", + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", ] [[package]] -name = "config" -version = "0.15.19" +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30fa8254caad766fc03cb0ccae691e14bf3bd72bfff27f72802ce729551b3d6" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ - "convert_case 0.6.0", - "pathdiff", - "serde_core", - "toml 0.9.12+spec-1.1.0", - "winnow", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "console" -version = "0.16.2" +name = "idna_adapter" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "unicode-width", - "windows-sys 0.61.2", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "console_error_panic_hook" -version = "0.1.7" +name = "indexmap" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ - "cfg-if", - "wasm-bindgen", + "equivalent", + "hashbrown", ] [[package]] -name = "const-oid" -version = "0.9.6" +name = "indicatif" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" +dependencies = [ + "console", + "portable-atomic", + "unicode-width", + "unit-prefix", + "web-time", +] [[package]] -name = "const-random" -version = "0.1.18" +name = "inotify" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +checksum = "533e68a5842e734946fe159fb03fc9bbbb254f590dd0d8ad321ae5ff7beca2c1" dependencies = [ - "const-random-macro", + "bitflags 2.13.0", + "inotify-sys", + "libc", ] [[package]] -name = "const-random-macro" -version = "0.1.16" +name = "inotify-sys" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +checksum = "9ea94e891b3606826e9c998be69ddca42247dad8ad50b1649a5cb7e1c9ae06fd" dependencies = [ - "getrandom 0.2.17", - "once_cell", - "tiny-keccak", + "libc", ] [[package]] -name = "const-str" -version = "0.7.1" +name = "interpolator" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0664d2867b4a32697dfe655557f5c3b187e9b605b38612a748e5ec99811d160" +checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8" [[package]] -name = "const_format" -version = "0.2.35" +name = "inventory" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" dependencies = [ - "const_format_proc_macros", + "rustversion", ] [[package]] -name = "const_format_proc_macros" -version = "0.2.34" +name = "itertools" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "either", ] [[package]] -name = "const_str_slice_concat" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b" - -[[package]] -name = "constant_time_eq" -version = "0.4.2" +name = "itoa" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] -name = "convert_case" -version = "0.6.0" +name = "jaq-core" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "7561783b20275a6c9cb576e39208b0c635f34ef14357f1f05a2927a774f3adec" dependencies = [ - "unicode-segmentation", + "dyn-clone", + "once_cell", + "typed-arena", ] [[package]] -name = "convert_case" -version = "0.8.0" +name = "jaq-json" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +checksum = "d4ec9aaad7340e6990c6c1878ef3b46dbec624e535d7f786cc9ddcf94f773d33" dependencies = [ - "unicode-segmentation", + "bstr", + "bytes", + "foldhash", + "hifijson", + "indexmap", + "jaq-core", + "jaq-std", + "num-bigint", + "num-traits", + "ryu", + "self_cell", ] [[package]] -name = "convert_case" -version = "0.10.0" +name = "jaq-std" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +checksum = "8bdc5a74b0feeb5e6a1dc2dd08c34280a61e37668d10a6a3b27ad69d0fb9ce2e" dependencies = [ - "unicode-segmentation", + "aho-corasick", + "base64", + "bstr", + "jaq-core", + "jiff", + "libm", + "log", + "regex-bites", + "urlencoding", ] [[package]] -name = "core-foundation" -version = "0.9.4" +name = "jiff" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "ccfe6121cbe750cf81efa362d85c0bde7ea298ec43092d3a193baca59cdbd634" dependencies = [ - "core-foundation-sys", - "libc", + "defmt", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", ] [[package]] -name = "core-foundation" -version = "0.10.1" +name = "jiff-static" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +checksum = "e165e897f662d428f3cd3828a919dbe067c2d42bb1031eede74ef9d27ecdedd2" dependencies = [ - "core-foundation-sys", - "libc", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "jiff-tzdb" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "6142247df1a93c2b3587402a19710be3e6e942f1581a1702e76408f2c21d6590" [[package]] -name = "cow-utils" +name = "jiff-tzdb-platform" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "jobserver" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.4", "libc", ] [[package]] -name = "crc32c" -version = "0.6.8" +name = "js-sys" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ - "rustc_version", + "cfg-if", + "futures-util", + "wasm-bindgen", ] [[package]] -name = "crc32fast" -version = "1.5.0" +name = "json-five" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "865f2d01a4549c1fd8c60640c03ae5249eb374cd8cde8b905628d4b1af95c87c" dependencies = [ - "cfg-if", + "serde", + "unicode-general-category", ] [[package]] -name = "crossbeam-channel" -version = "0.5.15" +name = "konst" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" dependencies = [ - "crossbeam-utils", + "konst_macro_rules", ] [[package]] -name = "crossbeam-deque" -version = "0.8.6" +name = "konst_macro_rules" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" [[package]] -name = "crossbeam-epoch" -version = "0.9.18" +name = "kqueue" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5" dependencies = [ - "crossbeam-utils", + "kqueue-sys", + "libc", ] [[package]] -name = "crossbeam-queue" -version = "0.3.12" +name = "kqueue-sys" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "crossbeam-utils", + "bitflags 2.13.0", + "libc", ] [[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "csv" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde_core", -] - -[[package]] -name = "csv-core" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" -dependencies = [ - "memchr", -] - -[[package]] -name = "darling" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" -dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", -] - -[[package]] -name = "darling" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" -dependencies = [ - "darling_core 0.23.0", - "darling_macro 0.23.0", -] - -[[package]] -name = "darling_core" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.114", -] - -[[package]] -name = "darling_core" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" -dependencies = [ - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.114", -] - -[[package]] -name = "darling_macro" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" -dependencies = [ - "darling_core 0.21.3", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "darling_macro" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" -dependencies = [ - "darling_core 0.23.0", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "dashmap" -version = "6.1.0" +name = "leptos" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +checksum = "705e2951f3688e0c4f66bbb7a2702282782dcee716971dbd6209c2619d272479" dependencies = [ + "any_spawner", "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "datafusion" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af15bb3c6ffa33011ef579f6b0bcbe7c26584688bd6c994f548e44df67f011a" -dependencies = [ - "arrow", - "arrow-ipc", - "arrow-schema", - "async-trait", - "bytes", - "chrono", - "datafusion-catalog", - "datafusion-catalog-listing", - "datafusion-common", - "datafusion-common-runtime", - "datafusion-datasource", - "datafusion-datasource-csv", - "datafusion-datasource-json", - "datafusion-execution", - "datafusion-expr", - "datafusion-expr-common", - "datafusion-functions", - "datafusion-functions-aggregate", - "datafusion-functions-nested", - "datafusion-functions-table", - "datafusion-functions-window", - "datafusion-optimizer", - "datafusion-physical-expr", - "datafusion-physical-expr-adapter", - "datafusion-physical-expr-common", - "datafusion-physical-optimizer", - "datafusion-physical-plan", - "datafusion-session", - "datafusion-sql", - "futures", - "itertools 0.14.0", - "log", - "object_store", - "parking_lot", - "rand 0.9.2", - "regex", - "sqlparser", - "tempfile", - "tokio", - "url", - "uuid", -] - -[[package]] -name = "datafusion-catalog" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187622262ad8f7d16d3be9202b4c1e0116f1c9aa387e5074245538b755261621" -dependencies = [ - "arrow", - "async-trait", - "dashmap", - "datafusion-common", - "datafusion-common-runtime", - "datafusion-datasource", - "datafusion-execution", - "datafusion-expr", - "datafusion-physical-expr", - "datafusion-physical-plan", - "datafusion-session", - "datafusion-sql", - "futures", - "itertools 0.14.0", - "log", - "object_store", - "parking_lot", - "tokio", -] - -[[package]] -name = "datafusion-catalog-listing" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9657314f0a32efd0382b9a46fdeb2d233273ece64baa68a7c45f5a192daf0f83" -dependencies = [ - "arrow", - "async-trait", - "datafusion-catalog", - "datafusion-common", - "datafusion-datasource", - "datafusion-execution", - "datafusion-expr", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "datafusion-physical-plan", - "datafusion-session", - "futures", - "log", - "object_store", - "tokio", -] - -[[package]] -name = "datafusion-common" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a83760d9a13122d025fbdb1d5d5aaf93dd9ada5e90ea229add92aa30898b2d1" -dependencies = [ - "ahash", - "arrow", - "arrow-ipc", - "base64", - "chrono", - "half", - "hashbrown 0.14.5", - "indexmap 2.13.0", - "libc", - "log", - "object_store", - "paste", - "sqlparser", - "tokio", - "web-time", -] - -[[package]] -name = "datafusion-common-runtime" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6234a6c7173fe5db1c6c35c01a12b2aa0f803a3007feee53483218817f8b1e" -dependencies = [ - "futures", - "log", - "tokio", -] - -[[package]] -name = "datafusion-datasource" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7256c9cb27a78709dd42d0c80f0178494637209cac6e29d5c93edd09b6721b86" -dependencies = [ - "arrow", - "async-trait", - "bytes", - "chrono", - "datafusion-common", - "datafusion-common-runtime", - "datafusion-execution", - "datafusion-expr", - "datafusion-physical-expr", - "datafusion-physical-expr-adapter", - "datafusion-physical-expr-common", - "datafusion-physical-plan", - "datafusion-session", - "futures", - "glob", - "itertools 0.14.0", - "log", - "object_store", - "rand 0.9.2", - "tokio", - "url", -] - -[[package]] -name = "datafusion-datasource-csv" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64533a90f78e1684bfb113d200b540f18f268134622d7c96bbebc91354d04825" -dependencies = [ - "arrow", - "async-trait", - "bytes", - "datafusion-catalog", - "datafusion-common", - "datafusion-common-runtime", - "datafusion-datasource", - "datafusion-execution", - "datafusion-expr", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "datafusion-physical-plan", - "datafusion-session", - "futures", - "object_store", - "regex", - "tokio", -] - -[[package]] -name = "datafusion-datasource-json" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7ebeb12c77df0aacad26f21b0d033aeede423a64b2b352f53048a75bf1d6e6" -dependencies = [ - "arrow", - "async-trait", - "bytes", - "datafusion-catalog", - "datafusion-common", - "datafusion-common-runtime", - "datafusion-datasource", - "datafusion-execution", - "datafusion-expr", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "datafusion-physical-plan", - "datafusion-session", - "futures", - "object_store", - "serde_json", - "tokio", -] - -[[package]] -name = "datafusion-doc" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ee6b1d9a80d13f9deb2291f45c07044b8e62fb540dbde2453a18be17a36429" - -[[package]] -name = "datafusion-execution" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4cec0a57653bec7b933fb248d3ffa3fa3ab3bd33bd140dc917f714ac036f531" -dependencies = [ - "arrow", - "async-trait", - "dashmap", - "datafusion-common", - "datafusion-expr", + "either_of", "futures", - "log", - "object_store", - "parking_lot", - "rand 0.9.2", - "tempfile", - "url", -] - -[[package]] -name = "datafusion-expr" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef76910bdca909722586389156d0aa4da4020e1631994d50fadd8ad4b1aa05fe" -dependencies = [ - "arrow", - "async-trait", - "chrono", - "datafusion-common", - "datafusion-doc", - "datafusion-expr-common", - "datafusion-functions-aggregate-common", - "datafusion-functions-window-common", - "datafusion-physical-expr-common", - "indexmap 2.13.0", - "paste", - "serde_json", - "sqlparser", -] - -[[package]] -name = "datafusion-expr-common" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d155ccbda29591ca71a1344dd6bed26c65a4438072b400df9db59447f590bb6" -dependencies = [ - "arrow", - "datafusion-common", - "indexmap 2.13.0", - "itertools 0.14.0", - "paste", -] - -[[package]] -name = "datafusion-functions" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de2782136bd6014670fd84fe3b0ca3b3e4106c96403c3ae05c0598577139977" -dependencies = [ - "arrow", - "arrow-buffer", - "base64", - "blake2", - "blake3", - "chrono", - "datafusion-common", - "datafusion-doc", - "datafusion-execution", - "datafusion-expr", - "datafusion-expr-common", - "datafusion-macros", - "hex", - "itertools 0.14.0", - "log", - "md-5", - "rand 0.9.2", - "regex", - "sha2", - "unicode-segmentation", - "uuid", -] - -[[package]] -name = "datafusion-functions-aggregate" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07331fc13603a9da97b74fd8a273f4238222943dffdbbed1c4c6f862a30105bf" -dependencies = [ - "ahash", - "arrow", - "datafusion-common", - "datafusion-doc", - "datafusion-execution", - "datafusion-expr", - "datafusion-functions-aggregate-common", - "datafusion-macros", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "half", - "log", - "paste", -] - -[[package]] -name = "datafusion-functions-aggregate-common" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5951e572a8610b89968a09b5420515a121fbc305c0258651f318dc07c97ab17" -dependencies = [ - "ahash", - "arrow", - "datafusion-common", - "datafusion-expr-common", - "datafusion-physical-expr-common", -] - -[[package]] -name = "datafusion-functions-nested" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdacca9302c3d8fc03f3e94f338767e786a88a33f5ebad6ffc0e7b50364b9ea3" -dependencies = [ - "arrow", - "arrow-ord", - "datafusion-common", - "datafusion-doc", - "datafusion-execution", - "datafusion-expr", - "datafusion-functions", - "datafusion-functions-aggregate", - "datafusion-functions-aggregate-common", - "datafusion-macros", - "datafusion-physical-expr-common", - "itertools 0.14.0", - "log", - "paste", -] - -[[package]] -name = "datafusion-functions-table" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37ff8a99434fbbad604a7e0669717c58c7c4f14c472d45067c4b016621d981" -dependencies = [ - "arrow", - "async-trait", - "datafusion-catalog", - "datafusion-common", - "datafusion-expr", - "datafusion-physical-plan", - "parking_lot", + "hydration_context", + "leptos_config", + "leptos_dom", + "leptos_hot_reload", + "leptos_macro", + "leptos_server", + "oco_ref", + "or_poisoned", "paste", -] - -[[package]] -name = "datafusion-functions-window" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e2aea7c79c926cffabb13dc27309d4eaeb130f4a21c8ba91cdd241c813652b" -dependencies = [ - "arrow", - "datafusion-common", - "datafusion-doc", - "datafusion-expr", - "datafusion-functions-window-common", - "datafusion-macros", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "log", - "paste", -] - -[[package]] -name = "datafusion-functions-window-common" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fead257ab5fd2ffc3b40fda64da307e20de0040fe43d49197241d9de82a487f" -dependencies = [ - "datafusion-common", - "datafusion-physical-expr-common", -] - -[[package]] -name = "datafusion-macros" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec6f637bce95efac05cdfb9b6c19579ed4aa5f6b94d951cfa5bb054b7bb4f730" -dependencies = [ - "datafusion-expr", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "datafusion-optimizer" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6583ef666ae000a613a837e69e456681a9faa96347bf3877661e9e89e141d8a" -dependencies = [ - "arrow", - "chrono", - "datafusion-common", - "datafusion-expr", - "datafusion-expr-common", - "datafusion-physical-expr", - "indexmap 2.13.0", - "itertools 0.14.0", - "log", - "regex", - "regex-syntax", -] - -[[package]] -name = "datafusion-physical-expr" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8668103361a272cbbe3a61f72eca60c9b7c706e87cc3565bcf21e2b277b84f6" -dependencies = [ - "ahash", - "arrow", - "datafusion-common", - "datafusion-expr", - "datafusion-expr-common", - "datafusion-functions-aggregate-common", - "datafusion-physical-expr-common", - "half", - "hashbrown 0.14.5", - "indexmap 2.13.0", - "itertools 0.14.0", - "log", - "parking_lot", - "paste", - "petgraph 0.8.3", -] - -[[package]] -name = "datafusion-physical-expr-adapter" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "815acced725d30601b397e39958e0e55630e0a10d66ef7769c14ae6597298bb0" -dependencies = [ - "arrow", - "datafusion-common", - "datafusion-expr", - "datafusion-functions", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "itertools 0.14.0", -] - -[[package]] -name = "datafusion-physical-expr-common" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6652fe7b5bf87e85ed175f571745305565da2c0b599d98e697bcbedc7baa47c3" -dependencies = [ - "ahash", - "arrow", - "datafusion-common", - "datafusion-expr-common", - "hashbrown 0.14.5", - "itertools 0.14.0", -] - -[[package]] -name = "datafusion-physical-optimizer" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b7d623eb6162a3332b564a0907ba00895c505d101b99af78345f1acf929b5c" -dependencies = [ - "arrow", - "datafusion-common", - "datafusion-execution", - "datafusion-expr", - "datafusion-expr-common", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "datafusion-physical-plan", - "datafusion-pruning", - "itertools 0.14.0", - "log", -] - -[[package]] -name = "datafusion-physical-plan" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2f7f778a1a838dec124efb96eae6144237d546945587557c9e6936b3414558c" -dependencies = [ - "ahash", - "arrow", - "arrow-ord", - "arrow-schema", - "async-trait", - "chrono", - "datafusion-common", - "datafusion-common-runtime", - "datafusion-execution", - "datafusion-expr", - "datafusion-functions-aggregate-common", - "datafusion-functions-window-common", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "futures", - "half", - "hashbrown 0.14.5", - "indexmap 2.13.0", - "itertools 0.14.0", - "log", - "parking_lot", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "datafusion-pruning" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1e59e2ca14fe3c30f141600b10ad8815e2856caa59ebbd0e3e07cd3d127a65" -dependencies = [ - "arrow", - "arrow-schema", - "datafusion-common", - "datafusion-datasource", - "datafusion-expr-common", - "datafusion-physical-expr", - "datafusion-physical-expr-common", - "datafusion-physical-plan", - "itertools 0.14.0", - "log", -] - -[[package]] -name = "datafusion-session" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21ef8e2745583619bd7a49474e8f45fbe98ebb31a133f27802217125a7b3d58d" -dependencies = [ - "arrow", - "async-trait", - "dashmap", - "datafusion-common", - "datafusion-common-runtime", - "datafusion-execution", - "datafusion-expr", - "datafusion-physical-expr", - "datafusion-physical-plan", - "datafusion-sql", - "futures", - "itertools 0.14.0", - "log", - "object_store", - "parking_lot", - "tokio", -] - -[[package]] -name = "datafusion-sql" -version = "50.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89abd9868770386fede29e5a4b14f49c0bf48d652c3b9d7a8a0332329b87d50b" -dependencies = [ - "arrow", - "bigdecimal", - "datafusion-common", - "datafusion-expr", - "indexmap 2.13.0", - "log", - "regex", - "sqlparser", -] - -[[package]] -name = "deepsize" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cdb987ec36f6bf7bfbea3f928b75590b736fc42af8e54d97592481351b2b96c" -dependencies = [ - "deepsize_derive", -] - -[[package]] -name = "deepsize_derive" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990101d41f3bc8c1a45641024377ee284ecc338e5ecf3ea0f0e236d897c72796" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" -dependencies = [ - "powerfmt", - "serde_core", -] - -[[package]] -name = "derive-where" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dirs" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.61.2", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "dlv-list" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" -dependencies = [ - "const-random", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "downcast-rs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc" - -[[package]] -name = "dragonbox_ecma" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8e701084c37e7ef62d3f9e453b618130cbc0ef3573847785952a3ac3f746bf" - -[[package]] -name = "drain_filter_polyfill" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "dyn-clone" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" - -[[package]] -name = "ecb" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a8bfa975b1aec2145850fcaa1c6fe269a16578c44705a532ae3edc92b8881c7" -dependencies = [ - "cipher", -] - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "either_of" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216d23e0ec69759a17f05e1c553f3a6870e5ec73420fbb07807a6f34d5d1d5a4" -dependencies = [ - "paste", - "pin-project-lite", -] - -[[package]] -name = "encode_unicode" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "erased" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1731451909bde27714eacba19c2566362a7f35224f52b153d3f42cf60f72472" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "ethnum" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" - -[[package]] -name = "euclid" -version = "0.20.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb7ef65b3777a325d1eeefefab5b6d4959da54747e33bd6258e789640f307ad" -dependencies = [ - "num-traits", -] - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fast-float2" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8eb564c5c7423d25c886fb561d1e4ee69f72354d16918afa32c08811f6b6a55" - -[[package]] -name = "fastdivide" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afc2bd4d5a73106dd53d10d73d3401c2f32730ba2c0b93ddb888a8983680471" - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "file-id" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc6a637b6dc58414714eddd9170ff187ecb0933d4c7024d1abbd23a3cc26e9" -dependencies = [ - "windows-sys 0.60.2", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - -[[package]] -name = "flatbuffers" -version = "25.12.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" -dependencies = [ - "bitflags 2.10.0", - "rustc_version", -] - -[[package]] -name = "flate2" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "float-cmp" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" -dependencies = [ - "num-traits", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs4" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e180ac76c23b45e767bd7ae9579bc0bb458618c4bc71835926e098e61d15f8" -dependencies = [ - "rustix 0.38.44", - "windows-sys 0.52.0", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "fsevent-sys" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" -dependencies = [ - "libc", -] - -[[package]] -name = "fsst" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2475ce218217196b161b025598f77e2b405d5e729f7c37bfff145f5df00a41" -dependencies = [ - "arrow-array", - "rand 0.9.2", -] - -[[package]] -name = "fst" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" -dependencies = [ - "utf8-ranges", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generator" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" -dependencies = [ - "cc", - "cfg-if", - "libc", - "log", - "rustversion", - "windows-link", - "windows-result", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", - "wasip3", -] - -[[package]] -name = "git2" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" -dependencies = [ - "bitflags 2.10.0", - "libc", - "libgit2-sys", - "log", - "url", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "globset" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "gloo-net" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils", - "http 1.4.0", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror 1.0.69", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-utils" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "guardian" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17e2ac29387b1aa07a1e448f7bb4f35b500787971e965b02842b900afa5c8f6f" - -[[package]] -name = "h2" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.4.0", - "indexmap 2.13.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "half" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" -dependencies = [ - "cfg-if", - "crunchy", - "num-traits", - "zerocopy", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "allocator-api2", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hifijson" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a7763b98ba8a24f59e698bf9ab197e7676c640d6455d1580b4ce7dc560f0f0d" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "html-escape" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" -dependencies = [ - "utf8-width", -] - -[[package]] -name = "htmlescape" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.4.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http 1.4.0", - "http-body 1.0.1", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" - -[[package]] -name = "hydration_context" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8714ae4adeaa846d838f380fbd72f049197de629948f91bf045329e0cf0a283" -dependencies = [ - "futures", - "js-sys", - "once_cell", - "or_poisoned", - "pin-project-lite", - "serde", - "throw_error", - "wasm-bindgen", -] - -[[package]] -name = "hyper" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2", - "http 1.4.0", - "http-body 1.0.1", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http 1.4.0", - "hyper", - "hyper-util", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-util", - "http 1.4.0", - "http-body 1.0.1", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "system-configuration", - "tokio", - "tower-service", - "tracing", - "windows-registry", -] - -[[package]] -name = "hyperloglogplus" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "621debdf94dcac33e50475fdd76d34d5ea9c0362a834b9db08c3024696c1fbe3" -dependencies = [ - "serde", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" -dependencies = [ - "equivalent", - "hashbrown 0.16.1", - "serde", - "serde_core", -] - -[[package]] -name = "indicatif" -version = "0.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88" -dependencies = [ - "console", - "portable-atomic", - "unicode-width", - "unit-prefix", - "web-time", -] - -[[package]] -name = "inotify" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" -dependencies = [ - "bitflags 2.10.0", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "interpolator" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8" - -[[package]] -name = "inventory" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" -dependencies = [ - "rustversion", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" - -[[package]] -name = "jaq-core" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77526a72eb79412c29fd141767a6549bbfcb1cb40e00556fe16532d5e878e098" -dependencies = [ - "dyn-clone", - "once_cell", - "typed-arena", -] - -[[package]] -name = "jaq-json" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01dbdbd07b076e8403abac68ce7744d93e2ecd953bbc44bf77bf00e1e81172bc" -dependencies = [ - "foldhash", - "hifijson", - "indexmap 2.13.0", - "jaq-core", - "jaq-std", -] - -[[package]] -name = "jaq-std" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c264fe397c981705976c71f1bfe020382b9eda52ae950e57fe885e147bdd67d" -dependencies = [ - "aho-corasick", - "base64", - "chrono", - "jaq-core", - "libm", - "log", - "regex-lite", - "urlencoding", -] - -[[package]] -name = "jiff" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89a5b5e10d5a9ad6e5d1f4bd58225f655d6fe9767575a5e8ac5a6fe64e04495" -dependencies = [ - "jiff-static", - "jiff-tzdb-platform", - "log", - "portable-atomic", - "portable-atomic-util", - "serde_core", - "windows-sys 0.61.2", -] - -[[package]] -name = "jiff-static" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff7a39c8862fc1369215ccf0a8f12dd4598c7f6484704359f0351bd617034dbf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "jiff-tzdb" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2" - -[[package]] -name = "jiff-tzdb-platform" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" -dependencies = [ - "jiff-tzdb", -] - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "json-five" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "865f2d01a4549c1fd8c60640c03ae5249eb374cd8cde8b905628d4b1af95c87c" -dependencies = [ - "serde", - "unicode-general-category", -] - -[[package]] -name = "jsonb" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a901f06163d352fbe41c3c2ff5e08b75330a003cc941e988fb501022f5421e6" -dependencies = [ - "byteorder", - "ethnum", - "fast-float2", - "itoa", - "jiff", - "nom 8.0.0", - "num-traits", - "ordered-float", - "rand 0.9.2", - "ryu", - "serde", - "serde_json", -] - -[[package]] -name = "jsonwebtoken" -version = "9.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" -dependencies = [ - "base64", - "js-sys", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "kqueue" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" -dependencies = [ - "kqueue-sys", - "libc", -] - -[[package]] -name = "kqueue-sys" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" -dependencies = [ - "bitflags 1.3.2", - "libc", -] - -[[package]] -name = "lance" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f0ca022d0424d991933a62d2898864cf5621873962bd84e65e7d1f023f9c36" -dependencies = [ - "arrow", - "arrow-arith", - "arrow-array", - "arrow-buffer", - "arrow-ipc", - "arrow-ord", - "arrow-row", - "arrow-schema", - "arrow-select", - "async-recursion", - "async-trait", - "async_cell", - "aws-credential-types", - "byteorder", - "bytes", - "chrono", - "dashmap", - "datafusion", - "datafusion-expr", - "datafusion-functions", - "datafusion-physical-expr", - "datafusion-physical-plan", - "deepsize", - "either", - "futures", - "half", - "humantime", - "itertools 0.13.0", - "lance-arrow", - "lance-core", - "lance-datafusion", - "lance-encoding", - "lance-file", - "lance-index", - "lance-io", - "lance-linalg", - "lance-namespace", - "lance-table", - "log", - "moka", - "object_store", - "permutation", - "pin-project", - "prost", - "prost-types", - "rand 0.9.2", - "roaring", - "semver", - "serde", - "serde_json", - "snafu", - "tantivy 0.24.2", - "tokio", - "tokio-stream", - "tracing", - "url", - "uuid", -] - -[[package]] -name = "lance-arrow" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7552f8d528775bf0ab21e1f75dcb70bdb2a828eeae58024a803b5a4655fd9a11" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-cast", - "arrow-data", - "arrow-schema", - "arrow-select", - "bytes", - "getrandom 0.2.17", - "half", - "jsonb", - "num-traits", - "rand 0.9.2", -] - -[[package]] -name = "lance-bitpacking" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ea14583cc6fa0bb190bcc2d3bc364b0aa545b345702976025f810e4740e8ce" -dependencies = [ - "arrayref", - "paste", - "seq-macro", -] - -[[package]] -name = "lance-core" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69c752dedd207384892006c40930f898d6634e05e3d489e89763abfe4b9307e7" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-schema", - "async-trait", - "byteorder", - "bytes", - "chrono", - "datafusion-common", - "datafusion-sql", - "deepsize", - "futures", - "lance-arrow", - "libc", - "log", - "mock_instant", - "moka", - "num_cpus", - "object_store", - "pin-project", - "prost", - "rand 0.9.2", - "roaring", - "serde_json", - "snafu", - "tempfile", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", - "url", -] - -[[package]] -name = "lance-datafusion" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e1e98ca6e5cd337bdda2d9fb66063f295c0c2852d2bc6831366fea833ee608" -dependencies = [ - "arrow", - "arrow-array", - "arrow-buffer", - "arrow-ord", - "arrow-schema", - "arrow-select", - "async-trait", - "chrono", - "datafusion", - "datafusion-common", - "datafusion-functions", - "datafusion-physical-expr", - "futures", - "jsonb", - "lance-arrow", - "lance-core", - "lance-datagen", - "log", - "pin-project", - "prost", - "snafu", - "tokio", - "tracing", -] - -[[package]] -name = "lance-datagen" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483c643fc2806ed1a2766edf4d180511bbd1d549bcc60373e33f4785c6185891" -dependencies = [ - "arrow", - "arrow-array", - "arrow-cast", - "arrow-schema", - "chrono", - "futures", - "half", - "hex", - "rand 0.9.2", - "rand_xoshiro", - "random_word", -] - -[[package]] -name = "lance-encoding" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a199d1fa3487529c5ffc433fbd1721231330b9350c2ff9b0c7b7dbdb98f0806a" -dependencies = [ - "arrow-arith", - "arrow-array", - "arrow-buffer", - "arrow-cast", - "arrow-data", - "arrow-schema", - "arrow-select", - "bytemuck", - "byteorder", - "bytes", - "fsst", - "futures", - "hex", - "hyperloglogplus", - "itertools 0.13.0", - "lance-arrow", - "lance-bitpacking", - "lance-core", - "log", - "lz4", - "num-traits", - "prost", - "prost-build", - "prost-types", - "rand 0.9.2", - "snafu", - "strum", - "tokio", - "tracing", - "xxhash-rust", - "zstd", -] - -[[package]] -name = "lance-file" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57def2279465232cf5a8cd996300c632442e368745768bbed661c7f0a35334b" -dependencies = [ - "arrow-arith", - "arrow-array", - "arrow-buffer", - "arrow-data", - "arrow-schema", - "arrow-select", - "async-recursion", - "async-trait", - "byteorder", - "bytes", - "datafusion-common", - "deepsize", - "futures", - "lance-arrow", - "lance-core", - "lance-encoding", - "lance-io", - "log", - "num-traits", - "object_store", - "prost", - "prost-build", - "prost-types", - "snafu", - "tokio", - "tracing", -] - -[[package]] -name = "lance-index" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75938c61e986aef8c615dc44c92e4c19e393160a59e2b57402ccfe08c5e63af" -dependencies = [ - "arrow", - "arrow-arith", - "arrow-array", - "arrow-ord", - "arrow-schema", - "arrow-select", - "async-channel", - "async-recursion", - "async-trait", - "bitpacking", - "bitvec", - "bytes", - "crossbeam-queue", - "datafusion", - "datafusion-common", - "datafusion-expr", - "datafusion-physical-expr", - "datafusion-sql", - "deepsize", - "dirs", - "fst", - "futures", - "half", - "itertools 0.13.0", - "jsonb", - "lance-arrow", - "lance-core", - "lance-datafusion", - "lance-datagen", - "lance-encoding", - "lance-file", - "lance-io", - "lance-linalg", - "lance-table", - "libm", - "log", - "ndarray", - "num-traits", - "object_store", - "prost", - "prost-build", - "prost-types", - "rand 0.9.2", - "rand_distr 0.5.1", - "rayon", - "roaring", - "serde", - "serde_json", - "snafu", - "tantivy 0.24.2", - "tempfile", - "tokio", - "tracing", - "twox-hash", - "uuid", -] - -[[package]] -name = "lance-io" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6c3b5b28570d6c951206c5b043f1b35c936928af14fca6f2ac25b0097e4c32" -dependencies = [ - "arrow", - "arrow-arith", - "arrow-array", - "arrow-buffer", - "arrow-cast", - "arrow-data", - "arrow-schema", - "arrow-select", - "async-recursion", - "async-trait", - "aws-config", - "aws-credential-types", - "byteorder", - "bytes", - "chrono", - "deepsize", - "futures", - "lance-arrow", - "lance-core", - "lance-namespace", - "log", - "object_store", - "object_store_opendal", - "opendal", - "path_abs", - "pin-project", - "prost", - "rand 0.9.2", - "serde", - "shellexpand", - "snafu", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "lance-linalg" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3cbc7e85a89ff9cb3a4627559dea3fd1c1fb16c0d8bc46ede75eefef51eec06" -dependencies = [ - "arrow-array", - "arrow-buffer", - "arrow-schema", - "cc", - "deepsize", - "half", - "lance-arrow", - "lance-core", - "num-traits", - "rand 0.9.2", -] - -[[package]] -name = "lance-namespace" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897dd6726816515bb70a698ce7cda44670dca5761637696d7905b45f405a8cd9" -dependencies = [ - "arrow", - "async-trait", - "bytes", - "lance-core", - "lance-namespace-reqwest-client", - "snafu", -] - -[[package]] -name = "lance-namespace-impls" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e3cfcd3ba369de2719abf6fb6233f69cda639eb5cbcb328487a790e745ab988" -dependencies = [ - "arrow", - "arrow-ipc", - "arrow-schema", - "async-trait", - "bytes", - "lance", - "lance-core", - "lance-io", - "lance-namespace", - "object_store", - "reqwest", - "serde_json", - "snafu", - "url", -] - -[[package]] -name = "lance-namespace-reqwest-client" -version = "0.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea349999bcda4eea53fc05d334b3775ec314761e6a706555c777d7a29b18d19" -dependencies = [ - "reqwest", - "serde", - "serde_json", - "serde_repr", - "url", -] - -[[package]] -name = "lance-table" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8facc13760ba034b6c38767b16adba85e44cbcbea8124dc0c63c43865c60630" -dependencies = [ - "arrow", - "arrow-array", - "arrow-buffer", - "arrow-ipc", - "arrow-schema", - "async-trait", - "byteorder", - "bytes", - "chrono", - "deepsize", - "futures", - "lance-arrow", - "lance-core", - "lance-file", - "lance-io", - "log", - "object_store", - "prost", - "prost-build", - "prost-types", - "rand 0.9.2", - "rangemap", - "roaring", - "semver", - "serde", - "serde_json", - "snafu", - "tokio", - "tracing", - "url", - "uuid", -] - -[[package]] -name = "lance-testing" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05052ef86188d6ae6339bdd9f2c5d77190e8ad1158f3dc8a42fa91bde9e5246" -dependencies = [ - "arrow-array", - "arrow-schema", - "lance-arrow", - "num-traits", - "rand 0.9.2", -] - -[[package]] -name = "lancedb" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1da241266792d8caa58005a3deb06ba1388a99350d89b5c904ef6f8de5d936f" -dependencies = [ - "ahash", - "arrow", - "arrow-array", - "arrow-cast", - "arrow-data", - "arrow-ipc", - "arrow-ord", - "arrow-schema", - "arrow-select", - "async-trait", - "bytes", - "chrono", - "datafusion", - "datafusion-catalog", - "datafusion-common", - "datafusion-execution", - "datafusion-expr", - "datafusion-physical-plan", - "futures", - "half", - "lance", - "lance-arrow", - "lance-core", - "lance-datafusion", - "lance-datagen", - "lance-encoding", - "lance-file", - "lance-index", - "lance-io", - "lance-linalg", - "lance-namespace", - "lance-namespace-impls", - "lance-table", - "lance-testing", - "lazy_static", - "log", - "moka", - "num-traits", - "object_store", - "pin-project", - "rand 0.9.2", - "regex", - "semver", - "serde", - "serde_json", - "serde_with", - "snafu", - "tempfile", - "tokio", - "url", - "uuid", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - -[[package]] -name = "leptos" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9569fc37575a5d64c0512145af7630bf651007237ef67a8a77328199d315bb" -dependencies = [ - "any_spawner", - "cfg-if", - "either_of", - "futures", - "hydration_context", - "leptos_config", - "leptos_dom", - "leptos_hot_reload", - "leptos_macro", - "leptos_server", - "oco_ref", - "or_poisoned", - "paste", - "reactive_graph", - "rustc-hash 2.1.1", - "rustc_version", - "send_wrapper", - "serde", - "serde_json", - "serde_qs", - "server_fn", - "slotmap", - "tachys", - "thiserror 2.0.18", - "throw_error", - "typed-builder 0.23.2", - "typed-builder-macro 0.23.2", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm_split_helpers", - "web-sys", -] - -[[package]] -name = "leptos_config" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071fc40aeb9fcab885965bad1887990477253ad51f926cd19068f45a44c59e89" -dependencies = [ - "config", - "regex", - "serde", - "thiserror 2.0.18", - "typed-builder 0.21.2", -] - -[[package]] -name = "leptos_dom" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f4330c88694c5575e0bfe4eecf81b045d14e76a4f8b00d5fd2a63f8779f895" -dependencies = [ - "js-sys", - "or_poisoned", - "reactive_graph", - "send_wrapper", - "tachys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "leptos_hot_reload" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d61ec3e1ff8aaee8c5151688550c0363f85bc37845450764c31ff7584a33f38" -dependencies = [ - "anyhow", - "camino", - "indexmap 2.13.0", - "parking_lot", - "proc-macro2", - "quote", - "rstml", - "serde", - "syn 2.0.114", - "walkdir", -] - -[[package]] -name = "leptos_macro" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86ffd2e9cf3e264e9b3e16bdb086cefa26bd0fa7bc6a26b0cc5f6c1fd3178ed" -dependencies = [ - "attribute-derive", - "cfg-if", - "convert_case 0.10.0", - "html-escape", - "itertools 0.14.0", - "leptos_hot_reload", - "prettyplease", - "proc-macro-error2", - "proc-macro2", - "quote", - "rstml", - "rustc_version", - "server_fn_macro", - "syn 2.0.114", - "uuid", -] - -[[package]] -name = "leptos_server" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf1045af93050bf3388d1c138426393fc131f6d9e46a65519da884c033ed730" -dependencies = [ - "any_spawner", - "base64", - "codee", - "futures", - "hydration_context", - "or_poisoned", - "reactive_graph", - "send_wrapper", - "serde", - "serde_json", - "server_fn", - "tachys", -] - -[[package]] -name = "levenshtein_automata" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" - -[[package]] -name = "lexical-core" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d8d125a277f807e55a77304455eb7b1cb52f2b18c143b60e766c120bd64a594" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a9f232fbd6f550bc0137dcb5f99ab674071ac2d690ac69704593cb4abbea56" -dependencies = [ - "lexical-parse-integer", - "lexical-util", -] - -[[package]] -name = "lexical-parse-integer" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a7a039f8fb9c19c996cd7b2fcce303c1b2874fe1aca544edc85c4a5f8489b34" -dependencies = [ - "lexical-util", -] - -[[package]] -name = "lexical-util" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2604dd126bb14f13fb5d1bd6a66155079cb9fa655b37f875b3a742c705dbed17" - -[[package]] -name = "lexical-write-float" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c438c87c013188d415fbabbb1dceb44249ab81664efbd31b14ae55dabb6361" -dependencies = [ - "lexical-util", - "lexical-write-integer", -] - -[[package]] -name = "lexical-write-integer" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "409851a618475d2d5796377cad353802345cba92c867d9fbcde9cf4eac4e14df" -dependencies = [ - "lexical-util", -] - -[[package]] -name = "libc" -version = "0.2.181" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" - -[[package]] -name = "libgit2-sys" -version = "0.18.3+1.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" -dependencies = [ - "cc", - "libc", - "libz-sys", - "pkg-config", -] - -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - -[[package]] -name = "libredox" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" -dependencies = [ - "bitflags 2.10.0", - "libc", -] - -[[package]] -name = "libz-sys" -version = "1.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linear-map" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee" - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "loctree" -version = "0.8.17" -dependencies = [ - "anyhow", - "assert_cmd", - "chrono", - "colored", - "console", - "dirs", - "git2", - "globset", - "heck", - "indicatif", - "jaq-core", - "jaq-json", - "jaq-std", - "json-five", - "notify", - "notify-debouncer-full", - "once_cell", - "oxc_allocator", - "oxc_ast", - "oxc_ast_visit", - "oxc_parser", - "oxc_semantic", - "oxc_span", - "predicates", - "regex", - "report-leptos", - "rmcp-memex", - "serde", - "serde_json", - "serial_test", - "sha2", - "strsim", - "tempfile", - "time", - "tokio", - "toml 1.0.6+spec-1.1.0", - "urlencoding", - "uuid", - "walkdir", -] - -[[package]] -name = "loctree-mcp" -version = "0.8.17" -dependencies = [ - "anyhow", - "clap", - "libc", - "loctree", - "regex", - "rmcp 0.17.0", - "schemars 1.2.1", - "serde", - "serde_json", - "tempfile", - "thiserror 2.0.18", - "tokio", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "lopdf" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7184fdea2bc3cd272a1acec4030c321a8f9875e877b3f92a53f2f6033fdc289" -dependencies = [ - "aes", - "bitflags 2.10.0", - "cbc", - "ecb", - "encoding_rs", - "flate2", - "getrandom 0.3.4", - "indexmap 2.13.0", - "itoa", - "log", - "md-5", - "nom 8.0.0", - "nom_locate", - "rand 0.9.2", - "rangemap", - "sha2", - "stringprep", - "thiserror 2.0.18", - "ttf-parser", - "weezl", -] - -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.5", -] - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "lz4" -version = "1.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4" -dependencies = [ - "lz4-sys", -] - -[[package]] -name = "lz4-sys" -version = "1.11.1+lz4-1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "lz4_flex" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a" -dependencies = [ - "twox-hash", -] - -[[package]] -name = "manyhow" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587" -dependencies = [ - "manyhow-macros", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "manyhow-macros" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495" -dependencies = [ - "proc-macro-utils", - "proc-macro2", - "quote", -] - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "matchit" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" - -[[package]] -name = "matrixmultiply" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" -dependencies = [ - "autocfg", - "num_cpus", - "once_cell", - "rawpointer", - "thread-tree", -] - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest", -] - -[[package]] -name = "measure_time" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbefd235b0aadd181626f281e1d684e116972988c14c264e42069d5e8a5775cc" -dependencies = [ - "instant", - "log", -] - -[[package]] -name = "measure_time" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51c55d61e72fc3ab704396c5fa16f4c184db37978ae4e94ca8959693a235fc0e" -dependencies = [ - "log", -] - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "memmap2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" -dependencies = [ - "libc", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "minicov" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4869b6a491569605d66d3952bcdf03df789e5b536e5f0cf7758a7f08a55ae24d" -dependencies = [ - "cc", - "walkdir", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "mock_instant" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce6dd36094cac388f119d2e9dc82dc730ef91c32a6222170d630e5414b956e6" - -[[package]] -name = "moka" -version = "0.12.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac832c50ced444ef6be0767a008b02c106a909ba79d1d830501e94b96f6b7e" -dependencies = [ - "async-lock", - "crossbeam-channel", - "crossbeam-epoch", - "crossbeam-utils", - "equivalent", - "event-listener", - "futures-util", - "parking_lot", - "portable-atomic", - "smallvec", - "tagptr", - "uuid", -] - -[[package]] -name = "multimap" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" - -[[package]] -name = "murmurhash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe 0.1.6", - "openssl-sys", - "schannel", - "security-framework 2.11.1", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndarray" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" -dependencies = [ - "matrixmultiply", - "num-complex", - "num-integer", - "num-traits", - "portable-atomic", - "portable-atomic-util", - "rawpointer", -] - -[[package]] -name = "next_tuple" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60993920e071b0c9b66f14e2b32740a4e27ffc82854dcd72035887f336a09a28" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nom" -version = "8.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" -dependencies = [ - "memchr", -] - -[[package]] -name = "nom_locate" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b577e2d69827c4740cba2b52efaad1c4cc7c73042860b199710b3575c68438d" -dependencies = [ - "bytecount", - "memchr", - "nom 8.0.0", -] - -[[package]] -name = "nonmax" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[package]] -name = "notify" -version = "8.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" -dependencies = [ - "bitflags 2.10.0", - "fsevent-sys", - "inotify", - "kqueue", - "libc", - "log", - "mio", - "notify-types", - "walkdir", - "windows-sys 0.60.2", -] - -[[package]] -name = "notify-debouncer-full" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02b49179cfebc9932238d04d6079912d26de0379328872846118a0fa0dbb302" -dependencies = [ - "file-id", - "log", - "notify", - "notify-types", - "walkdir", -] - -[[package]] -name = "notify-types" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" -dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-bigint-dig" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" -dependencies = [ - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object_store" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbfbfff40aeccab00ec8a910b57ca8ecf4319b335c542f2edcd19dd25a1e2a00" -dependencies = [ - "async-trait", - "base64", - "bytes", - "chrono", - "form_urlencoded", - "futures", - "http 1.4.0", - "http-body-util", - "httparse", - "humantime", - "hyper", - "itertools 0.14.0", - "md-5", - "parking_lot", - "percent-encoding", - "quick-xml 0.38.4", - "rand 0.9.2", - "reqwest", - "ring", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "thiserror 2.0.18", - "tokio", - "tracing", - "url", - "walkdir", - "wasm-bindgen-futures", - "web-time", -] - -[[package]] -name = "object_store_opendal" -version = "0.54.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b88fc0e0c4890c1d99e2b8c519c5db40f7d9b69a0f562ff1ad4967a4c8bbc6" -dependencies = [ - "async-trait", - "bytes", - "futures", - "object_store", - "opendal", - "pin-project", - "tokio", -] - -[[package]] -name = "oco_ref" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0423ff9973dea4d6bd075934fdda86ebb8c05bdf9d6b0507067d4a1226371d" -dependencies = [ - "serde", - "thiserror 2.0.18", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - -[[package]] -name = "oneshot" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269bca4c2591a28585d6bf10d9ed0332b7d76900a1b02bec41bdc3a2cdcda107" - -[[package]] -name = "oorandom" -version = "11.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" - -[[package]] -name = "opendal" -version = "0.54.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42afda58fa2cf50914402d132cc1caacff116a85d10c72ab2082bb7c50021754" -dependencies = [ - "anyhow", - "backon", - "base64", - "bytes", - "chrono", - "crc32c", - "futures", - "getrandom 0.2.17", - "http 1.4.0", - "http-body 1.0.1", - "log", - "md-5", - "percent-encoding", - "quick-xml 0.38.4", - "reqsign", - "reqwest", - "serde", - "serde_json", - "sha2", - "tokio", - "uuid", -] - -[[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-sys" -version = "0.9.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "or_poisoned" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c04f5d74368e4d0dfe06c45c8627c81bd7c317d52762d118fb9b3076f6420fd" - -[[package]] -name = "ordered-float" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" -dependencies = [ - "num-traits", -] - -[[package]] -name = "ordered-multimap" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" -dependencies = [ - "dlv-list", - "hashbrown 0.14.5", -] - -[[package]] -name = "outref" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" - -[[package]] -name = "ownedbytes" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a059efb063b8f425b948e042e6b9bd85edfe60e913630ed727b23e2dfcc558" -dependencies = [ - "stable_deref_trait", -] - -[[package]] -name = "ownedbytes" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbd56f7631767e61784dc43f8580f403f4475bd4aaa4da003e6295e1bab4a7e" -dependencies = [ - "stable_deref_trait", -] - -[[package]] -name = "owo-colors" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" - -[[package]] -name = "oxc-miette" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a7ba54c704edefead1f44e9ef09c43e5cfae666bdc33516b066011f0e6ebf7" -dependencies = [ - "cfg-if", - "owo-colors", - "oxc-miette-derive", - "textwrap", - "thiserror 2.0.18", - "unicode-segmentation", - "unicode-width", -] - -[[package]] -name = "oxc-miette-derive" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4faecb54d0971f948fbc1918df69b26007e6f279a204793669542e1e8b75eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "oxc_allocator" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d4295cf7888893b80ae70ff65c078ae3f9f52d5381cfc7eeffab089e07305" -dependencies = [ - "allocator-api2", - "hashbrown 0.16.1", - "oxc_data_structures", - "rustc-hash 2.1.1", -] - -[[package]] -name = "oxc_ast" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be755331a7de00100c60e03151663f26037a0dd720be238de57c036be03b4033" -dependencies = [ - "bitflags 2.10.0", - "oxc_allocator", - "oxc_ast_macros", - "oxc_data_structures", - "oxc_diagnostics", - "oxc_estree", - "oxc_regular_expression", - "oxc_span", - "oxc_syntax", -] - -[[package]] -name = "oxc_ast_macros" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13a58adcfaadd4710b4f7d80ad422599ed5bb4956f4747d07e821c5897b16ef" -dependencies = [ - "phf 0.13.1", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "oxc_ast_visit" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e33ffb874949ea07fce9b686c2dba7e221c849e047232c04a84b13bae4496ef" -dependencies = [ - "oxc_allocator", - "oxc_ast", - "oxc_span", - "oxc_syntax", -] - -[[package]] -name = "oxc_data_structures" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6c22a48542899e5f74162d55710ea2f95735c5d3a809196308b2dbf557f434" - -[[package]] -name = "oxc_diagnostics" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5961a78ce2a24d288f5e7090f19ce49d062486e0d65e6140d01582198c94fd" -dependencies = [ - "cow-utils", - "oxc-miette", - "percent-encoding", -] - -[[package]] -name = "oxc_ecmascript" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb3d121c372df31514f95d87c92693001739d2c9e56be37909499b5396faf1" -dependencies = [ - "cow-utils", - "num-bigint", - "num-traits", - "oxc_allocator", - "oxc_ast", - "oxc_regular_expression", - "oxc_span", - "oxc_syntax", -] - -[[package]] -name = "oxc_estree" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38fc12975751e104dc53c369cba1598ff15aa8ca30aaac49e63937256316969" - -[[package]] -name = "oxc_index" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3e6120999627ec9703025eab7c9f410ebb7e95557632a8902ca48210416c2b" -dependencies = [ - "nonmax", - "serde", -] - -[[package]] -name = "oxc_parser" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "341602ba5eb6629f7f90e49c1fce06bb8eed989412a4178acd8e7f48cf2c7f9d" -dependencies = [ - "bitflags 2.10.0", - "cow-utils", - "memchr", - "num-bigint", - "num-traits", - "oxc_allocator", - "oxc_ast", - "oxc_data_structures", - "oxc_diagnostics", - "oxc_ecmascript", - "oxc_regular_expression", - "oxc_span", - "oxc_syntax", - "rustc-hash 2.1.1", - "seq-macro", -] - -[[package]] -name = "oxc_regular_expression" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e810182cbde172aeada70acc45dae74f6773384e0d295cc27e6e377b1fc277c" -dependencies = [ - "bitflags 2.10.0", - "oxc_allocator", - "oxc_ast_macros", - "oxc_diagnostics", - "oxc_span", - "phf 0.13.1", - "rustc-hash 2.1.1", - "unicode-id-start", -] - -[[package]] -name = "oxc_semantic" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb04bd9f59bb6d8340bb186b0003bb6e8f1988e17048c61a5473ea216e9ed71" -dependencies = [ - "itertools 0.14.0", - "memchr", - "oxc_allocator", - "oxc_ast", - "oxc_ast_visit", - "oxc_data_structures", - "oxc_diagnostics", - "oxc_ecmascript", - "oxc_index", - "oxc_span", - "oxc_syntax", - "rustc-hash 2.1.1", - "self_cell", - "smallvec", -] - -[[package]] -name = "oxc_span" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9999ef787b0b989b8c2b31669069d3bdca20d017ff34a7284ff9e983cf7b1d8" -dependencies = [ - "compact_str", - "oxc-miette", - "oxc_allocator", - "oxc_ast_macros", - "oxc_estree", - "oxc_str", -] - -[[package]] -name = "oxc_str" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6fde66bc256ea0d09895c2a56a24f79e76abffd977f6c171516e42f1efdea51" -dependencies = [ - "compact_str", - "hashbrown 0.16.1", - "oxc_allocator", - "oxc_estree", -] - -[[package]] -name = "oxc_syntax" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77ea5bd4ea42ce05b2f51bcef8e46a4598cea5038ab25877a2d27601a90da83" -dependencies = [ - "bitflags 2.10.0", - "cow-utils", - "dragonbox_ecma", - "nonmax", - "oxc_allocator", - "oxc_ast_macros", - "oxc_estree", - "oxc_index", - "oxc_span", - "phf 0.13.1", - "unicode-id-start", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pastey" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec" - -[[package]] -name = "path_abs" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ef02f6342ac01d8a93b65f96db53fe68a92a15f41144f97fb00a9e669633c3" -dependencies = [ - "serde", - "serde_derive", - "std_prelude", - "stfu8", -] - -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest", - "hmac", -] - -[[package]] -name = "pdf-extract" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28ba1758a3d3f361459645780e09570b573fc3c82637449e9963174c813a98" -dependencies = [ - "adobe-cmap-parser", - "cff-parser", - "encoding_rs", - "euclid", - "log", - "lopdf", - "postscript", - "type1-encoding-parser", - "unicode-normalization", -] - -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64", - "serde_core", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "permutation" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df202b0b0f5b8e389955afd5f27b007b00fb948162953f1db9c70d2c7e3157d7" - -[[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap 2.13.0", -] - -[[package]] -name = "petgraph" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" -dependencies = [ - "fixedbitset", - "hashbrown 0.15.5", - "indexmap 2.13.0", - "serde", -] - -[[package]] -name = "phf" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" -dependencies = [ - "phf_shared 0.12.1", -] - -[[package]] -name = "phf" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" -dependencies = [ - "phf_macros", - "phf_shared 0.13.1", - "serde", -] - -[[package]] -name = "phf_generator" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" -dependencies = [ - "fastrand", - "phf_shared 0.13.1", -] - -[[package]] -name = "phf_macros" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" -dependencies = [ - "phf_generator", - "phf_shared 0.13.1", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "phf_shared" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs5" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" -dependencies = [ - "aes", - "cbc", - "der", - "pbkdf2", - "scrypt", - "sha2", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "pkcs5", - "rand_core 0.6.4", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "pom" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f6ce597ecdcc9a098e7fddacb1065093a3d66446fa16c675e7e71d1b5c28e6" - -[[package]] -name = "portable-atomic" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" - -[[package]] -name = "portable-atomic-util" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "postscript" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78451badbdaebaf17f053fd9152b3ffb33b516104eacb45e7864aaa9c712f306" - -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "predicates" -version = "3.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" -dependencies = [ - "anstyle", - "difflib", - "float-cmp", - "normalize-line-endings", - "predicates-core", - "regex", -] - -[[package]] -name = "predicates-core" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" - -[[package]] -name = "predicates-tree" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "pretty_assertions" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" -dependencies = [ - "diff", - "yansi", -] - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.114", -] - -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "proc-macro-utils" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071" -dependencies = [ - "proc-macro2", - "quote", - "smallvec", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", - "version_check", - "yansi", -] - -[[package]] -name = "prost" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" -dependencies = [ - "heck", - "itertools 0.14.0", - "log", - "multimap", - "once_cell", - "petgraph 0.7.1", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn 2.0.114", - "tempfile", -] - -[[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]] -name = "prost-types" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" -dependencies = [ - "prost", -] - -[[package]] -name = "protoc-bin-vendored" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa" -dependencies = [ - "protoc-bin-vendored-linux-aarch_64", - "protoc-bin-vendored-linux-ppcle_64", - "protoc-bin-vendored-linux-s390_64", - "protoc-bin-vendored-linux-x86_32", - "protoc-bin-vendored-linux-x86_64", - "protoc-bin-vendored-macos-aarch_64", - "protoc-bin-vendored-macos-x86_64", - "protoc-bin-vendored-win32", -] - -[[package]] -name = "protoc-bin-vendored-linux-aarch_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c" - -[[package]] -name = "protoc-bin-vendored-linux-ppcle_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c" - -[[package]] -name = "protoc-bin-vendored-linux-s390_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0" - -[[package]] -name = "protoc-bin-vendored-linux-x86_32" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5" - -[[package]] -name = "protoc-bin-vendored-linux-x86_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78" - -[[package]] -name = "protoc-bin-vendored-macos-aarch_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092" - -[[package]] -name = "protoc-bin-vendored-macos-x86_64" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756" - -[[package]] -name = "protoc-bin-vendored-win32" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3" - -[[package]] -name = "quick-xml" -version = "0.37.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "quick-xml" -version = "0.38.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" -dependencies = [ - "memchr", + "reactive_graph", + "rustc-hash", + "rustc_version", + "send_wrapper", "serde", + "serde_json", + "serde_qs", + "server_fn", + "slotmap", + "tachys", + "thiserror 2.0.18", + "throw_error", + "typed-builder", + "typed-builder-macro", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm_split_helpers", + "web-sys", ] [[package]] -name = "quinn" -version = "0.11.9" +name = "leptos_config" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c06f751315bccc0d193fab302ac01d25bcfcd97474d4676440e7e3250dc3fc3" dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.1.1", - "rustls", - "socket2", + "config", + "regex", + "serde", "thiserror 2.0.18", - "tokio", - "tracing", - "web-time", + "typed-builder", ] [[package]] -name = "quinn-proto" -version = "0.11.14" +name = "leptos_dom" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "35742e9ed8f8aaf9e549b454c68a7ac0992536e06856365639b111f72ab07884" dependencies = [ - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash 2.1.1", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.18", - "tinyvec", - "tracing", - "web-time", + "js-sys", + "or_poisoned", + "reactive_graph", + "send_wrapper", + "tachys", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "quinn-udp" -version = "0.5.14" +name = "leptos_hot_reload" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "9d2a0f220c8a5ef3c51199dfb9cdd702bc0eb80d52fbe70c7890adfaaae8a4b1" dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", + "anyhow", + "camino", + "indexmap", + "or_poisoned", + "proc-macro2", + "quote", + "rstml", + "serde", + "syn", + "walkdir", ] [[package]] -name = "quote" -version = "1.0.44" +name = "leptos_macro" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "96de6e8da9d4f1a7b74b447b317d590ebabb38709f588f7ee20564b773ccbcce" dependencies = [ + "attribute-derive", + "cfg-if", + "convert_case 0.11.0", + "convert_case_extras", + "html-escape", + "itertools", + "leptos_hot_reload", + "prettyplease", + "proc-macro-error2", "proc-macro2", + "quote", + "rstml", + "rustc_version", + "server_fn_macro", + "syn", + "uuid", ] [[package]] -name = "quote-use" -version = "0.8.4" +name = "leptos_server" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e" +checksum = "da974775c5ccbb6bd64be7f53f75e8321542e28f21563a416574dbe4d5447eae" dependencies = [ - "quote", - "quote-use-macros", + "any_spawner", + "base64", + "codee", + "futures", + "hydration_context", + "or_poisoned", + "reactive_graph", + "send_wrapper", + "serde", + "serde_json", + "server_fn", + "tachys", ] [[package]] -name = "quote-use-macros" -version = "0.8.4" +name = "libc" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35" -dependencies = [ - "proc-macro-utils", - "proc-macro2", - "quote", - "syn 2.0.114", -] +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] -name = "r-efi" -version = "5.3.0" +name = "libgit2-sys" +version = "0.18.5+1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "005d6ae6eac1912906073e069f7db60b1fa98e052a68227824afe3e3a1c59ca2" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] [[package]] -name = "radium" -version = "0.7.0" +name = "libm" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] -name = "rand" -version = "0.8.5" +name = "libredox" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", ] [[package]] -name = "rand" -version = "0.9.2" +name = "libz-sys" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "linux-raw-sys" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] -name = "rand_chacha" -version = "0.9.0" +name = "litemap" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] -name = "rand_core" -version = "0.6.4" +name = "lock_api" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "getrandom 0.2.17", + "scopeguard", ] [[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +name = "loctree" +version = "0.13.0" dependencies = [ - "getrandom 0.3.4", + "anyhow", + "assert_cmd", + "chrono", + "colored", + "console", + "dirs", + "fs4", + "git2", + "globset", + "heck", + "indicatif", + "jaq-core", + "jaq-json", + "jaq-std", + "json-five", + "libc", + "loctree-ast", + "notify", + "notify-debouncer-full", + "once_cell", + "oxc_allocator", + "oxc_ast", + "oxc_ast_visit", + "oxc_parser", + "oxc_semantic", + "oxc_span", + "predicates", + "prost", + "regex", + "report-leptos", + "rmcp", + "schemars", + "serde", + "serde_json", + "serde_yaml", + "serial_test", + "sha2 0.11.0", + "strsim", + "tempfile", + "time", + "tokio", + "toml", + "tree-sitter", + "tree-sitter-c", + "tree-sitter-cpp", + "tree-sitter-objc", + "tree-sitter-swift", + "urlencoding", + "uuid", + "walkdir", ] [[package]] -name = "rand_distr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +name = "loctree-ast" +version = "0.13.0" dependencies = [ - "num-traits", - "rand 0.8.5", + "thiserror 2.0.18", + "tree-sitter", + "tree-sitter-javascript", + "tree-sitter-python", + "tree-sitter-typescript", ] [[package]] -name = "rand_distr" -version = "0.5.1" +name = "log" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" -dependencies = [ - "num-traits", - "rand 0.9.2", -] +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] -name = "rand_xoshiro" -version = "0.7.0" +name = "manyhow" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587" dependencies = [ - "rand_core 0.9.5", + "manyhow-macros", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "random_word" -version = "0.5.2" +name = "manyhow-macros" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47a395bdb55442b883c89062d6bcff25dc90fa5f8369af81e0ac6d49d78cf81" +checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495" dependencies = [ - "ahash", - "brotli", - "paste", - "rand 0.9.2", - "unicase", + "proc-macro-utils", + "proc-macro2", + "quote", ] [[package]] -name = "rangemap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" - -[[package]] -name = "rawpointer" -version = "0.2.1" +name = "memchr" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] -name = "rayon" -version = "1.11.0" +name = "mio" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ - "either", - "rayon-core", + "libc", + "log", + "wasi", + "windows-sys 0.61.2", ] [[package]] -name = "rayon-core" -version = "1.13.0" +name = "next_tuple" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] +checksum = "60993920e071b0c9b66f14e2b32740a4e27ffc82854dcd72035887f336a09a28" [[package]] -name = "reactive_graph" -version = "0.2.12" +name = "nix" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f0df355582937223ea403e52490201d65295bd6981383c69bfae5a1f8730c2" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "any_spawner", - "async-lock", - "futures", - "guardian", - "hydration_context", - "indexmap 2.13.0", - "or_poisoned", - "paste", - "pin-project-lite", - "rustc-hash 2.1.1", - "rustc_version", - "send_wrapper", - "serde", - "slotmap", - "thiserror 2.0.18", - "web-sys", + "bitflags 2.13.0", + "cfg-if", + "cfg_aliases", + "libc", ] [[package]] -name = "reactive_stores" -version = "0.3.1" +name = "nonmax" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35372f05664a62a3dd389503371a15b8feb3396f99f6ec000de651fddb030942" -dependencies = [ - "dashmap", - "guardian", - "itertools 0.14.0", - "or_poisoned", - "paste", - "reactive_graph", - "reactive_stores_macro", - "rustc-hash 2.1.1", - "send_wrapper", -] +checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" [[package]] -name = "reactive_stores_macro" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa40919eb2975100283b2a70e68eafce1e8bcf81f0622ff168e4c2b3f8d46bb" -dependencies = [ - "convert_case 0.8.0", - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.114", -] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "notify" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.13.0", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.60.2", ] [[package]] -name = "redox_users" -version = "0.5.2" +name = "notify-debouncer-full" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "c02b49179cfebc9932238d04d6079912d26de0379328872846118a0fa0dbb302" dependencies = [ - "getrandom 0.2.17", - "libredox", - "thiserror 2.0.18", + "file-id", + "log", + "notify", + "notify-types", + "walkdir", ] [[package]] -name = "ref-cast" -version = "1.0.25" +name = "notify-types" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "ref-cast-impl", + "bitflags 2.13.0", ] [[package]] -name = "ref-cast-impl" -version = "1.0.25" +name = "num-bigint" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +checksum = "c863e9ab5e7bf9c99ba75e1050f1e4d624ae87ed3532d6238ffbdc7b585dbbe6" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", + "num-integer", + "num-traits", ] [[package]] -name = "regex" -version = "1.12.3" +name = "num-conv" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] -name = "regex-automata" -version = "0.4.14" +name = "num-integer" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "num-traits", ] [[package]] -name = "regex-lite" -version = "0.1.9" +name = "num-traits" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] [[package]] -name = "regex-syntax" -version = "0.8.9" +name = "oco_ref" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" - -[[package]] -name = "report-leptos" -version = "0.8.17" +checksum = "ed0423ff9973dea4d6bd075934fdda86ebb8c05bdf9d6b0507067d4a1226371d" dependencies = [ - "leptos", - "pretty_assertions", "serde", - "serde_json", + "thiserror 2.0.18", ] [[package]] -name = "report-wasm" -version = "0.8.17" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "report-leptos", - "serde", - "serde_json", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] -name = "reqsign" -version = "0.16.5" +name = "option-ext" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43451dbf3590a7590684c25fb8d12ecdcc90ed3ac123433e500447c7d77ed701" -dependencies = [ - "anyhow", - "async-trait", - "base64", - "chrono", - "form_urlencoded", - "getrandom 0.2.17", - "hex", - "hmac", - "home", - "http 1.4.0", - "jsonwebtoken", - "log", - "once_cell", - "percent-encoding", - "quick-xml 0.37.5", - "rand 0.8.5", - "reqwest", - "rsa", - "rust-ini", - "serde", - "serde_json", - "sha1", - "sha2", - "tokio", -] +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] -name = "reqwest" -version = "0.12.28" +name = "or_poisoned" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http 1.4.0", - "http-body 1.0.1", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "js-sys", - "log", - "mime", - "mime_guess", - "native-tls", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tokio-rustls", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", -] +checksum = "8c04f5d74368e4d0dfe06c45c8627c81bd7c317d52762d118fb9b3076f6420fd" [[package]] -name = "ring" -version = "0.17.14" +name = "owo-colors" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] +checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] -name = "rmcp" -version = "0.12.0" +name = "oxc-miette" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528d42f8176e6e5e71ea69182b17d1d0a19a6b3b894b564678b74cd7cab13cfa" +checksum = "4356a61f2ed4c9b3610245215fbf48970eb277126919f87db9d0efa93a74245c" dependencies = [ - "async-trait", - "base64", - "chrono", - "futures", - "pastey", - "pin-project-lite", - "rmcp-macros 0.12.0", - "schemars 1.2.1", - "serde", - "serde_json", + "cfg-if", + "owo-colors", + "oxc-miette-derive", + "textwrap", "thiserror 2.0.18", - "tokio", - "tokio-util", - "tracing", + "unicode-segmentation", + "unicode-width", ] [[package]] -name = "rmcp" -version = "0.17.0" +name = "oxc-miette-derive" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0ce46f9101dc911f07e1468084c057839d15b08040d110820c5513312ef56a" +checksum = "b237422b014f8f8fff75bb9379e697d13f8d57551a22c88bebb39f073c1bf696" dependencies = [ - "async-trait", - "base64", - "chrono", - "futures", - "pastey", - "pin-project-lite", - "rmcp-macros 0.17.0", - "schemars 1.2.1", - "serde", - "serde_json", - "thiserror 2.0.18", - "tokio", - "tokio-util", - "tracing", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "rmcp-common" -version = "0.8.17" +name = "oxc_allocator" +version = "0.128.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b554cc48bdde5684b8a2bf3355524694ee47d9de4246eaf6199b8aecfd952cb" dependencies = [ - "serde", - "serde_json", + "allocator-api2", + "hashbrown", + "oxc_data_structures", + "rustc-hash", ] [[package]] -name = "rmcp-macros" -version = "0.12.0" +name = "oxc_ast" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f81daaa494eb8e985c9462f7d6ce1ab05e5299f48aafd76cdd3d8b060e6f59" +checksum = "d027d8f8b23257e1711e0db8b80c9dacb3ab567a3357b4560eaa1d0a04da2d30" dependencies = [ - "darling 0.23.0", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.114", + "bitflags 2.13.0", + "oxc_allocator", + "oxc_ast_macros", + "oxc_data_structures", + "oxc_diagnostics", + "oxc_estree", + "oxc_regular_expression", + "oxc_span", + "oxc_str", + "oxc_syntax", ] [[package]] -name = "rmcp-macros" -version = "0.17.0" +name = "oxc_ast_macros" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abad6f5f46e220e3bda2fc90fd1ad64c1c2a2bd716d52c845eb5c9c64cda7542" +checksum = "340ac9cb05bc9963811e3dc1585b85618471cc339d0ab0072d097dd85d78d09e" dependencies = [ - "darling 0.23.0", + "phf", "proc-macro2", "quote", - "serde_json", - "syn 2.0.114", + "syn", ] [[package]] -name = "rmcp-memex" -version = "0.3.6" +name = "oxc_ast_visit" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b8c2946c389624223ffaf4f0c8720615251dcd82ee81c944f6c91f61e11030b" +checksum = "cf96f11ef5a8152aadd004616f4a91405cedab5e081f9fc816bcc02019d5f8db" dependencies = [ - "anyhow", - "arrow-array", - "arrow-schema", - "async-stream", - "axum", - "chrono", - "futures", - "glob", - "lancedb", - "lazy_static", - "pdf-extract", - "protoc-bin-vendored", - "regex", - "reqwest", - "rmcp 0.12.0", - "serde", - "serde_json", - "sha2", - "shellexpand", - "tantivy 0.22.1", - "tokio", - "tokio-stream", - "toml 0.8.23", - "tower-http", - "tracing", - "tracing-subscriber", - "uuid", - "walkdir", + "oxc_allocator", + "oxc_ast", + "oxc_span", + "oxc_syntax", ] [[package]] -name = "roaring" -version = "0.10.12" +name = "oxc_data_structures" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e8d2cfa184d94d0726d650a9f4a1be7f9b76ac9fdb954219878dc00c1c1e7b" -dependencies = [ - "bytemuck", - "byteorder", -] +checksum = "c425cdc1a05603d9b6d13786892d69364a0c18de06ffa511109a9e0a760b423c" [[package]] -name = "rsa" -version = "0.9.10" +name = "oxc_diagnostics" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +checksum = "fa06c0bec3b31c76e6b30b935f80dd3b29c01bf0d0fbc13b5b8f3eca508ad9ee" dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "sha2", - "signature", - "spki", - "subtle", - "zeroize", + "cow-utils", + "oxc-miette", + "percent-encoding", ] [[package]] -name = "rstml" -version = "0.12.1" +name = "oxc_ecmascript" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61cf4616de7499fc5164570d40ca4e1b24d231c6833a88bff0fe00725080fd56" +checksum = "c675d7ad122e907016b6b7eb3e01228f313e6ff59f2a49d35d230ce214a8be9d" dependencies = [ - "derive-where", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.114", - "syn_derive", - "thiserror 2.0.18", + "cow-utils", + "num-bigint", + "num-traits", + "oxc_allocator", + "oxc_ast", + "oxc_regular_expression", + "oxc_span", + "oxc_syntax", ] [[package]] -name = "rust-ini" -version = "0.21.3" +name = "oxc_estree" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" -dependencies = [ - "cfg-if", - "ordered-multimap", -] +checksum = "0aef225084b2735b871215ceba04582ecfe15be563c4c3a9e22f33e34fab74f4" [[package]] -name = "rust-stemmers" -version = "1.2.0" +name = "oxc_index" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" +checksum = "eb3e6120999627ec9703025eab7c9f410ebb7e95557632a8902ca48210416c2b" dependencies = [ + "nonmax", "serde", - "serde_derive", ] [[package]] -name = "rustc-hash" -version = "1.1.0" +name = "oxc_parser" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "6ad27270e0ef6b957eeda354a9a4c3ba2b42a055d4d3f2311bc72735cefaac5f" +dependencies = [ + "bitflags 2.13.0", + "cow-utils", + "memchr", + "num-bigint", + "num-traits", + "oxc_allocator", + "oxc_ast", + "oxc_data_structures", + "oxc_diagnostics", + "oxc_ecmascript", + "oxc_regular_expression", + "oxc_span", + "oxc_str", + "oxc_syntax", + "rustc-hash", + "seq-macro", +] [[package]] -name = "rustc-hash" -version = "2.1.1" +name = "oxc_regular_expression" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "9e92ddddf8645910675528f66b3159c018c553fa47e4644514513705f5d3c22b" +dependencies = [ + "bitflags 2.13.0", + "oxc_allocator", + "oxc_ast_macros", + "oxc_diagnostics", + "oxc_span", + "oxc_str", + "phf", + "rustc-hash", + "unicode-id-start", +] [[package]] -name = "rustc_version" -version = "0.4.1" +name = "oxc_semantic" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "498ad9075150275623586c2461461c4ef6e5e7b99ceb0665aec88574dd9b90ae" dependencies = [ - "semver", + "itertools", + "memchr", + "oxc_allocator", + "oxc_ast", + "oxc_ast_visit", + "oxc_diagnostics", + "oxc_ecmascript", + "oxc_index", + "oxc_span", + "oxc_str", + "oxc_syntax", + "rustc-hash", + "self_cell", ] [[package]] -name = "rustix" -version = "0.38.44" +name = "oxc_span" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "f03b54ae4c2254ffdbba43f82e4ea097182b300d2f3ccd1f81f8ca145556e659" dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "compact_str", + "oxc-miette", + "oxc_allocator", + "oxc_ast_macros", + "oxc_estree", + "oxc_str", ] [[package]] -name = "rustix" -version = "1.1.3" +name = "oxc_str" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "686c0fe58e5a4a3698921871fbe23043ac271cf324540591dfcc5e7d0f127a5a" dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "compact_str", + "hashbrown", + "oxc_allocator", + "oxc_estree", ] [[package]] -name = "rustls" -version = "0.23.39" +name = "oxc_syntax" +version = "0.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" +checksum = "35c0e13e50d92d4c518ed2484d4c5beea46c2f3311688aaff866420abf6a73eb" dependencies = [ - "aws-lc-rs", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", + "bitflags 2.13.0", + "cow-utils", + "dragonbox_ecma", + "nonmax", + "oxc_allocator", + "oxc_ast_macros", + "oxc_estree", + "oxc_index", + "oxc_span", + "oxc_str", + "phf", + "unicode-id-start", ] [[package]] -name = "rustls-native-certs" -version = "0.8.3" +name = "parking" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" -dependencies = [ - "openssl-probe 0.2.1", - "rustls-pki-types", - "schannel", - "security-framework 3.5.1", -] +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] -name = "rustls-pemfile" -version = "2.2.0" +name = "parking_lot" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ - "rustls-pki-types", + "lock_api", + "parking_lot_core", ] [[package]] -name = "rustls-pki-types" -version = "1.14.0" +name = "parking_lot_core" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ - "web-time", - "zeroize", + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", ] [[package]] -name = "rustls-webpki" -version = "0.103.13" +name = "paste" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "rustversion" -version = "1.0.22" +name = "pastey" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] -name = "ryu" -version = "1.0.23" +name = "pathdiff" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] -name = "salsa20" -version = "0.10.2" +name = "percent-encoding" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "same-file" -version = "1.0.6" +name = "phf" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "winapi-util", + "phf_macros", + "phf_shared", + "serde", ] [[package]] -name = "scc" -version = "2.4.0" +name = "phf_generator" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ - "sdd", + "fastrand", + "phf_shared", ] [[package]] -name = "schannel" -version = "0.1.28" +name = "phf_macros" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "windows-sys 0.61.2", + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "schemars" -version = "0.9.0" +name = "phf_shared" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", + "siphasher", ] [[package]] -name = "schemars" -version = "1.2.1" +name = "pin-project" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ - "chrono", - "dyn-clone", - "ref-cast", - "schemars_derive", - "serde", - "serde_json", + "pin-project-internal", ] [[package]] -name = "schemars_derive" -version = "1.2.1" +name = "pin-project-internal" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "serde_derive_internals", - "syn 2.0.114", + "syn", ] [[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "scrypt" -version = "0.11.0" +name = "pin-project-lite" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" -dependencies = [ - "pbkdf2", - "salsa20", - "sha2", -] +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] -name = "sdd" -version = "3.0.10" +name = "pkg-config" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] -name = "security-framework" -version = "2.11.1" +name = "portable-atomic" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] -name = "security-framework" -version = "3.5.1" +name = "portable-atomic-util" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.10.1", - "core-foundation-sys", - "libc", - "security-framework-sys", + "portable-atomic", ] [[package]] -name = "security-framework-sys" -version = "2.15.0" +name = "potential_utf" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ - "core-foundation-sys", - "libc", + "zerovec", ] [[package]] -name = "self_cell" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" - -[[package]] -name = "semver" -version = "1.0.27" +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] -name = "send_wrapper" -version = "0.6.0" +name = "predicates" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" +checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" dependencies = [ - "futures-core", + "anstyle", + "difflib", + "float-cmp", + "normalize-line-endings", + "predicates-core", + "regex", ] [[package]] -name = "seq-macro" -version = "0.3.6" +name = "predicates-core" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" +checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" [[package]] -name = "serde" -version = "1.0.228" +name = "predicates-tree" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" dependencies = [ - "serde_core", - "serde_derive", + "predicates-core", + "termtree", ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "pretty_assertions" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ - "serde_derive", + "diff", + "yansi", ] [[package]] -name = "serde_derive" -version = "1.0.228" +name = "prettyplease" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "quote", - "syn 2.0.114", + "syn", ] [[package]] -name = "serde_derive_internals" -version = "0.29.1" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", ] [[package]] -name = "serde_json" -version = "1.0.149" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "serde_path_to_error" -version = "0.1.20" +name = "proc-macro-utils" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071" dependencies = [ - "itoa", - "serde", - "serde_core", + "proc-macro2", + "quote", + "smallvec", ] [[package]] -name = "serde_qs" -version = "0.15.0" +name = "proc-macro2" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ - "percent-encoding", - "serde", - "thiserror 2.0.18", + "unicode-ident", ] [[package]] -name = "serde_repr" -version = "0.1.20" +name = "proc-macro2-diagnostics" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", + "version_check", + "yansi", ] [[package]] -name = "serde_spanned" -version = "0.6.9" +name = "process-wrap" +version = "9.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "2e842efad9119158434d193c6682e2ebee4b44d6ad801d7b349623b3f57cdf55" dependencies = [ - "serde", + "futures", + "indexmap", + "nix", + "tokio", + "tracing", + "windows", ] [[package]] -name = "serde_spanned" -version = "1.0.4" +name = "prost" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ - "serde_core", + "bytes", + "prost-derive", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "prost-derive" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "serde_with" -version = "3.16.1" +name = "quote" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.13.0", - "schemars 0.9.0", - "schemars 1.2.1", - "serde_core", - "serde_json", - "serde_with_macros", - "time", + "proc-macro2", ] [[package]] -name = "serde_with_macros" -version = "3.16.1" +name = "quote-use" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e" dependencies = [ - "darling 0.21.3", - "proc-macro2", "quote", - "syn 2.0.114", + "quote-use-macros", ] [[package]] -name = "serial_test" -version = "3.3.1" +name = "quote-use-macros" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555" +checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35" dependencies = [ - "futures-executor", - "futures-util", - "log", - "once_cell", - "parking_lot", - "scc", - "serial_test_derive", + "proc-macro-utils", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "serial_test_derive" -version = "3.3.1" +name = "r-efi" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] -name = "server_fn" -version = "0.8.9" +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "reactive_graph" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353d02fa2886cd8dae0b8da0965289fa8f2ecc7df633d1ce965f62fdf9644d29" +checksum = "00c5a025366836190c7030e883cc2bcd9e384ff555336e3c7954741ca411b177" dependencies = [ - "base64", - "bytes", - "const-str", - "const_format", - "dashmap", + "any_spawner", + "async-lock", "futures", - "gloo-net", - "http 1.4.0", - "inventory", - "js-sys", + "guardian", + "hydration_context", + "indexmap", + "or_poisoned", + "paste", "pin-project-lite", + "rustc-hash", "rustc_version", - "rustversion", "send_wrapper", "serde", - "serde_json", - "serde_qs", - "server_fn_macro_default", + "slotmap", "thiserror 2.0.18", - "throw_error", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", "web-sys", - "xxhash-rust", ] [[package]] -name = "server_fn_macro" -version = "0.8.8" +name = "reactive_stores" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "950b8cfc9ff5f39ca879c5a7c5e640de2695a199e18e424c3289d0964cabe642" +checksum = "c30fd35b7d299c591293bb69fed47a703eb2703b1cff0493e78b16ed007e5382" dependencies = [ - "const_format", - "convert_case 0.8.0", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.114", - "xxhash-rust", + "guardian", + "indexmap", + "itertools", + "or_poisoned", + "paste", + "reactive_graph", + "reactive_stores_macro", + "rustc-hash", + "send_wrapper", ] [[package]] -name = "server_fn_macro_default" -version = "0.8.5" +name = "reactive_stores_macro" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63eb08f80db903d3c42f64e60ebb3875e0305be502bdc064ec0a0eab42207f00" +checksum = "68072edd607edd30b9ebf57d984ba45d8ab8809e598d0f6046278373fb76a5a0" dependencies = [ - "server_fn_macro", - "syn 2.0.114", + "convert_case 0.11.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "sha1" -version = "0.10.6" +name = "redox_syscall" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "bitflags 2.13.0", ] [[package]] -name = "sha2" -version = "0.10.9" +name = "redox_users" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "ref-cast" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ - "lazy_static", + "ref-cast-impl", ] [[package]] -name = "shellexpand" -version = "3.1.1" +name = "ref-cast-impl" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ - "dirs", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" +name = "regex" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ - "errno", - "libc", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "signature" -version = "2.2.0" +name = "regex-automata" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ - "digest", - "rand_core 0.6.4", + "aho-corasick", + "memchr", + "regex-syntax", ] [[package]] -name = "simd-adler32" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" - -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] -name = "simple_asn1" -version = "0.6.3" +name = "regex-bites" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror 2.0.18", - "time", -] +checksum = "b6a15a2fa0bfda9361941c45550896ae87b15cc6c8c939ea350079670332e211" [[package]] -name = "siphasher" -version = "1.0.2" +name = "regex-syntax" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" +name = "report-leptos" +version = "0.13.0" dependencies = [ + "leptos", + "pretty_assertions", "serde", + "serde_json", ] [[package]] -name = "sketches-ddsketch" -version = "0.3.0" +name = "rmcp" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" +checksum = "1d1f571c72940a19d9532fe52dbea8bc9912bf1d766c2970bb824056b86f3f59" dependencies = [ + "async-trait", + "base64", + "chrono", + "futures", + "pastey", + "pin-project-lite", + "process-wrap", + "rmcp-macros", + "schemars", "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", ] [[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "slotmap" -version = "1.1.1" +name = "rmcp-macros" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +checksum = "1aad0035b69380782d78ea95b508327e6deaa2235909053e596eea8f27b5e1d5" dependencies = [ - "version_check", + "darling", + "proc-macro2", + "quote", + "serde_json", + "syn", ] [[package]] -name = "smallvec" -version = "1.15.1" +name = "rstml" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "61cf4616de7499fc5164570d40ca4e1b24d231c6833a88bff0fe00725080fd56" dependencies = [ - "serde", + "derive-where", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", + "syn_derive", + "thiserror 2.0.18", ] [[package]] -name = "smawk" -version = "0.3.2" +name = "rustc-hash" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] -name = "snafu" -version = "0.8.9" +name = "rustc_version" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "snafu-derive", + "semver", ] [[package]] -name = "snafu-derive" -version = "0.8.9" +name = "rustix" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.114", + "bitflags 2.13.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", ] [[package]] -name = "socket2" -version = "0.6.2" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] -name = "spin" -version = "0.9.8" +name = "ryu" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] -name = "spki" -version = "0.7.3" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "base64ct", - "der", + "winapi-util", ] [[package]] -name = "sqlparser" -version = "0.58.0" +name = "schemars" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4b661c54b1e4b603b37873a18c59920e4c51ea8ea2cf527d925424dbd4437c" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" dependencies = [ - "log", - "sqlparser_derive", + "chrono", + "dyn-clone", + "ref-cast", + "schemars_derive", + "serde", + "serde_json", ] [[package]] -name = "sqlparser_derive" -version = "0.3.0" +name = "schemars_derive" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da5fc6819faabb412da764b99d3b713bb55083c11e7e0c00144d386cd6a1939c" +checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "serde_derive_internals", + "syn", ] [[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "static_assertions" -version = "1.1.0" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "std_prelude" -version = "0.2.12" +name = "self_cell" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8207e78455ffdf55661170876f88daf85356e4edd54e0a3dbc79586ca1e50cbe" +checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" [[package]] -name = "stfu8" -version = "0.2.7" +name = "semver" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51f1e89f093f99e7432c491c382b88a6860a5adbe6bf02574bf0a08efff1978" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] -name = "stringprep" -version = "0.1.5" +name = "send_wrapper" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" dependencies = [ - "unicode-bidi", - "unicode-normalization", - "unicode-properties", + "futures-core", ] [[package]] -name = "strsim" -version = "0.11.1" +name = "seq-macro" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] -name = "strum" -version = "0.26.3" +name = "serde" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ - "strum_macros", + "serde_core", + "serde_derive", ] [[package]] -name = "strum_macros" -version = "0.26.4" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.114", + "serde_derive", ] [[package]] -name = "subtle" -version = "2.6.1" +name = "serde_derive" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "syn" -version = "1.0.109" +name = "serde_derive_internals" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] -name = "syn" -version = "2.0.114" +name = "serde_json" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", ] [[package]] -name = "syn_derive" -version = "0.2.0" +name = "serde_qs" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb066a04799e45f5d582e8fc6ec8e6d6896040d00898eb4e6a835196815b219" +checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" dependencies = [ - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.114", + "percent-encoding", + "serde", + "thiserror 2.0.18", ] [[package]] -name = "sync_wrapper" -version = "1.0.2" +name = "serde_spanned" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ - "futures-core", + "serde_core", ] [[package]] -name = "synstructure" -version = "0.13.2" +name = "serde_yaml" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", ] [[package]] -name = "system-configuration" -version = "0.7.0" +name = "serial_test" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +checksum = "699f4197115b8a7e7ff19c9a315a4bd6fffec26cc4626ef45ecaea389e081c6d" dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.9.4", - "system-configuration-sys", + "futures-executor", + "futures-util", + "log", + "once_cell", + "parking_lot", + "serial_test_derive", ] [[package]] -name = "system-configuration-sys" -version = "0.6.0" +name = "serial_test_derive" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c" dependencies = [ - "core-foundation-sys", - "libc", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "tachys" -version = "0.2.11" +name = "server_fn" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b2db11e455f7e84e2cc3e76f8a3f3843f7956096265d5ecff781eabe235077" +checksum = "be8559dd05af1b5b7e363a150616589d5a88af5187273f7f331ba0dae8922812" dependencies = [ - "any_spawner", - "async-trait", - "const_str_slice_concat", - "drain_filter_polyfill", - "either_of", - "erased", + "base64", + "bytes", + "const-str", + "const_format", "futures", - "html-escape", - "indexmap 2.13.0", - "itertools 0.14.0", + "gloo-net", + "http", + "inventory", "js-sys", - "linear-map", - "next_tuple", - "oco_ref", "or_poisoned", - "parking_lot", - "paste", - "reactive_graph", - "reactive_stores", - "rustc-hash 2.1.1", + "pin-project-lite", "rustc_version", + "rustversion", "send_wrapper", - "slotmap", + "serde", + "serde_json", + "serde_qs", + "server_fn_macro_default", + "thiserror 2.0.18", "throw_error", + "url", "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", "web-sys", + "xxhash-rust", ] [[package]] -name = "tagptr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" - -[[package]] -name = "tantivy" -version = "0.22.1" +name = "server_fn_macro" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96599ea6fccd844fc833fed21d2eecac2e6a7c1afd9e044057391d78b1feb141" +checksum = "1295b54815397d30d986b63f93cfd515fa86d5e528e0bb589ce9d530502f9e0f" dependencies = [ - "aho-corasick", - "arc-swap", - "base64", - "bitpacking", - "byteorder", - "census", - "crc32fast", - "crossbeam-channel", - "downcast-rs 1.2.1", - "fastdivide", - "fnv", - "fs4", - "htmlescape", - "itertools 0.12.1", - "levenshtein_automata", - "log", - "lru", - "lz4_flex", - "measure_time 0.8.3", - "memmap2", - "num_cpus", - "once_cell", - "oneshot", - "rayon", - "regex", - "rust-stemmers", - "rustc-hash 1.1.0", - "serde", - "serde_json", - "sketches-ddsketch 0.2.2", - "smallvec", - "tantivy-bitpacker 0.6.0", - "tantivy-columnar 0.3.0", - "tantivy-common 0.7.0", - "tantivy-fst", - "tantivy-query-grammar 0.22.0", - "tantivy-stacker 0.3.0", - "tantivy-tokenizer-api 0.3.0", - "tempfile", - "thiserror 1.0.69", - "time", - "uuid", - "winapi", + "const_format", + "convert_case 0.11.0", + "proc-macro2", + "quote", + "rustc_version", + "syn", + "xxhash-rust", ] [[package]] -name = "tantivy" -version = "0.24.2" +name = "server_fn_macro_default" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a966cb0e76e311f09cf18507c9af192f15d34886ee43d7ba7c7e3803660c43" +checksum = "63eb08f80db903d3c42f64e60ebb3875e0305be502bdc064ec0a0eab42207f00" dependencies = [ - "aho-corasick", - "arc-swap", - "base64", - "bitpacking", - "bon", - "byteorder", - "census", - "crc32fast", - "crossbeam-channel", - "downcast-rs 2.0.2", - "fastdivide", - "fnv", - "fs4", - "htmlescape", - "hyperloglogplus", - "itertools 0.14.0", - "levenshtein_automata", - "log", - "lru", - "lz4_flex", - "measure_time 0.9.0", - "memmap2", - "once_cell", - "oneshot", - "rayon", - "regex", - "rust-stemmers", - "rustc-hash 2.1.1", - "serde", - "serde_json", - "sketches-ddsketch 0.3.0", - "smallvec", - "tantivy-bitpacker 0.8.0", - "tantivy-columnar 0.5.0", - "tantivy-common 0.9.0", - "tantivy-fst", - "tantivy-query-grammar 0.24.0", - "tantivy-stacker 0.5.0", - "tantivy-tokenizer-api 0.5.0", - "tempfile", - "thiserror 2.0.18", - "time", - "uuid", - "winapi", + "server_fn_macro", + "syn", ] [[package]] -name = "tantivy-bitpacker" -version = "0.6.0" +name = "sha2" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284899c2325d6832203ac6ff5891b297fc5239c3dc754c5bc1977855b23c10df" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ - "bitpacking", + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", ] [[package]] -name = "tantivy-bitpacker" -version = "0.8.0" +name = "sha2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adc286a39e089ae9938935cd488d7d34f14502544a36607effd2239ff0e2494" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ - "bitpacking", + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] -name = "tantivy-columnar" -version = "0.3.0" +name = "shlex" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12722224ffbe346c7fec3275c699e508fd0d4710e629e933d5736ec524a1f44e" -dependencies = [ - "downcast-rs 1.2.1", - "fastdivide", - "itertools 0.12.1", - "serde", - "tantivy-bitpacker 0.6.0", - "tantivy-common 0.7.0", - "tantivy-sstable 0.3.0", - "tantivy-stacker 0.3.0", -] +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] -name = "tantivy-columnar" -version = "0.5.0" +name = "signal-hook-registry" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6300428e0c104c4f7db6f95b466a6f5c1b9aece094ec57cdd365337908dc7344" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ - "downcast-rs 2.0.2", - "fastdivide", - "itertools 0.14.0", - "serde", - "tantivy-bitpacker 0.8.0", - "tantivy-common 0.9.0", - "tantivy-sstable 0.5.0", - "tantivy-stacker 0.5.0", + "errno", + "libc", ] [[package]] -name = "tantivy-common" -version = "0.7.0" +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8019e3cabcfd20a1380b491e13ff42f57bb38bf97c3d5fa5c07e50816e0621f4" -dependencies = [ - "async-trait", - "byteorder", - "ownedbytes 0.7.0", - "serde", - "time", -] +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] -name = "tantivy-common" -version = "0.9.0" +name = "slotmap" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b6ea6090ce03dc72c27d0619e77185d26cc3b20775966c346c6d4f7e99d7f" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" dependencies = [ - "async-trait", - "byteorder", - "ownedbytes 0.9.0", - "serde", - "time", + "version_check", ] [[package]] -name = "tantivy-fst" -version = "0.5.0" +name = "smallvec" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d60769b80ad7953d8a7b2c70cdfe722bbcdcac6bccc8ac934c40c034d866fc18" -dependencies = [ - "byteorder", - "regex-syntax", - "utf8-ranges", -] +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] -name = "tantivy-query-grammar" -version = "0.22.0" +name = "smawk" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847434d4af57b32e309f4ab1b4f1707a6c566656264caa427ff4285c4d9d0b82" -dependencies = [ - "nom 7.1.3", -] +checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] -name = "tantivy-query-grammar" -version = "0.24.0" +name = "stable_deref_trait" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e810cdeeebca57fc3f7bfec5f85fdbea9031b2ac9b990eb5ff49b371d52bbe6a" -dependencies = [ - "nom 7.1.3", - "serde", - "serde_json", -] +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] -name = "tantivy-sstable" -version = "0.3.0" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c69578242e8e9fc989119f522ba5b49a38ac20f576fc778035b96cc94f41f98e" -dependencies = [ - "tantivy-bitpacker 0.6.0", - "tantivy-common 0.7.0", - "tantivy-fst", - "zstd", -] +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "tantivy-sstable" -version = "0.5.0" +name = "streaming-iterator" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709f22c08a4c90e1b36711c1c6cad5ae21b20b093e535b69b18783dd2cb99416" -dependencies = [ - "futures-util", - "itertools 0.14.0", - "tantivy-bitpacker 0.8.0", - "tantivy-common 0.9.0", - "tantivy-fst", - "zstd", -] +checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" [[package]] -name = "tantivy-stacker" -version = "0.3.0" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56d6ff5591fc332739b3ce7035b57995a3ce29a93ffd6012660e0949c956ea8" -dependencies = [ - "murmurhash32", - "rand_distr 0.4.3", - "tantivy-common 0.7.0", -] +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "tantivy-stacker" -version = "0.5.0" +name = "syn" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bcdebb267671311d1e8891fd9d1301803fdb8ad21ba22e0a30d0cab49ba59c1" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ - "murmurhash32", - "rand_distr 0.4.3", - "tantivy-common 0.9.0", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "tantivy-tokenizer-api" -version = "0.3.0" +name = "syn_derive" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0dcade25819a89cfe6f17d932c9cedff11989936bf6dd4f336d50392053b04" +checksum = "cdb066a04799e45f5d582e8fc6ec8e6d6896040d00898eb4e6a835196815b219" dependencies = [ - "serde", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "tantivy-tokenizer-api" -version = "0.5.0" +name = "synstructure" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa942fcee81e213e09715bbce8734ae2180070b97b33839a795ba1de201547d" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ - "serde", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "tap" -version = "1.0.1" +name = "tachys" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "a92ba81187437cc5df4281f2326a2e13cc81e8f96448292d1112388e2025ca66" +dependencies = [ + "any_spawner", + "async-trait", + "const_str_slice_concat", + "drain_filter_polyfill", + "either_of", + "erased", + "futures", + "html-escape", + "indexmap", + "itertools", + "js-sys", + "next_tuple", + "oco_ref", + "or_poisoned", + "paste", + "reactive_graph", + "reactive_stores", + "rustc-hash", + "rustc_version", + "send_wrapper", + "slotmap", + "throw_error", + "wasm-bindgen", + "web-sys", +] [[package]] name = "tempfile" -version = "3.25.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.1", + "getrandom 0.4.3", "once_cell", - "rustix 1.1.3", + "rustix", "windows-sys 0.61.2", ] @@ -8089,7 +3074,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -8100,25 +3085,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", -] - -[[package]] -name = "thread-tree" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbd370cb847953a25954d9f63e14824a36113f8c72eecf6eccef5dc4b45d630" -dependencies = [ - "crossbeam-channel", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", + "syn", ] [[package]] @@ -8132,12 +3099,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde_core", @@ -8147,100 +3113,54 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", ] -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", ] -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.49.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", "mio", - "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", + "syn", ] [[package]] @@ -8269,39 +3189,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit", -] - -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "serde_core", - "serde_spanned 1.0.4", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "winnow", -] - -[[package]] -name = "toml" -version = "1.0.6+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399b1124a3c9e16766831c6bba21e50192572cdd98706ea114f9502509686ffc" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "indexmap 2.13.0", + "indexmap", "serde_core", - "serde_spanned 1.0.4", - "toml_datetime 1.0.0+spec-1.1.0", + "serde_spanned", + "toml_datetime", "toml_parser", "toml_writer", "winnow", @@ -8309,116 +3204,27 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_datetime" -version = "1.0.0+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap 2.13.0", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", - "winnow", -] - [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ "winnow", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" - -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "async-compression", - "bitflags 2.10.0", - "bytes", - "futures-core", - "futures-util", - "http 1.4.0", - "http-body 1.0.1", - "http-body-util", - "iri-string", - "pin-project-lite", - "tokio", - "tokio-util", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tracing" @@ -8426,7 +3232,6 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -8440,7 +3245,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -8450,101 +3255,111 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", - "valuable", ] [[package]] -name = "tracing-log" -version = "0.2.0" +name = "tree-sitter" +version = "0.25.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87" dependencies = [ - "log", - "once_cell", - "tracing-core", + "cc", + "regex", + "regex-syntax", + "serde_json", + "streaming-iterator", + "tree-sitter-language", ] [[package]] -name = "tracing-subscriber" -version = "0.3.22" +name = "tree-sitter-c" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "a9b2eb57a55fed6b00812912e730b7a275cf4fe98bfd6a5d76263d4438371728" dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", + "cc", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-cpp" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2196ea9d47b4ab4a31b9297eaa5a5d19a0b121dceb9f118f6790ad0ab94743" +dependencies = [ + "cc", + "tree-sitter-language", ] [[package]] -name = "try-lock" -version = "0.2.5" +name = "tree-sitter-javascript" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "68204f2abc0627a90bdf06e605f5c470aa26fdcb2081ea553a04bdad756693f5" +dependencies = [ + "cc", + "tree-sitter-language", +] [[package]] -name = "ttf-parser" -version = "0.25.1" +name = "tree-sitter-language" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782" [[package]] -name = "twox-hash" -version = "2.1.2" +name = "tree-sitter-objc" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" +checksum = "9ca8bb556423fc176f0535e79d525f783a6684d3c9da81bf9d905303c129e1d2" dependencies = [ - "rand 0.9.2", + "cc", + "tree-sitter-language", ] [[package]] -name = "type1-encoding-parser" -version = "0.1.0" +name = "tree-sitter-python" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d6cc09e1a99c7e01f2afe4953789311a1c50baebbdac5b477ecf78e2e92a5b" +checksum = "6bf85fd39652e740bf60f46f4cda9492c3a9ad75880575bf14960f775cb74a1c" dependencies = [ - "pom", + "cc", + "tree-sitter-language", ] [[package]] -name = "typed-arena" -version = "2.0.2" +name = "tree-sitter-swift" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" +checksum = "fe36052155b9dd69ca82b3b8f1b4ccfb2d867125ac1a4db1dd7331829242668c" +dependencies = [ + "cc", + "tree-sitter-language", +] [[package]] -name = "typed-builder" -version = "0.21.2" +name = "tree-sitter-typescript" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef81aec2ca29576f9f6ae8755108640d0a86dd3161b2e8bca6cfa554e98f77d" +checksum = "6c5f76ed8d947a75cc446d5fccd8b602ebf0cde64ccf2ffa434d873d7a575eff" dependencies = [ - "typed-builder-macro 0.21.2", + "cc", + "tree-sitter-language", ] +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + [[package]] name = "typed-builder" version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31aa81521b70f94402501d848ccc0ecaa8f93c8eb6999eb9747e72287757ffda" dependencies = [ - "typed-builder-macro 0.23.2", -] - -[[package]] -name = "typed-builder-macro" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecb9ecf7799210407c14a8cfdfe0173365780968dc57973ed082211958e0b18" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", + "typed-builder-macro", ] [[package]] @@ -8555,26 +3370,14 @@ checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicase" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" - -[[package]] -name = "unicode-bidi" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-general-category" @@ -8590,9 +3393,9 @@ checksum = "81b79ad29b5e19de4260020f8919b443b2ef0277d242ce532ec7b7a2cc8b6007" [[package]] name = "unicode-ident" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-linebreak" @@ -8600,32 +3403,17 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" -[[package]] -name = "unicode-normalization" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-properties" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" - [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -8640,10 +3428,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" [[package]] -name = "untrusted" -version = "0.9.0" +name = "unsafe-libyaml" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "url" @@ -8663,12 +3451,6 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - [[package]] name = "utf8-width" version = "0.1.8" @@ -8681,30 +3463,17 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - [[package]] name = "uuid" -version = "1.20.0" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "js-sys", - "serde_core", "wasm-bindgen", ] -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - [[package]] name = "vcpkg" version = "0.2.15" @@ -8717,12 +3486,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vsimd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" - [[package]] name = "wait-timeout" version = "0.2.1" @@ -8742,15 +3505,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -8759,27 +3513,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -8790,23 +3535,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8814,92 +3555,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-bindgen-test" -version = "0.3.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45649196a53b0b7a15101d845d44d2dda7374fc1b5b5e2bbf58b7577ff4b346d" -dependencies = [ - "async-trait", - "cast", - "js-sys", - "libm", - "minicov", - "nu-ansi-term", - "num-traits", - "oorandom", - "serde", - "serde_json", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", - "wasm-bindgen-test-shared", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f579cdd0123ac74b94e1a4a72bd963cf30ebac343f2df347da0b8df24cdebed2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "wasm-bindgen-test-shared" -version = "0.2.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8145dd1593bf0fb137dbfa85b8be79ec560a447298955877804640e40c2d6ea" - -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.13.0", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" dependencies = [ "futures-util", "js-sys", @@ -8910,9 +3590,9 @@ dependencies = [ [[package]] name = "wasm_split_helpers" -version = "0.2.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a114b3073258dd5de3d812cdd048cca6842342755e828a14dbf15f843f2d1b84" +checksum = "ab578aae2fe2916edaea06843187d50f87b0965622da0ceef648edca27b385ba" dependencies = [ "async-once-cell", "wasm_split_macros", @@ -8920,33 +3600,21 @@ dependencies = [ [[package]] name = "wasm_split_macros" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56481f8ed1a9f9ae97ea7b08a5e2b12e8adf9a7818a6ba952b918e09c7be8bf0" +checksum = "3e653af7ee4a9ef0fce481a9ec6f43cb78de20d0cdb4f4f5862e1dc6e407e6c8" dependencies = [ "base16", "quote", - "sha2", - "syn 2.0.114", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.10.0", - "hashbrown 0.15.5", - "indexmap 2.13.0", - "semver", + "sha2 0.10.9", + "syn", ] [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -8963,51 +3631,35 @@ dependencies = [ ] [[package]] -name = "webpki-roots" -version = "1.0.6" +name = "winapi-util" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "rustls-pki-types", + "windows-sys 0.61.2", ] [[package]] -name = "weezl" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" - -[[package]] -name = "winapi" -version = "0.3.9" +name = "windows" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.11" +name = "windows-collections" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-sys 0.61.2", + "windows-core", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-core" version = "0.62.2" @@ -9021,6 +3673,17 @@ dependencies = [ "windows-strings", ] +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + [[package]] name = "windows-implement" version = "0.60.2" @@ -9029,7 +3692,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -9040,7 +3703,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] @@ -9050,14 +3713,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "windows-registry" -version = "0.6.1" +name = "windows-numerics" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ + "windows-core", "windows-link", - "windows-result", - "windows-strings", ] [[package]] @@ -9078,15 +3740,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.59.0" @@ -9147,6 +3800,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -9245,127 +3907,30 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap 2.13.0", - "prettyplease", - "syn 2.0.114", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.114", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.10.0", - "indexmap 2.13.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.13.0", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xmlparser" -version = "0.13.6" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xxhash-rust" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" +checksum = "4d93c89cdc2d3a63c3ec48ffe926931bdc069eafa8e4402fe6d8f790c9d1e576" [[package]] name = "yansi" @@ -9375,9 +3940,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -9386,68 +3951,42 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.8.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.114", -] - [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", "synstructure", ] -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -9456,9 +3995,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -9467,45 +4006,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn", ] [[package]] name = "zmij" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", -] +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index d51e70bb..ed262b49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,56 +1,41 @@ [workspace] resolver = "2" members = [ - "loctree_rs", - "loctree-mcp", - "rmcp-common", + "loctree-ast", + "loctree-rs", "reports", - "reports/wasm", ] -# Removed from workspace: -# - rust-memex: use crates.io version (0.3.2+), standalone: ~/Libraxis/rmcp-memex -# - rmcp-mux: deprecated (dead end approach) -# - rmcp-config-ui: moved to ~/Libraxis/rmcp-config-ui - [workspace.package] -version = "0.8.17" +version = "0.13.0" edition = "2024" rust-version = "1.85.0" -license = "MIT OR Apache-2.0" +license = "BUSL-1.1" authors = ["Loctree "] [workspace.dependencies] -# Core -tokio = { version = "1.0", features = ["full"] } +tokio = { version = "1.52", features = ["full"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -anyhow = "1.0" -thiserror = "2.0" - -# CLI +anyhow = "1" +thiserror = "2" clap = { version = "4.4", features = ["derive"] } - -# Logging tracing = "0.1" tracing-subscriber = "0.3" - -# MCP -rmcp = { version = "0.17", features = ["server"] } - -# Async +rmcp = { version = "1.7", features = ["server"] } futures = "0.3" - -# The local crates (for inter-crate dependencies) -loctree = { path = "loctree_rs", version = "0.8.17" } -report-leptos = { path = "reports", version = "0.8.17" } - -# Release profile - good defaults for all crates -[profile.release] -opt-level = 3 -lto = true -codegen-units = 1 -strip = true - -# WASM crates need size optimization - override when building with trunk/wasm-pack -# trunk uses its own Trunk.toml for wasm-opt settings +axum = { version = "0.8", features = ["json"] } +tower = { version = "0.5", features = ["util"] } +tokio-util = { version = "0.7", features = ["rt"] } +argon2 = "0.5" +password-hash = { version = "0.5", features = ["getrandom"] } +subtle = "2.6" +uuid = { version = "1", features = ["v4", "serde"] } +chrono = { version = "0.4", features = ["serde"] } +shellexpand = "3.1" +reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls-native-roots"] } +sha2 = "0.10" +schemars = "1" +loctree = { path = "loctree-rs", version = "0.13.0" } +loctree-ast = { path = "loctree-ast", version = "0.13.0" } +report-leptos = { path = "reports", version = "0.13.0" } diff --git a/LICENSE b/LICENSE index f3bf5d50..996317f8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,49 @@ -MIT License - -Copyright (c) 2025 Loctree - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Business Source License 1.1 +=========================== + +Loctree is provided under the Business Source License 1.1 (BUSL-1.1). + +SPDX-License-Identifier: BUSL-1.1 + +Canonical text of the Business Source License 1.1 is available at: +https://mariadb.com/bsl11/ + + +Parameters +---------- + + Licensor: Loctree Team (loct@loct.io) + + Licensed Work: Loctree + - This repository (loctree-suite) and all artifacts + published from it: loct, loctree-mcp, loctree-lsp, + the loctree library crate, report-leptos, + rmcp-common, and the loctree-landing site. + - Copyright (c) 2024-2026 Loctree Team. + + Additional Use Grant: You may make production use of the Licensed Work, + provided that your use does not include offering the + Licensed Work, or any substantial portion of its + functionality, to third parties as a hosted, managed, + or commercially distributed service that competes + with a service offered by the Licensor. + + Change Date: 2030-04-13 + (four years after the publication of Loctree v0.9.0). + + Change License: Apache License, Version 2.0 + + +For commercial licensing, hosted-service exemptions, OEM redistribution, or +any arrangement that falls outside the Additional Use Grant above, contact: + + loct@loct.io + + +Notice +------ + +The Business Source License (this document) is not an Open Source license. +However, the Licensed Work will, on the Change Date stated above, become +available under the Change License, and the rights granted in the paragraph +above will terminate. diff --git a/LICENSE-APACHE b/LICENSE-APACHE deleted file mode 100644 index 0318c0c6..00000000 --- a/LICENSE-APACHE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to the Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -Copyright 2024-2025 Loctree - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT deleted file mode 100644 index 6ec781ed..00000000 --- a/LICENSE-MIT +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024-2025 Loctree - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 00000000..cd397fd0 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,7 @@ +# Notice + +This snapshot is published under BUSL-1.1. + +The historical public Loctree engine line used dual MIT/Apache licensing. Starting with the 0.13 release line, this mirror follows the suite license decision: BUSL-1.1. + +This is a release mirror generated from the private integration monorepo. The snapshot contains only the component payload staged for `Loctree/loctree`. diff --git a/README.md b/README.md index aa1191c1..ddf81a1a 100644 --- a/README.md +++ b/README.md @@ -1,215 +1,21 @@ -

- loctree logo -

+# Loctree Engine 0.13.0 -

loctree

+This repository is the public release mirror for the Loctree engine. -

- Scan once, query everything.
- AI-oriented static analysis for dead exports, circular imports, dependency graphs, and holographic context slices. -

+It contains the `loctree` crate, the `loctree-ast` crate, and the internal report renderer required by the current engine build graph. This is a release mirror of a private integration monorepo; issues/PRs welcome here. -

- crates.io - downloads - docs.rs - CI - License -

- ---- - -## Install - -```bash -curl -fsSL https://loct.io/install.sh | sh # CLI + loctree-mcp -cargo install --locked loctree loctree-mcp # Cargo, reproducible -npm install -g loctree # CLI only; published targets follow the latest npm release -brew install loctree/cli/loct # CLI via Homebrew tap -brew install loctree/mcp/loctree-mcp # MCP via Homebrew tap -``` - -Public install channels track the latest published release, which can lag behind -the workspace version on `main`. If you're validating a specific release, check -crates.io, npm, or GitHub Releases rather than assuming branch parity. - -## Quick Start - -Artifacts are stored in your OS cache dir by default (override via `LOCT_CACHE_DIR`). -`loct` is the canonical CLI command. `loctree` remains available as a quiet compatibility alias. - -```bash -loct # Scan project, write cached artifacts -loct --for-ai # AI-optimized overview (health, hubs, quick wins) -loct slice src/App.tsx --consumers # Context: file + deps + consumers -loct find useAuth # Find symbol definitions -loct find 'Snapshot FileAnalysis' # Cross-match: where terms meet -loct impact src/utils/api.ts # What breaks if you change this? -loct health # Quick summary: cycles + dead + twins -loct dead --confidence high # Unused exports -loct cycles # Circular imports -loct twins # Dead parrots + duplicates + barrel chaos -loct audit # Full codebase review -``` - -## What It Does - -loctree captures your project's real dependency graph in a single scan, then answers structural questions instantly from the snapshot. Designed for AI agents that need focused context without reading every file. - -**Core capabilities:** - -- **Holographic Slice** - extract file + dependencies + consumers in one call -- **Cross-Match Search** - find where multiple terms co-occur (not flat grep) -- **Dead Export Detection** - find unused exports across JS/TS, Python, Rust, Go, Dart -- **Circular Import Detection** - Tarjan's SCC algorithm catches runtime bombs -- **Handler Tracing** - follow Tauri commands through the entire FE/BE pipeline -- **Impact Analysis** - see what breaks before you delete or refactor -- **jq Queries** - query snapshot data with jq syntax (`loct '.files | length'`) - -## Why loctree - -| | grep/rg | LSP | loctree | -|---|---------|-----|---------| -| Knows imports vs definitions | No | Per-file | Whole graph | -| Dead export detection | No | No | Yes (multi-lang) | -| Cross-file impact analysis | No | Limited | Full transitive | -| AI agent integration | No | No | MCP server + `--for-ai` | -| Speed on 1M LOC repo | Fast (text) | Slow (indexing) | **~3s** (structural) | -| Setup | None | Per-editor | One binary | - -## MCP Server - -loctree ships as an MCP server for seamless AI agent integration: - -```bash -loctree-mcp # Start via stdio (configure in your MCP client) -``` - -7 tools: `repo-view`, `slice`, `find`, `impact`, `focus`, `tree`, `follow`. Each tool accepts a `project` parameter — auto-scans on first use, caches snapshots in RAM. Project-agnostic: analyze any repo without configuration. - -```json -{ - "mcpServers": { - "loctree": { - "command": "loctree-mcp", - "args": [] - } - } -} -``` - -Direct download users can also fetch signed release assets from the monorepo -GitHub release page, which mirrors both the CLI and `loctree-mcp` tarballs. - -## Language Support - -| Language | Dead Export Accuracy | Notes | -|----------|---------------------|-------| -| **Rust** | ~0% FP | Tested on rust-lang/rust (35K files) | -| **Go** | ~0% FP | Tested on golang/go (17K files) | -| **TypeScript/JavaScript** | ~10-20% FP | JSX/TSX, React patterns, Flow, WeakMap | -| **Python** | ~20% FP | Library mode, `__all__`, stdlib detection | -| **Svelte** | <15% FP | Template analysis, .d.ts re-exports | -| **Vue** | ~15% FP | SFC support, Composition & Options API | -| **Dart/Flutter** | Full | pubspec.yaml detection | - -Auto-detects stack from `Cargo.toml`, `tsconfig.json`, `pyproject.toml`, `pubspec.yaml`, `src-tauri/`. - -## Holographic Slice - -Extract 3-layer context for any file: - -```bash -loct slice src/App.tsx --consumers -``` - -``` -Slice for: src/App.tsx - -Core (1 files, 150 LOC): - src/App.tsx (150 LOC, ts) - -Deps (3 files, 420 LOC): - [d1] src/hooks/useAuth.ts (80 LOC) - [d2] src/contexts/AuthContext.tsx (200 LOC) - [d2] src/utils/api.ts (140 LOC) - -Consumers (2 files, 180 LOC): - src/main.tsx (30 LOC) - src/routes/index.tsx (150 LOC) - -Total: 6 files, 750 LOC -``` - -## Cross-Match Search - -Multi-term queries show where terms meet, not flat OR: +## Build ```bash -loct find 'Snapshot FileAnalysis' -``` - -``` -=== Cross-Match Files (9) === - src/snapshot.rs: Snapshot(6), FileAnalysis(4) - src/slicer.rs: Snapshot(2), FileAnalysis(3) - ... - -=== Symbol Matches (222 in cross-match files) === - src/snapshot.rs:20 - Snapshot [struct] - src/types.rs:15 - FileAnalysis [struct] - ... - -=== Parameter Matches (4 cross-matched) === - src/slicer.rs:45 - snapshot: &Snapshot in build_slice(analyses: &[FileAnalysis]) -``` - -## jq Queries - -Query snapshot data directly: - -```bash -loct '.dead_parrots' # Dead code findings -loct '.files | length' # Count files -loct '.edges[] | select(.from | contains("api"))' # Filter edges -loct '.summary.health_score' # Health score -``` - -## CI Integration - -```bash -loct lint --fail --sarif > results.sarif # SARIF for GitHub/GitLab -loct findings | jq '.dead_exports.total' # Check dead export count -loct findings --summary | jq '.health_score' # Health summary JSON -``` - -## Crates - -| Crate | Description | -|-------|-------------| -| [`loctree`](https://crates.io/crates/loctree) | Core analyzer + CLI (`loct`, `loctree`) | -| [`report-leptos`](https://crates.io/crates/report-leptos) | HTML report renderer (Leptos SSR) | -| [`loctree-mcp`](https://crates.io/crates/loctree-mcp) | MCP server for AI agents | - -## Development - -```bash -make precheck # fmt + clippy + check (run before push) -make install # Install loct, loctree, loctree-mcp -make test # Run all workspace tests -make publish # Cascade publish to crates.io -``` - -## Badge - -```markdown -[![loctree](https://img.shields.io/badge/analyzed_with-loctree-a8a8a8?style=flat&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij48cmVjdCB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9IiMwMDAiLz48dGV4dCB4PSI4IiB5PSIxMiIgZm9udC1mYW1pbHk9Im1vbm9zcGFjZSIgZm9udC1zaXplPSIxMCIgZmlsbD0iI2E4YThhOCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+TDwvdGV4dD48L3N2Zz4=)](https://crates.io/crates/loctree) +cargo check --workspace ``` ## License -MIT OR Apache-2.0. See [LICENSE-MIT](LICENSE-MIT) and [LICENSE-APACHE](LICENSE-APACHE). +BUSL-1.1. See `LICENSE` and `NOTICE.md`. ---- +## Snapshot Notes -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team +- Target repo: `Loctree/loctree` +- Dependency mode: `local workspace snapshot` +- Engine staging vendors report-leptos as an internal build dependency because loctree 0.13.0 still depends on it and the 0.13.0 crate line is not yet published. diff --git a/SYNC-MANIFEST.md b/SYNC-MANIFEST.md new file mode 100644 index 00000000..59c9156c --- /dev/null +++ b/SYNC-MANIFEST.md @@ -0,0 +1,22 @@ +# Component Sync Manifest + +- Component: `engine` +- Version: `0.13.0` +- Target repo: `Loctree/loctree` +- Source commit: `a5a4ee12d5c5` +- Generated at: `2026-07-03T07:35:02Z` +- Push mode: `enabled` +- Dependency mode: `local workspace snapshot` + +## Included Payload + +- `loctree-rs` -> `loctree-rs` +- `loctree-ast` -> `loctree-ast` + +## Vendored Build Payload + +- `reports` -> `reports` + +## Dependency Note + +Engine staging vendors report-leptos as an internal build dependency because loctree 0.13.0 still depends on it and the 0.13.0 crate line is not yet published. diff --git a/ai-hooks/README.md b/ai-hooks/README.md deleted file mode 100644 index 9bcce830..00000000 --- a/ai-hooks/README.md +++ /dev/null @@ -1,205 +0,0 @@ -# AI Hooks - -Integration hooks for AI coding assistants (Claude Code, Codex CLI, Gemini CLI). - -## Hook Packages - -### 🌳 Loctree - Structural Analysis (v10) -**TRUE AUGMENTATION** - automatically adds semantic context to every grep/rg. - -| Pattern Type | Example | Augmentation | Time | -|--------------|---------|--------------|------| -| **Any symbol** | `passthrough` | `loct find` - semantic + params + dead status | ~75ms | -| **PascalCase** | `McpToolsState` | `loct find` - definition + similar symbols | ~75ms | -| **snake_case** | `detect_language` | `loct find` - all matches + params | ~75ms | -| **Directory** | `src/providers/` | `focus` - all files + deps | ~56ms | -| **File** | `toolRegistry.ts` | `slice` - deps + consumers tree | ~81ms | -| **Tauri command** | `mcp_list_integrations` | Backend handler + Frontend calls | ~47ms | - -**Key change in v10:** Uses `loct find` (~75ms) instead of `query where-symbol` for ALL symbol lookups. This provides: -- `symbol_matches`: Exact definitions with file + line -- `param_matches`: Function parameters matching the pattern (NEW in 0.8.4) -- `semantic_matches`: Similar symbols with similarity scores -- `dead_status`: Whether the symbol is exported and/or dead - -**Works with:** -- `Grep` tool → PostToolUse:Grep - -**Dual Output:** -- `stderr` → User sees in terminal -- `stdout` (JSON) → AI sees via `hookSpecificOutput.additionalContext` - -| Hook | Trigger | Function | -|------|---------|----------| -| `loct-grep-augment.sh` | PostToolUse:Grep | Auto-adds semantic context via `loct find` | -| `loct-smart-suggest.sh` | PostToolUse:* | Proactive refactoring suggestions | - -### 🧠 Memex - Memory/RAG Augmentation - -**INSTITUTIONAL KNOWLEDGE** - automatically loads relevant memories from your vector DB. - -| Hook | Trigger | Function | Time | -|------|---------|----------|------| -| `memex-startup.sh` | SessionStart | Load project-specific memories | ~50ms | -| `memex-context.sh` | PostToolUse:Grep | Augment grep with relevant memories | ~50ms | -| `memory-on-compact.sh` | PreCompact | Save session context before compaction | ~50ms | - -**Requires:** -- `rmcp-memex` server running: `rmcp-memex serve --http-port 8987` -- Indexed memories (use `rmcp-memex index ` or MCP tools) - -**Environment Variables:** -- `MEMEX_URL` - Server URL (default: `http://localhost:8987`) -- `MEMEX_LIMIT` - Max results per query (default: `3`) -- `MEMEX_TIMEOUT` - Request timeout in seconds (default: `3`) - -## Installation - -### Interactive (Recommended) -```bash -cd loctree-suite -make ai-hooks -``` - -You'll be prompted to choose which CLIs to configure (Claude Code, Codex CLI, etc.) - -### Non-Interactive -```bash -# Install hooks for Claude Code -make ai-hooks CLI=claude - -# Install hooks for all supported CLIs -make ai-hooks CLI=all -``` - -## Requirements - -### Loctree hooks -- `loct` CLI installed (`make install` in loctree-suite) -- `jq` for JSON parsing - -### Memex hooks (optional) -- `rmcp-memex` CLI installed (`cargo install rmcp-memex`) -- Memex server running (`rmcp-memex serve --http-port 8987`) -- `curl` and `jq` for HTTP API calls - -The installer will offer to install missing dependencies. - -## Manual Configuration - -If automatic settings.json update fails, add hooks manually: - -### Claude Code (~/.claude/settings.json) -```json -{ - "hooks": { - "PostToolUse": [ - { - "matcher": "Grep", - "hooks": [ - {"type": "command", "command": "~/.claude/hooks/loct-grep-augment.sh"} - ] - } - ] - } -} -``` - -## Environment Variables - -### Loctree -- `LOCT_AUGMENT=0` - Disable loctree augmentation -- `LOCT_MAX_LINES=40` - Max output lines -- `LOCT_TIMEOUT=15` - Command timeout (seconds) - -## Loctree Command Reference - -### ⚡ FAST Commands (<100ms) - -| Command | Description | Time | -|---------|-------------|------| -| `loct find ` | Semantic + params + dead status | ~75ms | -| `loct slice ` | File + deps + consumers | ~81ms | -| `loct impact ` | What breaks if file changes | ~49ms | -| `loct query who-imports ` | Files importing target | ~53ms | -| `loct query where-symbol ` | Where symbol is defined (exact) | ~75ms | -| `loct focus ` | All files in directory + deps | ~56ms | -| `loct commands` | Tauri command bridges | ~47ms | -| `loct health` | Quick health summary | ~372ms | - -> **All commands support `--json` output!** - -### 🔍 Analysis Commands - -| Command | Description | -|---------|-------------| -| `loct dead` | Unused exports (dead code) | -| `loct cycles` | Circular imports | -| `loct twins` | Duplicate symbol names | -| `loct zombie` | Dead + orphan + shadows | -| `loct routes` | FastAPI/Flask routes | - -### 🔤 Single-Letter Aliases - -| Alias | Command | -|-------|---------| -| `loct s` | slice | -| `loct f` | find | -| `loct i` | impact | -| `loct h` | health | -| `loct q` | query | - -## How It Works - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Claude: Grep "detect_language" (ripgrep ~10ms) │ -│ │ │ -│ ▼ │ -│ PostToolUse:Grep hook fires │ -│ │ │ -│ ▼ │ -│ ┌────────────────┐ │ -│ │ loct-grep │ │ -│ │ augment.sh v10 │ │ -│ │ (~75ms) │ │ -│ └────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────┐ │ -│ │ 🌳 LOCTREE CONTEXT │ │ -│ │ Symbol: classify.rs:27, twins.rs:500 │ │ -│ │ Semantic: detect_stack (0.53), detect_crowd... │ │ -│ │ Dead: exported=true, dead=false │ │ -│ └─────────────────────────────────────────────────┘ │ -│ │ -│ USER sees: stderr output in terminal │ -│ AI sees: system-reminder with full JSON context │ -└─────────────────────────────────────────────────────────────┘ -``` - -## What's New in v10 - -1. **`loct find` is now FAST** (~75ms vs ~14500ms in older versions) -2. **Catch-all pattern matching** - any alphanumeric pattern ≥3 chars triggers augmentation -3. **Parameter matching** - finds function parameters, not just exports -4. **Semantic matching** - typo recovery, similar symbol suggestions -5. **Dead code status** - instant feedback on whether symbol is used - -## Troubleshooting - -### Hooks not running -1. Check settings.json syntax: `jq . ~/.claude/settings.json` -2. Verify hook is executable: `ls -la ~/.claude/hooks/` -3. Restart AI CLI - -### Loctree not finding anything -1. Run initial scan: `loct scan` in project root -2. Check snapshot: `loct '.metadata'` (artifacts are cached by default; set `LOCT_CACHE_DIR=.loctree` for repo-local artifacts) - -### No augmentation for a pattern -- Pattern must be ≥3 chars and alphanumeric -- `loct find` must return matches (check with `loct find --json`) - ---- -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/ai-hooks/example-settings.json b/ai-hooks/example-settings.json deleted file mode 100644 index 497a3f76..00000000 --- a/ai-hooks/example-settings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "hooks": { - "PostToolUse": [ - { - "matcher": "Grep", - "hooks": [ - { - "type": "command", - "command": "~/.claude/hooks/loct-grep-augment.sh" - } - ] - } - ] - } -} diff --git a/ai-hooks/loct-grep-augment.sh b/ai-hooks/loct-grep-augment.sh deleted file mode 100755 index f96c8d9f..00000000 --- a/ai-hooks/loct-grep-augment.sh +++ /dev/null @@ -1,443 +0,0 @@ -#!/bin/bash -# ============================================================================ -# loct-grep-augment.sh v10 - SEMANTIC AUGMENTATION WITH loct find -# ============================================================================ -# Created by M&K ⓒ 2025-2026 The Loctree Team -# -# PHILOSOPHY: Every grep gets loctree context. Always <100ms. -# -# BENCHMARK (loctree 0.8.4 - UPDATED 2026-01): -# loct find ~75ms ✅ (semantic + params + dead status) -# loct commands ~47ms ✅ -# loct impact ~49ms ✅ -# loct query who-imports ~53ms ✅ -# loct focus ~56ms ✅ -# loct slice ~81ms ✅ -# loct health ~372ms ⚠️ (only for health queries) -# -# KEY CHANGE v10: loct find is now FAST! Use it for all symbol lookups. -# ============================================================================ - -set -uo pipefail -export PATH="$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH" - -# Quick exit if dependencies unavailable -command -v loct >/dev/null 2>&1 || exit 0 -command -v jq >/dev/null 2>&1 || exit 0 - -# ============================================================================ -# OPTIONAL LOGGING (default OFF - set LOCT_HOOK_LOG_FILE to enable) -# ============================================================================ -# Only logs metadata (pattern truncated, timing, action) - never tool_response! -# Enable: export LOCT_HOOK_LOG_FILE="$HOME/.claude/logs/loct-grep.log" - -LOG_FILE="${LOCT_HOOK_LOG_FILE:-}" -LOG_START_MS= - -log_meta() { - [[ -z "$LOG_FILE" ]] && return 0 - mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true - printf '%s\n' "$*" >> "$LOG_FILE" 2>/dev/null || true -} - -log_start() { - [[ -z "$LOG_FILE" ]] && return 0 - LOG_START_MS=$(($(date +%s%N 2>/dev/null || echo "$(date +%s)000000000") / 1000000)) - log_meta "" - log_meta "==== LOCT HOOK: $(date '+%Y-%m-%d %H:%M:%S') ====" -} - -log_end() { - [[ -z "$LOG_FILE" ]] && return 0 - local action="${1:-unknown}" - local pattern_short="${PATTERN:-?}" - [[ ${#pattern_short} -gt 40 ]] && pattern_short="${pattern_short:0:37}..." - - local end_ms=$(($(date +%s%N 2>/dev/null || echo "$(date +%s)000000000") / 1000000)) - local duration_ms=$((end_ms - LOG_START_MS)) - - log_meta "pattern: $pattern_short" - log_meta "path: ${PATH_ARG:-.}" - log_meta "action: $action" - log_meta "time: ${duration_ms}ms" - log_meta "----" -} - -# Start timing (if logging enabled) -log_start - -# Read hook input -HOOK_INPUT=$(cat) -[[ -z "$HOOK_INPUT" ]] && exit 0 - -# ============================================================================ -# PATTERN EXTRACTION -# ============================================================================ - -if [[ "${1:-}" == "--bash-filter" ]]; then - # Bash tool with rg/grep command - COMMAND=$(echo "$HOOK_INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null) - echo "$COMMAND" | grep -qE '(^|[[:space:]])(rg|ripgrep|grep)[[:space:]]' || exit 0 - - # Extract quoted pattern first, then unquoted - PATTERN=$(echo "$COMMAND" | grep -oE '"[^"]+"' | head -1 | tr -d '"') - [[ -z "$PATTERN" ]] && PATTERN=$(echo "$COMMAND" | grep -oE "'[^']+'" | head -1 | tr -d "'") - [[ -z "$PATTERN" ]] && PATTERN=$(echo "$COMMAND" | sed -nE 's/.*\b(rg|grep)\b[[:space:]]+([^[:space:]-][^[:space:]]*).*/\2/p') - - # Extract path (last arg if looks like path) - PATH_ARG=$(echo "$COMMAND" | awk '{print $NF}') - [[ ! "$PATH_ARG" =~ ^\.?/ ]] && [[ ! -e "$PATH_ARG" ]] && PATH_ARG="." -else - # Native Grep tool - PATTERN=$(echo "$HOOK_INPUT" | jq -r '.tool_input.pattern // empty' 2>/dev/null) - PATH_ARG=$(echo "$HOOK_INPUT" | jq -r '.tool_input.path // "."' 2>/dev/null) -fi - -# Change to appropriate directory for loctree context -# Priority: tool_input.path (if absolute) > session_cwd > current dir -if [[ "$PATH_ARG" == /* ]] && [[ -d "$PATH_ARG" ]]; then - # Absolute directory path - use it directly - cd "$PATH_ARG" -elif [[ "$PATH_ARG" == /* ]] && [[ -f "$PATH_ARG" ]]; then - # Absolute file path - use its parent directory - cd "$(dirname "$PATH_ARG")" -else - # Fall back to session_cwd - SESSION_CWD=$(echo "$HOOK_INPUT" | jq -r '.session_cwd // empty' 2>/dev/null) - [[ -n "$SESSION_CWD" ]] && [[ -d "$SESSION_CWD" ]] && cd "$SESSION_CWD" -fi - -# Find repo root (prefer git root; fall back to current dir). -# We no longer require a project-local `.loctree/` for cached artifacts. -REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) -if [[ -n "$REPO_ROOT" ]] && [[ -d "$REPO_ROOT" ]]; then - cd "$REPO_ROOT" -else - REPO_ROOT=$(pwd) -fi - -# Validation -[[ -z "$PATTERN" ]] && exit 0 -[[ ${#PATTERN} -lt 3 ]] && exit 0 -# Skip heavy regex patterns -echo "$PATTERN" | grep -qE '[\|\*\+\?\[\]\(\)\{\}\\]{3,}' && exit 0 - -# Clean quotes -PATTERN="${PATTERN%\"}" -PATTERN="${PATTERN#\"}" -PATTERN="${PATTERN%\'}" -PATTERN="${PATTERN#\'}" - -# ============================================================================ -# OUTPUT HELPER -# ============================================================================ - -# Max payload size (32KB) to avoid bloating additionalContext -MAX_PAYLOAD_BYTES=32768 - -truncate_payload() { - local text="$1" - local max="$2" - if [[ ${#text} -gt $max ]]; then - printf '%s\n\n[...truncated, showing first %d bytes of %d total]' \ - "${text:0:$max}" "$max" "${#text}" - else - printf '%s' "$text" - fi -} - -output_json() { - local header="$1" - local json_content="$2" - - # Log metadata (if enabled) - uses header as action name - log_end "$header" - - local msg=" -━━━ 🌳 LOCTREE: $header ━━━ -$json_content" - - # Truncate if too large (prevents client issues) - msg="$(truncate_payload "$msg" "$MAX_PAYLOAD_BYTES")" - - # Human-readable for Maciej (stderr) - echo "$msg" >&2 - - # JSON for Claude Code (stdout - CC parses hookSpecificOutput) - local escaped - escaped=$(echo "$msg" | jq -Rs .) - local output - output=$(cat << EOF -{ - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": $escaped - } -} -EOF -) - # Output to stdout - echo "$output" - - # Save to cache (if cache key is set) - [[ -n "${CACHE_KEY:-}" ]] && echo "$output" > "$CACHE_KEY" 2>/dev/null -} - -# ============================================================================ -# RESPONSE CACHE (dedup - same query within TTL returns cached response) -# ============================================================================ - -CACHE_DIR="/tmp/.loct-grep-cache" -CACHE_TTL=60 # seconds - -# Compute cache key from: repo_root + git_commit + pattern + path -compute_cache_key() { - local repo="$1" - local pattern="$2" - local path="$3" - - # Get current git commit (short hash) or "nocommit" - local commit - commit=$(git -C "$repo" rev-parse --short HEAD 2>/dev/null || echo "nocommit") - - # Create cache dir if needed - mkdir -p "$CACHE_DIR" 2>/dev/null || true - - # MD5 hash of key components - local hash - hash=$(printf '%s:%s:%s:%s' "$repo" "$commit" "$pattern" "$path" | md5 2>/dev/null || md5sum | cut -c1-32) - - echo "${CACHE_DIR}/${hash}.json" -} - -# Check cache - returns 0 and outputs cached response if hit, 1 if miss -check_cache() { - local cache_file="$1" - - [[ ! -f "$cache_file" ]] && return 1 - - # Check age - local cache_age - if stat -f%m "$cache_file" &>/dev/null; then - cache_age=$(($(date +%s) - $(stat -f%m "$cache_file"))) - else - cache_age=$(($(date +%s) - $(stat -c%Y "$cache_file"))) - fi - - if [[ $cache_age -lt $CACHE_TTL ]]; then - # Cache hit - output cached response - cat "$cache_file" - # Debug to log only (not stderr - would pollute UI) - log_meta "[cache] hit (${cache_age}s old)" - return 0 - fi - - # Cache expired - rm -f "$cache_file" 2>/dev/null - return 1 -} - -# ============================================================================ -# FAST AUGMENTATION FUNCTIONS (<100ms each!) -# ============================================================================ - -# Symbol lookup via loct find (FAST in 0.8.4: ~75ms with semantic matches!) -augment_symbol() { - local symbol="$1" - local result - - # loct find gives: symbol_matches + param_matches + semantic_matches + dead_status - result=$(loct find "$symbol" --json 2>/dev/null) - [[ -z "$result" ]] && return 1 - - # Check if ANY matches found (symbol, param, or semantic) - local has_matches - has_matches=$(echo "$result" | jq ' - (.symbol_matches.total_matches // 0) > 0 or - (.param_matches | length) > 0 or - (.semantic_matches | length) > 0 - ' 2>/dev/null) - [[ "$has_matches" != "true" ]] && return 1 - - output_json "find $symbol" "$result" - exit 0 -} - -# File context via slice -augment_file() { - local file="$1" - [[ ! -f "$file" ]] && return 1 - - local result - result=$(loct slice "$file" --json 2>/dev/null) - [[ -z "$result" ]] && return 1 - - output_json "slice $file" "$result" - exit 0 -} - -# File impact analysis -augment_impact() { - local file="$1" - [[ ! -f "$file" ]] && return 1 - - local result - result=$(loct impact "$file" --json 2>/dev/null) - [[ -z "$result" ]] && return 1 - - output_json "impact $file" "$result" - exit 0 -} - -# Who imports this file -augment_who_imports() { - local file="$1" - [[ ! -f "$file" ]] && return 1 - - local result - result=$(loct query who-imports "$file" --json 2>/dev/null) - [[ -z "$result" ]] && return 1 - - output_json "who-imports $file" "$result" - exit 0 -} - -# Directory overview via focus -augment_directory() { - local dir="$1" - [[ ! -d "$dir" ]] && return 1 - - local result - result=$(loct focus "$dir" --json 2>/dev/null) - [[ -z "$result" ]] && return 1 - - output_json "focus $dir" "$result" - exit 0 -} - -# Tauri command bridge -augment_tauri_command() { - local cmd="$1" - - local result - result=$(loct commands --json 2>/dev/null | jq --arg cmd "$cmd" '[.[] | select(.name | contains($cmd))]' 2>/dev/null) - [[ -z "$result" ]] || [[ "$result" == "[]" ]] && return 1 - - output_json "commands matching $cmd" "$result" - exit 0 -} - -# Health check (only for health-related queries, ~372ms) -augment_health() { - local result - result=$(loct health --json 2>/dev/null) - [[ -z "$result" ]] && return 1 - - output_json "health" "$result" - exit 0 -} - -# ============================================================================ -# CACHE CHECK - Return cached response if available (dedup) -# ============================================================================ - -CACHE_KEY=$(compute_cache_key "$REPO_ROOT" "$PATTERN" "$PATH_ARG") -if check_cache "$CACHE_KEY"; then - log_end "cache-hit" - exit 0 -fi - -# ============================================================================ -# SMART ROUTING - Pattern → Best Augmentation -# ============================================================================ - -# Priority 1: Exact file path → slice + who-imports -if [[ -f "$PATTERN" ]]; then - augment_file "$PATTERN" -fi - -# Priority 2: Path argument is specific file → impact analysis -if [[ "$PATH_ARG" != "." ]] && [[ -f "$PATH_ARG" ]]; then - augment_impact "$PATH_ARG" -fi - -# Priority 3: Directory path → focus -if [[ -d "$PATTERN" ]] || [[ "$PATTERN" == */ ]]; then - augment_directory "${PATTERN%/}" -fi -if [[ "$PATH_ARG" != "." ]] && [[ -d "$PATH_ARG" ]]; then - augment_directory "$PATH_ARG" -fi - -# Priority 4: Tauri snake_case commands (mcp_list_integrations, etc.) -if echo "$PATTERN" | grep -qE '^[a-z][a-z0-9]*(_[a-z0-9]+)+$'; then - augment_tauri_command "$PATTERN" -fi - -# Priority 5: File-like pattern (has extension) → find file, then slice -if echo "$PATTERN" | grep -qE '\.(ts|tsx|rs|js|jsx|py|vue|svelte|css|scss)$'; then - FOUND=$(find . -path "./.git" -prune -o -name "$PATTERN" -type f -print 2>/dev/null | head -1) - [[ -n "$FOUND" ]] && augment_file "$FOUND" -fi - -# Priority 6: Symbol patterns → FAST query where-symbol -# PascalCase: Components, Types, Interfaces (ChatPanel, PatientRecord) -if echo "$PATTERN" | grep -qE '^[A-Z][a-zA-Z0-9]{2,}$'; then - augment_symbol "$PATTERN" -fi - -# camelCase with uppercase: hooks, handlers (useVistaAgent, handleClick) -if echo "$PATTERN" | grep -qE '^[a-z]+[A-Z][a-zA-Z0-9]*$'; then - augment_symbol "$PATTERN" -fi - -# React hooks: useXxx -if echo "$PATTERN" | grep -qE '^use[A-Z][a-zA-Z0-9]+$'; then - augment_symbol "$PATTERN" -fi - -# Event handlers: handleXxx, onXxx -if echo "$PATTERN" | grep -qE '^(handle|on)[A-Z][a-zA-Z0-9]+$'; then - augment_symbol "$PATTERN" -fi - -# snake_case identifiers (Rust, Python) -if echo "$PATTERN" | grep -qE '^[a-z][a-z0-9]*_[a-z_0-9]+$'; then - augment_symbol "$PATTERN" -fi - -# Boolean prefixes: isActive, hasPermission, canEdit -if echo "$PATTERN" | grep -qE '^(is|has|can|should|will)[A-Z][a-zA-Z0-9]*$'; then - augment_symbol "$PATTERN" -fi - -# SCREAMING_CASE constants -if echo "$PATTERN" | grep -qE '^[A-Z][A-Z0-9_]+$'; then - augment_symbol "$PATTERN" -fi - -# Priority 7: Path-like patterns → try to resolve -if [[ "$PATTERN" == *"/"* ]]; then - # Try as file - FOUND=$(find . -path "./.git" -prune -o -path "*$PATTERN*" -type f -print 2>/dev/null | head -1) - [[ -n "$FOUND" ]] && augment_file "$FOUND" - - # Try as directory - FOUND_DIR=$(find . -path "./.git" -prune -o -path "*$PATTERN*" -type d -print 2>/dev/null | head -1) - [[ -n "$FOUND_DIR" ]] && augment_directory "$FOUND_DIR" -fi - -# Priority 8: Health-related keywords (only case where we use slower command) -if echo "$PATTERN" | grep -qiE 'dead|unused|orphan|stale|deprecated|circular|cycle|duplicate|twin'; then - augment_health -fi - -# Priority 9: CATCH-ALL - Any alphanumeric pattern ≥3 chars → try loct find -# This catches patterns like "passthrough", "handler", "template" that fell through -if echo "$PATTERN" | grep -qE '^[a-zA-Z_][a-zA-Z0-9_]{2,}$'; then - augment_symbol "$PATTERN" -fi - -# No augmentation needed for pure text/regex searches -log_end "no-match" -exit 0 diff --git a/ai-hooks/loct-smart-suggest.sh b/ai-hooks/loct-smart-suggest.sh deleted file mode 100755 index 7516f915..00000000 --- a/ai-hooks/loct-smart-suggest.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/bash -export PATH="$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH" - -# Quick exit if jq unavailable (has grep fallback but jq preferred) -command -v jq >/dev/null 2>&1 || exit 0 - -# ============================================================================ -# loct-smart-suggest.sh - Context-aware loct suggestions for Claude Code -# ============================================================================ -# -# ALTERNATIVE APPROACH: PreToolUse hook that SUGGESTS loct commands -# instead of automatically augmenting. Use this if you prefer manual control. -# -# Non-blocking! Just adds helpful hints to stderr when loct would be better. -# -# INSTALLATION: -# 1. Copy to ~/.claude/hooks/loct-smart-suggest.sh -# 2. chmod +x ~/.claude/hooks/loct-smart-suggest.sh -# 3. Add to ~/.claude/settings.json under PreToolUse (not PostToolUse) -# -# ============================================================================ - -INPUT=$(cat) - -# Extract pattern from JSON -PATTERN=$(echo "$INPUT" | jq -r '.pattern // .tool_input.pattern // empty' 2>/dev/null) -if [[ -z "$PATTERN" ]]; then - PATTERN=$(echo "$INPUT" | grep -oP '"pattern"\s*:\s*"\K[^"]+' 2>/dev/null || echo "") -fi - -[[ -z "$PATTERN" ]] && exit 0 - -# Track suggestions to avoid spam (max 3 per session) -SUGGEST_COUNT_FILE="/tmp/.loct-suggest-count-$(date +%Y%m%d)" -SUGGEST_COUNT=$(cat "$SUGGEST_COUNT_FILE" 2>/dev/null || echo "0") -[[ "$SUGGEST_COUNT" -ge 3 ]] && exit 0 - -suggest() { - local hint="$1" - local cmd="$2" - echo "" >&2 - echo "┌─────────────────────────────────────────────────────────────" >&2 - echo "│ 🌳 $hint" >&2 - echo "│ → $cmd" >&2 - echo "└─────────────────────────────────────────────────────────────" >&2 - echo "" >&2 - echo $((SUGGEST_COUNT + 1)) > "$SUGGEST_COUNT_FILE" -} - -# Case 1: React Component or Type (PascalCase) -if [[ "$PATTERN" =~ ^[A-Z][a-zA-Z0-9]{2,}$ ]]; then - suggest "Symbol search? loct finds definition + all usages" \ - "loct f $PATTERN" - exit 0 -fi - -# Case 2: React Hook (useXxx) -if [[ "$PATTERN" =~ ^use[A-Z][a-zA-Z0-9]+$ ]]; then - suggest "Hook search? loct shows definition + import chain" \ - "loct f $PATTERN" - exit 0 -fi - -# Case 3: Event Handler (handleXxx, onXxx) -if [[ "$PATTERN" =~ ^(handle|on)[A-Z][a-zA-Z0-9]+$ ]]; then - suggest "Handler search? loct finds definition + prop passing" \ - "loct f $PATTERN" - exit 0 -fi - -# Case 4: Tauri command patterns -if [[ "$PATTERN" =~ invoke|safeInvoke|emit\( ]]; then - suggest "Tauri bridge? loct trace shows FE↔BE coverage" \ - "loct trace " - exit 0 -fi - -# Case 5: Import/export analysis -if [[ "$PATTERN" =~ ^import|^export|from.+import ]]; then - suggest "Import analysis? loct has full dependency graph" \ - "loct q who-imports " - exit 0 -fi - -# Case 6: Snake_case symbol (Rust/Python) -if [[ "$PATTERN" =~ ^[a-z][a-z0-9]*_[a-z_0-9]+$ ]]; then - suggest "Symbol search? loct finds across TS+Rust with context" \ - "loct f $PATTERN" - exit 0 -fi - -# Case 7: Checking if something exists/is used -if [[ "$PATTERN" =~ ^(is|has|can|should)[A-Z] ]]; then - suggest "Checking usage? loct can tell if it's dead code" \ - "loct f $PATTERN" - exit 0 -fi - -# Case 8: Dead/unused patterns -if [[ "$PATTERN" =~ dead|unused|orphan|stale ]]; then - suggest "Dead code hunt? loct has pre-indexed findings" \ - "loct health" - exit 0 -fi - -# Case 9: Circular/cycle patterns -if [[ "$PATTERN" =~ circular|cycle|loop|recursive ]]; then - suggest "Cycle detection? loct has SCC analysis ready" \ - "loct health" - exit 0 -fi - -# Case 10: Duplicate/twin patterns -if [[ "$PATTERN" =~ duplicate|twin|copy|similar ]]; then - suggest "Finding duplicates? loct detected exact twins" \ - "loct health" - exit 0 -fi - -# No match - grep is fine -exit 0 diff --git a/ai-hooks/memex-context.sh b/ai-hooks/memex-context.sh deleted file mode 100755 index 226a28d2..00000000 --- a/ai-hooks/memex-context.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -# ============================================================================ -# memex-context.sh - Project context loader via HTTP API -# ============================================================================ -# Created by M&K ⓒ 2025-2026 VetCoders -# -# TRIGGER: PostToolUse (Grep, Read) -# PURPOSE: Augment tool results with relevant memories from memex -# -# REQUIRES: rmcp-memex server running (rmcp-memex serve --http-port 8987) -# BENCHMARK: ~50ms (HTTP API) -# ============================================================================ - -set -uo pipefail -export PATH="$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH" - -# Configuration -MEMEX_URL="${MEMEX_URL:-http://localhost:8987}" -MEMEX_LIMIT="${MEMEX_LIMIT:-3}" -MEMEX_TIMEOUT="${MEMEX_TIMEOUT:-2}" - -# Quick exits -command -v curl &>/dev/null || exit 0 -command -v jq &>/dev/null || exit 0 - -# Read hook input -HOOK_INPUT=$(cat) -[[ -z "$HOOK_INPUT" ]] && exit 0 - -# Extract pattern from Grep tool -PATTERN=$(echo "$HOOK_INPUT" | jq -r '.tool_input.pattern // empty' 2>/dev/null) -[[ -z "$PATTERN" ]] && exit 0 -[[ ${#PATTERN} -lt 3 ]] && exit 0 - -# Skip heavy regex patterns -echo "$PATTERN" | grep -qE '[\|\*\+\?\[\]\(\)\{\}\\]{3,}' && exit 0 - -# Check if server is up -if ! curl -s --max-time 1 "$MEMEX_URL/health" >/dev/null 2>&1; then - exit 0 -fi - -# Search memex -SEARCH_RESULT=$(curl -s --max-time "$MEMEX_TIMEOUT" \ - "$MEMEX_URL/cross-search?q=$(echo "$PATTERN" | jq -sRr @uri)&limit=$MEMEX_LIMIT" \ - 2>/dev/null) - -[[ -z "$SEARCH_RESULT" ]] && exit 0 - -# Check if we got results -RESULT_COUNT=$(echo "$SEARCH_RESULT" | jq -r '.total_results // 0' 2>/dev/null) -[[ "$RESULT_COUNT" == "0" ]] && exit 0 - -# Format output -MEMORIES=$(echo "$SEARCH_RESULT" | jq -r ' - .results[:3] | - to_entries | - map("[\(.value.namespace)] \(.value.text | .[0:200] | gsub("\n"; " "))")[] -' 2>/dev/null) - -[[ -z "$MEMORIES" ]] && exit 0 - -CONTEXT=" ---- MEMEX: $RESULT_COUNT memories for '$PATTERN' --- -$MEMORIES" - -# Human-readable (stderr) -echo "$CONTEXT" >&2 - -# JSON for Claude Code (stdout) -ESCAPED=$(echo "$CONTEXT" | jq -Rs .) -cat << EOF -{ - "hookSpecificOutput": { - "hookEventName": "PostToolUse", - "additionalContext": $ESCAPED - } -} -EOF -exit 0 diff --git a/ai-hooks/memex-startup.sh b/ai-hooks/memex-startup.sh deleted file mode 100755 index 5e3d7a2c..00000000 --- a/ai-hooks/memex-startup.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash -# ============================================================================ -# memex-startup.sh - Project context loader at session start -# ============================================================================ -# Created by M&K ⓒ 2025-2026 VetCoders -# -# TRIGGER: SessionStart hook -# PURPOSE: Load institutional knowledge about the current project from memex -# -# REQUIRES: rmcp-memex server running (rmcp-memex serve --http-port 8987) -# BENCHMARK: ~50ms (HTTP API with 1h caching) -# ============================================================================ - -set -uo pipefail -export PATH="$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH" - -# Configuration -MEMEX_URL="${MEMEX_URL:-http://localhost:8987}" -MEMEX_LIMIT="${MEMEX_LIMIT:-3}" -MEMEX_TIMEOUT="${MEMEX_TIMEOUT:-3}" -CACHE_TTL=3600 # 1 hour - -# Quick exits -command -v curl &>/dev/null || exit 0 -command -v jq &>/dev/null || exit 0 - -# Find repo root (git root or .loctree parent) -REPO_ROOT=$(pwd) -GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || true) -if [[ -n "$GIT_ROOT" ]]; then - REPO_ROOT="$GIT_ROOT" -else - # Fallback: find .loctree directory - while [[ "$REPO_ROOT" != "/" ]] && [[ ! -d "$REPO_ROOT/.loctree" ]]; do - REPO_ROOT=$(dirname "$REPO_ROOT") - done - [[ ! -d "$REPO_ROOT/.loctree" ]] && REPO_ROOT=$(pwd) -fi - -# Cache uses repo root (not PWD) to avoid subfolder confusion -CACHE_FILE="/tmp/memex-startup-$(echo "$REPO_ROOT" | md5 2>/dev/null || md5sum <<< "$REPO_ROOT" | cut -c1-8).cache" - -# Cache check - only load once per project per hour -if [[ -f "$CACHE_FILE" ]]; then - if stat -f%m "$CACHE_FILE" &>/dev/null; then - CACHE_AGE=$(($(date +%s) - $(stat -f%m "$CACHE_FILE"))) - else - CACHE_AGE=$(($(date +%s) - $(stat -c%Y "$CACHE_FILE"))) - fi - if [[ $CACHE_AGE -lt $CACHE_TTL ]]; then - exit 0 - fi -fi - -# Check if server is up -if ! curl -s --max-time 1 "$MEMEX_URL/health" >/dev/null 2>&1; then - touch "$CACHE_FILE" - exit 0 -fi - -# Project detection (use already-resolved REPO_ROOT) -PROJECT_NAME=$(basename "$REPO_ROOT") -PROJECT_QUERY=$(echo "$PROJECT_NAME" | tr '-_' ' ') - -# Search memex -SEARCH_RESULT=$(curl -s --max-time "$MEMEX_TIMEOUT" \ - "$MEMEX_URL/cross-search?q=$(echo "$PROJECT_QUERY" | jq -sRr @uri)&limit=$MEMEX_LIMIT&total_limit=$((MEMEX_LIMIT * 2))" \ - 2>/dev/null) - -touch "$CACHE_FILE" - -[[ -z "$SEARCH_RESULT" ]] && exit 0 - -# Check if we got results -RESULT_COUNT=$(echo "$SEARCH_RESULT" | jq -r '.total_results // 0' 2>/dev/null) -[[ "$RESULT_COUNT" == "0" ]] && exit 0 - -# Format output -MEMORIES=$(echo "$SEARCH_RESULT" | jq -r ' - .results[:3] | - to_entries | - map("[\(.value.namespace)] \(.value.text | .[0:300] | gsub("\n"; " "))")[] -' 2>/dev/null) - -[[ -z "$MEMORIES" ]] && exit 0 - -NS_SEARCHED=$(echo "$SEARCH_RESULT" | jq -r '.namespaces_searched // 0' 2>/dev/null) - -CONTEXT=" ---- MEMEX: $PROJECT_NAME (searched $NS_SEARCHED namespaces) --- -$MEMORIES" - -# Human-readable (stderr) -echo "$CONTEXT" >&2 - -# JSON for Claude Code (stdout) -ESCAPED=$(echo "$CONTEXT" | jq -Rs .) -cat << EOF -{ - "hookSpecificOutput": { - "hookEventName": "SessionStart", - "additionalContext": $ESCAPED - } -} -EOF -exit 0 diff --git a/ai-hooks/memory-on-compact.sh b/ai-hooks/memory-on-compact.sh deleted file mode 100755 index 8655e182..00000000 --- a/ai-hooks/memory-on-compact.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# ============================================================================ -# memory-on-compact.sh - Save session context before compaction -# ============================================================================ -# Created by M&K ⓒ 2025-2026 VetCoders -# -# TRIGGER: PreCompact hook (manual or auto) -# PURPOSE: Persist conversation context to memex before context window compacts -# -# REQUIRES: rmcp-memex server running (rmcp-memex serve --http-port 8987) -# BENCHMARK: ~50ms (HTTP API) -# ============================================================================ - -set -uo pipefail -export PATH="$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH" - -# Configuration -MEMEX_URL="${MEMEX_URL:-http://localhost:8987}" -MEMEX_TIMEOUT="${MEMEX_TIMEOUT:-5}" -NAMESPACE="ai-sessions" -TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - -# Quick exits -command -v curl &>/dev/null || exit 0 -command -v jq &>/dev/null || exit 0 - -# Read hook input -input=$(cat) - -# Parse JSON fields -session_id=$(echo "$input" | jq -r '.session_id // "unknown"') -transcript_path=$(echo "$input" | jq -r '.transcript_path // ""') -trigger=$(echo "$input" | jq -r '.trigger // "manual"') -custom_instructions=$(echo "$input" | jq -r '.custom_instructions // ""') - -ID="compact-$(date +%Y%m%d-%H%M%S)-${session_id:0:8}" - -# Extract summary from transcript if available -summary="" -if [ -n "$transcript_path" ] && [ -f "$transcript_path" ]; then - summary=$(tail -n 20 "$transcript_path" 2>/dev/null | head -c 5000) -fi - -# Add custom instructions if provided -if [ -n "$custom_instructions" ]; then - summary="CUSTOM: $custom_instructions - -$summary" -fi - -# Only upsert if we have content -if [ -z "$summary" ]; then - echo "No content to save for compact" >&2 - exit 0 -fi - -# Check if server is up -if ! curl -s --max-time 1 "$MEMEX_URL/health" >/dev/null 2>&1; then - echo "Memex server not available, skipping" >&2 - exit 0 -fi - -# Build JSON payload -JSON_PAYLOAD=$(jq -n \ - --arg namespace "$NAMESPACE" \ - --arg id "$ID" \ - --arg text "$summary" \ - --arg type "compact" \ - --arg trigger "$trigger" \ - --arg timestamp "$TIMESTAMP" \ - --arg host "$(hostname)" \ - --arg session "$session_id" \ - '{ - namespace: $namespace, - id: $id, - text: $text, - metadata: { - type: $type, - trigger: $trigger, - timestamp: $timestamp, - host: $host, - session: $session - } - }') - -# Upsert to memex via HTTP -RESPONSE=$(curl -s --max-time "$MEMEX_TIMEOUT" \ - -X POST "$MEMEX_URL/upsert" \ - -H "Content-Type: application/json" \ - -d "$JSON_PAYLOAD" 2>/dev/null) - -if echo "$RESPONSE" | jq -e '.success' &>/dev/null; then - echo "Compact memory saved: $ID ($trigger)" >&2 -else - echo "Failed to save compact memory: $RESPONSE" >&2 -fi - -exit 0 diff --git a/assets/Loctree.icon/Assets/loctree_logo.png b/assets/Loctree.icon/Assets/loctree_logo.png deleted file mode 100644 index df0d34a0..00000000 Binary files a/assets/Loctree.icon/Assets/loctree_logo.png and /dev/null differ diff --git a/assets/Loctree.icon/icon.json b/assets/Loctree.icon/icon.json deleted file mode 100644 index 45a3105b..00000000 --- a/assets/Loctree.icon/icon.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "fill-specializations" : [ - { - "value" : { - "linear-gradient" : [ - "display-p3:0.01901,0.01917,0.01934,1.00000", - "display-p3:0.03012,0.01695,0.04535,1.00000" - ] - } - }, - { - "appearance" : "dark", - "value" : "system-dark" - } - ], - "groups" : [ - { - "blend-mode" : "hard-light", - "blur-material-specializations" : [ - { - "value" : null - }, - { - "appearance" : "dark", - "value" : null - } - ], - "hidden-specializations" : [ - { - "idiom" : "square", - "value" : false - } - ], - "layers" : [ - { - "blend-mode" : "lighten", - "fill" : { - "solid" : "extended-gray:1.00000,1.00000" - }, - "glass-specializations" : [ - { - "appearance" : "dark", - "value" : false - } - ], - "image-name-specializations" : [ - { - "value" : "loctree_logo 2.png" - }, - { - "idiom" : "square", - "value" : "loctree_logo.png" - } - ], - "name" : "loctree_logo", - "position-specializations" : [ - { - "idiom" : "square", - "value" : { - "scale" : 1.5, - "translation-in-points" : [ - 0, - 0 - ] - } - } - ] - } - ], - "lighting-specializations" : [ - { - "value" : "combined" - }, - { - "appearance" : "dark", - "value" : "combined" - } - ], - "opacity" : 0.9, - "position-specializations" : [ - { - "idiom" : "square", - "value" : { - "scale" : 1.25, - "translation-in-points" : [ - 0, - 21.9296875 - ] - } - } - ], - "shadow" : { - "kind" : "none", - "opacity" : 0.5 - }, - "specular-specializations" : [ - { - "value" : false - }, - { - "appearance" : "dark", - "value" : false - } - ], - "translucency-specializations" : [ - { - "value" : { - "enabled" : false, - "value" : 0.5 - } - }, - { - "appearance" : "dark", - "value" : { - "enabled" : false, - "value" : 0.5 - } - } - ] - } - ], - "supported-platforms" : { - "circles" : [ - "watchOS" - ], - "squares" : "shared" - } -} \ No newline at end of file diff --git a/assets/loctree-badge.svg b/assets/loctree-badge.svg deleted file mode 100644 index 606c9a51..00000000 --- a/assets/loctree-badge.svg +++ /dev/null @@ -1,21 +0,0 @@ - - analyzed with: loctree - - - - - - - - - - - - - - - analyzed with - - loctree - - diff --git a/assets/loctree-logo.png b/assets/loctree-logo.png deleted file mode 100644 index e49f41b5..00000000 Binary files a/assets/loctree-logo.png and /dev/null differ diff --git a/assets/loctree-logo.svg b/assets/loctree-logo.svg deleted file mode 100644 index ccc4e58a..00000000 --- a/assets/loctree-logo.svg +++ /dev/null @@ -1,30 +0,0 @@ - - Loctree Logo - Minimalist node tree - dynamic and slightly unsettling - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/loctree_logo.png b/assets/loctree_logo.png deleted file mode 100644 index df0d34a0..00000000 Binary files a/assets/loctree_logo.png and /dev/null differ diff --git a/build-landing.sh b/build-landing.sh deleted file mode 100755 index 3a5b19f0..00000000 --- a/build-landing.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e - -echo "=== Building Loctree Landing Page ===" - -cd landing -trunk build --release - -echo "=== Copying to public_dist ===" -cd .. -rm -rf public_dist -cp -r landing/dist public_dist - -echo "" -echo "=== Build complete! ===" -echo "Files ready in public_dist/" -echo "" -echo "Now click 'Publish' in Replit to deploy." diff --git a/distribution/README.md b/distribution/README.md deleted file mode 100644 index 547173d1..00000000 --- a/distribution/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Distribution Spine - -This directory is the single source of truth for every release channel that is -not "cargo publish the crate and hope for the best." - -## Channels - -- `crates/` - Rust crates.io release contract and publish notes. -- `homebrew/` - Formula source, tap sync notes, and helper scripts. -- `npm/` - Canonical npm wrapper and platform-package release flow. -- `macos/` - Signing, notarization, and direct-download bundle contract. -- `linux/` - Linux release asset contract. -- `windows/` - Windows release asset contract. - -## Principle - -One channel, one home. - -Do not scatter release state across root-level `Formula/`, ad-hoc docs, and -half-remembered shell rituals. If a distribution path is real, it belongs in -`distribution/`. diff --git a/distribution/crates/README.md b/distribution/crates/README.md deleted file mode 100644 index a69631c5..00000000 --- a/distribution/crates/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# crates.io - -The crates.io release is still the canonical Rust package surface: - -- `loctree` -- `report-leptos` -- `loctree-mcp` - -This channel is necessary, but no longer sufficient on its own. The rest of the -`distribution/` tree exists so the product can be installed by normal humans, -not only Rust users. diff --git a/distribution/homebrew/README.md b/distribution/homebrew/README.md deleted file mode 100644 index 6a7fa6ce..00000000 --- a/distribution/homebrew/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Homebrew Distribution - -The monorepo does not ship one generic Homebrew formula anymore. - -Instead: - -- CLI formula is rendered into `Loctree/homebrew-cli` -- MCP formula is rendered into `Loctree/homebrew-mcp` - -The rendering source of truth lives in: - -- `scripts/render-homebrew-formula.sh` -- `.github/workflows/homebrew-release.yml` - -## Release Contract - -1. `publish.yml` builds and uploads binary assets into the thin repos: - - `Loctree/loct` - - `Loctree/loctree-mcp` -2. `homebrew-release.yml` downloads those tarballs, computes SHA256 values, and - writes the tap formulas. - -## Local Test Flow - -After a release exists, you can render formulas locally by exporting the same -SHA variables the workflow uses and running: - -```bash -scripts/render-homebrew-formula.sh loct 0.9.0 /tmp/loct.rb -scripts/render-homebrew-formula.sh loctree-mcp 0.9.0 /tmp/loctree-mcp.rb -``` - -Then test with Homebrew: - -```bash -brew install --build-from-source /tmp/loct.rb -brew install --build-from-source /tmp/loctree-mcp.rb -``` diff --git a/distribution/linux/README.md b/distribution/linux/README.md deleted file mode 100644 index fdca26ff..00000000 --- a/distribution/linux/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Linux - -Linux release assets should stay boring and reliable: - -- one artifact name per supported target -- checksum alongside each uploaded release asset -- npm should only claim the targets that CI actually builds and smoke tests - -Right now the honest npm baseline is narrower than the old aspirational docs. -That is a feature, not a bug. diff --git a/distribution/macos/README.md b/distribution/macos/README.md deleted file mode 100644 index 70e554b7..00000000 --- a/distribution/macos/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# macOS - -This channel is for direct Loctree downloads outside Homebrew and npm. - -Target shape: - -- signed `loctree` and `loct` binaries -- notarized archive for direct download -- optional installer package later if we want a friendlier non-terminal path - -Current direction: - -- sign binaries with Developer ID Application -- notarize a zipped bundle with `notarytool` -- upload the notarized macOS asset to GitHub Releases -- run `distribution/macos/smoke-releaseability.sh` before packaging so releases fail on non-system dylib paths such as `/opt/homebrew/...` - -Releaseability smoke path: - -```bash -make smoke-release-macos-arm64 -``` - -Apple references: - -- Notarizing macOS software before distribution -- Signing Mac Software with Developer ID diff --git a/distribution/macos/sign-and-notarize.sh b/distribution/macos/sign-and-notarize.sh deleted file mode 100755 index 29d4c62a..00000000 --- a/distribution/macos/sign-and-notarize.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -if [[ $# -lt 2 ]]; then - echo "Usage: $0 " - exit 1 -fi - -DIST_DIR="$1" -OUTPUT_ZIP="$2" - -: "${MACOS_DEVELOPER_ID_APPLICATION:?Set MACOS_DEVELOPER_ID_APPLICATION}" - -if [[ ! -d "$DIST_DIR" ]]; then - echo "Missing dist dir: $DIST_DIR" - exit 1 -fi - -# --- Codesign --- -for bin in loctree loct; do - target="$DIST_DIR/$bin" - if [[ -f "$target" ]]; then - codesign --force --timestamp --options runtime --sign "$MACOS_DEVELOPER_ID_APPLICATION" "$target" - fi -done - -rm -f "$OUTPUT_ZIP" -ditto -c -k --keepParent "$DIST_DIR" "$OUTPUT_ZIP" - -# --- Notarization (API key auth, 3 retries, 15m timeout) --- - -# Resolve auth: prefer API key, fallback to app-specific password -NOTARY_AUTH=() -if [[ -n "${APPLE_API_KEY_BASE64:-}" && -n "${APPLE_API_KEY_ID:-}" && -n "${APPLE_API_ISSUER_ID:-}" ]]; then - KEY_PATH="$RUNNER_TEMP/AuthKey_${APPLE_API_KEY_ID}.p8" - echo "$APPLE_API_KEY_BASE64" | base64 --decode > "$KEY_PATH" - NOTARY_AUTH=(--key "$KEY_PATH" --key-id "$APPLE_API_KEY_ID" --issuer "$APPLE_API_ISSUER_ID") - echo "Using API key auth (key-id: $APPLE_API_KEY_ID)" -elif [[ -n "${APPLE_ID:-}" && -n "${APPLE_APP_SPECIFIC_PASSWORD:-}" && -n "${APPLE_TEAM_ID:-}" ]]; then - NOTARY_AUTH=(--apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD") - echo "Using app-specific password auth" -else - echo "ERROR: No notarization credentials. Set APPLE_API_KEY_* or APPLE_ID+APPLE_APP_SPECIFIC_PASSWORD" - exit 1 -fi - -for attempt in 1 2 3; do - echo "Notarization attempt $attempt/3..." - if xcrun notarytool submit "$OUTPUT_ZIP" "${NOTARY_AUTH[@]}" --wait --timeout 15m; then - echo "Notarized archive ready: $OUTPUT_ZIP" - exit 0 - fi - echo "Attempt $attempt failed, retrying in 10s..." - sleep 10 -done - -echo "Notarization failed after 3 attempts" -exit 1 diff --git a/distribution/macos/smoke-releaseability.sh b/distribution/macos/smoke-releaseability.sh deleted file mode 100644 index 73fddf90..00000000 --- a/distribution/macos/smoke-releaseability.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -if [[ $# -lt 1 ]]; then - echo "Usage: $0 [...]" - exit 1 -fi - -if [[ "$(uname -s)" != "Darwin" ]]; then - echo "This smoke check only runs on macOS." - exit 1 -fi - -RUN_BINARIES="${RUN_BINARIES:-1}" -status=0 - -for bin in "$@"; do - if [[ ! -x "$bin" ]]; then - echo "[smoke][error] Missing executable: $bin" - status=1 - continue - fi - - echo "[smoke] Inspecting $bin" - - unexpected=() - while IFS= read -r dep; do - [[ -z "$dep" ]] && continue - case "$dep" in - /System/Library/*|/usr/lib/*|@executable_path/*|@loader_path/*) - ;; - *) - unexpected+=("$dep") - ;; - esac - done < <(otool -L "$bin" | awk 'NR > 1 { print $1 }') - - if ((${#unexpected[@]})); then - echo "[smoke][error] Non-portable runtime dependencies found in $bin:" - printf ' - %s\n' "${unexpected[@]}" - status=1 - else - echo "[smoke] Runtime deps are macOS-system-safe" - fi - - if [[ "$RUN_BINARIES" == "1" ]]; then - if "$bin" --version >/dev/null; then - echo "[smoke] Version check passed" - else - echo "[smoke][error] Version check failed for $bin" - status=1 - fi - fi -done - -exit "$status" diff --git a/distribution/npm/.github/workflows/test-install.yml b/distribution/npm/.github/workflows/test-install.yml deleted file mode 100644 index 12292c9b..00000000 --- a/distribution/npm/.github/workflows/test-install.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Test Package Installation - -on: - push: - branches: [main, develop] - pull_request: - branches: [main, develop] - -jobs: - test-install: - name: Test on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - node-version: [14.x, 16.x, 18.x, 20.x] - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - - name: Install package - run: npm install - - - name: Verify binary exists - run: node -e "console.log(require('./index.js').getBinaryPath())" - - - name: Test version command - run: node -e "console.log(require('./index.js').execLoctreeSync(['--version']))" - - - name: Test help command - run: npx loctree --help - - - name: Run example - run: node example.js - - test-platform-packages: - name: Test platform package ${{ matrix.package }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - package: darwin-arm64 - os: macos-14 # M1 runner - - package: linux-x64-gnu - os: ubuntu-latest - - package: win32-x64-msvc - os: windows-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: 20.x - - - name: Test platform package install - working-directory: platform-packages/${{ matrix.package }} - run: | - npm install - node -e "require('fs').accessSync('./loctree${{ matrix.os == 'windows-latest' && '.exe' || '' }}')" - - - name: Test binary execution - working-directory: platform-packages/${{ matrix.package }} - run: ./loctree${{ matrix.os == 'windows-latest' && '.exe' || '' }} --version diff --git a/distribution/npm/.npmignore b/distribution/npm/.npmignore deleted file mode 100644 index 3671aac2..00000000 --- a/distribution/npm/.npmignore +++ /dev/null @@ -1,39 +0,0 @@ -# Source files -*.ts -*.md.backup - -# Tests -test/ -tests/ -__tests__/ -*.test.js -*.spec.js - -# Development -.git/ -.github/ -.vscode/ -.idea/ -*.swp -*.swo -*~ - -# Build artifacts -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Directories -node_modules/ -coverage/ -.nyc_output/ -platform-packages/ -scripts/ - -# Misc -.DS_Store -.env -.env.local -.env.*.local diff --git a/distribution/npm/CREATE_PLATFORM_PACKAGES.sh b/distribution/npm/CREATE_PLATFORM_PACKAGES.sh deleted file mode 100755 index fffffbbb..00000000 --- a/distribution/npm/CREATE_PLATFORM_PACKAGES.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash -# Script to create the currently supported platform package directories - -set -e - -VERSION="${1:-$(node -p "require('./package.json').version")}" - -PLATFORMS=( - "darwin-arm64:macOS Apple Silicon (ARM64):darwin:arm64" - "darwin-x64:macOS Intel (x64):darwin:x64" - "linux-x64-gnu:Linux x64 (glibc):linux:x64" - "win32-x64-msvc:Windows x64:win32:x64" -) - -for platform_spec in "${PLATFORMS[@]}"; do - IFS=: read -r platform desc os cpu <<< "$platform_spec" - - dir="platform-packages/$platform" - mkdir -p "$dir" - - cat > "$dir/package.json" << PACKAGE_EOF -{ - "name": "@loctree/$platform", - "version": "$VERSION", - "description": "loct binary for $desc", - "keywords": ["loctree", "$os", "$cpu"], - "license": "MIT OR Apache-2.0", - "os": ["$os"], - "cpu": ["$cpu"], - "repository": { - "type": "git", - "url": "git+https://github.com/Loctree/loctree-ast.git" - }, - "files": [ - "loct$([ "$os" = "win32" ] && echo ".exe" || echo "")", - "postinstall.js" - ], - "scripts": { - "postinstall": "node postinstall.js" - } -} -PACKAGE_EOF - - # Copy postinstall script - cp platform-packages/postinstall.js "$dir/" - - echo "Created $dir" -done - -echo "" -echo "All platform-specific packages created!" -echo "" -echo "Next steps:" -echo "1. Run this script to refresh all supported package directories" -echo "2. Publish each platform package" -echo "3. Publish the main package" diff --git a/distribution/npm/LICENSE b/distribution/npm/LICENSE deleted file mode 100644 index 3aa9d856..00000000 --- a/distribution/npm/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Loctree Contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/distribution/npm/PACKAGE_OVERVIEW.md b/distribution/npm/PACKAGE_OVERVIEW.md deleted file mode 100644 index 7e8cc7db..00000000 --- a/distribution/npm/PACKAGE_OVERVIEW.md +++ /dev/null @@ -1,32 +0,0 @@ -# npm Package Overview - -`distribution/npm` is the canonical npm release surface for Loctree. - -## Shape - -- main package: `loctree` -- command alias: `loct` -- platform packages: - - `@loctree/darwin-arm64` - - `@loctree/darwin-x64` - - `@loctree/linux-x64-gnu` - - `@loctree/win32-x64-msvc` - -The main package depends on those platform packages through -`optionalDependencies`. Each platform package first tries the matching GitHub -release asset from `Loctree/loct`, then falls back to the monorepo release in -`Loctree/loctree-ast` if the thin repo has not mirrored that asset yet. - -## Why this shape - -- one publish home under `distribution/npm` -- no accidental root-level npm publish -- only claim the targets CI actually builds - -## Release contract - -1. Build release assets in GitHub Actions. -2. Sync versions with `node distribution/npm/sync-version.mjs `. -3. Regenerate platform package manifests with `./distribution/npm/CREATE_PLATFORM_PACKAGES.sh `. -4. Publish platform packages first. -5. Publish the main `loctree` package last. diff --git a/distribution/npm/PUBLISHING.md b/distribution/npm/PUBLISHING.md deleted file mode 100644 index 32889294..00000000 --- a/distribution/npm/PUBLISHING.md +++ /dev/null @@ -1,105 +0,0 @@ -# Publishing Guide for the loctree npm Package - -The npm package is a CLI wrapper around thin release assets from -`Loctree/loct`. The canonical publish path is the monorepo release workflow: - -- verify release tag and versions -- publish thin release assets -- refresh npm package versions -- publish platform packages -- publish the main `loctree` package - -See `.github/workflows/publish.yml` for the live source of truth. - -## Current Layout - -The npm surface follows the `optionalDependencies` pattern: - -1. `loctree` — main package with the JavaScript wrapper -2. `@loctree/darwin-arm64` -3. `@loctree/darwin-x64` -4. `@loctree/linux-x64-gnu` -5. `@loctree/win32-x64-msvc` - -The main package depends on the platform packages. Each platform package -downloads its matching thin release asset from `Loctree/loct`, with a -monorepo-release fallback in `Loctree/loctree-ast` while mirroring catches up. - -## Required Thin Assets - -For a release tag `vX.Y.Z`, the publish workflow expects these CLI assets: - -- `loct-darwin-aarch64.tar.gz` -- `loct-darwin-x86_64.tar.gz` -- `loct-linux-x86_64.tar.gz` -- `loct-windows-x86_64.zip` - -The npm platform packages currently consume: - -- `loct-darwin-aarch64.tar.gz` -- `loct-darwin-x86_64.tar.gz` -- `loct-linux-x86_64.tar.gz` -- `loct-windows-x86_64.zip` - -## Standard Publish Flow - -The normal operator path is a tagged release: - -```bash -make version TYPE=minor TAG=1 PUSH=1 -``` - -That triggers `.github/workflows/publish.yml`, which then: - -1. syncs `distribution/npm/package.json` to the release version -2. regenerates `platform-packages/*` with `CREATE_PLATFORM_PACKAGES.sh` -3. publishes each platform package -4. publishes the main `loctree` npm package - -## Manual Fallback - -Use this only when you intentionally need a local/manual npm publish: - -```bash -VERSION="$(node -p "require('./distribution/npm/package.json').version")" -cd distribution/npm -node sync-version.mjs "$VERSION" -./CREATE_PLATFORM_PACKAGES.sh "$VERSION" -``` - -Publish platform packages first: - -```bash -for dir in platform-packages/*/; do - (cd "$dir" && npm publish --access public) -done -``` - -Then publish the main package: - -```bash -npm publish --access public -``` - -## Verification - -Sanity-check the release surface before or after publishing: - -```bash -VERSION="$(node -p "require('./distribution/npm/package.json').version")" -echo "https://github.com/Loctree/loct/releases/tag/v${VERSION}" - -mkdir -p /tmp/loctree-npm-smoke -cd /tmp/loctree-npm-smoke -npm init -y -npm install loctree -npx loct --version -node -e "console.log(require('loctree').getBinaryPath())" -``` - -## Notes - -- Do not hard-code old version numbers in docs or helper commands. -- Do not publish the main package before the platform packages. -- The source of truth for asset filenames is `distribution/npm/platform-packages/postinstall.js`. -- The source of truth for publish choreography is `.github/workflows/publish.yml`. diff --git a/distribution/npm/QUICKSTART.md b/distribution/npm/QUICKSTART.md deleted file mode 100644 index bc0744ff..00000000 --- a/distribution/npm/QUICKSTART.md +++ /dev/null @@ -1,78 +0,0 @@ -# npm Quick Start - -Fast path to publish the `loctree` npm surface after the CLI thin release -assets already exist. - -## Prerequisites - -- npm publish access -- CLI thin release assets published to `Loctree/loct` -- Node.js 20+ available (matches the release workflow) - -## 1. Sync Versions - -Run from the repo root: - -```bash -VERSION="$(node -p "require('./distribution/npm/package.json').version")" -cd distribution/npm -node sync-version.mjs "$VERSION" -./CREATE_PLATFORM_PACKAGES.sh "$VERSION" -``` - -## 2. Verify Thin Assets - -For `v$VERSION`, the CLI release repo should already contain: - -- `loct-darwin-aarch64.tar.gz` -- `loct-darwin-x86_64.tar.gz` -- `loct-linux-x86_64.tar.gz` -- `loct-windows-x86_64.zip` - -Release page: - -```text -https://github.com/Loctree/loct/releases/tag/v$VERSION -``` - -## 3. Publish Platform Packages - -```bash -for dir in platform-packages/*/; do - (cd "$dir" && npm publish --access public) -done -``` - -Wait a few seconds for npm registry propagation. - -## 4. Publish the Main Package - -```bash -npm publish --access public -``` - -## 5. Smoke Test - -```bash -mkdir -p /tmp/loctree-npm-smoke -cd /tmp/loctree-npm-smoke -npm init -y -npm install loctree -npx loct --version -``` - -## Canonical Automation - -The normal path is still the repo release workflow, not manual publishing: - -```bash -make version TYPE=patch TAG=1 PUSH=1 -``` - -That tag push runs `.github/workflows/publish.yml`, which refreshes versions, -publishes platform packages, and then publishes the main package. - -## Need More Detail? - -Read [PUBLISHING.md](./PUBLISHING.md) for the full operator guide and the live -sources of truth. diff --git a/distribution/npm/README.md b/distribution/npm/README.md deleted file mode 100644 index 7b661f3d..00000000 --- a/distribution/npm/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# loctree - -Structural code intelligence for AI agents. - -This package is the canonical npm distribution surface for Loctree. It installs -the matching platform package, which then downloads the corresponding GitHub -release asset for your machine from the `Loctree/loct` thin release repo and -falls back to the `Loctree/loctree-ast` monorepo release page if the thin repo -has not mirrored that asset yet. - -This npm channel is CLI-only. If you also need `loctree-mcp`, install it via -Cargo, Homebrew, or the GitHub release assets. - -`loct` is the canonical CLI command. `loctree` may still exist as a compatibility -alias on some install channels, but new docs and examples use `loct`. - -## Supported npm targets - -- macOS Apple Silicon: `@loctree/darwin-arm64` -- macOS Intel: `@loctree/darwin-x64` -- Linux x64 glibc: `@loctree/linux-x64-gnu` -- Windows x64: `@loctree/win32-x64-msvc` - -We only claim the targets CI actually builds today. - -## Install - -```bash -npm install loctree -# or -pnpm add loctree -``` - -For global CLI usage: - -```bash -npm install -g loctree -``` - -On Linux, the npm channel currently targets glibc builds only. Alpine/musl -users should install via Cargo or direct release assets instead. - -Then run: - -```bash -loct --help -``` - -For the MCP server: - -```bash -cargo install --locked loctree-mcp -# or -brew install loctree/mcp/loctree-mcp -``` - -If you already installed Loctree globally via Homebrew, do not mix `brew` and -`npm -g` for the same machine-level CLI. Pick one global channel or remove the -existing binary first. - -## CLI examples - -```bash -npx loct . -npx loct health -npx loct slice src/App.tsx --consumers -npx loct report --serve --port 4173 -``` - -## What you get - -- dependency-aware structural analysis -- dead code and cycle signals -- report generation -- Tauri bridge analysis -- MCP-ready artifacts for AI workflows - -## Troubleshooting - -If installation fails: - -1. verify the matching GitHub release assets exist -2. ensure your package manager did not disable `optionalDependencies` -3. fall back to `cargo install --locked loctree` -4. install `loctree-mcp` separately if your workflow needs MCP - -## Links - -- Source: https://github.com/Loctree/loctree-ast -- CLI releases: https://github.com/Loctree/loct/releases -- Docs: https://docs.rs/loctree -- Website: https://loct.io diff --git a/distribution/npm/bin/loctree b/distribution/npm/bin/loctree deleted file mode 100644 index 633c5a01..00000000 --- a/distribution/npm/bin/loctree +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env node - -// This is a simple wrapper that delegates to the main index.js -// The bin field in package.json points here for the CLI command - -require('../index.js'); diff --git a/distribution/npm/example.js b/distribution/npm/example.js deleted file mode 100644 index 6e3440e0..00000000 --- a/distribution/npm/example.js +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env node - -/** - * Example usage of loctree npm package - */ - -const { execLoctreeSync, execLoctree, getBinaryPath } = require('./index.js'); - -console.log('=== loctree npm package examples (loct binary) ===\n'); - -// Example 1: Get binary path -console.log('1. Binary location:'); -try { - const binaryPath = getBinaryPath(); - console.log(` ${binaryPath}\n`); -} catch (err) { - console.error(` Error: ${err.message}\n`); - process.exit(1); -} - -// Example 2: Get version -console.log('2. Version check:'); -try { - const version = execLoctreeSync(['--version']); - console.log(` ${version.trim()}\n`); -} catch (err) { - console.error(` Error: ${err.message}\n`); -} - -// Example 3: Show help -console.log('3. Available commands:'); -try { - const help = execLoctreeSync(['--help']); - console.log(help); -} catch (err) { - console.error(` Error: ${err.message}\n`); -} - -// Example 4: Analyze current directory (if it has source files) -console.log('4. Analyzing current directory:'); -try { - // This will use inherited stdio, so output goes directly to console - execLoctree(['.', '--dead', '--confidence', 'high']); -} catch (err) { - console.error(` Analysis failed: ${err.message}`); -} diff --git a/distribution/npm/index.d.ts b/distribution/npm/index.d.ts deleted file mode 100644 index e9084eee..00000000 --- a/distribution/npm/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * TypeScript definitions for loctree npm package - */ - -import { ExecFileSyncOptions } from 'child_process'; - -/** - * Execute loct with given arguments - * @param args - Command line arguments to pass to loct - * @param options - Node.js child_process execution options - * @returns stdout from loct execution - * @throws Error if loct binary is not found or execution fails - */ -export function execLoctree(args?: string[], options?: ExecFileSyncOptions): Buffer | string; - -/** - * Execute loct and return result as string - * @param args - Command line arguments to pass to loct - * @returns stdout from loct as UTF-8 string - * @throws Error if loct binary is not found or execution fails - */ -export function execLoctreeSync(args?: string[]): string; - -/** - * Get the absolute path to the loct binary for the current platform - * @returns Absolute path to the loct binary - * @throws Error if platform is unsupported or binary is not found - */ -export function getBinaryPath(): string; diff --git a/distribution/npm/index.js b/distribution/npm/index.js deleted file mode 100644 index c8461da9..00000000 --- a/distribution/npm/index.js +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env node - -const { execFileSync } = require('child_process'); -const { join } = require('path'); -const { existsSync } = require('fs'); - -const { - getPackageNameForPlatformKey, - resolvePlatformKey, - unsupportedPlatformMessage, -} = require('./platform-support'); - -function getBinaryPath() { - const platformKey = resolvePlatformKey(); - - if (!platformKey) { - throw new Error(`Unsupported platform: ${process.platform}-${process.arch}`); - } - - const packageName = getPackageNameForPlatformKey(platformKey); - - if (!packageName) { - throw new Error(unsupportedPlatformMessage({ platformKey })); - } - - const binaryName = process.platform === 'win32' ? 'loct.exe' : 'loct'; - const binaryPath = join(__dirname, 'node_modules', packageName, binaryName); - - if (!existsSync(binaryPath)) { - throw new Error( - `loct binary not found at ${binaryPath}. ` + - `This may happen if optionalDependencies are disabled. ` + - `Please ensure "${packageName}" is installed.` - ); - } - - return binaryPath; -} - -/** - * Execute loct with given arguments - * @param {string[]} args - Command line arguments - * @param {object} options - Execution options - * @returns {Buffer|string} - stdout from loct - */ -function execLoctree(args = [], options = {}) { - const binaryPath = getBinaryPath(); - - const execOptions = { - stdio: 'pipe', - ...options, - }; - - try { - return execFileSync(binaryPath, args, execOptions); - } catch (err) { - if (err.status !== undefined) { - process.exit(err.status); - } - throw err; - } -} - -/** - * Execute loct and return result as string - * @param {string[]} args - Command line arguments - * @returns {string} - stdout from loct - */ -function execLoctreeSync(args = []) { - const binaryPath = getBinaryPath(); - - try { - return execFileSync(binaryPath, args, { encoding: 'utf8' }); - } catch (err) { - if (err.stdout) return err.stdout; - throw err; - } -} - -// Export API -module.exports = { - execLoctree, - execLoctreeSync, - getBinaryPath, -}; - -// CLI execution -if (require.main === module) { - const args = process.argv.slice(2); - execFileSync(getBinaryPath(), args, { stdio: 'inherit' }); -} diff --git a/distribution/npm/install.js b/distribution/npm/install.js deleted file mode 100644 index c5bc3710..00000000 --- a/distribution/npm/install.js +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env node - -const { existsSync } = require('fs'); -const { join } = require('path'); -const { spawnSync } = require('child_process'); - -const { - getPackageNameForPlatformKey, - resolvePlatformKey, - unsupportedPlatformMessage, -} = require('./platform-support'); - -function validateInstallation() { - const platformKey = resolvePlatformKey(); - - if (!platformKey) { - console.error(`Unsupported platform: ${process.platform}-${process.arch}`); - console.error('Supported platforms:'); - console.error(' - macOS Apple Silicon (ARM64)'); - console.error(' - macOS Intel (x64)'); - console.error(' - Linux x64 (glibc)'); - console.error(' - Windows x64'); - process.exit(1); - } - - const packageName = getPackageNameForPlatformKey(platformKey); - - if (!packageName) { - console.error(unsupportedPlatformMessage({ platformKey })); - process.exit(1); - } - - // Check if the platform-specific package was installed - const binaryName = process.platform === 'win32' ? 'loct.exe' : 'loct'; - const binaryPath = join(__dirname, 'node_modules', packageName, binaryName); - - if (!existsSync(binaryPath)) { - console.warn(`Warning: loct binary not found at ${binaryPath}`); - console.warn('This may happen if optionalDependencies are disabled.'); - console.warn('The package may not work correctly.'); - return; - } - - // Verify binary is executable and correct version - try { - const result = spawnSync(binaryPath, ['--version'], { encoding: 'utf8' }); - if (result.status === 0) { - console.log(`loct binary installed successfully: ${result.stdout.trim()}`); - } else { - console.warn(`Warning: loct binary may not be working correctly`); - } - } catch (err) { - console.warn(`Warning: Could not verify loct binary: ${err.message}`); - } -} - -// Run validation -validateInstallation(); diff --git a/distribution/npm/package.json b/distribution/npm/package.json deleted file mode 100644 index 226c4662..00000000 --- a/distribution/npm/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "loctree", - "version": "0.8.17", - "description": "Structural code intelligence for AI agents. Dead exports, circular imports, dependency graphs, reports, and MCP-ready analysis.", - "keywords": [ - "static-analysis", - "dead-code", - "imports", - "exports", - "codebase", - "typescript", - "javascript", - "rust", - "circular-dependencies", - "dependency-graph" - ], - "main": "index.js", - "types": "index.d.ts", - "bin": { - "loctree": "bin/loctree", - "loct": "bin/loctree" - }, - "files": [ - "index.js", - "index.d.ts", - "bin/loctree", - "install.js", - "platform-support.js", - "README.md", - "LICENSE" - ], - "scripts": { - "postinstall": "node install.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Loctree/loctree-ast.git" - }, - "homepage": "https://loct.io", - "bugs": { - "url": "https://github.com/Loctree/loctree-ast/issues" - }, - "license": "MIT OR Apache-2.0", - "author": "Loctree ", - "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "@loctree/darwin-arm64": "0.8.17", - "@loctree/darwin-x64": "0.8.17", - "@loctree/linux-x64-gnu": "0.8.17", - "@loctree/win32-x64-msvc": "0.8.17" - } -} diff --git a/distribution/npm/platform-packages/darwin-arm64/package.json b/distribution/npm/platform-packages/darwin-arm64/package.json deleted file mode 100644 index 4542c1a6..00000000 --- a/distribution/npm/platform-packages/darwin-arm64/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@loctree/darwin-arm64", - "version": "0.8.17", - "description": "loct binary for macOS Apple Silicon (ARM64)", - "keywords": ["loctree", "darwin", "arm64"], - "license": "MIT OR Apache-2.0", - "os": ["darwin"], - "cpu": ["arm64"], - "repository": { - "type": "git", - "url": "git+https://github.com/Loctree/loctree-ast.git" - }, - "files": [ - "loct", - "postinstall.js" - ], - "scripts": { - "postinstall": "node postinstall.js" - } -} diff --git a/distribution/npm/platform-packages/darwin-arm64/postinstall.js b/distribution/npm/platform-packages/darwin-arm64/postinstall.js deleted file mode 100644 index f37ab319..00000000 --- a/distribution/npm/platform-packages/darwin-arm64/postinstall.js +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env node - -/** - * Postinstall script for platform-specific packages. - * Downloads the current release asset from GitHub releases and extracts it in place. - */ - -const https = require('https'); -const { createWriteStream, chmodSync, existsSync, unlinkSync } = require('fs'); -const { join } = require('path'); -const { pipeline } = require('stream'); -const { promisify } = require('util'); -const { execSync } = require('child_process'); - -const streamPipeline = promisify(pipeline); - -// Prefer the thin release repo, but fall back to the monorepo release page -// while publish choreography is still catching up. -const RELEASE_REPOS = Object.freeze([ - { - repo: 'Loctree/loct', - label: 'thin release repo', - }, - { - repo: 'Loctree/loctree-ast', - label: 'monorepo release fallback', - }, -]); -const VERSION = require('./package.json').version; - -// Platform-specific release assets currently shipped by CI -const BINARY_MAPPINGS = { - '@loctree/darwin-arm64': { - file: 'loct-darwin-aarch64.tar.gz', - target: 'loct', - }, - '@loctree/darwin-x64': { - file: 'loct-darwin-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/linux-x64-gnu': { - file: 'loct-linux-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/win32-x64-msvc': { - file: 'loct-windows-x86_64.zip', - target: 'loct.exe', - }, -}; - -async function downloadFile(url, destPath) { - return new Promise((resolve, reject) => { - https.get(url, { - headers: { 'User-Agent': 'loct-npm-installer' }, - followRedirect: true, - }, (response) => { - // Handle redirects - if (response.statusCode === 301 || response.statusCode === 302) { - return downloadFile(response.headers.location, destPath).then(resolve).catch(reject); - } - - if (response.statusCode !== 200) { - reject(new Error(`Failed to download: HTTP ${response.statusCode}`)); - return; - } - - const fileStream = createWriteStream(destPath); - streamPipeline(response, fileStream) - .then(resolve) - .catch(reject); - }).on('error', reject); - }); -} - -function buildDownloadTargets(version, file) { - return RELEASE_REPOS.map(({ repo, label }) => ({ - label, - url: `https://github.com/${repo}/releases/download/v${version}/${file}`, - })); -} - -async function downloadReleaseAsset(downloadTargets, destPath) { - let lastError = null; - - for (const target of downloadTargets) { - if (existsSync(destPath)) { - unlinkSync(destPath); - } - - console.log(`Downloading loct release asset from ${target.url} (${target.label})...`); - - try { - await downloadFile(target.url, destPath); - return target; - } catch (error) { - lastError = error; - console.warn(`Download failed from ${target.label}: ${error.message}`); - } - } - - throw lastError || new Error('No download targets available'); -} - -async function install() { - const packageName = require('./package.json').name; - const mapping = BINARY_MAPPINGS[packageName]; - - if (!mapping) { - console.error(`Unknown package: ${packageName}`); - process.exit(1); - } - - const { file, target } = mapping; - const downloadTargets = buildDownloadTargets(VERSION, file); - const targetPath = join(__dirname, target); - const archivePath = join(__dirname, file); - - // Skip if already exists - if (existsSync(targetPath)) { - console.log(`Binary already exists at ${targetPath}`); - return; - } - - try { - const downloadedFrom = await downloadReleaseAsset(downloadTargets, archivePath); - - if (file.endsWith('.tar.gz')) { - execSync(`tar -xzf "${archivePath}" -C "${__dirname}"`, { stdio: 'inherit' }); - } else if (file.endsWith('.zip')) { - if (process.platform === 'win32') { - execSync( - `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${__dirname}' -Force"`, - { stdio: 'inherit' } - ); - } else { - execSync(`unzip -o "${archivePath}" -d "${__dirname}"`, { stdio: 'inherit' }); - } - } - - if (existsSync(archivePath)) { - unlinkSync(archivePath); - } - - // Make executable (Unix-like systems) - if (process.platform !== 'win32') { - chmodSync(targetPath, 0o755); - } - - console.log(`Successfully installed loct binary to ${targetPath} via ${downloadedFrom.label}`); - } catch (error) { - console.error(`Failed to download loct binary: ${error.message}`); - console.error('Attempted URLs:'); - downloadTargets.forEach((target) => console.error(`- ${target.url}`)); - console.error(''); - console.error('Possible solutions:'); - console.error('1. Check your internet connection'); - console.error('2. Verify the matching release assets exist on GitHub'); - console.error('3. Install loct manually from the thin release repo: https://github.com/Loctree/loct/releases'); - console.error('4. If the thin repo is still missing the asset, try the monorepo fallback: https://github.com/Loctree/loctree-ast/releases'); - process.exit(1); - } -} - -install(); diff --git a/distribution/npm/platform-packages/darwin-x64/package.json b/distribution/npm/platform-packages/darwin-x64/package.json deleted file mode 100644 index 4a9818df..00000000 --- a/distribution/npm/platform-packages/darwin-x64/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@loctree/darwin-x64", - "version": "0.8.17", - "description": "loct binary for macOS Intel (x64)", - "keywords": ["loctree", "darwin", "x64"], - "license": "MIT OR Apache-2.0", - "os": ["darwin"], - "cpu": ["x64"], - "repository": { - "type": "git", - "url": "git+https://github.com/Loctree/loctree-ast.git" - }, - "files": [ - "loct", - "postinstall.js" - ], - "scripts": { - "postinstall": "node postinstall.js" - } -} diff --git a/distribution/npm/platform-packages/darwin-x64/postinstall.js b/distribution/npm/platform-packages/darwin-x64/postinstall.js deleted file mode 100644 index f37ab319..00000000 --- a/distribution/npm/platform-packages/darwin-x64/postinstall.js +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env node - -/** - * Postinstall script for platform-specific packages. - * Downloads the current release asset from GitHub releases and extracts it in place. - */ - -const https = require('https'); -const { createWriteStream, chmodSync, existsSync, unlinkSync } = require('fs'); -const { join } = require('path'); -const { pipeline } = require('stream'); -const { promisify } = require('util'); -const { execSync } = require('child_process'); - -const streamPipeline = promisify(pipeline); - -// Prefer the thin release repo, but fall back to the monorepo release page -// while publish choreography is still catching up. -const RELEASE_REPOS = Object.freeze([ - { - repo: 'Loctree/loct', - label: 'thin release repo', - }, - { - repo: 'Loctree/loctree-ast', - label: 'monorepo release fallback', - }, -]); -const VERSION = require('./package.json').version; - -// Platform-specific release assets currently shipped by CI -const BINARY_MAPPINGS = { - '@loctree/darwin-arm64': { - file: 'loct-darwin-aarch64.tar.gz', - target: 'loct', - }, - '@loctree/darwin-x64': { - file: 'loct-darwin-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/linux-x64-gnu': { - file: 'loct-linux-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/win32-x64-msvc': { - file: 'loct-windows-x86_64.zip', - target: 'loct.exe', - }, -}; - -async function downloadFile(url, destPath) { - return new Promise((resolve, reject) => { - https.get(url, { - headers: { 'User-Agent': 'loct-npm-installer' }, - followRedirect: true, - }, (response) => { - // Handle redirects - if (response.statusCode === 301 || response.statusCode === 302) { - return downloadFile(response.headers.location, destPath).then(resolve).catch(reject); - } - - if (response.statusCode !== 200) { - reject(new Error(`Failed to download: HTTP ${response.statusCode}`)); - return; - } - - const fileStream = createWriteStream(destPath); - streamPipeline(response, fileStream) - .then(resolve) - .catch(reject); - }).on('error', reject); - }); -} - -function buildDownloadTargets(version, file) { - return RELEASE_REPOS.map(({ repo, label }) => ({ - label, - url: `https://github.com/${repo}/releases/download/v${version}/${file}`, - })); -} - -async function downloadReleaseAsset(downloadTargets, destPath) { - let lastError = null; - - for (const target of downloadTargets) { - if (existsSync(destPath)) { - unlinkSync(destPath); - } - - console.log(`Downloading loct release asset from ${target.url} (${target.label})...`); - - try { - await downloadFile(target.url, destPath); - return target; - } catch (error) { - lastError = error; - console.warn(`Download failed from ${target.label}: ${error.message}`); - } - } - - throw lastError || new Error('No download targets available'); -} - -async function install() { - const packageName = require('./package.json').name; - const mapping = BINARY_MAPPINGS[packageName]; - - if (!mapping) { - console.error(`Unknown package: ${packageName}`); - process.exit(1); - } - - const { file, target } = mapping; - const downloadTargets = buildDownloadTargets(VERSION, file); - const targetPath = join(__dirname, target); - const archivePath = join(__dirname, file); - - // Skip if already exists - if (existsSync(targetPath)) { - console.log(`Binary already exists at ${targetPath}`); - return; - } - - try { - const downloadedFrom = await downloadReleaseAsset(downloadTargets, archivePath); - - if (file.endsWith('.tar.gz')) { - execSync(`tar -xzf "${archivePath}" -C "${__dirname}"`, { stdio: 'inherit' }); - } else if (file.endsWith('.zip')) { - if (process.platform === 'win32') { - execSync( - `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${__dirname}' -Force"`, - { stdio: 'inherit' } - ); - } else { - execSync(`unzip -o "${archivePath}" -d "${__dirname}"`, { stdio: 'inherit' }); - } - } - - if (existsSync(archivePath)) { - unlinkSync(archivePath); - } - - // Make executable (Unix-like systems) - if (process.platform !== 'win32') { - chmodSync(targetPath, 0o755); - } - - console.log(`Successfully installed loct binary to ${targetPath} via ${downloadedFrom.label}`); - } catch (error) { - console.error(`Failed to download loct binary: ${error.message}`); - console.error('Attempted URLs:'); - downloadTargets.forEach((target) => console.error(`- ${target.url}`)); - console.error(''); - console.error('Possible solutions:'); - console.error('1. Check your internet connection'); - console.error('2. Verify the matching release assets exist on GitHub'); - console.error('3. Install loct manually from the thin release repo: https://github.com/Loctree/loct/releases'); - console.error('4. If the thin repo is still missing the asset, try the monorepo fallback: https://github.com/Loctree/loctree-ast/releases'); - process.exit(1); - } -} - -install(); diff --git a/distribution/npm/platform-packages/linux-x64-gnu/package.json b/distribution/npm/platform-packages/linux-x64-gnu/package.json deleted file mode 100644 index 25a4cee8..00000000 --- a/distribution/npm/platform-packages/linux-x64-gnu/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@loctree/linux-x64-gnu", - "version": "0.8.17", - "description": "loct binary for Linux x64 (glibc)", - "keywords": ["loctree", "linux", "x64"], - "license": "MIT OR Apache-2.0", - "os": ["linux"], - "cpu": ["x64"], - "repository": { - "type": "git", - "url": "git+https://github.com/Loctree/loctree-ast.git" - }, - "files": [ - "loct", - "postinstall.js" - ], - "scripts": { - "postinstall": "node postinstall.js" - } -} diff --git a/distribution/npm/platform-packages/linux-x64-gnu/postinstall.js b/distribution/npm/platform-packages/linux-x64-gnu/postinstall.js deleted file mode 100644 index f37ab319..00000000 --- a/distribution/npm/platform-packages/linux-x64-gnu/postinstall.js +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env node - -/** - * Postinstall script for platform-specific packages. - * Downloads the current release asset from GitHub releases and extracts it in place. - */ - -const https = require('https'); -const { createWriteStream, chmodSync, existsSync, unlinkSync } = require('fs'); -const { join } = require('path'); -const { pipeline } = require('stream'); -const { promisify } = require('util'); -const { execSync } = require('child_process'); - -const streamPipeline = promisify(pipeline); - -// Prefer the thin release repo, but fall back to the monorepo release page -// while publish choreography is still catching up. -const RELEASE_REPOS = Object.freeze([ - { - repo: 'Loctree/loct', - label: 'thin release repo', - }, - { - repo: 'Loctree/loctree-ast', - label: 'monorepo release fallback', - }, -]); -const VERSION = require('./package.json').version; - -// Platform-specific release assets currently shipped by CI -const BINARY_MAPPINGS = { - '@loctree/darwin-arm64': { - file: 'loct-darwin-aarch64.tar.gz', - target: 'loct', - }, - '@loctree/darwin-x64': { - file: 'loct-darwin-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/linux-x64-gnu': { - file: 'loct-linux-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/win32-x64-msvc': { - file: 'loct-windows-x86_64.zip', - target: 'loct.exe', - }, -}; - -async function downloadFile(url, destPath) { - return new Promise((resolve, reject) => { - https.get(url, { - headers: { 'User-Agent': 'loct-npm-installer' }, - followRedirect: true, - }, (response) => { - // Handle redirects - if (response.statusCode === 301 || response.statusCode === 302) { - return downloadFile(response.headers.location, destPath).then(resolve).catch(reject); - } - - if (response.statusCode !== 200) { - reject(new Error(`Failed to download: HTTP ${response.statusCode}`)); - return; - } - - const fileStream = createWriteStream(destPath); - streamPipeline(response, fileStream) - .then(resolve) - .catch(reject); - }).on('error', reject); - }); -} - -function buildDownloadTargets(version, file) { - return RELEASE_REPOS.map(({ repo, label }) => ({ - label, - url: `https://github.com/${repo}/releases/download/v${version}/${file}`, - })); -} - -async function downloadReleaseAsset(downloadTargets, destPath) { - let lastError = null; - - for (const target of downloadTargets) { - if (existsSync(destPath)) { - unlinkSync(destPath); - } - - console.log(`Downloading loct release asset from ${target.url} (${target.label})...`); - - try { - await downloadFile(target.url, destPath); - return target; - } catch (error) { - lastError = error; - console.warn(`Download failed from ${target.label}: ${error.message}`); - } - } - - throw lastError || new Error('No download targets available'); -} - -async function install() { - const packageName = require('./package.json').name; - const mapping = BINARY_MAPPINGS[packageName]; - - if (!mapping) { - console.error(`Unknown package: ${packageName}`); - process.exit(1); - } - - const { file, target } = mapping; - const downloadTargets = buildDownloadTargets(VERSION, file); - const targetPath = join(__dirname, target); - const archivePath = join(__dirname, file); - - // Skip if already exists - if (existsSync(targetPath)) { - console.log(`Binary already exists at ${targetPath}`); - return; - } - - try { - const downloadedFrom = await downloadReleaseAsset(downloadTargets, archivePath); - - if (file.endsWith('.tar.gz')) { - execSync(`tar -xzf "${archivePath}" -C "${__dirname}"`, { stdio: 'inherit' }); - } else if (file.endsWith('.zip')) { - if (process.platform === 'win32') { - execSync( - `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${__dirname}' -Force"`, - { stdio: 'inherit' } - ); - } else { - execSync(`unzip -o "${archivePath}" -d "${__dirname}"`, { stdio: 'inherit' }); - } - } - - if (existsSync(archivePath)) { - unlinkSync(archivePath); - } - - // Make executable (Unix-like systems) - if (process.platform !== 'win32') { - chmodSync(targetPath, 0o755); - } - - console.log(`Successfully installed loct binary to ${targetPath} via ${downloadedFrom.label}`); - } catch (error) { - console.error(`Failed to download loct binary: ${error.message}`); - console.error('Attempted URLs:'); - downloadTargets.forEach((target) => console.error(`- ${target.url}`)); - console.error(''); - console.error('Possible solutions:'); - console.error('1. Check your internet connection'); - console.error('2. Verify the matching release assets exist on GitHub'); - console.error('3. Install loct manually from the thin release repo: https://github.com/Loctree/loct/releases'); - console.error('4. If the thin repo is still missing the asset, try the monorepo fallback: https://github.com/Loctree/loctree-ast/releases'); - process.exit(1); - } -} - -install(); diff --git a/distribution/npm/platform-packages/postinstall.js b/distribution/npm/platform-packages/postinstall.js deleted file mode 100644 index f37ab319..00000000 --- a/distribution/npm/platform-packages/postinstall.js +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env node - -/** - * Postinstall script for platform-specific packages. - * Downloads the current release asset from GitHub releases and extracts it in place. - */ - -const https = require('https'); -const { createWriteStream, chmodSync, existsSync, unlinkSync } = require('fs'); -const { join } = require('path'); -const { pipeline } = require('stream'); -const { promisify } = require('util'); -const { execSync } = require('child_process'); - -const streamPipeline = promisify(pipeline); - -// Prefer the thin release repo, but fall back to the monorepo release page -// while publish choreography is still catching up. -const RELEASE_REPOS = Object.freeze([ - { - repo: 'Loctree/loct', - label: 'thin release repo', - }, - { - repo: 'Loctree/loctree-ast', - label: 'monorepo release fallback', - }, -]); -const VERSION = require('./package.json').version; - -// Platform-specific release assets currently shipped by CI -const BINARY_MAPPINGS = { - '@loctree/darwin-arm64': { - file: 'loct-darwin-aarch64.tar.gz', - target: 'loct', - }, - '@loctree/darwin-x64': { - file: 'loct-darwin-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/linux-x64-gnu': { - file: 'loct-linux-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/win32-x64-msvc': { - file: 'loct-windows-x86_64.zip', - target: 'loct.exe', - }, -}; - -async function downloadFile(url, destPath) { - return new Promise((resolve, reject) => { - https.get(url, { - headers: { 'User-Agent': 'loct-npm-installer' }, - followRedirect: true, - }, (response) => { - // Handle redirects - if (response.statusCode === 301 || response.statusCode === 302) { - return downloadFile(response.headers.location, destPath).then(resolve).catch(reject); - } - - if (response.statusCode !== 200) { - reject(new Error(`Failed to download: HTTP ${response.statusCode}`)); - return; - } - - const fileStream = createWriteStream(destPath); - streamPipeline(response, fileStream) - .then(resolve) - .catch(reject); - }).on('error', reject); - }); -} - -function buildDownloadTargets(version, file) { - return RELEASE_REPOS.map(({ repo, label }) => ({ - label, - url: `https://github.com/${repo}/releases/download/v${version}/${file}`, - })); -} - -async function downloadReleaseAsset(downloadTargets, destPath) { - let lastError = null; - - for (const target of downloadTargets) { - if (existsSync(destPath)) { - unlinkSync(destPath); - } - - console.log(`Downloading loct release asset from ${target.url} (${target.label})...`); - - try { - await downloadFile(target.url, destPath); - return target; - } catch (error) { - lastError = error; - console.warn(`Download failed from ${target.label}: ${error.message}`); - } - } - - throw lastError || new Error('No download targets available'); -} - -async function install() { - const packageName = require('./package.json').name; - const mapping = BINARY_MAPPINGS[packageName]; - - if (!mapping) { - console.error(`Unknown package: ${packageName}`); - process.exit(1); - } - - const { file, target } = mapping; - const downloadTargets = buildDownloadTargets(VERSION, file); - const targetPath = join(__dirname, target); - const archivePath = join(__dirname, file); - - // Skip if already exists - if (existsSync(targetPath)) { - console.log(`Binary already exists at ${targetPath}`); - return; - } - - try { - const downloadedFrom = await downloadReleaseAsset(downloadTargets, archivePath); - - if (file.endsWith('.tar.gz')) { - execSync(`tar -xzf "${archivePath}" -C "${__dirname}"`, { stdio: 'inherit' }); - } else if (file.endsWith('.zip')) { - if (process.platform === 'win32') { - execSync( - `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${__dirname}' -Force"`, - { stdio: 'inherit' } - ); - } else { - execSync(`unzip -o "${archivePath}" -d "${__dirname}"`, { stdio: 'inherit' }); - } - } - - if (existsSync(archivePath)) { - unlinkSync(archivePath); - } - - // Make executable (Unix-like systems) - if (process.platform !== 'win32') { - chmodSync(targetPath, 0o755); - } - - console.log(`Successfully installed loct binary to ${targetPath} via ${downloadedFrom.label}`); - } catch (error) { - console.error(`Failed to download loct binary: ${error.message}`); - console.error('Attempted URLs:'); - downloadTargets.forEach((target) => console.error(`- ${target.url}`)); - console.error(''); - console.error('Possible solutions:'); - console.error('1. Check your internet connection'); - console.error('2. Verify the matching release assets exist on GitHub'); - console.error('3. Install loct manually from the thin release repo: https://github.com/Loctree/loct/releases'); - console.error('4. If the thin repo is still missing the asset, try the monorepo fallback: https://github.com/Loctree/loctree-ast/releases'); - process.exit(1); - } -} - -install(); diff --git a/distribution/npm/platform-packages/win32-x64-msvc/package.json b/distribution/npm/platform-packages/win32-x64-msvc/package.json deleted file mode 100644 index b0b35439..00000000 --- a/distribution/npm/platform-packages/win32-x64-msvc/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@loctree/win32-x64-msvc", - "version": "0.8.17", - "description": "loct binary for Windows x64", - "keywords": ["loctree", "win32", "x64"], - "license": "MIT OR Apache-2.0", - "os": ["win32"], - "cpu": ["x64"], - "repository": { - "type": "git", - "url": "git+https://github.com/Loctree/loctree-ast.git" - }, - "files": [ - "loct.exe", - "postinstall.js" - ], - "scripts": { - "postinstall": "node postinstall.js" - } -} diff --git a/distribution/npm/platform-packages/win32-x64-msvc/postinstall.js b/distribution/npm/platform-packages/win32-x64-msvc/postinstall.js deleted file mode 100644 index f37ab319..00000000 --- a/distribution/npm/platform-packages/win32-x64-msvc/postinstall.js +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env node - -/** - * Postinstall script for platform-specific packages. - * Downloads the current release asset from GitHub releases and extracts it in place. - */ - -const https = require('https'); -const { createWriteStream, chmodSync, existsSync, unlinkSync } = require('fs'); -const { join } = require('path'); -const { pipeline } = require('stream'); -const { promisify } = require('util'); -const { execSync } = require('child_process'); - -const streamPipeline = promisify(pipeline); - -// Prefer the thin release repo, but fall back to the monorepo release page -// while publish choreography is still catching up. -const RELEASE_REPOS = Object.freeze([ - { - repo: 'Loctree/loct', - label: 'thin release repo', - }, - { - repo: 'Loctree/loctree-ast', - label: 'monorepo release fallback', - }, -]); -const VERSION = require('./package.json').version; - -// Platform-specific release assets currently shipped by CI -const BINARY_MAPPINGS = { - '@loctree/darwin-arm64': { - file: 'loct-darwin-aarch64.tar.gz', - target: 'loct', - }, - '@loctree/darwin-x64': { - file: 'loct-darwin-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/linux-x64-gnu': { - file: 'loct-linux-x86_64.tar.gz', - target: 'loct', - }, - '@loctree/win32-x64-msvc': { - file: 'loct-windows-x86_64.zip', - target: 'loct.exe', - }, -}; - -async function downloadFile(url, destPath) { - return new Promise((resolve, reject) => { - https.get(url, { - headers: { 'User-Agent': 'loct-npm-installer' }, - followRedirect: true, - }, (response) => { - // Handle redirects - if (response.statusCode === 301 || response.statusCode === 302) { - return downloadFile(response.headers.location, destPath).then(resolve).catch(reject); - } - - if (response.statusCode !== 200) { - reject(new Error(`Failed to download: HTTP ${response.statusCode}`)); - return; - } - - const fileStream = createWriteStream(destPath); - streamPipeline(response, fileStream) - .then(resolve) - .catch(reject); - }).on('error', reject); - }); -} - -function buildDownloadTargets(version, file) { - return RELEASE_REPOS.map(({ repo, label }) => ({ - label, - url: `https://github.com/${repo}/releases/download/v${version}/${file}`, - })); -} - -async function downloadReleaseAsset(downloadTargets, destPath) { - let lastError = null; - - for (const target of downloadTargets) { - if (existsSync(destPath)) { - unlinkSync(destPath); - } - - console.log(`Downloading loct release asset from ${target.url} (${target.label})...`); - - try { - await downloadFile(target.url, destPath); - return target; - } catch (error) { - lastError = error; - console.warn(`Download failed from ${target.label}: ${error.message}`); - } - } - - throw lastError || new Error('No download targets available'); -} - -async function install() { - const packageName = require('./package.json').name; - const mapping = BINARY_MAPPINGS[packageName]; - - if (!mapping) { - console.error(`Unknown package: ${packageName}`); - process.exit(1); - } - - const { file, target } = mapping; - const downloadTargets = buildDownloadTargets(VERSION, file); - const targetPath = join(__dirname, target); - const archivePath = join(__dirname, file); - - // Skip if already exists - if (existsSync(targetPath)) { - console.log(`Binary already exists at ${targetPath}`); - return; - } - - try { - const downloadedFrom = await downloadReleaseAsset(downloadTargets, archivePath); - - if (file.endsWith('.tar.gz')) { - execSync(`tar -xzf "${archivePath}" -C "${__dirname}"`, { stdio: 'inherit' }); - } else if (file.endsWith('.zip')) { - if (process.platform === 'win32') { - execSync( - `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${__dirname}' -Force"`, - { stdio: 'inherit' } - ); - } else { - execSync(`unzip -o "${archivePath}" -d "${__dirname}"`, { stdio: 'inherit' }); - } - } - - if (existsSync(archivePath)) { - unlinkSync(archivePath); - } - - // Make executable (Unix-like systems) - if (process.platform !== 'win32') { - chmodSync(targetPath, 0o755); - } - - console.log(`Successfully installed loct binary to ${targetPath} via ${downloadedFrom.label}`); - } catch (error) { - console.error(`Failed to download loct binary: ${error.message}`); - console.error('Attempted URLs:'); - downloadTargets.forEach((target) => console.error(`- ${target.url}`)); - console.error(''); - console.error('Possible solutions:'); - console.error('1. Check your internet connection'); - console.error('2. Verify the matching release assets exist on GitHub'); - console.error('3. Install loct manually from the thin release repo: https://github.com/Loctree/loct/releases'); - console.error('4. If the thin repo is still missing the asset, try the monorepo fallback: https://github.com/Loctree/loctree-ast/releases'); - process.exit(1); - } -} - -install(); diff --git a/distribution/npm/platform-support.js b/distribution/npm/platform-support.js deleted file mode 100644 index 63742719..00000000 --- a/distribution/npm/platform-support.js +++ /dev/null @@ -1,112 +0,0 @@ -const SUPPORTED_NPM_TARGETS = Object.freeze([ - { - key: 'darwin-arm64', - packageName: '@loctree/darwin-arm64', - label: 'macOS Apple Silicon (ARM64)', - }, - { - key: 'darwin-x64', - packageName: '@loctree/darwin-x64', - label: 'macOS Intel (x64)', - }, - { - key: 'linux-x64-gnu', - packageName: '@loctree/linux-x64-gnu', - label: 'Linux x64 (glibc)', - }, - { - key: 'win32-x64-msvc', - packageName: '@loctree/win32-x64-msvc', - label: 'Windows x64', - }, -]); - -const PLATFORM_PACKAGES = Object.freeze( - Object.fromEntries( - SUPPORTED_NPM_TARGETS.map((target) => [target.key, target.packageName]), - ), -); - -function normalizeArch(arch) { - const archMap = { - x64: 'x64', - arm64: 'arm64', - aarch64: 'arm64', - }; - - return archMap[arch] || arch; -} - -function isMuslLibc(spawnSyncImpl) { - const spawnSync = spawnSyncImpl || require('child_process').spawnSync; - try { - const lddVersion = spawnSync('ldd', ['--version'], { encoding: 'utf8' }); - return Boolean(lddVersion.stderr && lddVersion.stderr.includes('musl')); - } catch (_err) { - return false; - } -} - -function resolvePlatformKey(options = {}) { - const platform = options.platform || process.platform; - const arch = options.arch || process.arch; - const normalizedArch = normalizeArch(arch); - - if (platform === 'linux') { - const libcVariant = options.libcVariant || (isMuslLibc(options.spawnSync) ? 'musl' : 'gnu'); - return `${platform}-${normalizedArch}-${libcVariant}`; - } - - if (platform === 'win32') { - return `${platform}-${normalizedArch}-msvc`; - } - - if (platform === 'darwin') { - return `${platform}-${normalizedArch}`; - } - - return null; -} - -function getPackageNameForPlatformKey(platformKey) { - return PLATFORM_PACKAGES[platformKey] || null; -} - -function supportedTargetSummary() { - return SUPPORTED_NPM_TARGETS.map((target) => target.label).join(', '); -} - -function unsupportedPlatformMessage(options = {}) { - const platform = options.platform || process.platform; - const arch = options.arch || process.arch; - const platformKey = options.platformKey || resolvePlatformKey({ platform, arch }); - const subject = platformKey || `${platform}-${normalizeArch(arch)}`; - - const lines = [ - `No npm package is published for platform: ${subject}.`, - `Supported npm targets: ${supportedTargetSummary()}.`, - ]; - - if (subject === 'linux-x64-musl') { - lines.push( - 'Linux musl/Alpine is not packaged on npm yet. Use `cargo install --locked loctree`, a direct release asset, or another supported install channel.', - ); - } else { - lines.push( - 'Use `cargo install --locked loctree`, a direct release asset, or another supported install channel instead.', - ); - } - - return lines.join(' '); -} - -module.exports = { - SUPPORTED_NPM_TARGETS, - PLATFORM_PACKAGES, - getPackageNameForPlatformKey, - isMuslLibc, - normalizeArch, - resolvePlatformKey, - supportedTargetSummary, - unsupportedPlatformMessage, -}; diff --git a/distribution/npm/scripts/publish-all.sh b/distribution/npm/scripts/publish-all.sh deleted file mode 100755 index 64d0cc66..00000000 --- a/distribution/npm/scripts/publish-all.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/bash -# Automated publishing script for loctree npm packages - -set -e - -VERSION=${1:-$(node -p "require('../package.json').version")} -DRY_RUN=${DRY_RUN:-false} - -echo "=== loctree npm Publishing Script ===" -echo "Version: $VERSION" -echo "Dry run: $DRY_RUN" -echo "" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Check if we're logged in to npm -if ! npm whoami &> /dev/null; then - echo -e "${RED}Error: Not logged in to npm${NC}" - echo "Run: npm login" - exit 1 -fi - -NPM_USER=$(npm whoami) -echo -e "${GREEN}Logged in as: $NPM_USER${NC}" -echo "" - -# Function to publish a package -publish_package() { - local package_dir=$1 - local package_name=$2 - - echo -e "${YELLOW}Publishing $package_name...${NC}" - - cd "$package_dir" - - if [ "$DRY_RUN" = true ]; then - echo " [DRY RUN] Would publish: $package_name" - npm pack --dry-run - else - npm publish --access public - echo -e "${GREEN} ✓ Published $package_name${NC}" - fi - - cd - > /dev/null - echo "" -} - -# Step 1: Verify GitHub releases -echo "Step 1: Verifying GitHub releases..." -RELEASE_URL="https://github.com/Loctree/loct/releases/tag/v$VERSION" - -if command -v curl &> /dev/null; then - if curl -s -o /dev/null -w "%{http_code}" "$RELEASE_URL" | grep -q "200"; then - echo -e "${GREEN} ✓ Release v$VERSION exists${NC}" - else - echo -e "${RED} ✗ Release v$VERSION not found at $RELEASE_URL${NC}" - echo " Create the release first, then try again" - exit 1 - fi -else - echo -e "${YELLOW} ⚠ curl not found, skipping release verification${NC}" -fi -echo "" - -# Step 2: Create platform packages -echo "Step 2: Creating platform packages..." -if [ -x ./CREATE_PLATFORM_PACKAGES.sh ]; then - ./CREATE_PLATFORM_PACKAGES.sh "$VERSION" -else - echo -e "${YELLOW} ⚠ CREATE_PLATFORM_PACKAGES.sh not found or not executable${NC}" -fi -echo "" - -# Step 3: Publish platform packages -echo "Step 3: Publishing platform packages..." - -PLATFORMS=( - "darwin-arm64:@loctree/darwin-arm64" - "darwin-x64:@loctree/darwin-x64" - "linux-x64-gnu:@loctree/linux-x64-gnu" - "win32-x64-msvc:@loctree/win32-x64-msvc" -) - -for platform_spec in "${PLATFORMS[@]}"; do - IFS=: read -r platform_dir package_name <<< "$platform_spec" - publish_package "platform-packages/$platform_dir" "$package_name" -done - -# Step 4: Wait for packages to propagate -if [ "$DRY_RUN" = false ]; then - echo "Step 4: Waiting for packages to propagate..." - echo " Sleeping for 30 seconds to ensure npm registry is updated..." - sleep 30 - echo "" -fi - -# Step 5: Publish main package -echo "Step 5: Publishing main package..." -publish_package "." "loctree" - -# Step 6: Verify installation -if [ "$DRY_RUN" = false ]; then - echo "Step 6: Verifying installation..." - - TEST_DIR=$(mktemp -d) - cd "$TEST_DIR" - - echo " Testing in: $TEST_DIR" - npm init -y > /dev/null - npm install loctree - - if npx loct --version; then - echo -e "${GREEN} ✓ Installation verified successfully${NC}" - else - echo -e "${RED} ✗ Installation verification failed${NC}" - exit 1 - fi - - cd - > /dev/null - rm -rf "$TEST_DIR" -fi - -echo "" -echo -e "${GREEN}=== Publishing Complete! ===${NC}" -echo "" -echo "Next steps:" -echo "1. Test installation on different platforms" -echo "2. Update documentation if needed" -echo "3. Announce the release" -echo "" -echo "Test installation with:" -echo " npm install loctree@$VERSION" diff --git a/distribution/npm/sync-version.mjs b/distribution/npm/sync-version.mjs deleted file mode 100644 index dda520cd..00000000 --- a/distribution/npm/sync-version.mjs +++ /dev/null @@ -1,35 +0,0 @@ -import fs from "node:fs"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; - -const version = process.argv[2]; - -if (!version) { - console.error("Usage: node distribution/npm/sync-version.mjs "); - process.exit(1); -} - -const scriptDir = path.dirname(fileURLToPath(import.meta.url)); -const root = scriptDir; -const mainPackagePath = path.join(root, "package.json"); -const mainPackage = JSON.parse(fs.readFileSync(mainPackagePath, "utf8")); - -mainPackage.version = version; -for (const dep of Object.keys(mainPackage.optionalDependencies ?? {})) { - mainPackage.optionalDependencies[dep] = version; -} -fs.writeFileSync(mainPackagePath, `${JSON.stringify(mainPackage, null, 2)}\n`); - -const platformRoot = path.join(root, "platform-packages"); -if (fs.existsSync(platformRoot)) { - for (const entry of fs.readdirSync(platformRoot, { withFileTypes: true })) { - if (!entry.isDirectory()) continue; - const pkgPath = path.join(platformRoot, entry.name, "package.json"); - if (!fs.existsSync(pkgPath)) continue; - const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); - pkg.version = version; - fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`); - } -} - -console.log(`distribution/npm synced to ${version}`); diff --git a/distribution/npm/test/platform-support.test.js b/distribution/npm/test/platform-support.test.js deleted file mode 100644 index 5b8aad95..00000000 --- a/distribution/npm/test/platform-support.test.js +++ /dev/null @@ -1,120 +0,0 @@ -const test = require('node:test'); -const assert = require('node:assert/strict'); -const fs = require('node:fs'); -const os = require('node:os'); -const path = require('node:path'); - -const packageJson = require('../package.json'); -const { - SUPPORTED_NPM_TARGETS, - getPackageNameForPlatformKey, - resolvePlatformKey, - unsupportedPlatformMessage, -} = require('../platform-support'); -const { execLoctree, execLoctreeSync, getBinaryPath } = require('../index'); - -test('darwin x64 resolves to a published npm package', () => { - const platformKey = resolvePlatformKey({ platform: 'darwin', arch: 'x64' }); - assert.equal(platformKey, 'darwin-x64'); - assert.equal(getPackageNameForPlatformKey(platformKey), '@loctree/darwin-x64'); -}); - -test('musl platforms return an actionable unsupported-platform message', () => { - const message = unsupportedPlatformMessage({ - platform: 'linux', - arch: 'x64', - platformKey: 'linux-x64-musl', - }); - - assert.match(message, /Linux musl\/Alpine is not packaged on npm yet/); - assert.match(message, /cargo install --locked loctree/); -}); - -test('main npm package optionalDependencies match supported targets', () => { - const supportedPackages = SUPPORTED_NPM_TARGETS.map((target) => target.packageName).sort(); - const optionalDependencies = Object.keys(packageJson.optionalDependencies).sort(); - - assert.deepEqual(optionalDependencies, supportedPackages); -}); - -test('platform postinstall scripts fall back from thin repo to monorepo release assets', () => { - const repoRoot = path.resolve(__dirname, '..'); - const templatePath = path.join(repoRoot, 'platform-packages', 'postinstall.js'); - const templateSource = fs.readFileSync(templatePath, 'utf8'); - - assert.match(templateSource, /Loctree\/loct/); - assert.match(templateSource, /Loctree\/loctree-ast/); - assert.match(templateSource, /Attempted URLs:/); - - for (const target of SUPPORTED_NPM_TARGETS) { - const packageDir = target.packageName.replace('@loctree/', ''); - const packagePath = path.join(repoRoot, 'platform-packages', packageDir, 'postinstall.js'); - const packageSource = fs.readFileSync(packagePath, 'utf8'); - - assert.equal(packageSource, templateSource, `${packageDir} postinstall.js drifted from template`); - } -}); - -test('npm API captures stdout for programmatic calls', async (t) => { - const platformKey = resolvePlatformKey({ - platform: process.platform, - arch: process.arch, - libcVariant: 'gnu', - }); - const packageName = getPackageNameForPlatformKey(platformKey); - - if (!packageName) { - t.skip(`Current platform is not supported by the npm package: ${process.platform}-${process.arch}`); - return; - } - - const repoRoot = path.resolve(__dirname, '..'); - const binaryName = process.platform === 'win32' ? 'loct.exe' : 'loct'; - const binaryDir = path.join(repoRoot, 'node_modules', packageName); - const binaryPath = path.join(binaryDir, binaryName); - const hadOriginalBinary = fs.existsSync(binaryPath); - const originalBinary = hadOriginalBinary ? fs.readFileSync(binaryPath) : null; - - fs.mkdirSync(binaryDir, { recursive: true }); - - if (process.platform === 'win32') { - fs.writeFileSync( - binaryPath, - '@echo off\r\nif "%~1"=="--version" (echo loct test-version) else (echo %*)\r\n', - 'utf8', - ); - } else { - fs.writeFileSync( - binaryPath, - '#!/usr/bin/env node\n' + - 'if (process.argv[2] === "--version") {\n' + - ' process.stdout.write("loct test-version\\n");\n' + - '} else {\n' + - ' process.stdout.write(process.argv.slice(2).join(" "));\n' + - '}\n', - 'utf8', - ); - fs.chmodSync(binaryPath, 0o755); - } - - t.after(() => { - if (hadOriginalBinary && originalBinary) { - fs.writeFileSync(binaryPath, originalBinary); - if (process.platform !== 'win32') { - fs.chmodSync(binaryPath, 0o755); - } - return; - } - - fs.rmSync(path.join(repoRoot, 'node_modules'), { recursive: true, force: true }); - }); - - assert.equal(getBinaryPath(), binaryPath); - - const stdout = execLoctree(['alpha', 'beta']); - assert.equal(Buffer.isBuffer(stdout), true); - assert.equal(stdout.toString('utf8'), 'alpha beta'); - - const version = execLoctreeSync(['--version']); - assert.equal(version.trim(), 'loct test-version'); -}); diff --git a/distribution/windows/README.md b/distribution/windows/README.md deleted file mode 100644 index 5086afd8..00000000 --- a/distribution/windows/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Windows - -Windows distribution is release-asset first: - -- zipped `loctree.exe` and `loct.exe` -- npm wrapper only for targets we actually build in CI - -If we add winget later, it should join this tree rather than becoming another -root-level ritual. diff --git a/docs/01_homebrew_release.md b/docs/01_homebrew_release.md deleted file mode 100644 index 02ea6f67..00000000 --- a/docs/01_homebrew_release.md +++ /dev/null @@ -1,79 +0,0 @@ -# Homebrew Release Architecture - -Loctree no longer treats `homebrew-core` as the primary install path. - -The shipping architecture is now: - -- source + CI + versioning: `Loctree/loctree-ast` -- CLI binary releases: `Loctree/loct` -- MCP binary releases: `Loctree/loctree-mcp` -- CLI tap: `Loctree/homebrew-cli` -- MCP tap: `Loctree/homebrew-mcp` - -## User-Facing Commands - -```bash -brew install loctree/cli/loct -brew install loctree/mcp/loctree-mcp -``` - -## Why This Shape - -- The monorepo stays focused on code and CI instead of serving as a public asset bucket. -- CLI and MCP now have separate binary channels, which keeps install paths honest. -- Homebrew formulas can target exactly one product each. -- Release automation becomes deterministic: build once in the monorepo, distribute outward. - -## Release Sequence - -The human trigger remains the same: - -```bash -make version TYPE=minor TAG=1 PUSH=1 -``` - -That tag push triggers: - -1. crate publishing in `Loctree/loctree-ast` -2. binary builds for CLI and MCP -3. asset upload to `Loctree/loct` and `Loctree/loctree-mcp` -4. npm publish from `distribution/npm` -5. monorepo release publication -6. Homebrew tap sync into `Loctree/homebrew-cli` and `Loctree/homebrew-mcp` - -## Homebrew Formula Source of Truth - -The formulas are rendered by: - -```bash -scripts/render-homebrew-formula.sh -``` - -The workflow computes release SHA256 checksums from the thin repos and writes the -resulting files directly into the tap repos. The tap repos should not maintain -hand-edited version drift. - -## First Release Bootstrap - -Before the first release on this layout, create these GitHub repositories: - -- `Loctree/loct` -- `Loctree/loctree-mcp` -- `Loctree/homebrew-cli` -- `Loctree/homebrew-mcp` - -Also configure `HOMEBREW_GITHUB_API_TOKEN` in `Loctree/loctree-ast` with write access -to all four repositories. - -## Supported Homebrew Targets - -- macOS Apple Silicon -- macOS Intel -- Linux x86_64 - -## Operational Notes - -- The monorepo release is an orchestration/changelog release, not the main binary channel. -- npm should prefer CLI assets from `Loctree/loct`; the monorepo release stays a - temporary fallback while mirror lag catches up. -- If a tap sync fails, fix the thin release assets first, then re-run `homebrew-release.yml`. diff --git a/docs/02_query_mode.md b/docs/02_query_mode.md deleted file mode 100644 index 2cbdbedc..00000000 --- a/docs/02_query_mode.md +++ /dev/null @@ -1,636 +0,0 @@ -# Query Mode - jq-like Codebase Queries - -`loct` provides a jq-like interface for querying loctree snapshots. Instead of parsing JSON manually, use familiar filter syntax to extract insights from your codebase analysis. - -## Quick Start - -### What is Query Mode? - -Query mode lets you interrogate loctree snapshots using jq-style filters. Unlike raw jq, `loct` automatically discovers the latest snapshot and understands the codebase schema. - -```bash -# Basic filter - get snapshot metadata -loct '.metadata' - -# Get all file paths -loct '.files[].path' - -# Count dead exports -loct '.files | map(.exports | map(select(.dead == true))) | flatten | length' -``` - -### How it Differs from jq - -| Feature | jq | loct query | -|---------|-----|------------| -| Snapshot discovery | Manual path | Auto-discovers the latest snapshot from cache (see `LOCT_CACHE_DIR`) | -| Schema awareness | None | Validates against snapshot schema | -| Preset queries | None | `@imports`, `@exports`, `@dead`, etc. | -| Error messages | Generic JSON errors | Codebase-specific hints | - -## Usage - -``` -loct [OPTIONS] -loct [OPTIONS] @ [ARGS] -``` - -### Arguments - -- `` - jq-compatible filter expression -- `@` - Named preset query (see Preset Queries) - -### Examples - -```bash -# Raw filter -loct '.metadata.languages' - -# Preset query -loct @imports src/utils/auth.ts - -# Preset with options -loct @dead --confidence high -``` - -## Filter Syntax - -Query mode uses jq filter syntax. For comprehensive jq documentation, see [jq Manual](https://jqlang.github.io/jq/manual/). - -### Common Patterns - -#### Object Access -```bash -# Single field -loct '.metadata' - -# Nested field -loct '.metadata.git_branch' - -# Optional field (no error if missing) -loct '.metadata.git_repo?' -``` - -#### Array Operations -```bash -# All elements -loct '.files[]' - -# First element -loct '.files[0]' - -# Slice -loct '.files[0:10]' - -# Length -loct '.files | length' -``` - -#### Filtering -```bash -# Select by condition -loct '.files[] | select(.loc > 500)' - -# Select by path pattern -loct '.files[] | select(.path | contains("components"))' - -# Multiple conditions -loct '.files[] | select(.loc > 100 and .exports | length > 5)' -``` - -#### Transformation -```bash -# Extract specific fields -loct '.files[] | {path, loc, language}' - -# Map over array -loct '.files | map(.path)' - -# Flatten nested arrays -loct '.files | map(.exports) | flatten' -``` - -#### Aggregation -```bash -# Count -loct '.files | length' - -# Sum -loct '[.files[].loc] | add' - -# Group by -loct '.files | group_by(.language)' - -# Sort -loct '.files | sort_by(.loc) | reverse | .[0:10]' -``` - -## Options - -### Output Format - -| Option | Description | -|--------|-------------| -| `-r, --raw-output` | Output strings without JSON quotes | -| `-c, --compact` | Compact JSON output (single line) | - -```bash -# Get paths as raw strings (one per line) -loct -r '.files[].path' - -# Compact JSON for piping -loct -c '.metadata' | other-tool -``` - -### Variables - -| Option | Description | -|--------|-------------| -| `--arg NAME VALUE` | Bind `$NAME` to string `VALUE` | -| `--argjson NAME JSON` | Bind `$NAME` to parsed JSON | - -```bash -# Filter by variable -loct --arg file "auth.ts" '.files[] | select(.path | endswith($file))' - -# Numeric threshold -loct --argjson threshold 500 '.files[] | select(.loc > $threshold)' -``` - -### Snapshot Selection - -| Option | Description | -|--------|-------------| -| `--snapshot PATH` | Use specific snapshot file instead of auto-discovery | - -```bash -# Use specific snapshot -loct --snapshot /path/to/snapshot.json '.metadata' - -# Compare two snapshots -diff <(loct --snapshot old.json '.files | length') \ - <(loct --snapshot new.json '.files | length') -``` - -### Exit Status - -| Option | Description | -|--------|-------------| -| `-e, --exit-status` | Set exit code based on result | - -```bash -# Exit 1 if no dead exports found (for CI) -loct -e '.files | map(.exports) | flatten | map(select(.dead)) | length > 0' -``` - -## Preset Queries - -Presets are optimized queries for common operations. They handle edge cases and provide better output formatting. - -### @imports - Find Importers - -Find all files that import a given file (follows re-export chains). - -```bash -loct @imports -``` - -**Examples:** -```bash -# Who imports this component? -loct @imports src/components/Button.tsx - -# Raw output for scripting -loct @imports src/utils/auth.ts -r - -# JSON for AI agents -loct @imports src/hooks/usePatient.ts --json -``` - -**Output:** -```json -{ - "target": "src/components/Button.tsx", - "importers": [ - { "file": "src/App.tsx", "line": 5, "via": "import" }, - { "file": "src/pages/Home.tsx", "line": 12, "via": "reexport" } - ], - "count": 2 -} -``` - -### @exports - List Exports - -List all symbols exported by a file. - -```bash -loct @exports -``` - -**Examples:** -```bash -# What does this file export? -loct @exports src/utils/helpers.ts - -# Just the names -loct @exports src/api/index.ts -r | sort -``` - -**Output:** -```json -{ - "file": "src/utils/helpers.ts", - "exports": [ - { "name": "formatDate", "kind": "function", "line": 10, "dead": false }, - { "name": "parseId", "kind": "function", "line": 25, "dead": true } - ], - "count": 2 -} -``` - -### @dead - Unused Exports - -Find exports with no importers (dead code candidates). - -```bash -loct @dead [OPTIONS] -``` - -**Options:** -- `--confidence ` - Filter by confidence: `high`, `normal` (default), `low` -- `--path ` - Filter by file path pattern -- `--limit ` - Limit results (default: 20) - -**Examples:** -```bash -# All dead exports -loct @dead - -# High confidence only (safer to remove) -loct @dead --confidence high - -# Dead exports in specific directory -loct @dead --path "components/" - -# JSON output with full details -loct @dead --json -``` - -**Output:** -```json -{ - "dead_exports": [ - { - "file": "src/utils/legacy.ts", - "name": "oldHelper", - "line": 42, - "confidence": "high", - "reason": "No imports found, not in entry point" - } - ], - "count": 1 -} -``` - -### @cycles - Circular Imports - -Find circular import chains. - -```bash -loct @cycles [OPTIONS] -``` - -**Options:** -- `--path ` - Filter cycles involving this path -- `--min-length ` - Minimum cycle length to report - -**Examples:** -```bash -# All cycles -loct @cycles - -# Cycles involving auth -loct @cycles --path "auth" - -# Only complex cycles (3+ files) -loct @cycles --min-length 3 -``` - -**Output:** -```json -{ - "cycles": [ - { - "files": ["src/a.ts", "src/b.ts", "src/c.ts"], - "length": 3, - "severity": "warning" - } - ], - "count": 1 -} -``` - -### @who-imports - Transitive Importers - -Find all files that depend on a file (transitive closure). - -```bash -loct @who-imports -``` - -**Examples:** -```bash -# Blast radius of a change -loct @who-imports src/core/types.ts - -# Count affected files -loct @who-imports src/api/client.ts | jq '.count' -``` - -### @where-symbol - Symbol Lookup - -Find where a symbol is defined. - -```bash -loct @where-symbol -``` - -**Examples:** -```bash -# Find definition of a function -loct @where-symbol useAuth - -# Find all files exporting a name -loct @where-symbol Button --all -``` - -### @barrels - Barrel File Analysis - -Analyze barrel files (index.ts re-exports). - -```bash -loct @barrels [OPTIONS] -``` - -**Options:** -- `--deep` - Show deep re-export chains -- `--missing` - Show directories without barrels - -**Examples:** -```bash -# List all barrels -loct @barrels - -# Find barrel chains -loct @barrels --deep -``` - -### @commands - Tauri Command Bridges - -List Tauri FE/BE command mappings. - -```bash -loct @commands [OPTIONS] -``` - -**Options:** -- `--missing` - Only show missing handlers -- `--unused` - Only show unused handlers -- `--name ` - Filter by command name - -**Examples:** -```bash -# All commands -loct @commands - -# Missing handlers (FE calls without BE impl) -loct @commands --missing - -# Filter by name -loct @commands --name "auth" -``` - -### @events - Event Bridge Analysis - -List event emit/listen pairs. - -```bash -loct @events [OPTIONS] -``` - -**Options:** -- `--orphan` - Show events without listeners -- `--ghost` - Show listeners without emitters - -**Examples:** -```bash -# All events -loct @events - -# Orphan events (emitted but never handled) -loct @events --orphan -``` - -## Examples - -### Common Workflows - -#### Find All Files Importing a Component - -```bash -# Using preset -loct @imports src/components/Button.tsx - -# Using raw filter -loct '.edges[] | select(.to | endswith("Button.tsx")) | .from' -``` - -#### Count Dead Exports by Directory - -```bash -loct '.files | group_by(.path | split("/")[1]) | - map({ - dir: .[0].path | split("/")[1], - dead: [.[].exports[] | select(.dead)] | length - }) | - sort_by(.dead) | reverse' -``` - -#### Find Circular Dependencies Involving a File - -```bash -# Preset -loct @cycles --path "auth" - -# Raw filter -loct '.cycles[] | select(any(. | contains("auth")))' -``` - -#### Get Blast Radius of a File - -```bash -# How many files would be affected by changing this? -loct @who-imports src/core/types.ts -c | jq '.count' - -# List affected files -loct @who-imports src/api/client.ts -r -``` - -#### Export Data for External Tools - -```bash -# CSV of large files -loct -r '.files[] | select(.loc > 500) | [.path, .loc, .language] | @csv' - -# TSV for spreadsheet -loct -r '.files[] | [.path, .loc] | @tsv' > files.tsv - -# Markdown table -loct '.files | sort_by(.loc) | reverse | .[0:10] | - ["| File | LOC |", "|------|-----|"] + - map("| \(.path) | \(.loc) |") | .[]' -r -``` - -#### CI Integration - -```bash -# Fail if new dead exports -loct -e '@dead --confidence high | .count == 0' - -# Fail if cycles exist -loct -e '@cycles | .count == 0' - -# Check specific file isn't orphaned -loct -e '@imports src/utils/helper.ts | .count > 0' -``` - -## Snapshot Structure Reference - -The snapshot JSON has the following structure: - -```json -{ - "metadata": { - "schema_version": "0.5.0-rc", - "generated_at": "2025-01-15T10:30:00Z", - "roots": ["src", "lib"], - "languages": ["typescript", "rust"], - "file_count": 150, - "total_loc": 25000, - "scan_duration_ms": 1234, - "git_repo": "my-app", - "git_branch": "main", - "git_commit": "abc1234" - }, - "files": [ - { - "path": "src/main.ts", - "language": "typescript", - "loc": 150, - "exports": [ - { - "name": "main", - "kind": "function", - "export_type": "named", - "line": 10, - "dead": false - } - ], - "imports": ["./utils", "./config"], - "tauri_commands": [...], - "event_emits": [...], - "event_listens": [...] - } - ], - "edges": [ - { - "from": "src/app.ts", - "to": "src/utils.ts", - "label": "import" - } - ], - "export_index": { - "Button": ["src/components/Button.tsx"], - "useAuth": ["src/hooks/useAuth.ts", "src/legacy/auth.ts"] - }, - "command_bridges": [ - { - "name": "get_user", - "frontend_calls": [["src/api.ts", 42]], - "backend_handler": ["src-tauri/commands.rs", 100], - "has_handler": true, - "is_called": true - } - ], - "event_bridges": [ - { - "name": "user_updated", - "emits": [["src/user.rs", 50, "emit"]], - "listens": [["src/App.tsx", 30]] - } - ], - "barrels": [ - { - "path": "src/components/index.ts", - "module_id": "src/components", - "reexport_count": 15, - "targets": ["src/components/Button.tsx", "..."] - } - ] -} -``` - -### Key Fields - -| Path | Type | Description | -|------|------|-------------| -| `.metadata` | object | Scan metadata (version, git info, stats) | -| `.files` | array | All analyzed files with exports/imports | -| `.files[].exports` | array | Symbols exported by the file | -| `.files[].exports[].dead` | bool | Whether export has no importers | -| `.edges` | array | Import graph edges (from -> to) | -| `.export_index` | object | Symbol name -> files mapping | -| `.command_bridges` | array | Tauri FE/BE command mappings | -| `.event_bridges` | array | Event emit/listen pairs | -| `.barrels` | array | Detected barrel files (index.ts) | - -## Tips and Tricks - -### Combine with Other Tools - -```bash -# Pipe to rg for text search in results -loct '.files[].path' -r | rg "component" - -# Use fzf for interactive selection -loct '.files[].path' -r | fzf | xargs loct @imports - -# Generate AI context -loct @dead --json | claude "Review these dead exports" -``` - -### Performance - -```bash -# Use --snapshot for repeated queries (avoids re-discovery) -SNAP=$(loct '.metadata.git_scan_id' -r) -loct --snapshot "/path/to/snapshot.json" '.files | length' -loct --snapshot "/path/to/snapshot.json" '@dead' -``` - -### Debugging - -```bash -# See raw snapshot structure -loct '.' | head -100 - -# Check schema version -loct '.metadata.schema_version' - -# Validate snapshot exists -loct '.metadata' || echo "No snapshot found - run 'loct scan' first" -``` - ---- - -Developed by The Loctree Team ⓒ 2025-2026. diff --git a/docs/03_runtime_apis.md b/docs/03_runtime_apis.md deleted file mode 100644 index b65a0171..00000000 --- a/docs/03_runtime_apis.md +++ /dev/null @@ -1,117 +0,0 @@ -# Runtime API Detection (P1-03) - -## Problem -Node.js ES Module loader hooks and other runtime-invoked APIs are flagged as dead code because they're never statically imported. They're invoked by the runtime environment. - -## Solution -Loctree 0.7.x automatically detects runtime-invoked exports and excludes them from dead code detection. - -## Supported Runtime APIs - -### Node.js -- **ES Module loader hooks** (`resolve`, `load`, `globalPreload`, `initialize`) - - Files: `**/loader.{js,mjs,cjs}`, `**/loaders/*.{js,mjs,cjs}`, `lib/internal/modules/esm/*.js` - - Usage: `node --experimental-loader=./loader.mjs app.js` - -- **Test runner hooks** (`before`, `after`, `beforeEach`, `afterEach`) - - Files: `**/*.test.{js,mjs,cjs,ts,mts,cts}` - - Usage: `node --test test-runner.test.js` - -### Web APIs -- **Web Workers** (`onmessage`, `onmessageerror`, `onerror`) - - Files: `**/*.worker.{js,ts}` - -- **Service Workers** (`install`, `activate`, `fetch`, `message`, `sync`, `push`) - - Files: `**/service-worker.{js,ts}`, `**/sw.{js,ts}` - -### Build Tools -- **Vite plugins** (`config`, `configResolved`, `buildStart`, `buildEnd`) - - Files: `**/vite.config.{js,ts}` - -- **Webpack plugins** (`apply`) - - Files: `**/webpack.config.{js,ts}` - -### Frameworks -- **Next.js middleware** (`middleware`, `config`) - - Files: `**/middleware.{js,ts}` - -- **Astro** (`getStaticPaths`, `prerender`) - - Files: `**/*.astro` - -## Custom Runtime APIs - -Add custom patterns in `.loctree/config.toml`: - -```toml -[[runtime_apis]] -framework = "Remix" -exports = ["loader", "action", "meta", "links", "headers"] -file_patterns = ["**/routes/*.{jsx,tsx}", "**/routes/**/*.{jsx,tsx}"] - -[[runtime_apis]] -framework = "SvelteKit" -exports = ["load", "actions"] -file_patterns = ["**/+page.{js,ts}", "**/+layout.{js,ts}", "**/+server.{js,ts}"] -``` - -## CLI Flags - -### `--include-runtime` -Include runtime-invoked exports in dead code detection. - -Useful for auditing whether your loader hooks/middleware are actually being used. - -```bash -loct dead --include-runtime -``` - -Without this flag (default), runtime APIs are automatically excluded from dead detection. - -## Example - -### Before P1-03 (False Positives) -```bash -$ loct dead --path lib/internal/modules/esm - -Dead exports (7 false positives): - hooks.js:15 - resolve (never imported) - hooks.js:30 - load (never imported) - hooks.js:45 - globalPreload (never imported) - hooks.js:58 - initialize (never imported) -``` - -### After P1-03 (Zero False Positives) -```bash -$ loct dead --path lib/internal/modules/esm - -No dead exports found. - -Runtime-invoked APIs (excluded by default): - hooks.js:15 - resolve (Node.js ES Module loader hook) - hooks.js:30 - load (Node.js ES Module loader hook) - hooks.js:45 - globalPreload (Node.js ES Module loader hook) - hooks.js:58 - initialize (Node.js ES Module loader hook) - -Use --include-runtime to check if these hooks are actually being used. -``` - -## Impact -- **Before**: 7 false positives on Node.js codebase -- **After**: 0 false positives -- **Accuracy**: 100% reduction in false positive rate for runtime APIs - -## Test Fixtures -See `tools/fixtures/nodejs-loader/` for working examples: -- `loader.mjs` - ES Module loader hooks -- `test-runner.test.js` - Test runner hooks -- `.loctree/config.toml` - Custom runtime API configuration - -## Implementation -- Registry: `loctree_rs/src/analyzer/dead_parrots/runtime_apis.rs` -- Detection: `loctree_rs/src/analyzer/dead_parrots/mod.rs:650-658` -- Config: `loctree_rs/src/config.rs:23` -- Tests: `loctree_rs/src/analyzer/dead_parrots/mod.rs:1934-2077` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 06201f7b..00000000 --- a/docs/README.md +++ /dev/null @@ -1,330 +0,0 @@ -# loctree Documentation - -AI-oriented codebase analyzer for detecting dead code, circular imports, and generating dependency graphs. - -**Workspace version:** 0.8.17 -**CLI command:** `loct` (with `loctree` kept as a compatibility alias) - ---- - -## Quick Links - -- [Getting Started](getting-started.md) -- [CLI Commands](cli/commands.md) -- [CLI Options](cli/options.md) -- [Perception over Memory](../PERCEPTION.md) -- [Perception ADR](perception/adr.md) -- [Agent Context KPIs](perception/kpis.md) -- [Perception Research](perception/research.md) -- [Loctree Map + Vision](research/loctree-codebase-map-and-perception-first-vision-2026-02-17.md) -- [IDE Integration](#ide-integration) -- [AI Agent Integration](#ai-agent-integration) -- [CI/CD Integration](integrations/ci-cd.md) -- [Use Cases](use-cases/README.md) -- [Advanced Topics](#advanced) - ---- - -## Getting Started - -### Installation - -```bash -# Fastest public path: CLI + MCP server -curl -fsSL https://loct.io/install.sh | sh - -# From crates.io (reproducible lockfile build) -cargo install --locked loctree loctree-mcp - -# CLI-only npm channel -npm install -g loctree - -# From source -git clone https://github.com/Loctree/loctree-ast.git -cd loctree-ast -make install -``` - -Public install channels follow the latest published release, which can lag -behind the workspace version shown in this branch. Verify the exact published -version on crates.io, npm, or GitHub Releases when you're testing a release -surface. - -### First Scan - -```bash -cd your-project -loct # Auto-detects stack, writes cached artifacts (see LOCT_CACHE_DIR) -loct report --serve # Interactive HTML report -loct --for-ai # AI-optimized hierarchical output -``` - -### Essential Commands - -```bash -loct slice # Extract context for AI (deps + consumers) -loct health # Quick summary: cycles + dead + twins -loct dead --confidence high # Find unused exports -loct cycles # Detect circular imports -loct twins # Semantic duplicates analysis -``` - ---- - -## Core Concepts - -### Snapshot-Based Analysis - -loctree operates on snapshots stored in the artifacts dir (cache dir by default; override via `LOCT_CACHE_DIR`): - -- **snapshot.json** - Complete graph data (imports, exports, LOC per file) -- **findings.json** - All detected issues (dead code, cycles, duplicates) -- **agent.json** - AI-optimized context bundle -- **manifest.json** - Index for tooling and AI agents - -Scan once with `loct`, then query multiple times without re-parsing. - -### Findings Categories - -| Finding | Description | Command | -|---------|-------------|---------| -| **Dead Parrots** | Exports with 0 imports | `loct dead` | -| **Cycles** | Circular import chains | `loct cycles` | -| **Twins** | Semantic duplicates | `loct twins` | -| **Orphans** | Files with no imports/exports | `loct audit` | -| **Shadows** | Duplicate symbol definitions | `loct audit` | -| **Crowds** | Files with excessive connections | `loct audit` | - -### Artifacts - -All outputs are stored as artifacts in the artifacts dir (cache dir by default; override via `LOCT_CACHE_DIR`): - -```bash -loct # Creates snapshot + findings -loct report # Generates report.html -loct '.metadata' # Query snapshot.json directly -``` - ---- - -## IDE Integration - -> **Available in [loctree-suite](https://github.com/Loctree/loctree-suite)** - -Full LSP support for real-time dead code detection, cycle warnings, and code navigation is available through the language server included in loctree-suite. - -| Editor | Documentation | Status | -|--------|---------------|--------| -| VSCode | [ide/vscode.md](ide/vscode.md) | Ready (suite) | -| Neovim | [ide/neovim.md](ide/neovim.md) | Ready (suite) | -| Any LSP client | [ide/lsp-protocol.md](ide/lsp-protocol.md) | Ready (suite) | - -### Features - -- **Diagnostics** - Dead exports, cycles, twins as warnings -- **Hover** - Import counts, consumer files -- **Go to Definition** - Resolve re-export chains -- **References** - Find all importers -- **Code Actions** - Quick fixes for dead code - ---- - -## AI Agent Integration - -### Context Architecture (Default) - -For agentic workflows in this repo, the default strategy is **context-over-memory**: - -- [Perception over Memory](../PERCEPTION.md) -- [ADR](perception/adr.md) -- [KPI definitions](perception/kpis.md) -- [Research synthesis](perception/research.md) - -Guardrail sequence before non-trivial edits: -`repo-view -> focus -> slice -> impact -> find -> follow` - -### MCP Server - -loctree provides an MCP (Model Context Protocol) server for AI agents. - -**Full documentation:** [integrations/mcp-server.md](integrations/mcp-server.md) - -**Location:** `loctree-mcp/` -**Status:** Production-ready - -#### Setup - -Add to your MCP config (e.g., Claude Desktop): - -```json -{ - "mcpServers": { - "loctree": { - "command": "loctree-mcp", - "args": [] - } - } -} -``` - -#### Available Tools - -- `repo-view` - Repository overview: files, LOC, languages, health, top hubs -- `slice` - File context: dependencies + consumers in one call -- `find` - Symbol search with regex and multi-query support -- `impact` - Blast radius: direct + transitive consumers -- `focus` - Module deep-dive: files, internal edges, external deps -- `tree` - Directory structure with LOC counts -- `follow` - Pursue signals: dead exports, cycles, twins, hotspots - -#### Use Cases - -- **Context extraction** - Get relevant code for AI conversations -- **Duplicate detection** - Find existing components before creating new ones -- **Impact analysis** - Understand downstream effects of changes -- **Handler tracing** - Follow Tauri command pipelines - -### AI-Optimized Output - -```bash -loct --for-ai # Hierarchical JSON with quick wins -loct slice --json # Context bundle for AI agents -``` - -Output includes: -- Health score -- Quick wins (prioritized actions) -- Hub files (high-connectivity nodes) -- Dependency chains - ---- - -## Advanced - -### Architecture - -**Core components:** -- `loctree_rs/` - Main analyzer (Rust) -- `loctree-mcp/` - MCP server for AI agents -- `reports/` - HTML report renderer (Leptos SSR) -- Editor integrations and the LSP server are maintained in [loctree-suite](https://github.com/Loctree/loctree-suite) - -**Analysis flow:** -1. Auto-detect stack (Rust/TS/Python/Dart) -2. Parse imports/exports (language-specific) -3. Build dependency graph -4. Run detectors (dead code, cycles, twins) -5. Generate artifacts (snapshot, findings, reports) - -### Multi-Language Support - -| Language | Support | Parser | -|----------|---------|--------| -| Rust | Exceptional | Tree-sitter | -| TypeScript/JavaScript | Full | OXC | -| Python | Full | Custom | -| Go | Perfect | Tree-sitter | -| Dart/Flutter | Full | Tree-sitter | -| Svelte/Vue | Full | SFC + OXC | - -### Query Mode - -jq-compatible queries on snapshot data: - -```bash -loct '.metadata' # Extract metadata -loct '.files | length' # Count files -loct '.edges[] | select(.from | contains("api"))' # Filter edges -loct -r '.summary.health_score' # Raw output (no quotes) -loct -c '.dead_parrots' # Compact JSON -``` - -**Options:** -- `-r, --raw` - Raw output (no JSON quotes) -- `-c, --compact` - Compact one-line JSON -- `-e, --exit-status` - Exit 1 if result is false/null -- `--arg ` - Bind string variable -- `--argjson ` - Bind JSON variable - -### Tauri Integration - -Full command pipeline validation: - -```bash -loct commands # Missing/unregistered/unused handlers -loct trace # Follow FE invoke → BE handler -loct coverage --handlers # Test coverage for handlers -``` - -**Detects:** -- Missing handlers (frontend invokes non-existent backend) -- Unregistered handlers (`#[tauri::command]` not in `generate_handler![]`) -- Unused handlers (backend defined but never called) -- React.lazy() dynamic imports - -### Library Mode - -For libraries/frameworks with public APIs: - -```bash -loct --library-mode -``` - -**Features:** -- Auto-detects npm `exports` field -- Respects Python `__all__` declarations -- Ignores example/demo directories -- Excludes public APIs from dead code detection - -**Customization:** -```toml -# .loctree/config.toml -library_mode = true -library_example_globs = ["examples/*", "demos/*", "playground/*"] -``` - -### CI Integration - -Full documentation: [integrations/ci-cd.md](integrations/ci-cd.md) - -```bash -# Fail build on critical issues -loct lint --fail - -# SARIF output for GitHub/GitLab -loct lint --sarif > results.sarif - -# JSON output for custom processing -loct health --json -loct coverage --json -``` - -Supports: GitHub Actions, GitLab CI, CircleCI, pre-commit hooks. - -### Watch Mode - -```bash -loct watch # Auto-refresh on file changes -loct watch --serve # Live reload HTML report -``` - -### Contributing - -See [CONTRIBUTING.md](../CONTRIBUTING.md) for: -- Development setup -- Testing guidelines -- Adding language support -- Release process - ---- - -## Additional Resources - -- **Changelog:** [CHANGELOG.md](../CHANGELOG.md) -- **Main README:** [../README.md](../README.md) -- **Crates.io:** [loctree](https://crates.io/crates/loctree) -- **Repository:** [github.com/Loctree/loctree-ast](https://github.com/Loctree/loctree-ast) - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/benchmarks/01_v070_comparative_analysis.md b/docs/benchmarks/01_v070_comparative_analysis.md deleted file mode 100644 index df035317..00000000 --- a/docs/benchmarks/01_v070_comparative_analysis.md +++ /dev/null @@ -1,224 +0,0 @@ -# Loctree 0.7.0 Comparative Analysis - -> Benchmark date: 2025-12-16 -> Version: loctree 0.7.0-dev -> Platform: macOS Darwin 25.2.0 (Apple Silicon) - ---- - -## Executive Summary - -| Metric | Vista (large) | Loctree (medium) | -|--------|---------------|------------------| -| Files analyzed | 1,359 | 213 | -| Lines of code | 254,361 | 97,621 | -| Scan time | **24.3s** | **3.0s** | -| Health score | 78/100 | 80/100 | -| Throughput | 10,468 LOC/s | 32,540 LOC/s | - ---- - -## Test Projects - -### Vista (Production App) -- **Type**: Tauri desktop app (TypeScript + Rust) -- **Size**: 12GB repository, 1,359 source files -- **Languages**: TypeScript, TSX, Rust, CSS -- **Complexity**: Real-world PIMS veterinary application - -### Loctree (Self-analysis) -- **Type**: Rust CLI tool with multiple crates -- **Size**: 45GB repository (includes target/), 213 source files -- **Languages**: Rust, TypeScript, Python -- **Complexity**: Multi-language analyzer dogfooding itself - ---- - -## Performance Benchmarks - -### Full Scan (--fresh) - -| Project | Wall time | User time | System time | CPU % | -|---------|-----------|-----------|-------------|-------| -| Vista | 24.317s | 19.75s | 3.52s | 95% | -| Loctree | 3.006s | 1.74s | 0.95s | 89% | - -### Throughput Analysis - -``` -Vista: 254,361 LOC / 24.3s = 10,468 LOC/second -Loctree: 97,621 LOC / 3.0s = 32,540 LOC/second -``` - -Smaller projects have better cache locality and less I/O overhead. - ---- - -## Code Health Analysis - -### Vista Results - -```json -{ - "files": 1359, - "loc": 254361, - "health_score": 78, - "dead_parrots": 0, - "shadow_exports": 0, - "duplicate_groups": 160, - "cycles": { - "breaking": 2, - "structural": 0, - "diamond": 1 - } -} -``` - -**Interpretation**: -- Health score 78/100 - good overall health -- 2 breaking cycles - need attention -- 160 duplicate symbol groups - some consolidation opportunity -- No dead exports detected (clean codebase) - -### Loctree Results - -```json -{ - "files": 213, - "loc": 97621, - "health_score": 80, - "dead_parrots": 4, - "shadow_exports": 0, - "duplicate_groups": 68, - "cycles": { - "breaking": 0, - "structural": 0, - "diamond": 1 - } -} -``` - -**Interpretation**: -- Health score 80/100 - slightly better than Vista -- 4 dead exports in reports/wasm (acceptable for WASM bindings) -- No breaking cycles - clean dependency graph -- 68 duplicate groups (common names across crates) - ---- - -## Artifact Generation - -### New in 0.7.0 - -| Artifact | Vista | Loctree | Purpose | -|----------|-------|---------|---------| -| findings.json | 67 KB | 31 KB | Consolidated issues | -| manifest.json | ~1 KB | ~1 KB | AI/tooling index | -| snapshot.json | ~2 MB | ~500 KB | Full graph data | -| report.html | ~150 KB | ~80 KB | Human-readable report | -| report.sarif | ~50 KB | ~20 KB | IDE integration | - ---- - -## Command Performance - -### Alias Resolution (0.7.0 feature) - -| Command | Alias | Time | -|---------|-------|------| -| `loct slice` | `loct s` | <50ms | -| `loct find` | `loct f` | <50ms | -| `loct health` | `loct h` | <100ms | -| `loct dead` | `loct d` | <100ms | -| `loct doctor` | - | ~500ms | - -### Output Modes (0.7.0 feature) - -| Flag | Output | Use case | -|------|--------|----------| -| `--summary` | JSON to stdout | CI/scripts | -| `--findings` | JSON to stdout | AI agents | -| `--for-ai` | agent.json to stdout | Context loading | - ---- - -## Comparison: 0.6.x vs 0.7.0 - -### Mental Model - -| Aspect | 0.6.x | 0.7.0 | -|--------|-------|-------| -| Commands | 20+ separate | SCAN → QUERY → OUTPUT | -| Learning curve | Steep | Gentle | -| AI agent success | ~40% | ~90% (estimated) | -| Piping support | Partial | Full (stdout modes) | - -### New Features in 0.7.0 - -1. **Artifact-first architecture** - - findings.json consolidates all issues - - manifest.json guides AI agents - - Predictable output locations - -2. **Deprecation layer** - - Old commands still work - - Clear migration messages - - No breaking changes (yet) - -3. **Short aliases** - - `s`, `f`, `d`, `c`, `t`, `h`, `i`, `q` - - Faster interactive use - -4. **Doctor command** - - Unified diagnostics - - Auto-fixable vs needs-review - - Suppression suggestions - ---- - -## Recommendations - -### For Large Codebases (>100k LOC) - -- Use `--fresh` sparingly (cache is effective) -- Use `--summary` for quick checks -- Consider `.loctignore` for vendor directories - -### For AI Agents - -```bash -# Step 1: Read the index -cat .loctree/manifest.json - -# Step 2: Get issues -loct --findings | jq '.dead_parrots' - -# Step 3: Context for specific file -loct slice src/problematic-file.ts -``` - -### For CI/CD - -```bash -# Health check with threshold -loct --summary | jq -e '.health_score >= 70' - -# Fail on breaking cycles -loct --summary | jq -e '.cycles.breaking == 0' -``` - ---- - -## Conclusion - -Loctree 0.7.0 delivers: -- **3x simpler mental model** (SCAN → QUERY → OUTPUT) -- **Consistent performance** (~10-30k LOC/second) -- **AI-ready artifacts** (manifest.json, findings.json) -- **Backward compatibility** with deprecation warnings - -Ready for production use on codebases up to 500k+ LOC. - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/ci/README.md b/docs/ci/README.md deleted file mode 100644 index 115f4e9d..00000000 --- a/docs/ci/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# Loctree CI/CD Integration - -> Artifact-first structural analysis for your CI pipeline - -## Quick Start - -Add this badge to your README: - -```markdown -[![loctree](https://raw.githubusercontent.com/Loctree/loctree-ast/main/assets/loctree-badge.svg)](https://github.com/Loctree/loctree-ast) -``` - -Result: [![loctree](https://raw.githubusercontent.com/Loctree/loctree-ast/main/assets/loctree-badge.svg)](https://github.com/Loctree/loctree-ast) - -## GitHub Actions Workflow - -### Minimal (Python/JS/TS projects) - -```yaml -name: Loctree -on: [push, pull_request] - -jobs: - analyze: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - run: cargo install loctree --locked - # Write artifacts into the workspace (easy to upload/jq in CI) - - run: LOCT_CACHE_DIR=.loctree loct auto - - run: | - HEALTH=$(jq -r '.summary.health_score' .loctree/agent.json) - echo "Health: $HEALTH/100" - [ "$HEALTH" -lt 50 ] && exit 1 || exit 0 -``` - -### Full (with SARIF + PR comments) - -See [examples/ci/loctree-ci-v2.yml](../examples/ci/loctree-ci-v2.yml) - -## Key Commands for CI - -| Command | Purpose | Exit Code | -|---------|---------|-----------| -| `loct auto` | Full scan → artifacts dir (cache by default; set `LOCT_CACHE_DIR=.loctree` in CI) | Always 0 | -| `loct lint --fail` | Structural lint | 1 if issues | -| `loct dead --confidence high` | Dead exports | Always 0 | -| `loct cycles` | Circular imports | Always 0 | -| `loct health --json` | Quick summary | Always 0 | - -## Artifacts Generated - -By default, artifacts go to the OS cache dir. In CI, set `LOCT_CACHE_DIR=.loctree` to write artifacts into the workspace: - -``` -.loctree/ -├── snapshot.json # Full dependency graph (jq-queryable) -├── findings.json # All issues (dead, cycles, twins...) -├── agent.json # AI-optimized bundle with health_score -└── manifest.json # Index for tooling -``` - -## Health Score - -The `agent.json` contains a `health_score` (0-100): - -```bash -# Extract with jq -HEALTH=$(jq -r '.summary.health_score' .loctree/agent.json) -``` - -### Score Interpretation - -| Score | Status | Meaning | -|-------|--------|---------| -| 80-100 | 🟢 | Excellent structural health | -| 50-79 | 🟡 | Some issues, review recommended | -| 0-49 | 🔴 | Critical issues, fix before merge | - -## SARIF Integration - -Generate SARIF for GitHub Code Scanning: - -```yaml -- run: loct lint --sarif > loctree.sarif -- uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: loctree.sarif - category: loctree -``` - -## Environment Variables - -| Variable | Default | Description | -|----------|---------|-------------| -| `HEALTH_THRESHOLD` | 50 | Minimum health score to pass | -| `FAIL_ON_FINDINGS` | false | Exit 1 if any findings | -| `MAX_DEAD_EXPORTS` | ∞ | Max dead exports allowed | -| `MAX_CYCLES` | 0 | Max circular imports allowed | - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/cli/commands.md b/docs/cli/commands.md deleted file mode 100644 index 93e6aecc..00000000 --- a/docs/cli/commands.md +++ /dev/null @@ -1,1072 +0,0 @@ -# loctree CLI Command Reference - -Complete reference for all loctree commands. For global options and environment variables, see [options.md](./options.md). - -## Philosophy - -**Scan once, query everything.** Run `loct` to create cached artifacts (cache dir by default; override via `LOCT_CACHE_DIR`), then use subcommands to query them. - ---- - -## Table of Contents - -- [Quick Start](#quick-start) -- [Instant Commands (<100ms)](#instant-commands-100ms) -- [Analysis Commands](#analysis-commands) -- [Framework-Specific Commands](#framework-specific-commands) -- [Management Commands](#management-commands) -- [Core Workflow Commands](#core-workflow-commands) -- [JQ Query Mode](#jq-query-mode) -- [Aliases](#aliases) -- [Artifacts](#artifacts) - ---- - -## Quick Start - -| Command | Description | Speed | -|---------|-------------|-------| -| `loct` | Auto-scan and analyze current directory | ~2s | -| `loct health` | Quick health check (cycles + dead + twins) | <100ms | -| `loct slice ` | Extract file + dependencies for AI context | <100ms | -| `loct dead` | Find unused exports / dead code | <100ms | - ---- - -## Instant Commands (<100ms) - -These commands query pre-built artifacts and return results in milliseconds. - -### `focus` - Directory Context - -Extract holographic context for a directory (like `slice` but for directories). - -```bash -loct focus [OPTIONS] -``` - -**Options:** -- `--consumers`, `-c` - Include files that import from this directory -- `--depth ` - Maximum depth for external dependency traversal -- `--root ` - Project root (default: current directory) - -**Examples:** -```bash -loct focus src/features/patients/ # Focus on patients feature -loct focus src/components/ --consumers # Include external consumers -loct focus lib/utils/ --depth 1 # Limit external dep depth -loct focus src/api/ --json # JSON output for AI tools -``` - -**Output:** -- Core files (all files in the directory) -- Internal edges (imports within the directory) -- External deps (files outside the directory that are imported) -- Consumers (files outside that import from the directory) - ---- - -### `hotspots` - Import Frequency Heatmap - -Show import frequency heatmap - which files are core vs peripheral. - -```bash -loct hotspots [OPTIONS] -``` - -**Options:** -- `--min ` - Minimum import count to show (default: 1) -- `--limit ` - Maximum files to show (default: 50) -- `--leaves` - Show only leaf nodes (0 importers) -- `--coupling` - Include out-degree (files that import many others) -- `--root ` - Project root - -**Examples:** -```bash -loct hotspots # Show top 50 most-imported files -loct hotspots --limit 20 # Top 20 only -loct hotspots --leaves # Find leaf nodes (entry points / dead) -loct hotspots --coupling # Show both in-degree and out-degree -loct hotspots --min 5 # Only files with 5+ importers -``` - -**Output Categories:** -- **CORE** (10+ importers) - Critical infrastructure -- **SHARED** (3-9 importers) - Shared utilities -- **PERIPHERAL** (1-2 importers) - Feature-specific -- **LEAF** (0 importers) - Entry points or potentially dead code - ---- - -### `commands` - Tauri FE↔BE Handler Bridges - -Show Tauri command bridges between frontend and backend. - -```bash -loct commands [OPTIONS] [PATHS...] -``` - -**Options:** -- `--name ` - Filter to commands matching pattern -- `--missing-only` - Show only missing handlers -- `--unused-only` - Show only unused handlers -- `--limit ` - Maximum results to show - -**Examples:** -```bash -loct commands # Full coverage report -loct commands --missing-only # Only missing handlers -loct commands --json --missing # JSON for CI -``` - -**Detects:** -- Missing handlers: FE calls `invoke('cmd')` but no BE `#[tauri::command]` -- Unused handlers: BE has `#[tauri::command]` but FE never calls it -- Matched handlers: Both FE and BE exist (healthy) - ---- - -### `events` - Event Flow Analysis - -Show event emit/listen flow and issues. - -```bash -loct events [OPTIONS] [PATHS...] -``` - -**Options:** -- `--ghost` - Show ghost events (emitted but not handled) -- `--orphan` - Show orphan handlers (handlers without emitters) -- `--races` - Show potential race conditions -- `--fe-sync` - Show only FE<->FE sync events (window sync pattern) - -**Examples:** -```bash -loct events # Full event analysis -loct events --ghost # Only ghost events -loct events --races # Race condition detection -``` - ---- - -### `coverage` - Test Coverage Gaps - -Analyze test coverage gaps (structural coverage, not line coverage). - -```bash -loct coverage [OPTIONS] [PATHS...] -``` - -**Options:** -- `--handlers-only` - Only show handler gaps (skip events/exports) -- `--events-only` - Only show event gaps (skip handlers/exports) -- `--min-severity ` - Filter by minimum severity: critical, high, medium, low - -**Examples:** -```bash -loct coverage # Show all coverage gaps -loct coverage --handlers-only # Focus on untested handlers -loct coverage --min-severity high # Only critical/high issues -``` - -**Severity Levels:** -- **CRITICAL:** Handlers without any test (used in production!) -- **HIGH:** Events emitted but never tested -- **MEDIUM:** Exports without test imports -- **LOW:** Tests that import unused code - ---- - -### `health` - Quick Health Check - -One-shot summary of all structural issues. - -```bash -loct health [OPTIONS] [PATHS...] -``` - -**Options:** -- `--include-tests` - Include test files in analysis (default: false) - -**Examples:** -```bash -loct health # Quick health summary -loct health --include-tests # Include test files -loct health src/ # Analyze specific directory -loct health --json # Machine-readable output -``` - -**Output:** -- Cycles: Circular import count (hard vs structural) -- Dead: Unused exports (high confidence count) -- Twins: Duplicate symbol names across files - ---- - -### `slice` - File Context Extraction - -Extract holographic context for a file (file + all its dependencies). - -```bash -loct slice [OPTIONS] -``` - -**Options:** -- `--consumers`, `-c` - Include reverse dependencies (files that import this) -- `--depth ` - Maximum dependency depth to traverse -- `--root ` - Project root for resolving imports -- `--rescan` - Force snapshot update (includes new/uncommitted files) - -**Examples:** -```bash -loct slice src/main.rs # File + its dependencies -loct slice src/utils.ts --consumers # Include reverse deps -loct slice lib/api.ts --depth 2 # Limit to 2 levels -loct slice src/app.tsx --json # JSON output for AI tools -loct slice src/new-file.ts --rescan # Slice a newly created file -``` - -**Note:** Shows what the file USES, not what USES it. For reverse dependencies, use `--consumers` or `loct query who-imports`. - ---- - -### `impact` - Change Impact Analysis - -Analyze impact of modifying or removing a file. - -```bash -loct impact [OPTIONS] -``` - -**Options:** -- `--depth ` - Limit traversal depth (default: unlimited) -- `--root ` - Project root - -**Examples:** -```bash -loct impact src/utils.ts # Full impact analysis -loct impact src/api.ts --depth 2 # Limit to 2 levels deep -loct impact lib/helpers.ts --json # JSON output -``` - -**Difference from `query who-imports`:** -- `who-imports`: Finds direct importers only -- `impact`: Finds ALL affected files (direct + transitive) - ---- - -### `query` - Graph Queries - -Query the import graph and symbol index for specific relationships. - -```bash -loct query -``` - -**Query Kinds:** - -| Kind | Description | Example | -|------|-------------|---------| -| `who-imports ` | Find all files that import the file | `loct query who-imports src/utils.ts` | -| `where-symbol ` | Find where a symbol is defined/exported | `loct query where-symbol PatientRecord` | -| `component-of ` | Show which component/module contains the file | `loct query component-of src/ui/Button.tsx` | - -**Examples:** -```bash -loct query who-imports src/utils.ts # What imports utils.ts? -loct query where-symbol PatientRecord # Where is it defined? -loct query component-of src/ui/Button.tsx # What owns Button? -``` - ---- - -## Analysis Commands - -Commands that perform deeper analysis on the codebase. - -### `dead` - Unused Export Detection - -Detect unused exports / dead code. - -```bash -loct dead [OPTIONS] [PATHS...] -``` - -**Options:** -- `--confidence ` - `normal` or `high` (default: normal) -- `--top ` - Limit results to top N (default: 20) -- `--full`, `--all` - Show all results (ignore --top limit) -- `--path ` - Filter by file path pattern (regex) -- `--with-tests` - Include test files -- `--with-helpers` - Include helper files -- `--with-shadows` - Detect shadow exports (same symbol, multiple files) -- `--with-ambient` - Include ambient declarations (declare global/module/namespace) -- `--with-dynamic` - Include dynamically generated symbols (exec/eval/compile) - -**Examples:** -```bash -loct dead # Standard dead code analysis -loct dead --confidence high # Only high-confidence findings -loct dead --with-tests # Include test files -loct dead --with-shadows # Detect shadow exports -loct dead --full # Show all results -``` - ---- - -### `cycles` - Circular Import Detection - -Detect circular import chains. - -```bash -loct cycles [OPTIONS] [PATHS...] -``` - -**Options:** -- `--path ` - Filter to files matching pattern -- `--breaking-only` - Only show cycles that would break compilation -- `--explain` - Show detailed explanation for each cycle -- `--legacy-format` - Use legacy output format - -**Examples:** -```bash -loct cycles # Detect all cycles -loct cycles src/ # Only analyze src/ -loct cycles --json # JSON output for CI -loct cycles --explain # Detailed explanations -``` - -**Why Cycles Matter:** -- Runtime initialization errors -- Build/bundling failures -- Flaky test behavior - ---- - -### `twins` - Duplicate Symbol Detection - -Find dead parrots (0 imports) and duplicate exports. - -```bash -loct twins [OPTIONS] [PATH] -``` - -**Options:** -- `--path ` - Root directory to analyze -- `--dead-only` - Show only dead parrots (0 imports) -- `--include-tests` - Include test files (excluded by default) -- `--include-suppressed` - Show suppressed findings too -- `--ignore-conventions` - Ignore framework conventions when detecting twins - -**Examples:** -```bash -loct twins # Full analysis -loct twins --dead-only # Only exports with 0 imports -loct twins src/ # Analyze specific directory -loct twins --include-tests # Include test files -``` - -**Detects:** -- **Dead Parrots:** Exports with 0 imports anywhere in the codebase -- **Exact Twins:** Same symbol name exported from multiple files -- **Barrel Chaos:** Re-export anti-patterns (missing index.ts, deep re-export chains) - ---- - -### `zombie` - Comprehensive Dead Code Analysis - -Find all zombie code (dead exports + orphan files + shadows). - -```bash -loct zombie [OPTIONS] [PATHS...] -``` - -**Options:** -- `--include-tests` - Include test files in zombie detection (default: false) - -**Examples:** -```bash -loct zombie # Find all zombie code -loct zombie --include-tests # Include test files -loct zombie src/ # Analyze specific directory -``` - -**Combines:** -- **Dead Exports:** Symbols with 0 imports -- **Orphan Files:** Files with 0 importers (not entry points) -- **Shadow Exports:** Same symbol exported by multiple files where some have 0 imports - ---- - -### `audit` - Full Codebase Audit - -Comprehensive analysis combining all structural checks. - -```bash -loct audit [OPTIONS] [PATHS...] -``` - -**Options:** -- `--include-tests` - Include test files in analysis (default: false) -- `--todos` - Output as actionable todo checklist -- `--limit ` - Maximum items per category (default: 20) - -**Examples:** -```bash -loct audit # Full audit of current directory -loct audit --include-tests # Include test files -loct audit src/ # Audit specific directory -loct audit --todos # Actionable checklist format -``` - -**Includes:** -- Cycles (circular imports) -- Dead exports (unused code) -- Twins (duplicate symbols) -- Orphan files (0 importers) -- Shadow exports (consolidation candidates) -- Crowds (similar dependency patterns) - ---- - -### `crowd` - Functional Clustering - -Detect functional crowds (similar files clustering). - -```bash -loct crowd [PATTERN] [OPTIONS] -``` - -**Options:** -- `--pattern ` - Pattern to detect crowd around -- `--auto-detect` - Detect all crowds automatically -- `--min-size ` - Minimum crowd size to report (default: 2) -- `--limit ` - Maximum crowds to show in auto-detect mode (default: 10) -- `--include-tests` - Include test files in crowd detection (default: false) - -**Examples:** -```bash -loct crowd cache # Find cache-related clusters -loct crowd session # Find session-related clusters -loct crowd --auto-detect # Auto-detect all crowds -``` - ---- - -### `tagmap` - Unified Keyword Search - -Unified search around a keyword - aggregates files, crowds, and dead code. - -```bash -loct tagmap [OPTIONS] -``` - -**Options:** -- `--include-tests` - Include test files in analysis -- `--limit ` - Maximum results per section (default: 20) - -**Examples:** -```bash -loct tagmap patient # Everything about 'patient' feature -loct tagmap auth # Auth-related files, crowds, dead code -loct tagmap message --json # JSON output for AI processing -loct tagmap api --limit 10 # Limit results -``` - -**Aggregates:** -1. **FILES:** All files with keyword in path or name -2. **CROWD:** Functional clustering around the keyword -3. **DEAD:** Dead exports related to the keyword - ---- - -### `sniff` - Code Smell Aggregate - -Sniff for code smells (twins + dead parrots + crowds). - -```bash -loct sniff [OPTIONS] -``` - -**Options:** -- `--path ` - Root directory to analyze -- `--dead-only` - Show only dead parrots -- `--twins-only` - Show only twins -- `--crowds-only` - Show only crowds -- `--include-tests` - Include test files in analysis (default: false) -- `--min-crowd-size ` - Minimum crowd size to report (default: 2) - -**Examples:** -```bash -loct sniff # Full code smell analysis -loct sniff --dead-only # Only dead parrots -loct sniff --twins-only # Only duplicate names -loct sniff --crowds-only # Only similar file clusters -``` - -**Aggregates:** -- **TWINS:** Same symbol exported from multiple files -- **DEAD PARROTS:** Exports with 0 imports -- **CROWDS:** Files clustering around similar functionality - ---- - -### `doctor` - Interactive Diagnostics - -Interactive diagnostics with actionable recommendations. - -```bash -loct doctor [OPTIONS] [PATHS...] -``` - -**Options:** -- `--include-tests` - Include test files in analysis (default: false) -- `--apply-suppressions` - Auto-add suggested patterns to .loctignore - -**Examples:** -```bash -loct doctor # Interactive diagnostics -loct doctor --apply-suppressions # Auto-add .loctignore patterns -loct doctor src/ # Analyze specific directory -``` - -**Categorizes Findings:** -1. **Auto-fixable:** Issues with clear automated solutions -2. **Needs Review:** Potential issues requiring human judgment -3. **Suggested Suppressions:** Patterns to add to .loctignore - ---- - -## Framework-Specific Commands - -Commands designed for specific frameworks and tools. - -### `trace` - Tauri Handler Tracing - -Trace a Tauri/IPC handler end-to-end. - -```bash -loct trace [ROOTS...] -``` - -**Examples:** -```bash -loct trace toggle_assistant -loct trace standard_command apps/desktop -``` - -**Investigates:** -- Backend definition (file, line, exposed name) -- Frontend `invoke()` calls and plain mentions -- Registration status in `generate_handler![]` -- Verdict + suggestion to fix - ---- - -### `routes` - Backend Route Listing - -List backend/web routes (FastAPI/Flask). - -```bash -loct routes [OPTIONS] [PATHS...] -``` - -**Options:** -- `--framework ` - Filter by framework label (fastapi, flask) -- `--path ` - Filter by route path substring - -**Examples:** -```bash -loct routes # List all routes -loct routes --framework fastapi # Only FastAPI routes -loct routes --path /patients # Filter by path -``` - -**Detects:** -- **FastAPI:** `@app.get/post/put/delete/patch`, `@router.*`, `@api_router.*` -- **Flask:** `@app.route`, `@blueprint.route`, `.route(...)` - ---- - -### `dist` - Bundle Analysis - -Analyze bundle distribution using source maps. - -```bash -loct dist --source-map --src -``` - -**Options:** -- `--source-map ` - Path to source map file (e.g., dist/main.js.map) -- `--src ` - Source directory to scan (e.g., src/) - -**Examples:** -```bash -loct dist --source-map dist/main.js.map --src src/ -loct dist --source-map build/app.js.map --src app/src/ -``` - -**Compares:** -- Source code exports -- Bundled JavaScript (via source maps) -- Finds exports completely tree-shaken out by bundler - ---- - -### `layoutmap` - CSS Layout Analysis - -Analyze CSS layout properties (z-index, position, display). - -```bash -loct layoutmap [OPTIONS] -``` - -**Options:** -- `--zindex-only` - Show only z-index values -- `--sticky-only` - Show only sticky/fixed position elements -- `--grid-only` - Show only grid/flex layouts -- `--min-zindex ` - Filter z-index values >= N -- `--exclude ` - Exclude paths matching glob (can be repeated) -- `--root ` - Project root - -**Examples:** -```bash -loct layoutmap # Full CSS layout analysis -loct layoutmap --zindex-only # Only z-index hierarchy -loct layoutmap --sticky-only # Only sticky/fixed elements -loct layoutmap --min-zindex 100 # High z-index values (likely overlays) -loct layoutmap --exclude .obsidian --exclude prototype # Skip dirs -``` - -**Extracts:** -- **Z-INDEX:** All z-index values sorted by value (identifies layering conflicts) -- **POSITION:** Sticky/fixed positioned elements -- **DISPLAY:** Grid/flex layouts and their locations - ---- - -## Management Commands - -Commands for managing loctree analysis and configuration. - -### `doctor` - Interactive Diagnostics - -See [Analysis Commands](#doctor---interactive-diagnostics) section. - ---- - -### `suppress` - False Positive Management - -Manage false positive suppressions. - -```bash -loct suppress [OPTIONS] -loct suppress --list -loct suppress --clear -``` - -**Types:** -- `twins` - Exact twin (same symbol in multiple files) -- `dead_parrot` - Dead parrot (export with 0 imports) -- `dead_export` - Dead export (unused export) -- `circular` - Circular import - -**Options:** -- `--file ` - Only suppress in specific file (default: all files) -- `--reason ` - Document why this is a false positive -- `--list` - Show all current suppressions -- `--clear` - Remove all suppressions -- `--remove` - Remove a specific suppression - -**Examples:** -```bash -loct suppress twins Message # Suppress 'Message' twin everywhere -loct suppress twins Message --file src/types.ts # Only in specific file -loct suppress dead_parrot unusedHelper --reason 'Used via dynamic import' -loct suppress --list # View all suppressions -loct suppress --clear # Reset suppressions -``` - -**Storage:** -- Suppressions are stored in `.loctree/suppressions.toml` -- Commit this file to share suppressions with your team - ---- - -### `diff` - Snapshot Comparison - -Compare snapshots between branches/commits. - -```bash -loct diff --since [--to ] [OPTIONS] -``` - -**Options:** -- `--since ` - Base snapshot to compare from (required) -- `--to ` - Target snapshot (default: current working tree) -- `--auto-scan-base` - Auto-create git worktree and scan target branch -- `--problems-only` - Show only regressions (new dead code, new cycles) -- `--jsonl` - Output as JSONL (one line per change) - -**Examples:** -```bash -loct diff --since main # Compare main to working tree -loct diff --since HEAD~1 # Compare to previous commit -loct diff --since main --auto-scan-base # Auto-scan main branch -loct diff --since v1.0.0 --to v2.0.0 # Compare two tags -``` - -**Shows:** -- New/removed files and symbols -- Import graph changes -- New dead code introduced (regressions) -- New circular dependencies - ---- - -### `memex` - AI Memory Indexing - -Index analysis into AI memory (vector database). - -```bash -loct memex [OPTIONS] -``` - -**Options:** -- `--report-path ` - Path to .loctree directory or analysis.json file -- `--project-id ` - Unique project identifier (e.g., "github.com/org/repo") -- `--namespace ` - Namespace for the memory index (default: "loctree") -- `--db-path ` - Path to LanceDB storage directory - -**Examples:** -```bash -loct memex # Index current project -loct memex --project-id github.com/org/repo # Set project ID -loct memex --namespace myproject # Custom namespace -``` - ---- - -## Core Workflow Commands - -Commands for basic analysis and scanning. - -### `auto` - Full Auto-Scan (Default) - -Full auto-scan with stack detection (default command). - -```bash -loct auto [OPTIONS] [PATHS...] -loct [OPTIONS] [PATHS...] # 'auto' is the default command -``` - -**Options:** -- `--full-scan` - Force full rescan (ignore cache) -- `--scan-all` - Scan all files including hidden/ignored -- `--for-agent-feed` - Output optimized format for AI agents (JSONL stream) -- `--agent-json` - Emit a single agent bundle JSON - -**Examples:** -```bash -loct # Auto-scan current directory -loct auto # Explicit auto command -loct auto --full-scan # Force full rescan -loct auto src/ lib/ # Scan specific directories -loct --for-agent-feed # AI-optimized output (JSONL stream) -loct --agent-json # One-shot agent bundle JSON -``` - -**Performs:** -- Detects project type and language stack automatically -- Builds dependency graph and import relationships -- Analyzes code structure and exports -- Identifies potential issues (dead code, cycles, etc.) - ---- - -### `scan` - Build Snapshot - -Build/update snapshot for current HEAD. - -```bash -loct scan [OPTIONS] [PATHS...] -``` - -**Options:** -- `--full-scan` - Force full rescan, ignore cached data -- `--scan-all` - Include hidden and ignored files -- `--watch` - Watch for changes and re-scan automatically - -**Examples:** -```bash -loct scan # Scan current directory -loct scan --full-scan # Force complete rescan -loct scan src/ lib/ # Scan specific directories -loct scan --scan-all # Include all files (even hidden) -loct scan --watch # Watch mode with live refresh -``` - -**Note:** Unlike `auto`, it only builds the snapshot without extra analysis. - ---- - -### `tree` - Directory Tree with LOC - -Display LOC tree / structural overview. - -```bash -loct tree [OPTIONS] [PATHS...] -``` - -**Options:** -- `--depth `, `-L ` - Maximum depth (default: unlimited) -- `--summary [N]` - Show top N largest items (default: 5) -- `--top [N]` - Only show top N largest items (default: 50) -- `--loc ` - Only show items with LOC >= N -- `--min-loc ` - Alias for --loc -- `--show-hidden`, `-H` - Include hidden files/directories -- `--find-artifacts` - Highlight build/generated artifacts -- `--show-ignored` - Show gitignored files - -**Examples:** -```bash -loct tree # Full tree -loct tree --depth 3 # Limit depth -loct tree --summary 10 # Top 10 largest -loct tree --loc 100 # LOC threshold -loct tree src/ --show-hidden # Include dotfiles -``` - ---- - -### `find` - Symbol/File Search - -Semantic search for symbols by name pattern. - -```bash -loct find [QUERY] [OPTIONS] -``` - -**Options:** -- `--symbol ` - Search for symbols matching regex -- `--file ` - Search for files matching regex -- `--similar ` - Find symbols with similar names (fuzzy) -- `--dead` - Only show dead/unused symbols -- `--exported` - Only show exported symbols -- `--lang ` - Filter by language (ts, rs, js, py, etc.) -- `--limit ` - Maximum results to show - -**Examples:** -```bash -loct find Patient # Find symbols containing "Patient" -loct find --symbol ".*Config$" # Regex: symbols ending with Config -loct find --file "utils" # Files containing "utils" in path -loct find --dead --exported # Dead exported symbols -``` - -**Note:** NOT impact analysis - for dependency impact, use `loct impact`. NOT dead code detection - use `loct dead` or `loct twins`. - ---- - -### `lint` - Structural Linting - -Structural lint and policy checks. - -```bash -loct lint [OPTIONS] [PATHS...] -``` - -**Options:** -- `--entrypoints` - Check entrypoint coverage -- `--sarif` - Output in SARIF format for CI integration -- `--tauri` - Enable Tauri-specific checks -- `--fail` - Exit non-zero on issues (CI mode) - -**Examples:** -```bash -loct lint # Standard linting -loct lint --fail --sarif # CI mode with SARIF output -loct lint --tauri # Tauri-specific checks -``` - ---- - -### `report` - Generate Reports - -Generate HTML/JSON reports. - -```bash -loct report [OPTIONS] [PATHS...] -``` - -**Options:** -- `--format ` - Output format (html, json) -- `--output ` - Output file path -- `--serve` - Start a local server to view the report -- `--port ` - Server port (default: varies) -- `--editor ` - Editor integration (code, cursor, windsurf, jetbrains) - -**Examples:** -```bash -loct report --output report.html # Generate HTML report -loct report --serve --port 4173 # Serve report locally -loct report --editor code # VSCode integration -``` - ---- - -### `info` - Snapshot Metadata - -Show snapshot metadata and project info. - -```bash -loct info [OPTIONS] -``` - -**Options:** -- `--root ` - Root directory to check - -**Examples:** -```bash -loct info # Show snapshot metadata -loct info --root src/ # Check specific directory -``` - -**Displays:** -- Snapshot metadata -- Detected stack -- Analysis summary - ---- - -### `help` - Command Help - -Show help for commands. - -```bash -loct help [COMMAND] -loct --help -loct --help-full -loct --help-legacy -``` - -**Examples:** -```bash -loct help # Main help -loct help slice # Help for slice command -loct --help-full # All 27 commands -loct --help-legacy # Legacy flag migration guide -``` - ---- - -### `version` - Version Info - -Show version information. - -```bash -loct version -loct --version -``` - ---- - -## JQ Query Mode - -Query snapshot with jq-style filters. Requires jaq dependencies (enabled by default in CLI build). - -```bash -loct '' [OPTIONS] -``` - -**Options:** -- `-r`, `--raw-output` - Output raw strings, not JSON -- `-c`, `--compact-output` - Compact JSON output (no pretty-printing) -- `-e`, `--exit-status` - Set exit code based on output (0 if truthy) -- `--arg ` - Pass string variable to filter -- `--argjson ` - Pass JSON variable to filter -- `--snapshot ` - Use specific snapshot file instead of latest - -**Filter Syntax:** -- `.metadata` - Extract metadata field -- `.files[]` - Iterate over files array -- `.files[0]` - Get first file -- `.[\"key\"]` - Access key with special characters - -**Examples:** -```bash -loct '.metadata' # Extract metadata -loct '.files | length' # Count files -loct '.files[] | .path' # List file paths -loct '.metadata.total_loc' -r # Raw number output -loct '.files[] | select(.lang == "ts")' -c -loct '.files[] | select(.loc > 500)' -c -loct '.dead_parrots[]' # List dead exports -loct '.cycles[]' # List circular imports -``` - ---- - -## Aliases - -Quick shortcuts for common commands: - -| Alias | Equivalent | Description | -|-------|------------|-------------| -| `loct s ` | `loct slice ` | Extract file context | -| `loct f ` | `loct find ` | Search symbols/files | -| `loct h` | `loct health` | Health summary | - ---- - -## Artifacts - -loctree creates these artifacts in the artifacts dir (cache dir by default; override via `LOCT_CACHE_DIR`): - -| Artifact | Description | Use Case | -|----------|-------------|----------| -| `snapshot.json` | Full dependency graph | jq-queryable, complete project state | -| `findings.json` | All issues (dead, cycles, twins...) | CI integration, automated checks | -| `agent.json` | AI-optimized bundle with health_score | AI agent consumption | -| `manifest.json` | Index for tooling | Tooling integration | - -**Query artifacts:** -```bash -loct manifests --json # View manifest (stdout) -loct '.metadata' # Extract metadata from latest snapshot -loct '.files | length' # Count files using jq mode -``` - ---- - -## Examples - -### Quick Analysis -```bash -loct # Scan repo, create artifacts -loct health # Quick health check -loct hotspots # Find hub files (47ms!) -``` - -### Deep Analysis -```bash -loct focus src/features/ # Directory context (67ms!) -loct coverage # Test gaps (49ms!) -loct audit # Full audit -``` - -### AI Integration -```bash -loct slice src/main.rs --json | claude -loct --for-ai > context.json -``` - -### CI Integration -```bash -loct lint --fail --sarif > loctree.sarif -loct health --json | jq '.summary.health_score' -``` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/cli/options.md b/docs/cli/options.md deleted file mode 100644 index f1b909fb..00000000 --- a/docs/cli/options.md +++ /dev/null @@ -1,614 +0,0 @@ -# loctree CLI Global Options - -Global options and environment variables for loctree CLI. - ---- - -## Table of Contents - -- [Global Options](#global-options) -- [Output Options](#output-options) -- [Scan Behavior Options](#scan-behavior-options) -- [Filter Options](#filter-options) -- [Environment Variables](#environment-variables) -- [Color Mode](#color-mode) -- [Examples](#examples) - ---- - -## Global Options - -These options can be used with any loctree command. - -| Option | Description | Default | -|--------|-------------|---------| -| `--help`, `-h` | Show help for command | - | -| `--version` | Show version information | - | -| `--quiet` | Suppress non-essential output | Off | -| `--verbose` | Show detailed progress | Off | - -**Examples:** -```bash -loct --help # Main help -loct slice --help # Help for slice command -loct --version # Show version -loct scan --verbose # Detailed progress -loct dead --quiet # Minimal output -``` - ---- - -## Output Options - -Control output format and content. - -### `--json` - -Output as JSON (stdout only). Works with most commands. - -```bash -loct health --json -loct slice src/main.rs --json -loct dead --json -``` - -**Output:** -```json -{ - "summary": { - "cycles": 3, - "dead_exports": 12, - "twins": 2, - "health_score": 85 - } -} -``` - ---- - -### `findings` - -Emit the canonical findings JSON to stdout. Use this in new scripts instead of -the legacy bare `loct --findings` shortcut. - -```bash -loct findings -loct findings > findings.json -``` - -**Use Case:** -- CI integration -- Automated checks -- Custom processing - ---- - -### `findings --summary` - -Emit the compact summary JSON for CI/status checks. `--summary` remains valid on -`loct tree`, but for findings output the modern path is `loct findings --summary`. - -```bash -loct findings --summary -loct findings --summary | jq '.health_score' -loct tree --summary 10 -``` - -**Output:** -``` -{ - "health_score": 85, - "dead_exports": 12, - "cycles": 3, - "twins": 2 -} -``` - ---- - -### `--for-ai` - -Output AI context bundle (JSONL stream). Optimized for AI agents. - -```bash -loct --for-ai -loct --for-ai > context.jsonl -``` - -**Alias:** `loct --for-agent-feed` - -**Output Format:** JSONL (one JSON object per line) - ---- - -### `--agent-json` - -Emit single-shot agent JSON bundle (vs JSONL stream). Saved to the artifacts dir (cache by default; override via `LOCT_CACHE_DIR`). - -```bash -loct --agent-json -loct agent # Shortcut command -``` - -**Bundle Contains:** -- Handlers (Tauri commands) -- Duplicates (exact twins) -- Dead exports -- Dynamic imports -- Cycles -- Top files (by LOC) -- Health score - ---- - -## Scan Behavior Options - -Control how loctree scans and caches data. - -### `--fresh` - -Force rescan even if snapshot exists. Ignores mtime cache. - -```bash -loct --fresh -loct auto --fresh -loct scan --fresh -``` - -**Use When:** -- Snapshot is stale -- Files changed without mtime update -- Testing after code changes - ---- - -### `--no-scan` - -Fail if no snapshot exists (don't auto-scan). Query-only mode. - -```bash -loct slice src/main.rs --no-scan -loct health --no-scan -``` - -**Use When:** -- CI where scan happened in previous step -- You want to ensure you're using cached data -- Testing against existing snapshot - ---- - -### `--fail-stale` - -Fail if snapshot is stale (CI mode). Ensures snapshot is up-to-date. - -```bash -loct health --fail-stale -loct lint --fail-stale --sarif -``` - -**Use When:** -- CI pipeline -- Ensuring fresh analysis -- Pre-commit hooks - -**Exit Codes:** -- `0` - Snapshot is fresh -- `1` - Snapshot is stale - ---- - -### `--full-scan` - -Force full rescan ignoring mtime cache. Part of `auto` and `scan` commands. - -```bash -loct auto --full-scan -loct scan --full-scan -``` - -**Difference from `--fresh`:** -- `--fresh`: Global option, forces rescan for any command -- `--full-scan`: Scan option, ignores mtime optimization - ---- - -### `--scan-all` - -Include normally-ignored directories (node_modules, target, .venv). - -```bash -loct scan --scan-all -loct auto --scan-all -``` - -**Use When:** -- Analyzing vendored code -- Debugging missing imports -- Full codebase inspection - -**Default Ignored:** -- `node_modules/` -- `target/` -- `.venv/` -- `dist/` -- `build/` -- `.git/` - ---- - -## Filter Options - -Options for filtering and suppressing output. - -### `--no-duplicates` - -Suppress duplicate export sections in CLI output. Reduces noise. - -```bash -loct auto --no-duplicates -loct commands --no-duplicates -loct events --no-duplicates -loct lint --no-duplicates -``` - -**Affects:** -- `auto` command -- `commands` command -- `events` command -- `lint` command - ---- - -### `--no-dynamic-imports` - -Hide dynamic import sections in CLI output. Reduces noise. - -```bash -loct auto --no-dynamic-imports -loct events --no-dynamic-imports -loct lint --no-dynamic-imports -``` - -**Affects:** -- `auto` command -- `events` command -- `lint` command - ---- - -### `--py-root ` - -Additional Python package root for imports. Helps resolve Python imports. - -```bash -loct scan --py-root /path/to/python/packages -loct auto --py-root ./external-libs -``` - -**Use When:** -- Using external Python packages -- Custom Python package layout -- Monorepo with multiple Python roots - -**Example:** -```bash -# Resolve imports from both src/ and external-libs/ -loct scan --py-root ./external-libs -``` - ---- - -## Environment Variables - -### `LOCT_COLOR` - -Control color output. Overrides `--color` flag. - -**Values:** -- `auto` - Auto-detect TTY support (default) -- `always` - Force color output -- `never` - Disable color output - -**Example:** -```bash -export LOCT_COLOR=never -loct health # No color output - -LOCT_COLOR=always loct health | less -R # Force color in pipe -``` - ---- - -### `LOCT_CACHE_DIR` - -Override default cache directory. - -Default: platform user cache directory (`~/Library/Caches/loctree` on macOS, `~/.cache/loctree` on Linux). - -Tip: set `LOCT_CACHE_DIR=.loctree` to restore legacy project-local artifacts. - -**Example:** -```bash -export LOCT_CACHE_DIR=/tmp/loctree-cache -loct scan -``` - ---- - -### `LOCT_LOG_LEVEL` - -Set logging verbosity. Useful for debugging. - -**Values:** -- `error` - Only errors -- `warn` - Warnings and errors -- `info` - Informational messages (default) -- `debug` - Detailed debug output -- `trace` - Very detailed trace output - -**Example:** -```bash -export LOCT_LOG_LEVEL=debug -loct scan --verbose -``` - ---- - -## Color Mode - -Control color output with `--color` flag. - -```bash -loct --color -``` - -**Modes:** - -| Mode | Description | Use Case | -|------|-------------|----------| -| `auto` | Auto-detect TTY support | Default, smart detection | -| `always` | Force color output | Piping to `less -R`, HTML logs | -| `never` | Disable color output | CI logs, plain text files | - -**Examples:** -```bash -loct health --color auto # Auto-detect (default) -loct health --color always # Force color -loct health --color never # No color -loct health --color always | less -R # Color in less -``` - -**Auto-detection:** -- Checks if stdout is a TTY -- Checks `TERM` environment variable -- Checks `NO_COLOR` environment variable - ---- - -## Examples - -### CI Integration - -```bash -# Fail if snapshot is stale, output SARIF -loct lint --fail-stale --sarif --fail > loctree.sarif - -# JSON output for processing -loct health --json | jq '.summary.health_score' - -# Ensure fresh scan, fail on issues -loct --fresh audit --json > audit.json -``` - ---- - -### AI Agent Integration - -```bash -# Single-shot agent bundle -loct --agent-json > agent.json - -# JSONL stream for incremental processing -loct --for-ai > context.jsonl - -# Slice with JSON for AI consumption -loct slice src/main.rs --json | claude -``` - ---- - -### Development Workflow - -```bash -# Quick health check -loct h # Alias for --summary - -# Verbose scan with full rescan -loct scan --verbose --full-scan - -# Quiet mode for scripts -loct dead --quiet --json > dead.json - -# Watch mode for continuous analysis -loct scan --watch -``` - ---- - -### Debugging - -```bash -# Enable debug logging -export LOCT_LOG_LEVEL=debug -loct scan --verbose - -# Force color in pipe -loct health --color always | tee health.log - -# Use custom cache directory -export LOCT_CACHE_DIR=/tmp/loctree -loct scan -``` - ---- - -### Python Projects - -```bash -# Add custom Python root -loct scan --py-root ./external-libs - -# Multiple Python roots (run separate scans) -loct scan --py-root ./lib1 -loct scan --py-root ./lib2 - -# Include virtualenv in scan -loct scan --scan-all # Scans .venv/ too -``` - ---- - -## Option Precedence - -When options conflict, precedence is: - -1. Command-line flags (highest) -2. Environment variables -3. Configuration files (if any) -4. Defaults (lowest) - -**Example:** -```bash -# Environment variable -export LOCT_COLOR=never - -# Command-line flag overrides -loct health --color always # Uses 'always', not 'never' -``` - ---- - -## Best Practices - -### For CI - -```bash -# Use fail flags and JSON output -loct lint --fail-stale --fail --sarif > loctree.sarif -loct health --fail-stale --json > health.json - -# Disable color in CI logs -loct --color never health -# Or set environment variable -export LOCT_COLOR=never -``` - ---- - -### For Local Development - -```bash -# Use watch mode for continuous feedback -loct scan --watch - -# Quick health checks -loct h # Alias for --summary - -# Verbose for debugging -loct scan --verbose --full-scan -``` - ---- - -### For AI Integration - -```bash -# Agent bundle for one-shot context -loct agent > agent.json - -# JSONL stream for incremental processing -loct --for-ai > context.jsonl - -# JSON output for specific commands -loct slice src/main.rs --json -loct dead --json -loct health --json -``` - ---- - -## Common Patterns - -### Fresh Analysis - -```bash -# Force fresh scan and analysis -loct --fresh health -loct --fresh audit -loct scan --full-scan -``` - ---- - -### Query Only (No Scan) - -```bash -# Fail if no snapshot, don't auto-scan -loct slice src/main.rs --no-scan -loct health --no-scan -loct dead --no-scan -``` - ---- - -### Quiet Mode for Scripts - -```bash -# Minimal output, JSON for parsing -loct dead --quiet --json > dead.json -loct health --quiet --json | jq '.summary' -``` - ---- - -### Verbose Debugging - -```bash -# Detailed progress and logging -export LOCT_LOG_LEVEL=debug -loct scan --verbose --full-scan - -# Trace-level logging -export LOCT_LOG_LEVEL=trace -loct auto --verbose -``` - ---- - -## Summary Table - -| Option | Short | Type | Default | Commands | -|--------|-------|------|---------|----------| -| `--help` | `-h` | Flag | - | All | -| `--version` | - | Flag | - | All | -| `--json` | - | Flag | Off | Most | -| `--quiet` | - | Flag | Off | All | -| `--verbose` | - | Flag | Off | All | -| `--color ` | - | Value | `auto` | All | -| `--fresh` | - | Flag | Off | All | -| `--no-scan` | - | Flag | Off | Query commands | -| `--fail-stale` | - | Flag | Off | All | -| `--findings` | - | Flag | Legacy | bare `loct` only (compat alias for `findings`) | -| `--summary` | - | Flag | Legacy | bare `loct` compat alias for `findings --summary`; also `tree` | -| `--for-ai` | - | Flag | Off | `auto` | -| `--agent-json` | - | Flag | Off | `auto` | -| `--py-root ` | - | Value | - | `scan`, `auto` | -| `--full-scan` | - | Flag | Off | `scan`, `auto` | -| `--scan-all` | - | Flag | Off | `scan`, `auto` | -| `--no-duplicates` | - | Flag | Off | `auto`, `commands`, `events`, `lint` | -| `--no-dynamic-imports` | - | Flag | Off | `auto`, `events`, `lint` | - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/design/01_query_mode_test_plan.md b/docs/design/01_query_mode_test_plan.md deleted file mode 100644 index eb5a9bcf..00000000 --- a/docs/design/01_query_mode_test_plan.md +++ /dev/null @@ -1,614 +0,0 @@ -# Loctree Query Mode - Comprehensive Test Plan - -**Feature**: jq-style snapshot queries -**Command**: `loct `, `loct @preset `, `loct query ` -**Author**: AI Agent Design Document -**Date**: 2025-12-11 -**Status**: Design Phase - ---- - -## Overview - -Query mode enables jq-style filtering on loctree snapshots without re-scanning. -This document defines test cases for implementation. - -### Command Syntax - -```bash -# Filter syntax (jq-compatible) -loct '.metadata' # Simple field access -loct '.metadata.git_branch' # Nested access -loct '.edges[]' # Array iteration -loct '.edges | length' # Pipe to function -loct '.edges[] | select(.to == "foo")' # Filter with select - -# Preset queries (shorthand) -loct @imports src/foo.ts # Files that import foo.ts -loct @exports src/foo.ts # Symbols exported by foo.ts -loct @dead # Dead exports list -loct @consumers src/foo.ts # Files that consume foo.ts - -# Output flags -loct '.metadata.git_branch' -r # Raw output (no quotes) -loct '.edges' -c # Compact JSON -loct '.edges | length' -e # Exit code based on result - -# Explicit snapshot path -loct '.metadata' --snapshot .loctree/snapshot.json -``` - ---- - -## 1. Filter Detection Tests - -These tests verify the CLI correctly identifies filter expressions vs subcommands. - -### 1.1 Dot-prefix filter detection - -| Test ID | Input | Expected | Validates | -|---------|-------|----------|-----------| -| FD-001 | `loct '.metadata'` | Recognized as filter | Dot-prefix triggers filter mode | -| FD-002 | `loct '.metadata.git_branch'` | Recognized as filter | Nested dot-prefix works | -| FD-003 | `loct '.'` | Recognized as filter | Root selector works | -| FD-004 | `loct '.files[0]'` | Recognized as filter | Array index with dot-prefix | -| FD-005 | `loct '.edges[]'` | Recognized as filter | Array iteration with dot-prefix | - -### 1.2 Bracket-prefix filter detection - -| Test ID | Input | Expected | Validates | -|---------|-------|----------|-----------| -| FD-010 | `loct '[.metadata]'` | Recognized as filter | Bracket wrapping | -| FD-011 | `loct '[ .files[] ]'` | Recognized as filter | Bracket with spaces | -| FD-012 | `loct '[.edges[] | .from]'` | Recognized as filter | Complex bracket expression | - -### 1.3 Subcommand disambiguation - -| Test ID | Input | Expected | Validates | -|---------|-------|----------|-----------| -| FD-020 | `loct scan` | Recognized as subcommand | Known subcommand not treated as filter | -| FD-021 | `loct tree` | Recognized as subcommand | Another known subcommand | -| FD-022 | `loct dead` | Recognized as subcommand | Subcommand without args | -| FD-023 | `loct info` | Recognized as subcommand | Single-word subcommand | -| FD-024 | `loct query .metadata` | Explicit query subcommand | Explicit query mode | - -### 1.4 Preset detection - -| Test ID | Input | Expected | Validates | -|---------|-------|----------|-----------| -| FD-030 | `loct @imports foo.ts` | Recognized as preset | At-prefix triggers preset | -| FD-031 | `loct @exports foo.ts` | Recognized as preset | Known preset name | -| FD-032 | `loct @dead` | Recognized as preset | Preset without args | -| FD-033 | `loct @consumers foo.ts` | Recognized as preset | Consumer preset | -| FD-034 | `loct @unknown` | Error: unknown preset | Invalid preset rejected | - -### 1.5 Edge cases in detection - -| Test ID | Input | Expected | Validates | -|---------|-------|----------|-----------| -| FD-040 | `loct metadata` | Error or treated as path | Bare word not a filter | -| FD-041 | `loct .hidden-file.ts` | Ambiguous - file or filter? | Document behavior | -| FD-042 | `loct ''` | Error: empty filter | Empty string rejected | -| FD-043 | `loct ' .metadata '` | Recognized as filter | Whitespace trimmed | - ---- - -## 2. Snapshot Discovery Tests - -These tests verify correct snapshot file discovery and override behavior. - -### 2.1 Auto-discovery (newest snapshot) - -| Test ID | Setup | Command | Expected | Validates | -|---------|-------|---------|----------|-----------| -| SD-001 | Single `.loctree/snapshot.json` | `loct '.metadata'` | Uses that snapshot | Basic discovery | -| SD-002 | Multiple: `main@abc123/`, `develop@def456/` | `loct '.metadata'` | Uses newest by mtime | Multi-snapshot selection | -| SD-003 | Only `develop@xyz/snapshot.json` | `loct '.metadata'` | Uses branch-specific | Branch isolation works | -| SD-004 | Empty `.loctree/` directory | `loct '.metadata'` | Error: no snapshot found | Clear error on missing | -| SD-005 | No `.loctree/` directory | `loct '.metadata'` | Error: no snapshot found | Missing dir handled | - -### 2.2 Explicit snapshot path - -| Test ID | Setup | Command | Expected | Validates | -|---------|-------|---------|----------|-----------| -| SD-010 | Multiple snapshots exist | `loct '.metadata' --snapshot .loctree/old.json` | Uses specified file | Override works | -| SD-011 | Specified file missing | `loct '.metadata' --snapshot missing.json` | Error: file not found | Clear error | -| SD-012 | Invalid JSON file | `loct '.metadata' --snapshot broken.json` | Error: invalid snapshot | Parse error | -| SD-013 | Valid JSON, wrong schema | `loct '.metadata' --snapshot other.json` | Error or warning | Schema validation | - -### 2.3 Directory traversal - -| Test ID | Setup | Command | Expected | Validates | -|---------|-------|---------|----------|-----------| -| SD-020 | Run from subdirectory | `loct '.metadata'` | Finds parent's `.loctree/` | Upward search | -| SD-021 | Run from project root | `loct '.metadata'` | Finds `./.loctree/` | Direct path | -| SD-022 | Multiple `.loctree/` in ancestors | `loct '.metadata'` | Uses nearest | Closest wins | - ---- - -## 3. Filter Execution Tests - -These tests verify correct jq filter execution on snapshot data. - -### 3.1 Simple field access - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-001 | `.metadata` | Full metadata object | Top-level field | -| FE-002 | `.files` | Array of file analyses | Array field | -| FE-003 | `.edges` | Array of graph edges | Another array | -| FE-004 | `.barrels` | Array of barrel files | Optional field | -| FE-005 | `.nonexistent` | `null` | Missing field returns null | - -### 3.2 Nested field access - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-010 | `.metadata.git_branch` | `"develop"` (or current branch) | Nested string | -| FE-011 | `.metadata.file_count` | `44` (or current count) | Nested number | -| FE-012 | `.metadata.schema_version` | `"0.5.0-rc"` | Nested string | -| FE-013 | `.metadata.languages` | `["rs"]` or `["ts", "rs"]` | Nested array | -| FE-014 | `.metadata.nonexistent.deep` | `null` | Deep missing returns null | - -### 3.3 Array iteration - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-020 | `.files[]` | Each file as separate output | Array iteration | -| FE-021 | `.edges[]` | Each edge as separate output | Edge iteration | -| FE-022 | `.files[0]` | First file analysis | Index access | -| FE-023 | `.files[-1]` | Last file analysis | Negative index | -| FE-024 | `.files[0:3]` | First 3 files | Slice notation | - -### 3.4 Field extraction from arrays - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-030 | `.files[].path` | List of all file paths | Field from each | -| FE-031 | `.edges[].from` | List of all source files | Edge sources | -| FE-032 | `.edges[].to` | List of all target files | Edge targets | -| FE-033 | `.files[].exports[].name` | All export names | Nested array extraction | - -### 3.5 Select/filter expressions - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-040 | `.edges[] \| select(.to == "src/types.rs")` | Edges pointing to types.rs | Equality select | -| FE-041 | `.files[] \| select(.loc > 500)` | Files with >500 LOC | Numeric comparison | -| FE-042 | `.files[] \| select(.language == "ts")` | TypeScript files only | String match | -| FE-043 | `.files[] \| select(.is_test == true)` | Test files only | Boolean match | -| FE-044 | `.edges[] \| select(.label == "reexport")` | Re-export edges only | Label filter | -| FE-045 | `.files[] \| select(.path \| contains("utils"))` | Files with utils in path | String contains | -| FE-046 | `.files[] \| select(.path \| test(".*\\.rs$"))` | Rust files (regex) | Regex match | - -### 3.6 Variable binding (--arg) - -| Test ID | Command | Expected Output | Validates | -|---------|---------|-----------------|-----------| -| FE-050 | `loct '.edges[] \| select(.to == $file)' --arg file src/types.rs` | Edges to types.rs | String variable | -| FE-051 | `loct '.files[] \| select(.loc > $min)' --argjson min 100` | Files >100 LOC | JSON number variable | -| FE-052 | `loct '.edges[] \| select(.from == $f and .to == $t)' --arg f a.ts --arg t b.ts` | Specific edge | Multiple variables | - -### 3.7 Aggregate functions - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-060 | `.edges \| length` | Number of edges | Array length | -| FE-061 | `.files \| length` | Number of files | File count | -| FE-062 | `[.files[].loc] \| add` | Total LOC | Sum | -| FE-063 | `[.files[].loc] \| max` | Largest file LOC | Max | -| FE-064 | `[.files[].loc] \| min` | Smallest file LOC | Min | -| FE-065 | `.files \| group_by(.language) \| length` | Language count | Group by | -| FE-066 | `[.files[] \| select(.loc > 500)] \| length` | Count of large files | Filtered count | - -### 3.8 Object construction - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-070 | `.files[] \| {path, loc}` | Objects with path and loc | Field subset | -| FE-071 | `.edges[] \| {source: .from, target: .to}` | Renamed fields | Field renaming | -| FE-072 | `.files[] \| {path, exports: (.exports \| length)}` | Computed field | Nested computation | - -### 3.9 Sorting and limiting - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| FE-080 | `.files \| sort_by(.loc) \| reverse` | Files by LOC descending | Sort reverse | -| FE-081 | `.files \| sort_by(.loc) \| .[:10]` | Top 10 by LOC | Sort + limit | -| FE-082 | `.edges \| unique_by(.to)` | Unique targets | Deduplication | -| FE-083 | `[.files[] \| .path] \| sort` | Sorted file paths | Simple sort | - ---- - -## 4. Output Flag Tests - -These tests verify output formatting flags work correctly. - -### 4.1 Raw output (-r) - -| Test ID | Command | Expected Output | Validates | -|---------|---------|-----------------|-----------| -| OF-001 | `loct '.metadata.git_branch' -r` | `develop` (no quotes) | String unquoted | -| OF-002 | `loct '.metadata.file_count' -r` | `44` | Number unchanged | -| OF-003 | `loct '.files[0].path' -r` | `src/analyzer/assets.rs` | Path unquoted | -| OF-004 | `loct '.metadata' -r` | JSON object (formatted) | Objects unchanged | -| OF-005 | `loct '.files[].path' -r` | One path per line | Array items unquoted | - -### 4.2 Compact output (-c) - -| Test ID | Command | Expected Output | Validates | -|---------|---------|-----------------|-----------| -| OF-010 | `loct '.metadata' -c` | Single-line JSON | No pretty-print | -| OF-011 | `loct '.files[0]' -c` | Compact file JSON | Object compacted | -| OF-012 | `loct '.edges[:3]' -c` | Compact array | Array compacted | - -### 4.3 Exit code mode (-e) - -| Test ID | Command | Expected Exit Code | Validates | -|---------|---------|-------------------|-----------| -| OF-020 | `loct '.metadata' -e` | 0 | Non-null result | -| OF-021 | `loct '.nonexistent' -e` | 1 | Null result | -| OF-022 | `loct 'false' -e` | 1 | False result | -| OF-023 | `loct '""' -e` | 1 | Empty string | -| OF-024 | `loct '0' -e` | 0 | Zero is truthy | -| OF-025 | `loct '[]' -e` | 1 | Empty array is falsy | -| OF-026 | `loct '.edges \| length > 0' -e` | 0 | True condition | - -### 4.4 Combined flags - -| Test ID | Command | Expected | Validates | -|---------|---------|----------|-----------| -| OF-030 | `loct '.files[].path' -rc` | Compact paths, unquoted | Raw + compact | -| OF-031 | `loct '.edges \| length' -re` | Count, exit 0 if >0 | Raw + exit | - ---- - -## 5. Preset Query Tests - -These tests verify preset queries work correctly. - -### 5.1 @imports preset - -| Test ID | Command | Expected Output | Validates | -|---------|---------|-----------------|-----------| -| PQ-001 | `loct @imports src/types.rs` | Files importing types.rs | Basic imports | -| PQ-002 | `loct @imports src/nonexistent.ts` | `[]` (empty array) | Missing file | -| PQ-003 | `loct @imports types.rs` | Same as full path | Path normalization | -| PQ-004 | `loct @imports src/analyzer/` | Files importing from dir | Directory import | - -### 5.2 @exports preset - -| Test ID | Command | Expected Output | Validates | -|---------|---------|-----------------|-----------| -| PQ-010 | `loct @exports src/types.rs` | Export symbols | File exports | -| PQ-011 | `loct @exports src/nonexistent.ts` | Error or empty | Missing file | -| PQ-012 | `loct @exports src/analyzer/mod.rs` | Module exports | Rust mod exports | - -### 5.3 @dead preset - -| Test ID | Command | Expected Output | Validates | -|---------|---------|-----------------|-----------| -| PQ-020 | `loct @dead` | Dead export list | All dead exports | -| PQ-021 | `loct @dead --json` | JSON format dead | JSON output | -| PQ-022 | `loct @dead --top 5` | Top 5 dead exports | Limit works | - -### 5.4 @consumers preset - -| Test ID | Command | Expected Output | Validates | -|---------|---------|-----------------|-----------| -| PQ-030 | `loct @consumers src/types.rs` | Files that use types.rs | Transitive consumers | -| PQ-031 | `loct @consumers src/main.rs` | Entry point consumers | Entry file | - -### 5.5 Unknown preset - -| Test ID | Command | Expected | Validates | -|---------|---------|----------|-----------| -| PQ-040 | `loct @unknown` | Error: unknown preset '@unknown' | Clear error | -| PQ-041 | `loct @` | Error: empty preset name | Empty preset | - ---- - -## 6. Edge Cases - -### 6.1 Empty/null results - -| Test ID | Filter | Expected Output | Validates | -|---------|--------|-----------------|-----------| -| EC-001 | `.edges[] \| select(.to == "nonexistent")` | Empty output | No matches | -| EC-002 | `.barrels` (when empty) | `[]` | Empty array | -| EC-003 | `.files[999]` | `null` | Out of bounds | -| EC-004 | `.metadata.resolver_config` (when null) | `null` | Null field | - -### 6.2 Invalid filter syntax - -| Test ID | Filter | Expected | Validates | -|---------|--------|----------|-----------| -| EC-010 | `.metadata[` | Error: parse error | Unclosed bracket | -| EC-011 | `.edges \| select(` | Error: parse error | Unclosed paren | -| EC-012 | `.files \| unknownfn()` | Error: unknown function | Bad function | -| EC-013 | `. \| . \| . \| .` | Success (identity chain) | Valid but weird | - -### 6.3 Snapshot edge cases - -| Test ID | Scenario | Command | Expected | Validates | -|---------|----------|---------|----------|-----------| -| EC-020 | Snapshot with 0 files | `.files \| length` | `0` | Empty snapshot | -| EC-021 | Snapshot with 0 edges | `.edges \| length` | `0` | No edges | -| EC-022 | Corrupted JSON | `.metadata` | Error: invalid snapshot | Parse failure | -| EC-023 | Schema v0.4 snapshot | `.metadata` | Warning or error | Schema mismatch | - -### 6.4 Special characters - -| Test ID | Filter | Expected | Validates | -|---------|--------|----------|-----------| -| EC-030 | `.files[] \| select(.path \| contains("$"))` | Files with $ in path | Special char in string | -| EC-031 | `.edges[] \| select(.to == "src/types.d.ts")` | Edge to .d.ts | Dots in value | -| EC-032 | Filter with Unicode | Appropriate handling | Unicode support | - ---- - -## 7. Integration Tests - -### 7.1 Workflow: Scan then Query - -```bash -# Setup: Fresh project -loct scan # Create snapshot -loct '.metadata.file_count' # Query: should show count -loct '.edges | length' # Query: should show edge count -``` - -| Test ID | Step | Expected | Validates | -|---------|------|----------|-----------| -| IT-001 | After scan | Snapshot exists | Scan creates snapshot | -| IT-002 | Query after scan | Returns data | Query uses snapshot | -| IT-003 | Multiple queries | Consistent results | Snapshot stable | - -### 7.2 Workflow: Branch switching - -```bash -git checkout feature-branch -loct scan # Branch snapshot -loct '.metadata.git_branch' # Should show feature-branch -git checkout main -loct '.metadata.git_branch' # Should find main snapshot or error -``` - -| Test ID | Scenario | Expected | Validates | -|---------|----------|----------|-----------| -| IT-010 | Query on branch | Branch snapshot used | Branch isolation | -| IT-011 | Switch branch, no snapshot | Error: no snapshot | Clear error | - -### 7.3 Comparison with dead command - -```bash -# These should produce equivalent results -loct dead --json -loct @dead --json -loct '.files[] | select(.exports[] | select(.import_count == 0)) | .path' -``` - -| Test ID | Comparison | Expected | Validates | -|---------|------------|----------|-----------| -| IT-020 | @dead vs dead command | Same results | Preset matches command | -| IT-021 | Filter vs preset | Same results | Filter equivalent | - ---- - -## 8. Performance Tests - -### 8.1 Large snapshot handling - -| Test ID | Scenario | Metric | Threshold | Validates | -|---------|----------|--------|-----------|-----------| -| PT-001 | 10k files snapshot | Query time | < 100ms | Fast queries | -| PT-002 | 100k edges snapshot | Filter time | < 500ms | Edge handling | -| PT-003 | Deep nesting filter | Memory | < 100MB | Memory bound | - -### 8.2 Repeated queries - -| Test ID | Scenario | Expected | Validates | -|---------|----------|----------|-----------| -| PT-010 | 100 sequential queries | Consistent time | No degradation | -| PT-011 | Parallel queries | All succeed | Thread safety | - ---- - -## 9. Test Fixtures Required - -### 9.1 Fixture: simple_ts_for_query - -``` -simple_ts_for_query/ - .loctree/ - snapshot.json # Pre-generated snapshot - src/ - index.ts # Main entry - utils/ - helper.ts # Used by index - unused.ts # Dead export - types.ts # Shared types -``` - -Snapshot should contain: -- 4 files -- At least 3 edges -- 1 dead export in unused.ts -- metadata with git info - -### 9.2 Fixture: multi_snapshot - -``` -multi_snapshot/ - .loctree/ - snapshot.json # Current - main@abc1234/snapshot.json # Old main - develop@def5678/snapshot.json # Old develop -``` - -### 9.3 Fixture: empty_snapshot - -``` -empty_snapshot/ - .loctree/ - snapshot.json # Valid but empty: {metadata: {...}, files: [], edges: []} -``` - -### 9.4 Fixture: invalid_snapshots - -``` -invalid_snapshots/ - broken.json # Invalid JSON - old_schema.json # Valid JSON, wrong schema version - missing_fields.json # Missing required fields -``` - ---- - -## 10. Implementation Notes - -### 10.1 Recommended jq library - -For Rust implementation, consider: -- `jaq` crate (Rust-native jq implementation) -- `serde_json` + custom evaluator -- Shell out to `jq` binary (simpler but requires jq installed) - -### 10.2 Filter detection regex - -```rust -fn is_filter_expression(arg: &str) -> bool { - let arg = arg.trim(); - // Dot-prefix: .metadata, .files[], etc. - if arg.starts_with('.') { - return true; - } - // Bracket-prefix: [.metadata], [.files[]] - if arg.starts_with('[') && arg.ends_with(']') { - return true; - } - // Pipe expression without leading dot: length, keys, etc. - // These would need explicit `loct query` prefix - false -} - -fn is_preset(arg: &str) -> bool { - arg.starts_with('@') -} -``` - -### 10.3 Snapshot discovery algorithm - -```rust -fn find_snapshot(explicit: Option<&Path>) -> Result { - // 1. Explicit path takes precedence - if let Some(path) = explicit { - return Ok(path.to_path_buf()); - } - - // 2. Search upward for .loctree directory - let mut current = std::env::current_dir()?; - loop { - let loctree_dir = current.join(".loctree"); - if loctree_dir.exists() { - // 3. Find newest snapshot in directory - return find_newest_snapshot(&loctree_dir); - } - if !current.pop() { - break; - } - } - - Err(anyhow!("No snapshot found. Run `loct scan` first.")) -} -``` - ---- - -## Appendix A: Expected CLI Help Text - -``` -loct query - Query snapshot data with jq-style filters - -USAGE: - loct # Direct filter (starts with . or [) - loct @ [args] # Preset query - loct query [OPTIONS] # Explicit query command - -FILTERS: - .metadata Access metadata object - .files[] Iterate over files - .edges[] | select(.to == "x") Filter edges - .files | length Count files - -PRESETS: - @imports Files that import - @exports Symbols exported by - @consumers Files consuming - @dead Dead exports list - -OUTPUT OPTIONS: - -r, --raw-output Output strings without quotes - -c, --compact-output Compact JSON (no pretty-print) - -e, --exit-status Set exit code based on result - -SNAPSHOT OPTIONS: - --snapshot Use specific snapshot file - -EXAMPLES: - loct '.metadata.git_branch' - loct '.files[] | select(.loc > 500) | .path' -r - loct @imports src/utils.ts - loct '.edges | length' -e -``` - ---- - -## Appendix B: Snapshot Schema Reference - -```json -{ - "metadata": { - "schema_version": "0.5.0-rc", - "generated_at": "2025-12-11T10:30:00Z", - "roots": ["/path/to/project"], - "languages": ["ts", "rs"], - "file_count": 100, - "total_loc": 5000, - "scan_duration_ms": 500, - "git_repo": "Loctree", - "git_branch": "develop", - "git_commit": "abc1234" - }, - "files": [ - { - "path": "src/index.ts", - "loc": 50, - "language": "ts", - "kind": "code", - "is_test": false, - "is_generated": false, - "imports": [...], - "exports": [ - {"name": "main", "kind": "function", "export_type": "named", "line": 10} - ] - } - ], - "edges": [ - {"from": "src/app.ts", "to": "src/utils.ts", "label": "import"}, - {"from": "src/index.ts", "to": "src/types.ts", "label": "reexport"} - ], - "barrels": [...], - "export_index": {...}, - "command_bridges": [...], - "event_bridges": [...] -} -``` - ---- - -## Revision History - -| Version | Date | Author | Changes | -|---------|------|--------|---------| -| 1.0 | 2025-12-11 | AI Agent | Initial test plan design | diff --git a/docs/dev/.TL_DR/00_mcp_quickstart.md b/docs/dev/.TL_DR/00_mcp_quickstart.md deleted file mode 100644 index 43bdcbc4..00000000 --- a/docs/dev/.TL_DR/00_mcp_quickstart.md +++ /dev/null @@ -1,272 +0,0 @@ -# MCP Stack Quick Start - -## 1. Clone and install - -```bash -# Clone to any directory you like -git clone https://github.com/Loctree/loctree-suite.git -cd loctree-suite - -# Install MCP binaries (rmcp-mux, rmcp-mux-proxy, loctree-mcp, rmcp_memex) -make mcp-install -``` - -Alternatively, for the full suite including `loct` and `loctree` CLI: -```bash -make install-all -``` - -## 2. Setup directories - -```bash -make mux-setup -``` - -Creates: -``` -~/.rmcp_servers/ -├── config/mux.toml # <-- EDIT THIS -├── logs/ -├── pids/ -└── sockets/ -``` - -## 3. Configure mux.toml - -Copy example config (run from repo root): -```bash -cp docs/dev/.TL_DR/config-files/mux.toml ~/.rmcp_servers/config/mux.toml -``` - -**IMPORTANT**: Edit `~/.rmcp_servers/config/mux.toml` and replace all occurrences of: -- `/Users/YOURUSER/` → your actual home path (e.g., `/Users/monika/`) -- `YOUR_BRAVE_API_KEY_HERE` → your Brave Search API key -- `YOUR_GITHUB_TOKEN_HERE` → your GitHub personal access token - -## 4. Configure Claude Code - -Add to `~/.claude.json` (merge into existing `mcpServers` section): -```bash -cat docs/dev/.TL_DR/config-files/.claude/.claude.json -``` - -## 5. Start rmcp-mux - -```bash -make mux-start -``` - -This starts a **single rmcp-mux process** that manages ALL servers from `mux.toml`. - -## 6. Verify - -```bash -# Quick check via Makefile -make mux-status - -# Or query the daemon directly for detailed info -rmcp-mux daemon-status -``` - -Expected output from `daemon-status`: -``` -rmcp-mux v0.3.4 | uptime: 5s -──────────────────────────────────────────────────────────────────────── -Server State Clients Pending Restarts Heartbeat -──────────────────────────────────────────────────────────────────────── -brave-search ✓ START 0/3 0 0 - -loctree ✓ UP 0/5 0 0 - -rmcp-memex ✓ UP 0/5 0 0 - -youtube-transcript ✓ START 0/3 0 0 - -──────────────────────────────────────────────────────────────────────── -Total: 4 servers (4 running, 0 errors) -``` - -Legend: `UP` = running, `START` = lazy (starts on first connection), `FAIL` = error - -## Commands - -| Command | Description | -|---------|-------------| -| `make mux-start` | Start rmcp-mux (manages all servers) | -| `make mux-stop` | Stop rmcp-mux | -| `make mux-restart` | Restart rmcp-mux | -| `make mux-status` | Show status of all servers | -| `make mux-kill` | Force kill rmcp-mux | -| `make mux-tui` | Launch TUI interface | -| `make mux-restart-service SERVICE=name` | Restart a single service | -| `rmcp-mux daemon-status` | Query running daemon status | -| `rmcp-mux daemon-status --json` | Get status as JSON | -| `make mux-logs` | Tail mux.log (live) | -| `make mcp-health` | Health check sockets | - -## TUI Interface - -Launch the multi-server TUI dashboard: -```bash -make mux-tui -``` - -Keybindings: -- `j/k` or arrows - Navigate servers -- `r` - Restart selected server -- `s` - Stop selected server -- `S` - Start selected server -- `q` - Quit - -## CLI Flags - -Direct `rmcp-mux` usage: - -```bash -# Start all servers from config (default) -rmcp-mux --config ~/.rmcp_servers/config/mux.toml - -# Start only specific servers -rmcp-mux --config mux.toml --only loctree,rmcp-memex - -# Start all except some servers -rmcp-mux --config mux.toml --except youtube-transcript - -# Show status of all configured servers -rmcp-mux --show-status --config mux.toml - -# Restart a specific service -rmcp-mux --restart-service memex --config mux.toml -``` - -## Running Multiple Instances of the Same Server - -When you need multiple instances of the same MCP server (e.g., two rmcp-memex with different databases), **each instance MUST have a unique socket path**. - -### Example: Two rmcp-memex instances - -In `mux.toml`: -```toml -[servers.rmcp-memex] -socket = "~/.rmcp_servers/sockets/rmcp-memex.sock" # Unique socket! -cmd = "/Users/silver/.cargo/bin/rmcp_memex" -args = ["serve", "--db-path", "~/.rmcp_servers/rmcp_memex/lancedb"] - -[servers.rmcp-memex-ollama] -socket = "~/.rmcp_servers/sockets/rmcp-memex-ollama.sock" # Different socket! -cmd = "/Users/silver/.cargo/bin/rmcp_memex" -args = ["serve", "--db-path", "/path/to/other/lancedb"] -``` - -In `~/.claude.json`: -```json -{ - "mcpServers": { - "rmcp-memex": { - "command": "rmcp-mux", - "args": ["proxy", "--socket", "/Users/silver/.rmcp_servers/sockets/rmcp-memex.sock"] - }, - "rmcp-memex-ollama": { - "command": "rmcp-mux", - "args": ["proxy", "--socket", "/Users/silver/.rmcp_servers/sockets/rmcp-memex-ollama.sock"] - } - } -} -``` - -### Key Rules - -1. **Socket path must be unique per instance** - two servers cannot share a socket -2. **Server name in mux.toml must be unique** - this becomes the service name -3. **MCP server name in claude.json can be anything** - this is what Claude sees -4. **Same binary, different args** - the `cmd` can be identical, only args differ -5. **SLED_PATH required when sharing LanceDB** - see below - -### Sharing LanceDB Between Instances - -If multiple rmcp-memex instances point to the **same** LanceDB path (e.g., for different Claude sessions accessing shared knowledge), each instance needs its own sled K/V cache: - -```toml -[servers.memex-session-1] -socket = "~/.rmcp_servers/sockets/memex-1.sock" -cmd = "rmcp_memex" -args = ["serve", "--db-path", "/shared/lancedb"] -env = { SLED_PATH = "~/.rmcp_servers/sled/memex-1" } # Unique sled! - -[servers.memex-session-2] -socket = "~/.rmcp_servers/sockets/memex-2.sock" -cmd = "rmcp_memex" -args = ["serve", "--db-path", "/shared/lancedb"] # Same LanceDB OK -env = { SLED_PATH = "~/.rmcp_servers/sled/memex-2" } # Different sled! -``` - -**Why?** Sled is an embedded K/V store that requires exclusive file locking. Without unique `SLED_PATH`, you'll get: -``` -Error: could not acquire lock on ".../.sled/db": Resource temporarily unavailable -``` - -### Common Mistake - -```toml -# WRONG - same socket for different instances! -[servers.memex-1] -socket = "~/.rmcp_servers/sockets/memex.sock" # Same socket -cmd = "rmcp_memex" -args = ["serve", "--db-path", "/db1"] - -[servers.memex-2] -socket = "~/.rmcp_servers/sockets/memex.sock" # Conflict! -cmd = "rmcp_memex" -args = ["serve", "--db-path", "/db2"] -``` - -## Troubleshooting - -### Server won't start -```bash -# Check logs -tail -100 ~/.rmcp_servers/logs/mux.log - -# Common issue: wrong path in mux.toml -# Fix: use FULL paths, not ~/ -``` - -### Sled lock conflict (multiple memex instances) -``` -Error: could not acquire lock on ".../.sled/db": Resource temporarily unavailable -``` -**Fix**: Add unique `SLED_PATH` env var for each instance sharing the same LanceDB. -See "Sharing LanceDB Between Instances" section above. - -### Socket exists but server dead -```bash -make mux-kill # removes pids and sockets -make mux-start -``` - -### Claude Code can't connect -1. Check server is running: `make mux-status` -2. Check socket exists: `ls ~/.rmcp_servers/sockets/` -3. Restart Claude Code - -## Architecture - -``` -Claude Code - │ - ▼ (spawns) -rmcp-mux proxy --socket ~/.rmcp_servers/sockets/loctree.sock - │ - ▼ (Unix socket) -rmcp-mux daemon (SINGLE PROCESS - manages ALL servers) - │ - ├── loctree-mcp (child process) - ├── rmcp_memex (child process) - ├── brave-search (child process) - ├── sequential-thinking (child process) - └── youtube-transcript (child process) -``` - -Benefits: -- **Single process** manages all MCP servers -- One PID to track, one log to tail -- Atomic start/stop/restart -- Centralized TUI dashboard -- Shared Tokio runtime (memory efficient) -- Fast reconnection (no cold start) diff --git a/docs/dev/.TL_DR/config-files/.claude/.claude.json b/docs/dev/.TL_DR/config-files/.claude/.claude.json deleted file mode 100644 index fbff6e54..00000000 --- a/docs/dev/.TL_DR/config-files/.claude/.claude.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "_comment": "Add this mcpServers block to ~/.claude.json", - "_important": "Replace /Users/YOURUSER with your actual home path!", - "_architecture": "rmcp-mux runs as single daemon managing ALL servers. Proxy subcommand bridges Claude to mux sockets.", - - "mcpServers": { - "loctree": { - "command": "/Users/YOURUSER/.cargo/bin/rmcp-mux", - "args": ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/loctree.sock"], - "description": "Semantic codebase analysis - USE THIS BEFORE grep/search!" - }, - "rmcp-memex": { - "command": "/Users/YOURUSER/.cargo/bin/rmcp-mux", - "args": ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/rmcp-memex.sock"] - }, - "brave-search": { - "command": "/Users/YOURUSER/.cargo/bin/rmcp-mux", - "args": ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/brave-search.sock"] - }, - "sequential-thinking": { - "command": "/Users/YOURUSER/.cargo/bin/rmcp-mux", - "args": ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/sequential-thinking.sock"] - }, - "youtube-transcript": { - "command": "/Users/YOURUSER/.cargo/bin/rmcp-mux", - "args": ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/youtube-transcript.sock"] - } - } -} diff --git a/docs/dev/.TL_DR/config-files/.codex/config.toml b/docs/dev/.TL_DR/config-files/.codex/config.toml deleted file mode 100644 index 93f44fef..00000000 --- a/docs/dev/.TL_DR/config-files/.codex/config.toml +++ /dev/null @@ -1,36 +0,0 @@ -# Codex MCP Configuration -# Location: ~/.codex/config.toml -# -# ARCHITECTURE: rmcp-mux runs as single daemon managing ALL servers. -# The `rmcp-mux proxy` subcommand bridges Codex STDIO to mux Unix sockets. -# -# IMPORTANT: Replace /Users/YOURUSER with your actual home path! - -# ============================================================================= -# MCP Servers (via rmcp-mux proxy subcommand) -# ============================================================================= - -[mcp_servers.loctree] -command = "/Users/YOURUSER/.cargo/bin/rmcp-mux" -args = ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/loctree.sock"] -startup_timeout_sec = 5 - -[mcp_servers.rmcp-memex] -command = "/Users/YOURUSER/.cargo/bin/rmcp-mux" -args = ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/rmcp-memex.sock"] -startup_timeout_sec = 5 - -[mcp_servers.brave-search] -command = "/Users/YOURUSER/.cargo/bin/rmcp-mux" -args = ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/brave-search.sock"] -startup_timeout_sec = 60 - -[mcp_servers.sequential-thinking] -command = "/Users/YOURUSER/.cargo/bin/rmcp-mux" -args = ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/sequential-thinking.sock"] -startup_timeout_sec = 60 - -[mcp_servers.youtube-transcript] -command = "/Users/YOURUSER/.cargo/bin/rmcp-mux" -args = ["proxy", "--socket", "/Users/YOURUSER/.rmcp_servers/sockets/youtube-transcript.sock"] -startup_timeout_sec = 60 diff --git a/docs/dev/.TL_DR/config-files/mux.toml b/docs/dev/.TL_DR/config-files/mux.toml deleted file mode 100644 index 346d1729..00000000 --- a/docs/dev/.TL_DR/config-files/mux.toml +++ /dev/null @@ -1,141 +0,0 @@ -# rmcp-mux Configuration Template -# Location: ~/.rmcp-servers/config/mux.toml -# -# ARCHITECTURE: Single rmcp-mux process manages ALL servers defined here. -# Start with: rmcp-mux --config ~/.rmcp-servers/config/mux.toml -# or: make mux-start -# -# IMPORTANT: Replace /Users/YOURUSER with your actual home path! -# The ~ shorthand works for socket paths but NOT for cmd paths. -# -# ============================================================================= -# PARAMETER REFERENCE -# ============================================================================= -# -# socket - Unix socket path (required, supports ~) -# cmd - Command to run (required) -# args - Command arguments (default: []) -# env - Environment variables (default: {}) -# max_active_clients - Max concurrent clients (default: 5) -# lazy_start - Start on first request vs immediately (default: false) -# false = eager, starts with daemon -# true = lazy, spawns on first connection -# heartbeat_enabled - Enable health check pings (default: true) -# Set to false for servers that don't implement MCP ping -# tray - Show in system tray (default: false) -# -# ============================================================================= -# Core Servers (eager start - always running) -# ============================================================================= - -[servers.loctree] -socket = "~/.rmcp-servers/sockets/loctree.sock" -cmd = "/Users/YOURUSER/.cargo/bin/loctree-mcp" -args = [] -env = {} -max_active_clients = 5 -lazy_start = false -tray = false -heartbeat_enabled = false # loctree-mcp doesn't implement MCP ping yet - -[servers.rmcp-memex] -socket = "~/.rmcp-servers/sockets/rmcp-memex.sock" -cmd = "/Users/YOURUSER/.cargo/bin/rmcp_memex" -args = [ - "serve", - "--config", "/Users/YOURUSER/.rmcp-servers/rmcp_memex/config.toml", - "--db-path", "/Users/YOURUSER/.ai-memories/lancedb", - "--log-level", "info" -] -env = { SLED_PATH = "/Users/YOURUSER/.rmcp-servers/sled/memex" } -max_active_clients = 5 -lazy_start = false -tray = false -heartbeat_enabled = false # rmcp_memex doesn't implement MCP ping yet - -# ============================================================================= -# Utility Servers (lazy start - spawn on first request) -# ============================================================================= - -[servers.brave-search] -socket = "~/.rmcp-servers/sockets/brave-search.sock" -cmd = "npx" -args = ["-y", "@brave/brave-search-mcp-server"] -env = { BRAVE_API_KEY = "YOUR_BRAVE_API_KEY_HERE" } -max_active_clients = 3 -lazy_start = true -heartbeat_enabled = false # NPX servers don't implement MCP ping - -[servers.sequential-thinking] -socket = "~/.rmcp-servers/sockets/sequential-thinking.sock" -cmd = "npx" -args = ["-y", "@modelcontextprotocol/server-sequential-thinking"] -env = {} -max_active_clients = 3 -lazy_start = true -heartbeat_enabled = false - -[servers.youtube-transcript] -socket = "~/.rmcp-servers/sockets/youtube-transcript.sock" -cmd = "npx" -args = ["-y", "@kazuph/mcp-youtube"] -env = {} -max_active_clients = 3 -lazy_start = true -heartbeat_enabled = false - -# ============================================================================= -# Optional Servers (uncomment if needed) -# ============================================================================= - -# [servers.github] -# socket = "~/.rmcp-servers/sockets/github.sock" -# cmd = "npx" -# args = ["-y", "@modelcontextprotocol/server-github"] -# env = { GITHUB_PERSONAL_ACCESS_TOKEN = "YOUR_GITHUB_TOKEN_HERE" } -# max_active_clients = 3 -# lazy_start = true -# heartbeat_enabled = false - -# [servers.memory] -# socket = "~/.rmcp-servers/sockets/memory.sock" -# cmd = "npx" -# args = ["-y", "@modelcontextprotocol/server-memory"] -# env = { MEMORY_FILE_PATH = "/Users/YOURUSER/AI_memory/memory.json" } -# max_active_clients = 3 -# lazy_start = true -# heartbeat_enabled = false - -# [servers.curl] -# socket = "~/.rmcp-servers/sockets/curl.sock" -# cmd = "npx" -# args = ["-y", "@mcp-get-community/server-curl"] -# env = {} -# max_active_clients = 3 -# lazy_start = true -# heartbeat_enabled = false - -# ============================================================================= -# CLI Usage Examples -# ============================================================================= -# -# Start all servers: -# rmcp-mux --config ~/.rmcp-servers/config/mux.toml -# make mux-start -# -# Check status: -# rmcp-mux daemon-status # Query running daemon -# rmcp-mux daemon-status --json # JSON output -# make mux-status -# -# Start only specific servers: -# rmcp-mux --config mux.toml --only loctree,rmcp-memex -# -# Start all except some: -# rmcp-mux --config mux.toml --except youtube-transcript -# -# Restart single service: -# rmcp-mux --restart-service memex --config mux.toml -# -# TUI dashboard: -# make mux-tui diff --git a/docs/dev/00_readme.md b/docs/dev/00_readme.md deleted file mode 100644 index d1e56a49..00000000 --- a/docs/dev/00_readme.md +++ /dev/null @@ -1,57 +0,0 @@ -# Loctree Developer Docs - -Technical notes for contributors working inside the public `loctree-ast` -workspace. - -## Primary Docs - -| Document | Purpose | -|----------|---------| -| [01_installation.md](01_installation.md) | Install, verify, and update the workspace | -| [02_architecture.md](02_architecture.md) | Current workspace shape and blast-radius hubs | -| [03_cli_reference.md](03_cli_reference.md) | CLI contract and developer reference | - -## Quick Start - -```bash -git clone https://github.com/Loctree/loctree-ast.git -cd loctree-ast -make install -make precheck -``` - -## Workspace Crates - -The public workspace currently ships these members: - -| Crate | Version | Purpose | -|-------|---------|---------| -| `loctree` | 0.8.17 | Core analyzer + CLI (`loct`, `loctree`) | -| `loctree-mcp` | 0.8.17 | MCP server | -| `report-leptos` | 0.8.17 | HTML report renderer | -| `rmcp-common` | 0.8.17 | Shared MCP/common utilities | - -## Binaries - -| Binary | Purpose | -|--------|---------| -| `loct` | Canonical CLI | -| `loctree` | Quiet compatibility alias for `loct` | -| `loctree-mcp` | MCP server | - -## External Surfaces - -These are part of the broader Loctree ecosystem, but not members of this -workspace: - -- `loctree-suite` for editor/LSP surfaces -- thin release repos: `Loctree/loct` and `Loctree/loctree-mcp` -- Homebrew taps: `Loctree/homebrew-cli` and `Loctree/homebrew-mcp` - -## Core Gates - -```bash -make precheck # fast repo-wide check -make check # fmt + clippy + cargo check + semgrep -make test # workspace tests -``` diff --git a/docs/dev/01_installation.md b/docs/dev/01_installation.md deleted file mode 100644 index b321dcdf..00000000 --- a/docs/dev/01_installation.md +++ /dev/null @@ -1,217 +0,0 @@ -# Loctree - Installation Guide - -Complete installation guide for the public Loctree OSS workspace. - -## Quick Start - -```bash -# Fastest public install path: CLI + MCP server -curl -fsSL https://loct.io/install.sh | sh - -# Cargo alternative (reproducible lockfile build) -cargo install --locked loctree loctree-mcp - -# Or from source -git clone https://github.com/Loctree/loctree-ast.git -cd loctree-ast -make install -``` - -Public install channels follow the latest published release, which can lag -behind the workspace version on this branch. Verify the exact published version -on crates.io, npm, or GitHub Releases when you need release-exact behavior. - -## What Gets Installed - -| Binary | Crate | Description | -|--------|-------|-------------| -| `loct` | loctree | Primary CLI - fast, agent-optimized | -| `loctree` | loctree | Compatibility alias for `loct` | -| `loctree-mcp` | loctree-mcp | MCP server for AI agents (Claude, Cursor, etc.) | - -## Installation Methods - -### 1. One-Liner Installer - -```bash -curl -fsSL https://loct.io/install.sh | sh -``` - -The installer defaults to `loctree + loctree-mcp`. Set `INSTALL_MCP=0` only if -you explicitly want CLI-only. - -### 2. Cargo (Recommended) - -```bash -cargo install --locked loctree loctree-mcp -``` - -### 3. Homebrew (macOS/Linux) - -```bash -brew install loctree/cli/loct -brew install loctree/mcp/loctree-mcp -``` - -Use one global channel per machine. If you already installed Loctree globally -via Homebrew, avoid `npm install -g loctree` on the same setup unless you first -remove the existing global binaries. - -### 4. npm (CLI only) - -```bash -npm install -g loctree -``` - -Supported npm targets are defined by the latest published npm release. Alpine -/musl should use Cargo or direct release assets instead. - -This installs the CLI only. Install `loctree-mcp` separately via Cargo, -Homebrew, or GitHub Releases if your workflow needs MCP. - -### 5. Direct GitHub Release Assets - -The monorepo release page is the public fallback for installable CLI and MCP -tarballs. Thin release repos are part of the release choreography and may lag -while assets are being mirrored: - -- CLI: `Loctree/loct` -- MCP: `Loctree/loctree-mcp` - -### 6. From Source - -```bash -git clone https://github.com/Loctree/loctree-ast.git -cd loctree-ast -make install -``` - -## Clean-Room macOS Note - -The public release binaries use vendored `libgit2`, so macOS release artifacts -do not depend on Homebrew runtime paths such as `/opt/homebrew/opt/libgit2/...`. - -For a reproducible local verification on Apple Silicon: - -```bash -make smoke-release-macos-arm64 -``` - -## Workspace Structure - -```text -Loctree/ -├── loctree_rs/ # Core library + CLI (loct, loctree) -├── loctree-mcp/ # MCP server for loctree -├── rmcp-common/ # Shared MCP/common utilities -├── reports/ # Leptos-based HTML reports -└── distribution/ # Release/install channels and packaging docs -``` - -## Configuration - -### MCP Server Setup (Claude Code / Cursor) - -Add to your MCP config (`~/.config/claude/claude_desktop_config.json` or similar): - -```json -{ - "mcpServers": { - "loctree": { - "command": "loctree-mcp", - "args": [] - } - } -} -``` - -## Verification - -```bash -# Check versions -loct --version -loctree --version -loctree-mcp --version - -# Test loctree on current directory -loct - -# Test MCP server -echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | loctree-mcp -``` - -## Makefile Targets - -```bash -make install # Install loct, loctree, loctree-mcp -make install-cli # Install only loct + loctree -make install-mcp # Install only loctree-mcp -make build # Build all crates (release) -make build-core # Build only core -make precheck # Fast repo-wide gate -make test # Run all workspace tests -make check # Run the full quality gate -make fmt # Format code -make clean # Clean build artifacts -make mcp-build # Build loctree-mcp -make smoke-release-macos-arm64 # Verify macOS arm64 release portability -``` - -## Troubleshooting - -### Build Lock Conflict - -```text -Another build running (PID xxxx). Aborting. -``` - -Solution: - -```bash -make unlock -``` - -### Cargo Install Conflicts - -If you have both crates.io and local versions: - -```bash -cargo uninstall loctree loctree-mcp -make install -``` - -## Platform Support - -| Platform | CLI | MCP | Notes | -|----------|-----|-----|-------| -| macOS (Apple Silicon) | Full | Full | Primary releaseability target | -| macOS (Intel) | Full | Full | Built in release workflow | -| Linux (x86_64 glibc) | Full | Full | Built in release workflow | -| Windows (x86_64) | Full | Full | Built in release workflow | - -## Updating - -```bash -# From crates.io -cargo install --locked loctree loctree-mcp --force - -# From source -git pull -make install -``` - -## Uninstalling - -```bash -# Cargo-installed binaries -cargo uninstall loctree loctree-mcp - -# Or manually -rm ~/.cargo/bin/loct -rm ~/.cargo/bin/loctree -rm ~/.cargo/bin/loctree-mcp -``` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/dev/02_architecture.md b/docs/dev/02_architecture.md deleted file mode 100644 index fc97e6c5..00000000 --- a/docs/dev/02_architecture.md +++ /dev/null @@ -1,74 +0,0 @@ -# Loctree Architecture - -Current architecture of the public `loctree-ast` workspace. - -## Workspace Layout - -```text -loctree-ast/ -├── Cargo.toml # workspace manifest -├── Makefile # build, install, release, and smoke gates -├── loctree_rs/ # core library + CLI binaries -├── loctree-mcp/ # MCP server -├── rmcp-common/ # shared MCP/common utilities -├── reports/ # Leptos-based HTML reports -├── distribution/ # install and release channel contracts -├── docs/ # user + developer docs -├── scripts/ # release/install helpers -└── tools/ # hooks and fixtures -``` - -## Crate Graph - -```text - loctree (loctree_rs) - / \ - / \ - loctree-mcp report-leptos - \ - \ - rmcp-common -``` - -`reports/wasm` is a sub-crate under the report renderer for WASM assets. - -## High-Risk Hubs - -These files carry the largest blast radius in the live tree: - -- `loctree_rs/src/types.rs` -- `loctree_rs/src/snapshot.rs` -- `reports/src/types.rs` - -Before heavy edits, follow the repo discipline: - -```text -repo-view -> focus -> slice -> impact -> find -> follow -``` - -## Distribution Shape - -The monorepo is the source of truth for code, CI, and release choreography. - -User-facing binary distribution is split outward into thin repos and taps: - -- CLI release repo: `Loctree/loct` -- MCP release repo: `Loctree/loctree-mcp` -- CLI tap: `Loctree/homebrew-cli` -- MCP tap: `Loctree/homebrew-mcp` - -Those release channels are orchestrated from `.github/workflows/publish.yml` and -`distribution/`. - -## What Is Not In This Workspace - -Older docs sometimes referred to directories that no longer live here. The -public workspace does **not** contain: - -- `landing/` -- `rmcp-mux/` -- `rmcp-memex/` -- `loctree_memex/` - -Editor/LSP surfaces live in the external `loctree-suite` project rather than -this workspace. diff --git a/docs/dev/03_cli_reference.md b/docs/dev/03_cli_reference.md deleted file mode 100644 index 22c18e5c..00000000 --- a/docs/dev/03_cli_reference.md +++ /dev/null @@ -1,134 +0,0 @@ -# Loctree - CLI Reference - -Truthful reference for the public Loctree command surface in this repo. - -## loct - -`loct` is the canonical CLI. It auto-scans by default, writes artifacts to the -user cache dir (override with `LOCT_CACHE_DIR`), and lets you query the same -snapshot through focused commands. - -### Everyday usage - -```bash -loct # Default auto-scan for current directory -loct /path/to/project # Auto-scan a specific project -loct --fresh # Force rescan even if snapshot exists -loct --for-ai # AI context bundle (JSONL) -loct --agent-json # Single agent bundle JSON -``` - -### Query mode - -```bash -loct '.metadata' -loct '.files | length' -loct '.summary.health_score' -loct '.dead_parrots[]' -loct '.cycles[]' -``` - -### Core commands - -```bash -loct findings # Canonical findings JSON -loct findings --summary # Summary JSON for CI / status checks -loct slice src/App.tsx --consumers -loct find useAuth -loct impact src/utils/api.ts -loct health -loct dead --confidence high -loct cycles -loct twins -loct audit -loct doctor -loct lint --fail --sarif > loctree.sarif -loct report --serve --port 4173 -``` - -### Common flags - -| Flag | Description | -|------|-------------| -| `--fresh` | Force rescan even if snapshot exists | -| `--json` | JSON output on commands that support it | -| `--for-ai` | AI-optimized JSONL stream | -| `--agent-json` | One-shot agent bundle JSON | -| `--quiet`, `-q` | Suppress non-essential output | -| `--verbose` | Show detailed progress | -| `--fail-stale` | Fail if cached snapshot is stale | - -Notes: -- Prefer `loct findings` over the legacy bare `loct --findings` shortcut in new docs and scripts. -- Use `loct findings --summary` for summary JSON. The `--summary` flag still belongs on commands like `loct tree`. - -## loctree - -`loctree` is the quiet compatibility alias for `loct`. Keep using `loct` in new -examples; use `loctree` only when preserving older scripts or operator muscle -memory. - -## loctree-mcp - -`loctree-mcp` is the production MCP server for this workspace. It runs over -stdio and auto-scans a project on first use when no snapshot exists. - -### Usage - -```bash -loctree-mcp -loctree-mcp --version -``` - -### MCP tools - -| Tool | Description | -|------|-------------| -| `repo-view` | Repo overview: files, LOC, languages, health, top hubs | -| `slice` | File + dependencies + consumers in one call | -| `find` | Symbol search and reverse-import lookups | -| `impact` | Direct + transitive consumer blast radius | -| `focus` | Module/directory deep-dive | -| `tree` | Directory tree with LOC counts | -| `follow` | Structural signals: dead, cycles, twins, hotspots, trace, pipelines | - -### Configuration - -```json -{ - "mcpServers": { - "loctree": { - "command": "loctree-mcp", - "args": [] - } - } -} -``` - -### Recommended agent flow - -```text -repo-view -> focus -> slice -> impact -> find -> follow -``` - -## Exit codes - -| Code | Meaning | -|------|---------| -| `0` | Success | -| `1` | Command reported findings or general runtime failure | -| `2` | Invalid arguments / usage error | -| `101` | Rust panic | - -## Cross-check sources - -When this page and the runtime ever disagree, trust these repo-owned sources: - -- `loctree_rs/src/bin/loct.rs` -- `loctree_rs/src/cli/command/help.rs` -- `loctree_rs/src/cli/parser/core.rs` -- `loctree-mcp/src/main.rs` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/feature-requests/claude-code-smart-hook.md b/docs/feature-requests/claude-code-smart-hook.md deleted file mode 100644 index aa74236a..00000000 --- a/docs/feature-requests/claude-code-smart-hook.md +++ /dev/null @@ -1,112 +0,0 @@ -# Feature Request: Claude Code Smart Grep→loct Suggestion Hook - -## Summary - -Bundle an optional Claude Code hook that intelligently suggests `loct` commands when grep patterns would benefit from code-aware analysis. This would be installed alongside `mcp-server-loctree` configuration. - -## Motivation - -AI agents (Claude Code, Cursor, etc.) frequently use grep/ripgrep for code search. However, many search patterns would be served better by loct's semantic analysis: - -| grep pattern | What user wants | loct advantage | -|--------------|-----------------|----------------| -| `useAuthHandler` | Find hook definition + usages | `loct f` knows import chain | -| `ChatPanel` | Find component | `loct f` shows [DEF] + consumers | -| `run_agent` | Find Rust symbol | `loct f` works across TS+Rust | -| `dead` / `unused` | Find dead code | `loct '.dead_parrots'` is instant | -| `circular` | Find cycles | `loct '.cycles'` pre-indexed | - -## Proposed Solution - -### 1. New installer option - -```bash -loct install-claude-hook # Interactive setup -loct install-claude-hook -y # Auto-yes, non-interactive -``` - -### 2. What it installs - -**Hook script** → `~/.claude/hooks/loct-smart-suggest.sh` -- Non-blocking (always exit 0) -- Pattern detection for 12+ use cases -- Max 3 suggestions per session (anti-spam) -- Suggests jq-style queries where applicable - -**Settings update** → `~/.claude/settings.json` -```json -{ - "hooks": { - "PreToolUse": [ - { - "matcher": "Grep", - "hooks": [{ - "type": "command", - "command": "~/.claude/hooks/loct-smart-suggest.sh" - }] - } - ] - } -} -``` - -### 3. Combined with MCP server setup - -The existing `mcp-server-loctree` installation could offer this as optional step: - -``` -$ loct mcp install - -Installing MCP server for Claude Code... -✓ Added mcp-server-loctree to ~/.claude/settings.json - -Would you like to install the smart grep→loct suggestion hook? [Y/n] -This shows helpful loct commands when grep patterns would benefit from code-aware search. - -✓ Installed hook to ~/.claude/hooks/loct-smart-suggest.sh -✓ Added PreToolUse hook to settings.json - -Done! Restart Claude Code to activate. -``` - -## Pattern Detection Cases - -The hook detects when loct would genuinely help: - -1. **PascalCase** (`UserProfile`) → `loct f` for React components/types -2. **useXxx hooks** (`useAuth`) → `loct f` with import chain -3. **handleXxx/onXxx** → `loct f` for event handlers -4. **snake_case** (`run_agent`) → `loct f` cross-language -5. **invoke/emit** → `loct trace` for Tauri bridge -6. **import/export** → `loct query who-imports` -7. **dead/unused/orphan** → `loct '.dead_parrots'` -8. **circular/cycle** → `loct '.cycles'` -9. **duplicate/twin** → `loct '.twins'` -10. **count/total** → `loct '.files | length'` - -## Example Output - -When Claude Code uses Grep with pattern `useAgentSlashHandler`: - -``` -┌───────────────────────────────────────────────────────────── -│ 🌳 Hook search? loct shows definition + import chain -│ → loct f useAgentSlashHandler -└───────────────────────────────────────────────────────────── -``` - -## Implementation Notes - -- Hook reads tool input from stdin (JSON format) -- Uses jq for parsing, falls back to grep -- Session-based counter prevents suggestion spam -- Zero blocking - grep always runs, just with helpful hint - -## Reference Implementation - -Working prototype at: `~/.claude/hooks/loct-smart-suggest.sh` -(Created during Vista development session by M&K) - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/fixes/git-root-discovery.md b/docs/fixes/git-root-discovery.md deleted file mode 100644 index 8807bf5e..00000000 --- a/docs/fixes/git-root-discovery.md +++ /dev/null @@ -1,284 +0,0 @@ -# Fix: Git Root Discovery from Nested Directories - -**Issue**: Git context missing when running loctree from subdirectories -**Fixed in**: `v0.8.9` -**Affected versions**: `<= v0.8.8` - -## Problem Description - -Loctree was failing to detect git repository context when invoked from nested subdirectories, git worktrees, or certain monorepo structures. - -### Symptoms - -- Snapshot paths missing `branch@commit` segment (falling back to legacy path) -- `.gitignore` rules not being applied correctly -- `git_context` showing `null` values in snapshot metadata -- Different behavior depending on which directory you ran `loct` from - -### Example of Affected Scenario - -```bash -# From project root - works -$ cd /project -$ loct scan -[OK] Saved to ./.loctree/main@abc1234/snapshot.json - -# From nested directory - fails to detect git -$ cd /project/src/deep/nested/module -$ loct scan -[OK] Saved to ./.loctree/snapshot.json # Missing branch@commit! -``` - -## Root Cause - -Two components used shell commands that assumed the working directory was already inside a git repository: - -### 1. GitIgnoreChecker (fs_utils.rs) - -```rust -// OLD: Only works if `root` is directly in a git repo -Command::new("git") - .arg("-C") - .arg(root) // <- If this isn't in a git repo, fails - .arg("rev-parse") - .arg("--show-toplevel") -``` - -### 2. get_git_info (snapshot.rs) - -```rust -// OLD: Commands run with root as working directory -Command::new("git") - .args(["rev-parse", "--abbrev-ref", "HEAD"]) - .current_dir(root) // <- Assumes root is in a git repo -``` - -Neither implementation searched **upward** from the given path to find the actual `.git` directory. - -### When It Broke - -The bug manifested when loctree was called with a `root` parameter that wasn't directly inside a git repository, or when the scan was initiated from outside the repo: - -``` -/project/.git/ <- Git root -/project/src/module/ <- User runs: loct scan /project/src/module - -# Old code did: -git -C /project/src/module rev-parse --show-toplevel -# This actually WORKS (git searches upward) - -# But GitIgnoreChecker passed absolute paths that confused the logic, -# and get_git_info assumed current_dir was sufficient without explicit -# upward discovery. Edge cases like worktrees (.git as file) failed. -``` - -The real issues were: -1. **Inconsistent path handling** between different git operations -2. **No explicit upward search** - relied on git's implicit behavior which varied -3. **Worktrees not handled** - `.git` as a file broke assumptions - -The issue was particularly problematic for: -- **Monorepos**: Multiple packages, running from a package subdirectory -- **Git worktrees**: Where `.git` is a file pointing to the main repo -- **Deep directory structures**: Common in large projects - -## Solution - -### New Utility Function - -Added `find_git_root()` in `git.rs` that uses libgit2's `Repository::discover()`: - -```rust -/// Find the git repository root by searching upward from the given path. -/// -/// Uses libgit2's `Repository::discover()` which properly handles: -/// - Nested directories (searches upward to find .git) -/// - Git worktrees (where .git is a file, not a directory) -/// - Submodules -/// -/// Returns `None` if no git repository is found. -pub fn find_git_root(path: &Path) -> Option { - Repository::discover(path) - .ok() - .and_then(|repo| repo.workdir().map(|p| p.to_path_buf())) -} -``` - -### Updated GitIgnoreChecker - -```rust -impl GitIgnoreChecker { - pub fn new(root: &Path) -> Option { - // Use libgit2 to find git root (searches upward properly) - let repo_root = crate::git::find_git_root(root)?; - Some(Self { repo_root }) - } -} -``` - -### Updated get_git_info - -```rust -fn get_git_info(root: &Path) -> (Option, Option, Option) { - // Find the actual git root (searches upward from root) - let git_root = match crate::git::find_git_root(root) { - Some(r) => r, - None => return (None, None, None), - }; - - // Now run git commands from the discovered root - let repo = Command::new("git") - .args(["remote", "get-url", "origin"]) - .current_dir(&git_root) // <- Use discovered root - // ... -} -``` - -## Files Changed - -``` -loctree_rs/src/git.rs -├── find_git_root() - new utility function -├── test_find_git_root_from_repo_root() - test from root -├── test_find_git_root_from_nested_dir() - test from deep nested -├── test_find_git_root_non_git_dir() - test non-git returns None -├── test_find_git_root_worktree() - test worktree support -└── test_find_git_root_nested_repo_chooses_closest() - test nested repo picks closest - -loctree_rs/src/fs_utils.rs -└── GitIgnoreChecker::new() - now uses find_git_root() - -loctree_rs/src/snapshot.rs -└── get_git_info() - now uses find_git_root() -``` - -## Testing - -### Before Fix - -```bash -$ cd /project/src/components -$ loct scan -[OK] Saved to ./.loctree/snapshot.json -# Missing branch@commit in path! - -$ loct '.git_context' -{ - "repo": null, - "branch": null, - "commit": null, - "scan_id": null -} -``` - -### After Fix - -```bash -$ cd /project/src/components -$ loct scan -[OK] Saved to ./.loctree/main@abc1234/snapshot.json - -$ loct '.git_context' -{ - "repo": "my-project", - "branch": "main", - "commit": "abc1234", - "scan_id": "main@abc1234" -} -``` - -### Regression Tests - -```rust -#[test] -fn test_find_git_root_from_nested_dir() { - let (temp_dir, _repo) = create_test_repo(); - let path = temp_dir.path(); - - // Create deeply nested directory structure - let nested = path.join("src").join("deep").join("nested").join("dir"); - std::fs::create_dir_all(&nested).unwrap(); - - // find_git_root should find the repo root from nested dir - let root = find_git_root(&nested); - assert!(root.is_some(), "Should find git root from nested directory"); - - let expected = temp_dir.path().canonicalize().unwrap(); - let actual = root.unwrap().canonicalize().unwrap(); - assert_eq!(actual, expected); -} - -#[test] -fn test_find_git_root_non_git_dir() { - let temp_dir = TempDir::new().unwrap(); - let root = find_git_root(temp_dir.path()); - assert!(root.is_none(), "Should return None for non-git directory"); -} - -#[test] -fn test_find_git_root_worktree() { - let (main_dir, main_repo) = create_test_repo(); - let worktree_dir = TempDir::new().unwrap(); - - // Create a worktree (this creates a .git file pointing to main repo) - main_repo - .worktree("test-worktree", worktree_dir.path(), None) - .unwrap(); - - // find_git_root should work from worktree - let root = find_git_root(worktree_dir.path()); - assert!(root.is_some(), "Should find git root from worktree"); - - let actual = root.unwrap().canonicalize().unwrap(); - let expected = worktree_dir.path().canonicalize().unwrap(); - assert_eq!(actual, expected); -} - -#[test] -fn test_find_git_root_nested_repo_chooses_closest() { - let (outer_dir, _outer_repo) = create_test_repo(); - - // Create an inner git repo inside the outer one - let inner_path = outer_dir.path().join("packages").join("inner"); - std::fs::create_dir_all(&inner_path).unwrap(); - let inner_repo = Repository::init(&inner_path).unwrap(); - - // Create a nested dir inside the inner repo - let deep = inner_path.join("src").join("deep"); - std::fs::create_dir_all(&deep).unwrap(); - - // find_git_root from deep should find inner repo, not outer - let root = find_git_root(&deep); - assert!(root.is_some(), "Should find git root"); - - let actual = root.unwrap().canonicalize().unwrap(); - let expected = inner_path.canonicalize().unwrap(); - assert_eq!(actual, expected, "Should find closest (inner) repo, not outer"); -} -``` - -## Impact - -- Consistent git context detection regardless of working directory -- Proper `.gitignore` application from any subdirectory -- Correct `branch@commit` in snapshot paths -- Support for git worktrees and submodules - -## Technical Notes - -### Why libgit2 instead of shell commands? - -1. **Proper upward search**: `Repository::discover()` walks up the directory tree -2. **Worktree support**: Handles `.git` files (not just directories) -3. **No subprocess overhead**: Native library call -4. **Already a dependency**: Used by `GitRepo` for blame/diff features - -### Backwards Compatibility - -The fix is transparent - existing workflows continue to work, but now also work correctly from subdirectories. - -## Related - -- Git context in snapshots: `loct '.git_context'` -- GitIgnoreChecker: `loctree_rs/src/fs_utils.rs` -- Snapshot path resolution: `loctree_rs/src/snapshot.rs` diff --git a/docs/fixes/inline-comments-tauri-command-detection.md b/docs/fixes/inline-comments-tauri-command-detection.md deleted file mode 100644 index 72dcd74b..00000000 --- a/docs/fixes/inline-comments-tauri-command-detection.md +++ /dev/null @@ -1,181 +0,0 @@ -# Fix: Comments Breaking Tauri Command Detection - -**Issue**: False "missing handler" reports for valid `#[tauri::command]` functions -**Fixed in**: `v0.8.9` -**Affected versions**: `<= v0.8.8` - -## Problem Description - -Loctree was failing to detect Tauri command handlers when comments appeared after attributes. - -### Example of Affected Code - -```rust -#[tauri::command] -#[allow(non_snake_case)] // camelCase param matches frontend convention -pub async fn process_data( - app_handle: tauri::AppHandle, - inputData: Vec, -) -> Result, String> { - // ... -} -``` - -This pattern is common when developers document *why* an attribute is needed (e.g., explaining `#[allow(...)]` suppressions). - -### Symptoms - -- `loct commands` reported the handler as `[MISSING]` -- `handlers.json` showed `backend_handler: null` for the command -- The snapshot showed `command_handlers: []` for the file despite having valid `#[tauri::command]` functions - -## Root Cause - -The regex pattern for detecting `#[tauri::command]` functions only allowed whitespace (`\s*`) between: -1. The `#[tauri::command]` attribute -2. Additional attributes (like `#[allow(...)]`) -3. The `pub async fn` definition - -When a comment appeared after an attribute, the regex failed to match. - -### Original Regex (simplified) - -```regex -#[tauri::command...] -(?:\s*#\s*\[[^\]]*\])* <- additional attributes with whitespace -\s* <- ONLY whitespace allowed here -(?:pub...)?fn... -``` - -### The Breaking Patterns - -```rust -#[allow(non_snake_case)] // comment here - ^ NOT whitespace - regex fails -pub async fn handler() -``` - -```rust -#[allow(non_snake_case)] /* block comment */ - ^ also fails -pub fn handler() -``` - -## Solution - -Updated the regex with two improvements: - -### 1. Comment Support - -Accept whitespace, line comments (`// ...`), AND block comments (`/* ... */`): - -```regex -^\s*#[tauri::command...] -(?:\s*(?://[^\n]*|/\*[\s\S]*?\*/))? <- optional comment after main attr -(?:(?:\s|//[^\n]*|/\*[\s\S]*?\*/)*#\[...])* <- attrs with whitespace OR comments -(?:\s|//[^\n]*|/\*[\s\S]*?\*/)* <- whitespace OR comments before pub -(?:pub...)?fn... -``` - -The key change: `\s*` -> `(?:\s|//[^\n]*|/\*[\s\S]*?\*/)*` - -This allows: -- Pure whitespace (as before) -- Line comments (`// ...`) after attributes -- Block comments (`/* ... */`) after attributes -- Multiline block comments between attributes -- Standalone comment lines between attributes - -### 2. Line Anchoring - -Added `^\s*` at the start to anchor to line beginning. This prevents false positives from matching `#[tauri::command]` inside comments or strings: - -```rust -// This won't match anymore: -let example = "#[tauri::command]\npub fn fake() {}"; - -// Neither will this: -// #[tauri::command] -// pub fn commented_out() {} -``` - -## Files Changed - -``` -loctree_rs/src/analyzer/regexes.rs -+-- regex_tauri_command_fn() - main fix -+-- regex_custom_command_fn() - same fix for custom macros -| -+-- Positive tests (should match): -| +-- test_tauri_command_with_inline_comment() - // after attr -| +-- test_tauri_command_comment_between_attrs() - // between attrs -| +-- test_tauri_command_with_block_comment() - /* */ after attr -| +-- test_tauri_command_with_multiline_block_comment() -| -+-- Negative tests (should NOT match): - +-- test_tauri_command_in_line_comment_no_match() - +-- test_tauri_command_in_string_no_match() -``` - -## Testing - -### Before Fix - -```bash -$ loct commands | grep my_handler - [MISSING] my_handler - Frontend calls (1): src/services/api.ts:42 - [!] Why: Frontend calls invoke('my_handler') but no #[tauri::command] found -``` - -### After Fix - -```bash -$ loct commands | grep my_handler - [OK] my_handler - Frontend calls (1): src/services/api.ts:42 - Backend: src-tauri/src/commands/handlers.rs:15 -``` - -### Regression Tests - -```rust -#[test] -fn test_tauri_command_with_inline_comment() { - let re = regex_tauri_command_fn(); - let with_comment = r#"#[tauri::command] -#[allow(non_snake_case)] // parameter name matches frontend camelCase -pub async fn my_handler(...) -> Result {"#; - - assert!(re.captures(with_comment).is_some()); -} - -#[test] -fn test_tauri_command_with_block_comment() { - let re = regex_tauri_command_fn(); - let with_block = r#"#[tauri::command] -#[allow(non_snake_case)] /* camelCase for frontend */ -pub fn my_handler() {}"#; - - assert!(re.captures(with_block).is_some()); -} - -#[test] -fn test_tauri_command_in_line_comment_no_match() { - let re = regex_tauri_command_fn(); - let commented_out = r#"// #[tauri::command] -// pub fn disabled_handler() {}"#; - - assert!(re.captures(commented_out).is_none()); -} -``` - -## Impact - -Commands that were previously reported as "missing" due to comments after attributes are now correctly detected. The line anchoring also prevents false positives from commented-out or string-embedded code. - -## Related - -- Tauri command bridge detection: `loct commands` -- Rust analyzer: `loctree_rs/src/analyzer/rust/mod.rs` -- Custom command macros: Also fixed in `regex_custom_command_fn()` diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index a3c5e532..00000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,126 +0,0 @@ -# Getting Started with loctree - -5-minute quickstart to scanning a codebase, reading the artifacts, and wiring -Loctree into an AI workflow. - -## Install - -Choose one channel per machine: - -```bash -# Fastest public path: CLI + MCP server -curl -fsSL https://loct.io/install.sh | sh - -# Cargo, reproducible lockfile build -cargo install --locked loctree loctree-mcp - -# npm (CLI only; published targets follow the latest npm release) -npm install -g loctree - -# From source -git clone https://github.com/Loctree/loctree-ast.git -cd loctree-ast -make install -``` - -Public install channels follow the latest published release, not necessarily the -workspace version on the branch you're reading. Check crates.io, npm, or GitHub -Releases if you need release-exact verification. - -Verify the install: - -```bash -loct --version -loctree --version -loctree-mcp --version -``` - -## First Scan - -Run Loctree inside any project directory: - -```bash -cd your-project -loct -``` - -Artifacts are written into your OS cache directory by default. In CI or when -you want repo-local output, set `LOCT_CACHE_DIR=.loctree`. - -## Essential Commands - -```bash -loct # Scan or refresh the cached snapshot -loct --for-ai # AI-optimized overview -loct slice src/App.tsx --consumers # File + deps + consumers -loct find useAuth # Find symbol definitions/usages -loct impact src/utils/api.ts # Blast radius before refactor/delete -loct health # Quick health summary -loct dead --confidence high # High-confidence dead exports -loct cycles # Circular imports -loct twins # Duplicate exports / dead parrots / barrel drift -loct audit # Full structural review -``` - -## Artifacts - -After a scan, Loctree keeps four core files per project snapshot: - -- `snapshot.json` — the dependency graph and file metadata -- `findings.json` — structural findings such as dead exports and cycles -- `agent.json` — AI-optimized overview with quick wins and health data -- `manifest.json` — artifact index for tooling - -Query artifacts directly: - -```bash -loct '.metadata' -loct '.files | length' -loct findings | jq '.dead_exports.items[] | select(.confidence == "high")' -loct findings --summary | jq '.health_score' -``` - -## MCP Server - -`loctree-mcp` is the production MCP surface for AI agents. Start it via stdio: - -```bash -loctree-mcp -``` - -Example Claude Desktop / Claude Code config: - -```json -{ - "mcpServers": { - "loctree": { - "command": "loctree-mcp", - "args": [] - } - } -} -``` - -The server exposes seven tools: - -- `repo-view` -- `slice` -- `find` -- `impact` -- `focus` -- `tree` -- `follow` - -See [integrations/mcp-server.md](integrations/mcp-server.md) for the full MCP contract. - -## IDE / LSP - -The public OSS workspace does not ship `loct lsp`. Editor integrations live in -the external `loctree-suite` project. The docs in [`docs/ide/`](ide/) are kept -as compatibility notes and setup pointers for that external surface. - -## Next Steps - -- Read [CLI Commands](cli/commands.md) for the full command surface -- Read [Use Cases](use-cases/README.md) for real-world analysis flows -- Read [dev/01_installation.md](dev/01_installation.md) if you are contributing to the workspace itself diff --git a/docs/ide/lsp-protocol.md b/docs/ide/lsp-protocol.md deleted file mode 100644 index 3d1abb28..00000000 --- a/docs/ide/lsp-protocol.md +++ /dev/null @@ -1,169 +0,0 @@ -# LSP Protocol Reference - -> **Part of [loctree-suite](https://github.com/Loctree/loctree-suite)** -> The Loctree language server ships with loctree-suite. - -Technical reference for the Loctree Language Server Protocol implementation. - -## Server Capabilities - -```json -{ - "textDocumentSync": { - "openClose": true, - "save": { "includeText": false } - }, - "hoverProvider": true, - "definitionProvider": true, - "referencesProvider": true, - "codeActionProvider": { - "codeActionKinds": ["quickfix", "refactor"] - }, - "diagnosticProvider": { - "interFileDependencies": true, - "workspaceDiagnostics": true - } -} -``` - -## Supported Methods - -### Lifecycle - -| Method | Support | Notes | -|--------|---------|-------| -| `initialize` | ✅ | Returns capabilities | -| `initialized` | ✅ | Loads snapshot, starts file watcher | -| `shutdown` | ✅ | Cleanup | -| `exit` | ✅ | Process termination | - -### Text Document - -| Method | Support | Notes | -|--------|---------|-------| -| `textDocument/didOpen` | ✅ | Triggers diagnostics | -| `textDocument/didSave` | ✅ | Refreshes diagnostics | -| `textDocument/didClose` | ✅ | Clears diagnostics | -| `textDocument/hover` | ✅ | Import stats, consumers | -| `textDocument/definition` | ✅ | Export location | -| `textDocument/references` | ✅ | All import locations | -| `textDocument/codeAction` | ✅ | Quick fixes | -| `textDocument/publishDiagnostics` | ✅ | Dead/cycle/twin warnings | - -### Workspace - -| Method | Support | Notes | -|--------|---------|-------| -| `workspace/didChangeConfiguration` | ✅ | Settings updates | -| `workspace/didChangeWatchedFiles` | ✅ | Snapshot refresh | - -## Diagnostic Types - -### Dead Export (`loctree:dead-export`) - -```json -{ - "range": { "start": {"line": 10, "character": 7}, "end": {"line": 10, "character": 20} }, - "severity": 2, - "code": "dead-export", - "source": "loctree", - "message": "Export 'unusedFunction' has 0 imports", - "data": { - "symbol": "unusedFunction", - "confidence": "high" - } -} -``` - -**Severity levels:** -- `Warning (2)`: High confidence dead export -- `Information (3)`: Low confidence (might be API) -- `Hint (4)`: Test-only export - -### Circular Import (`loctree:cycle`) - -```json -{ - "range": { "start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 30} }, - "severity": 2, - "code": "cycle", - "source": "loctree", - "message": "Circular import: a.ts → b.ts → c.ts → a.ts", - "relatedInformation": [ - { - "location": { "uri": "file:///project/b.ts", "range": {...} }, - "message": "imports c.ts" - } - ] -} -``` - -### Twin Symbol (`loctree:twin`) - -```json -{ - "range": { "start": {"line": 5, "character": 7}, "end": {"line": 5, "character": 13} }, - "severity": 3, - "code": "twin", - "source": "loctree", - "message": "Symbol 'Config' also exported from 3 other files", - "relatedInformation": [ - { - "location": { "uri": "file:///project/other/config.ts", "range": {...} }, - "message": "Also exported here" - } - ] -} -``` - -## Code Actions - -### Quick Fixes (`quickfix`) - -| Action | Trigger | Effect | -|--------|---------|--------| -| Remove unused export | `dead-export` | Deletes `export` keyword | -| Add to .loctignore | `dead-export` | Appends pattern | -| Show in report | `dead-export` | Opens HTML report | -| Go to next in cycle | `cycle` | Navigates to next file | - -### Refactors (`refactor`) - -| Action | Description | -|--------|-------------| -| Extract to barrel | Move export to index.ts | -| Inline barrel export | Replace re-export with direct | -| Consolidate twins | Show picker for all locations | - -## Custom Commands - -Executable via `workspace/executeCommand`: - -| Command | Parameters | Description | -|---------|------------|-------------| -| `loctree.refresh` | none | Re-run analysis | -| `loctree.openReport` | none | Open HTML report | -| `loctree.navigateToFile` | `path: string` | Open file in editor | - -## Initialization Options - -```json -{ - "initializationOptions": { - "workspaceRoot": "/path/to/project", - "autoRefresh": false - } -} -``` - -## Error Codes - -| Code | Message | Resolution | -|------|---------|------------| -| -32001 | Snapshot not found | Run `loct` first | -| -32002 | Snapshot stale | Run `loct` to refresh | -| -32003 | Parse error | Check file syntax | - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/ide/neovim.md b/docs/ide/neovim.md deleted file mode 100644 index d9f7bc75..00000000 --- a/docs/ide/neovim.md +++ /dev/null @@ -1,143 +0,0 @@ -# Neovim Setup - -> **Part of [loctree-suite](https://github.com/Loctree/loctree-suite)** -> The LSP server and editor integrations ship with loctree-suite. -> Install the free CLI with `cargo install --locked loctree`, then upgrade to suite for IDE features. - -Configure Neovim to use the loctree-suite language server for dead code detection and navigation. - -## Prerequisites - -- Neovim 0.8+ -- [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig) -- [loctree-suite](https://github.com/Loctree/loctree-suite) with language server binary -- Loctree CLI installed: `cargo install --locked loctree` - -## Configuration - -Add to your Neovim config (`init.lua` or `lua/plugins/lsp.lua`): - -```lua --- Add loctree to lspconfig -local lspconfig = require('lspconfig') -local configs = require('lspconfig.configs') - --- Define loctree LSP if not already defined -if not configs.loctree then - configs.loctree = { - default_config = { - cmd = { '/path/to/suite-language-server' }, - filetypes = { - 'typescript', 'typescriptreact', - 'javascript', 'javascriptreact', - 'rust', 'python', 'go', 'vue', 'svelte' - }, - root_dir = lspconfig.util.root_pattern('.loctree', '.git'), - settings = {}, - }, - } -end - --- Setup with your preferred options -lspconfig.loctree.setup({ - on_attach = function(client, bufnr) - -- Your on_attach function - -- Loctree provides: diagnostics, hover, definition, references - end, -}) -``` - -## Lazy.nvim Example - -```lua -{ - 'neovim/nvim-lspconfig', - config = function() - local lspconfig = require('lspconfig') - local configs = require('lspconfig.configs') - - if not configs.loctree then - configs.loctree = { - default_config = { - cmd = { '/path/to/suite-language-server' }, - filetypes = { 'typescript', 'javascript', 'rust', 'python' }, - root_dir = lspconfig.util.root_pattern('.loctree', '.git'), - }, - } - end - - lspconfig.loctree.setup({}) - end, -} -``` - -## Features - -### Diagnostics - -Dead exports, cycles, and twins appear as LSP diagnostics: - -``` -W: Export 'unusedFunction' has 0 imports [loctree:dead-export] -W: Circular import: a.ts → b.ts → a.ts [loctree:cycle] -I: Symbol 'Config' also exported from 3 files [loctree:twin] -``` - -### Hover - -`:lua vim.lsp.buf.hover()` or `K` shows: - -``` -Export: useAuth -───────────────── -12 imports across 8 files -Top consumers: App.tsx, Login.tsx, Dashboard.tsx -``` - -### Go to Definition - -`gd` jumps to the original export location, resolving re-export chains. - -### References - -`gr` lists all files importing the symbol. - -## Keybindings - -Suggested mappings (add to your config): - -```lua -vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { desc = 'Go to definition' }) -vim.keymap.set('n', 'gr', vim.lsp.buf.references, { desc = 'Find references' }) -vim.keymap.set('n', 'K', vim.lsp.buf.hover, { desc = 'Hover info' }) -vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, { desc = 'Code actions' }) -vim.keymap.set('n', 'lr', ':!loct', { desc = 'Refresh loctree' }) -``` - -## Troubleshooting - -### LSP not starting - -```vim -:LspInfo -``` - -Check if loctree is listed and running. - -### No diagnostics - -Ensure a snapshot exists (run `loct` once): - -```bash -loct # Generate snapshot -``` - -### Check LSP logs - -```vim -:lua vim.cmd('edit ' .. vim.lsp.get_log_path()) -``` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/ide/vscode.md b/docs/ide/vscode.md deleted file mode 100644 index 1e1a5a99..00000000 --- a/docs/ide/vscode.md +++ /dev/null @@ -1,138 +0,0 @@ -# VSCode Extension - -> **Part of [loctree-suite](https://github.com/Loctree/loctree-suite)** -> The LSP server and editor integrations ship with loctree-suite. -> Install the free CLI with `cargo install --locked loctree`, then upgrade to suite for IDE features. - -The Loctree VSCode extension provides real-time dead code detection, circular import warnings, and code navigation powered by the loctree-suite language server. - -## Installation - -### From loctree-suite - -```bash -cd loctree-suite/editors/vscode -npm install -npm run compile -``` - -Then in VSCode: `F1` → "Developer: Install Extension from Location" → select `editors/vscode` - -### VSIX (Recommended for forks like Cursor/Windsurf) - -```bash -cd loctree-suite/editors/vscode -LOCTREE_LSP_PATH=/path/to/suite-language-server npm run package -``` - -### From Marketplace (Coming Soon) - -``` -ext install libraxis.loctree -``` - -## Features - -### Diagnostics - -The extension shows warnings directly in your editor: - -| Diagnostic | Severity | Description | -|------------|----------|-------------| -| Dead Export | Warning | Export has 0 imports across codebase | -| Circular Import | Warning | File is part of an import cycle | -| Twin Symbol | Information | Symbol exported from multiple files | - -### Hover Information - -Hover over any export to see: -- Import count across the codebase -- Top consumer files -- Export location details - -### Go to Definition - -`F12` or `Ctrl+Click` on imports to jump to: -- Original export location -- Re-export chain resolution -- Cross-language definitions (TS → Rust for Tauri) - -### Code Actions - -`Ctrl+.` on diagnostics to access quick fixes: -- **Remove unused export** - Delete the export keyword -- **Add to .loctignore** - Suppress this warning -- **Show in HTML report** - Open detailed analysis - -## Configuration - -In VSCode settings (`Ctrl+,`): - -```json -{ - "loctree.serverPath": "/custom/path/to/suite-language-server", - "loctree.autoRefresh": false, - "loctree.trace.server": "verbose" -} -``` - -| Setting | Default | Description | -|---------|---------|-------------| -| `serverPath` | auto-detect | Path to the loctree-suite language server binary | -| `autoRefresh` | `false` | Re-scan on file save | -| `autoDownload` | `true` | Download the loctree-suite language server if missing | -| `downloadBaseUrl` | (empty) | Override repo URL for downloads | -| `downloadTag` | `latest` | Release tag for downloads | -| `trace.server` | `off` | LSP message logging | - -## Status Bar - -The status bar shows loctree status: - -- 🌳 **Loctree: healthy** - No issues detected -- 🌳 **Loctree: 5 dead** - Number of dead exports -- 🌳 **Loctree: loading** - Scanning in progress - -Click to open the Output panel for details. - -## Commands - -Open command palette (`F1`) and search for "Loctree": - -| Command | Description | -|---------|-------------| -| `Loctree: Refresh` | Re-run `loct` and update diagnostics | -| `Loctree: Open Report` | Open HTML report in browser | -| `Loctree: Show Health` | Display health score summary | - -## Requirements - -- [loctree-suite](https://github.com/Loctree/loctree-suite) with the language server binary -- Loctree CLI installed (`cargo install --locked loctree`) -- Run `loct` once in the project root (writes snapshot to cache; set `LOCT_CACHE_DIR=.loctree` for repo-local artifacts) - -## Troubleshooting - -### No diagnostics appearing - -1. Check Output panel → "Loctree" for errors -2. Ensure a snapshot exists (run `loct` once) -3. Run `loct` in project root - -### Server not starting - -```bash -# Check if your language server binary is in PATH -which - -# Or set custom path in settings -"loctree.serverPath": "/path/to/suite-language-server" -``` - -### Stale diagnostics - -Click status bar → "Loctree: Refresh" or run `loct` in terminal. - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/integrations/ci-cd.md b/docs/integrations/ci-cd.md deleted file mode 100644 index 16c0bbc2..00000000 --- a/docs/integrations/ci-cd.md +++ /dev/null @@ -1,186 +0,0 @@ -# CI/CD Integration - -Integrate loctree into your continuous integration pipeline to catch dead code, circular imports, and duplicates before they reach production. - -## GitHub Actions - -### Basic Workflow - -```yaml -# .github/workflows/loctree.yml -name: Loctree Analysis - -on: - pull_request: - push: - branches: [main, develop] - -jobs: - analyze: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install loctree - run: cargo install --locked loctree - - - name: Run analysis - run: LOCT_CACHE_DIR=.loctree loct findings > .loctree/findings.json - - - name: Check for issues - run: | - DEAD=$(jq '.dead_exports.total' .loctree/findings.json) - CYCLES=$(jq '.cycles.total' .loctree/findings.json) - if [ "$DEAD" -gt 0 ] || [ "$CYCLES" -gt 0 ]; then - echo "Found $DEAD dead exports and $CYCLES cycles" - exit 1 - fi -``` - -### With Caching - -```yaml -jobs: - analyze: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Cache cargo - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/ - key: ${{ runner.os }}-cargo-loctree - - - name: Install loctree - run: | - if ! command -v loct &> /dev/null; then - cargo install --locked loctree - fi - - - name: Analyze summary - run: LOCT_CACHE_DIR=.loctree loct findings --summary > .loctree/summary.json -``` - -### PR Comment with Report - -```yaml - - name: Generate summary report - run: loct findings --summary > report.json - - - name: Comment on PR - if: github.event_name == 'pull_request' - uses: actions/github-script@v6 - with: - script: | - const fs = require('fs'); - const report = fs.readFileSync('report.json', 'utf8'); - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: '## Loctree Analysis\n```\n' + report + '\n```' - }); -``` - -## Pre-commit Hook - -### Using pre-commit framework - -```yaml -# .pre-commit-config.yaml -repos: - - repo: local - hooks: - - id: loctree-lint - name: Run structural lint - entry: loct lint --fail - language: system - pass_filenames: false -``` - -### Manual git hook - -```bash -#!/bin/sh -# .git/hooks/pre-push - -echo "Running loctree analysis..." -loct --quiet - -DEAD=$(loct findings | jq '.dead_exports.total') -if [ "$DEAD" -gt 0 ]; then - echo "ERROR: $DEAD dead exports found" - echo "Run 'loct dead' for details" - exit 1 -fi - -echo "Loctree: OK" -``` - -## CLI Flags for CI - -| Flag | Description | Use Case | -|------|-------------|----------| -| `--json` | JSON output | Parsing in scripts | -| `--quiet` | No progress output | Clean logs | -| `--fail-stale` | Fail if snapshot outdated | Enforce fresh analysis | -| `--fresh` | Force full rescan | Ensure accuracy | -| `findings --summary` | Summary JSON | Quick status / PR comments | - -## Exit Codes - -| Code | Meaning | -|------|---------| -| 0 | Success, no issues | -| 1 | Issues found (dead, cycles) | -| 2 | Configuration error | -| 3 | Snapshot missing/stale | - -## Badge - -Add to your README: - -```markdown -[![loctree](https://img.shields.io/badge/analyzed_with-loctree-a8a8a8)](https://crates.io/crates/loctree) -``` - -Result: [![loctree](https://img.shields.io/badge/analyzed_with-loctree-a8a8a8)](https://crates.io/crates/loctree) - -## GitLab CI - -```yaml -# .gitlab-ci.yml -loctree: - stage: test - image: rust:latest - script: - - cargo install --locked loctree - - loct --fail-stale - cache: - paths: - - /usr/local/cargo/bin/loct -``` - -## CircleCI - -```yaml -# .circleci/config.yml -version: 2.1 -jobs: - loctree: - docker: - - image: rust:latest - steps: - - checkout - - run: cargo install --locked loctree - - run: loct findings --summary > results.json - - store_artifacts: - path: results.json -``` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/integrations/mcp-server.md b/docs/integrations/mcp-server.md deleted file mode 100644 index 42cc2625..00000000 --- a/docs/integrations/mcp-server.md +++ /dev/null @@ -1,126 +0,0 @@ -# MCP Server Integration - -`loctree-mcp` exposes Loctree's structural analysis as MCP tools that AI agents -can call directly over stdio. - -For the repo's default operating model, pair this with: - -- [`PERCEPTION.md`](../../PERCEPTION.md) -- [`docs/perception/adr.md`](../perception/adr.md) - -## What Ships Here - -The public workspace ships one MCP binary: - -```bash -loctree-mcp -``` - -It is project-agnostic: - -- first use on a project auto-scans if needed -- snapshots are cached in memory -- every tool accepts an optional `project` parameter - -## Install - -Choose whichever channel matches your workflow: - -```bash -# Cargo -cargo install --locked loctree-mcp - -# Full public install path (CLI + MCP) -curl -fsSL https://loct.io/install.sh | sh - -# From source -git clone https://github.com/Loctree/loctree-ast.git -cd loctree-ast -make install-mcp -``` - -## Configuration - -Example Claude Desktop / Claude Code config: - -```json -{ - "mcpServers": { - "loctree": { - "command": "loctree-mcp", - "args": [] - } - } -} -``` - -If you use an external MCP multiplexer such as `rmcp-mux`, keep that config in -your client/runtime layer. It is not part of this workspace anymore. - -## Available Tools - -### `repo-view(project?: string)` - -Use this first. It returns repo summary, health, top hubs, quick wins, and the -recommended next loctree calls. - -### `slice(project?: string, file: string, consumers?: boolean)` - -Returns a file plus its dependencies and consumers. Use before modifying code. - -### `find(project?: string, name: string, limit?: number)` - -Symbol search with regex support. Use before creating new functions, types, or components. - -### `impact(project?: string, file: string)` - -Shows direct and transitive consumers. Use before deleting or major refactors. - -### `focus(project?: string, directory: string)` - -Module-level deep dive: files, LOC, exports, internal edges, and external dependencies. - -### `tree(project?: string, depth?: number, loc_threshold?: number)` - -Directory structure with LOC counts. - -### `follow(project?: string, scope: string, limit?: number, handler?: string)` - -Drills into repo-view signals such as dead exports, cycles, twins, hotspots, -commands, events, and pipelines. - -## Recommended Agent Flow - -The default Loctree sequence stays: - -```text -repo-view -> focus -> slice -> impact -> find -> follow -``` - -That keeps AI context grounded in structure instead of grep drift. - -## Verification - -Quick checks after install: - -```bash -loctree-mcp --version -``` - -If your client supports MCP inspection, confirm the server exposes these tool -names exactly: - -- `repo-view` -- `slice` -- `find` -- `impact` -- `focus` -- `tree` -- `follow` - -## Notes - -- The public OSS workspace does not ship a `for_ai()` MCP tool anymore. The - current overview entrypoint is `repo-view`. -- The public OSS workspace does not ship `loct lsp`. Editor/LSP integrations are - maintained outside this repo. diff --git a/docs/perception/adr.md b/docs/perception/adr.md deleted file mode 100644 index 3625e15c..00000000 --- a/docs/perception/adr.md +++ /dev/null @@ -1,97 +0,0 @@ -# ADR: Context over Memory - -- **Status:** Accepted -- **Date:** 2026-02-17 -- **Owners:** loctree maintainers - -## Context - -Agentic workflows have been increasingly optimized around persistent memory and retrieval layers. In practice, we observed recurring issues: - -- startup context bloat, -- stale retrieval against changing codebases, -- poor reproducibility across sessions, -- low explainability of "why this context was selected." - -At the same time, loctree already provides deterministic structural perception (`repo-view`, `focus`, `slice`, `impact`, `find`) with current-state guarantees. - -## Decision - -We standardize on **context-over-memory** as the primary architecture for agent workflows: - -1. Use graph-backed, on-demand perception as default context acquisition. -2. Use prepared context bundles for predictable recurrent workflows. -3. Keep long-term memory optional and subordinate to fresh structural data. - -## Scope - -This ADR applies to: - -- CLI and MCP usage guidance, -- documentation and examples, -- internal integration recommendations for agent teams. - -It does not force removal of existing memory integrations; it defines priority and default behavior. - -## Decision Drivers - -- Determinism -- Freshness -- Debuggability -- Lower latency -- Lower token overhead -- Safer refactors - -## Consequences - -### Positive - -- Better first-pass accuracy in code modifications. -- Lower context-token overhead for multi-step tasks. -- Clear provenance of context ("which command produced this view?"). -- Easier production incident analysis. - -### Negative / Trade-offs - -- Requires disciplined context mapping habits. -- Increases reliance on tool availability and quality. -- Some longitudinal use cases still benefit from memory layers. - -## Alternatives considered - -### A) Memory-first (vector retrieval as primary) - -Rejected as default due to probabilistic recall and drift under active code change. - -### B) Huge static preloaded prompts - -Rejected due to latency, cost, and context pollution. - -### C) Hybrid with memory as secondary (chosen) - -Accepted: memory can enrich, but perception and scoped context remain source of truth. - -## Guardrails - -Before non-trivial edits, workflows should perform: - -1. `repo-view` -2. `focus` -3. `slice` -4. `impact` -5. `find` - -Use grep as local detail tool, not as primary mapping layer. - -## Rollout - -1. Publish manifesto and KPI definitions. -2. Add these docs to `docs/README.md`. -3. Update integration examples to reference this ADR. -4. Track KPI deltas for at least 2 release cycles. - -## Success Criteria - -See: [Agent Context KPIs](../metrics/agent-context-kpis.md). - -This ADR is considered successful if reliability and context efficiency improve without reducing task throughput. diff --git a/docs/perception/kpis.md b/docs/perception/kpis.md deleted file mode 100644 index b2fd03cd..00000000 --- a/docs/perception/kpis.md +++ /dev/null @@ -1,83 +0,0 @@ -# Agent Context KPIs - -## Purpose -Define measurable outcomes for the `context-over-memory` architecture and track whether reliability improves without sacrificing throughput. - -## Measurement Window -- Track per release and rolling 30-day windows. -- Compare against a baseline collected before ADR `2026-02-17-context-over-memory`. -- Evaluate for at least 2 release cycles. - -## Primary KPIs - -### 1) First-Pass Correct Change Rate (FPCR) -Percentage of agent-authored changes accepted without rework requests. - -Formula: -`FPCR = accepted_without_rework / total_agent_changes` - -Target trend: -- Up and to the right. -- No release should regress more than 5% from previous stable baseline. - -### 2) Context Token Cost per Completed Task (CTC) -Average context tokens consumed to complete one successful task. - -Formula: -`CTC = total_context_tokens / completed_tasks` - -Target trend: -- Decrease while maintaining or improving FPCR. - -### 3) Context Provenance Coverage (CPC) -Share of non-trivial tasks where context sources are explicitly traceable to commands. - -Formula: -`CPC = tasks_with_command_provenance / non_trivial_tasks` - -Minimum threshold: -- 90%+ - -### 4) Freshness Violation Rate (FVR) -Rate of incidents where stale context caused wrong edits or wrong recommendations. - -Formula: -`FVR = stale_context_incidents / total_agent_tasks` - -Target trend: -- Near zero. - -### 5) Mean Context Bootstrap Time (MCBT) -Median time from task start to first actionable edit. - -Formula: -`MCBT = median(t_first_edit - t_task_start)` - -Target trend: -- Flat or down, despite stricter mapping guardrails. - -### 6) Post-Review Rework Rate (PRR) -Rate of tasks requiring follow-up fixes after initial review. - -Formula: -`PRR = tasks_with_post_review_rework / reviewed_tasks` - -Target trend: -- Down. - -## Secondary KPIs -- `Tool Coverage Rate`: percentage of non-trivial tasks that used the full mapping chain (`repo-view`, `focus`, `slice`, `impact`, `find`). -- `Refactor Safety Incident Rate`: breakages introduced in medium/large refactors. -- `Throughput`: completed tasks per engineer-day (must not materially decline). - -## Instrumentation Guidance -- Log task metadata: task size, touched files, commands used, token usage, outcome. -- Store a compact execution trace for reproducibility. -- Tag incidents with root cause category: stale context, missing context, tool failure, logic error. - -## Success Criteria -The ADR is successful when: -1. FPCR improves. -2. CTC decreases or stays flat with better FPCR. -3. FVR stays near zero. -4. Throughput does not regress materially. diff --git a/docs/perception/research.md b/docs/perception/research.md deleted file mode 100644 index 45965cf1..00000000 --- a/docs/perception/research.md +++ /dev/null @@ -1,74 +0,0 @@ -# Global Direction Research: Context over Memory - -- **Date:** 2026-02-17 -- **Method:** synthesis from `web.run` page reads and Brave web search across primary sources (vendor docs, protocol specs, research papers). -- **Objective:** validate whether `context-over-memory` is aligned with broader agent engineering direction. - -## Executive Summary -Global direction is converging on **context engineering** and **tool-mediated perception** rather than pure memory-first retrieval. The dominant pattern is: - -1. Keep context windows curated and scoped. -2. Retrieve fresh context through tools/protocols (especially MCP). -3. Use memory as a secondary layer for continuity, not as source of truth for current state. - -This supports loctree’s `repo-view -> focus -> slice -> impact -> find` workflow as a production-oriented default. - -## Evidence - -### 1) Vendor guidance now emphasizes context quality over raw context volume -- Anthropic’s agent guidance prioritizes simplicity, transparency, and strong tool interfaces over unnecessary complexity. -- Anthropic’s context-engineering guidance frames context as a managed state with finite attention budget. -- OpenAI’s agent guidance emphasizes tool-based context retrieval, guardrails, and workflow orchestration instead of monolithic prompts. - -### 2) MCP is becoming standard context infrastructure -- Official MCP specification (2025-06-18 revision) formalizes tools/resources/prompts and transport/lifecycle behavior. -- OpenAI documents MCP usage across API, connectors, and Codex workflows. -- Google Cloud announced official MCP support for Google services and Cloud systems. -- Microsoft announced GA MCP integrations in Copilot Studio and Visual Studio experiences. - -Inference from these sources: the ecosystem is standardizing on **protocolized context access** (discoverable, auditable, composable) rather than bespoke memory stacks. - -### 3) Long-context research still supports selective context strategies -- *Lost in the Middle* shows degradation when relevant information sits in the middle of long inputs, supporting selective retrieval and ordering. -- ReAct and Toolformer-era evidence supports tool use for grounding and action over pure in-prompt recall. - -Inference: larger windows help, but do not eliminate the need for careful context selection, compression, and provenance. - -## Implications for loctree -`Context-over-memory` is not a niche stance; it is compatible with current industry movement: - -- **Determinism:** tool call provenance is auditable. -- **Freshness:** context is generated from current repository state. -- **Debuggability:** failures can be traced to command outputs. -- **Cost control:** fewer irrelevant tokens than broad memory preload. - -Repository-specific mapping and roadmap are documented separately: -- `docs/research/loctree-codebase-map-and-perception-first-vision-2026-02-17.md` - -## Recommended Direction (next 2 cycles) -1. Keep perception-first guardrails as default for non-trivial edits. -2. Instrument KPIs from `docs/metrics/agent-context-kpis.md`. -3. Reference ADR/manifest in integration docs and examples. -4. Keep memory integrations available, but explicitly secondary to structural context. - -## Sources -Primary: -- MCP spec and docs: https://modelcontextprotocol.io/specification/2025-06-18 -- MCP GitHub repository: https://github.com/modelcontextprotocol/modelcontextprotocol -- Anthropic: Building Effective AI Agents: https://www.anthropic.com/research/building-effective-agents -- Anthropic: Effective context engineering for AI agents: https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents -- OpenAI practical guide: https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/ -- OpenAI building agents track: https://developers.openai.com/tracks/building-agents/ -- OpenAI MCP guide: https://platform.openai.com/docs/mcp -- OpenAI connectors + MCP: https://platform.openai.com/docs/guides/tools-connectors-mcp -- OpenAI Codex MCP docs: https://developers.openai.com/codex/mcp -- OpenAI cookbook (state/context pattern): https://cookbook.openai.com/examples/agents_sdk/context_personalization -- Google Cloud MCP support announcement: https://cloud.google.com/blog/products/ai-machine-learning/announcing-official-mcp-support-for-google-services -- Microsoft Copilot Studio MCP GA: https://www.microsoft.com/en-us/microsoft-copilot/blog/copilot-studio/model-context-protocol-mcp-is-now-generally-available-in-microsoft-copilot-studio/ -- Microsoft Visual Studio MCP GA: https://devblogs.microsoft.com/visualstudio/mcp-is-now-generally-available-in-visual-studio/ -- Lost in the Middle (ACL/TACL): https://aclanthology.org/2024.tacl-1.9/ -- ReAct paper: https://arxiv.org/abs/2210.03629 -- Toolformer paper: https://arxiv.org/abs/2302.04761 - -Supplementary signals (ecosystem/adoption tracking): -- Google adoption coverage: https://techcrunch.com/2025/04/09/google-says-itll-embrace-anthropics-standard-for-connecting-ai-models-to-data/ diff --git a/docs/refactor-strategist.md b/docs/refactor-strategist.md deleted file mode 100644 index 746d18ab..00000000 --- a/docs/refactor-strategist.md +++ /dev/null @@ -1,458 +0,0 @@ -# Refactor Strategist - -> **loct plan** - Generate architectural refactoring plans with risk-ordered execution phases - -The Refactor Strategist analyzes module coupling and generates safe refactoring plans. It detects architectural layers, identifies misplaced files, and produces phased migration scripts ordered by risk level. - ---- - -## Table of Contents - -- [Overview](#overview) -- [Quick Start](#quick-start) -- [Layer Detection](#layer-detection) -- [Risk Assessment](#risk-assessment) -- [Output Formats](#output-formats) -- [Shimming Strategy](#shimming-strategy) -- [Cyclic Dependency Handling](#cyclic-dependency-handling) -- [Configuration](#configuration) -- [Examples](#examples) -- [Integration with Other Commands](#integration-with-other-commands) - ---- - -## Overview - -Large codebases accumulate architectural debt over time. Files get placed in wrong directories, layers become blurred, and refactoring becomes risky due to complex dependencies. - -**Refactor Strategist** solves this by: - -1. **Detecting Layers** - Classifies files into UI, App, Kernel, Infra, or Test layers using path heuristics -2. **Analyzing Impact** - Uses dependency graph to calculate consumer counts and identify high-risk moves -3. **Detecting Cycles** - Identifies files involved in circular dependencies (via Tarjan's SCC) -4. **Ordering by Risk** - Sorts moves from LOW → MEDIUM → HIGH risk for safe incremental execution -5. **Generating Shims** - Creates re-export stubs for heavily-imported files to maintain backward compatibility - ---- - -## Quick Start - -```bash -# Generate markdown plan for current directory -loct plan - -# Generate plan for specific directory -loct plan src/features - -# Generate all formats (markdown, JSON, shell script) -loct plan --all -o refactor-2026 - -# Generate executable migration script -loct plan --script > migrate.sh -chmod +x migrate.sh -./migrate.sh --dry # Preview changes -./migrate.sh # Execute migration -``` - ---- - -## Layer Detection - -Files are classified into architectural layers based on path patterns: - -| Layer | Directory Patterns | File Patterns | -|-------|-------------------|---------------| -| **UI** | `components/`, `views/`, `pages/`, `ui/`, `widgets/`, `screens/` | `.tsx`, `.vue`, `.svelte` | -| **App** | `hooks/`, `services/`, `stores/`, `state/`, `context/`, `providers/` | `use*.ts` (React hooks) | -| **Kernel** | `core/`, `domain/`, `models/`, `entities/`, `business/` | - | -| **Infra** | `utils/`, `helpers/`, `lib/`, `adapters/`, `api/`, `clients/` | - | -| **Test** | `tests/`, `__tests__/`, `spec/` | `.test.*`, `.spec.*`, `*_test.*` | - -### Detection Priority - -1. Test patterns are checked first (highest priority) -2. UI patterns next (but excludes hooks/stores) -3. App patterns (hooks, services, stores) -4. Kernel patterns (core business logic) -5. Infra patterns (utilities, infrastructure) -6. If no match, `Unknown` layer is assigned - -### Custom Layer Mapping - -Override default layer detection with `--target-layout`: - -```bash -loct plan --target-layout "core=src/kernel,ui=src/views,infra=src/shared" -``` - ---- - -## Risk Assessment - -Each file move is assigned a risk level based on impact analysis: - -### Risk Levels - -| Risk | Icon | Thresholds | Description | -|------|------|------------|-------------| -| **LOW** | 🟢 | <5 consumers, <200 LOC, not in cycle | Safe to move with minimal impact | -| **MEDIUM** | 🟡 | 5-10 consumers, 200-500 LOC | Moderate impact, review recommended | -| **HIGH** | 🔴 | >10 consumers, >500 LOC, or in cycle | Significant impact, proceed carefully | - -### Risk Calculation Formula - -``` -if in_cycle → HIGH -if direct_consumers >= 10 OR transitive_consumers >= 50 → HIGH -if loc >= 500 → HIGH -if direct_consumers >= 5 OR transitive_consumers >= 20 → MEDIUM -if loc >= 200 → MEDIUM -else → LOW -``` - -### Phased Execution - -Moves are grouped into phases by risk level: - -``` -Phase 1: LOW Risk (10 files) ← Execute first -Phase 2: MEDIUM Risk (6 files) ← Execute second -Phase 3: HIGH Risk (10 files) ← Execute last, with extra care -``` - -This ordering minimizes disruption: if Phase 1 breaks something, you haven't touched the critical files yet. - ---- - -## Output Formats - -### Markdown (Default) - -Human-readable report with tables, git commands, and shim instructions: - -```bash -loct plan # Print to stdout -loct plan -o refactor.md # Write to file -``` - -**Sections:** -- Summary (file counts, risk breakdown) -- Layer distribution (before/after) -- Phased execution plan with tables -- Git commands for each phase -- Shimming strategy - -### JSON - -Machine-readable format for tooling integration: - -```bash -loct plan --json # Print to stdout -loct plan --json -o plan.json -``` - -**Structure:** -```json -{ - "target": "src/features", - "moves": [...], - "shims": [...], - "cyclic_groups": [...], - "phases": [...], - "stats": { - "total_files": 47, - "files_to_move": 23, - "shims_needed": 8, - "layer_before": {"Unknown": 23, "UI": 10, ...}, - "layer_after": {"Infra": 15, "UI": 10, ...}, - "by_risk": {"LOW": 12, "MEDIUM": 8, "HIGH": 3} - } -} -``` - -### Shell Script - -Executable bash script with phase functions: - -```bash -loct plan --script > migrate.sh -chmod +x migrate.sh - -# Usage options: -./migrate.sh # Execute all phases -./migrate.sh --dry # Preview (no changes) -./migrate.sh 1 # Execute only Phase 1 -./migrate.sh 2 # Execute only Phase 2 -``` - -**Script Features:** -- `set -e` for fail-fast execution -- Color-coded output (green/yellow/red by risk) -- Dry-run mode (`--dry`) -- Phase selection (`./migrate.sh 1`) -- Automatic `mkdir -p` for target directories -- Git mv commands with proper quoting - -### All Formats - -Generate all three formats at once: - -```bash -loct plan --all -o refactor-2026 -# Creates: -# refactor-2026.md -# refactor-2026.json -# refactor-2026.sh (executable) -``` - ---- - -## Shimming Strategy - -When a file has many importers (>3), moving it directly would require updating all import statements. Instead, a **shim** can be created at the old location that re-exports from the new location. - -### When Shims Are Suggested - -``` -direct_consumers > 3 → suggest shim -``` - -### Shim Examples - -**TypeScript/JavaScript:** -```typescript -// Old location: src/utils/format.ts (shim) -export { formatDate, formatCurrency } from '../infra/format'; -// or -export * from '../infra/format'; -``` - -**Rust:** -```rust -// Old location: src/utils.rs (shim) -pub use crate::infra::utils::*; -``` - -**Python:** -```python -# Old location: src/utils.py (shim) -from .infra.utils import * -``` - -### Gradual Migration - -1. Move file to new location -2. Create shim at old location -3. Update importers incrementally -4. Remove shim when no importers remain - ---- - -## Cyclic Dependency Handling - -Files involved in circular imports are flagged as **HIGH risk** and grouped together. - -### Detection - -Uses Tarjan's Strongly Connected Components (SCC) algorithm to detect cycles in the dependency graph. - -### Output - -```markdown -## ⚠️ Cyclic Dependencies - -The following groups of files have circular imports. Move these together or break the cycle first: - -**Cycle 1:** -- `src/a.ts` -- `src/b.ts` - -**Cycle 2:** -- `src/models/patient.ts` -- `src/services/patientService.ts` -- `src/hooks/usePatient.ts` -``` - -### Recommendations - -1. **Break the cycle first** - Extract shared types to a third module -2. **Move together** - If the cycle is intentional, move all files in the group together -3. **Review architecture** - Cycles often indicate design issues - ---- - -## Configuration - -### Command Options - -| Option | Short | Description | -|--------|-------|-------------| -| `--target-layout ` | | Custom layer mapping (e.g., `"core=src/kernel"`) | -| `--markdown` | `--md` | Output as markdown (default) | -| `--json` | | Output as JSON | -| `--script` | `--sh` | Output as executable shell script | -| `--all` | | Generate all formats (.md, .json, .sh) | -| `--output ` | `-o` | Output file path (without extension for --all) | -| `--no-open` | | Don't auto-open the generated report | -| `--include-tests` | | Include test files in analysis | -| `--min-coupling ` | | Minimum coupling score to include (0.0-1.0) | -| `--max-module-size ` | | Maximum module LOC before suggesting split | - -### Examples - -```bash -# Custom layer mapping -loct plan --target-layout "core=src/kernel,ui=src/components,infra=src/shared" - -# Include test files (normally excluded) -loct plan --include-tests - -# Generate all formats to specific directory -loct plan --all -o reports/refactor-$(date +%Y%m%d) - -# Pipe JSON to other tools -loct plan --json | jq '.moves | length' # Count moves -loct plan --json | jq '.stats.by_risk' # Risk breakdown -``` - ---- - -## Examples - -### Example 1: React Feature Module - -**Directory:** `src/features/patients/` - -**Before:** -``` -src/features/patients/ -├── PatientList.tsx → UI (correct) -├── PatientCard.tsx → UI (correct) -├── utils.ts → Unknown (should be Infra) -├── types.ts → Unknown (should be Kernel) -├── usePatients.ts → App (correct, hook pattern) -└── api.ts → Unknown (should be Infra) -``` - -**Command:** -```bash -loct plan src/features/patients -``` - -**Output:** -```markdown -# Refactor Plan: src/features/patients - -## Summary -- Files analyzed: 6 -- Files to move: 3 -- Risk: 2 LOW, 1 MEDIUM - -## 🟢 Phase 1: LOW Risk (2 files) -| File | From | To | Reason | -|------|------|-------|--------| -| utils.ts | Unknown | Infra | Utility functions | -| api.ts | Unknown | Infra | API client | - -## 🟡 Phase 2: MEDIUM Risk (1 file) -| File | From | To | Reason | -|------|------|-------|--------| -| types.ts | Unknown | Kernel | 5 consumers | -``` - -### Example 2: Rust Crate Reorganization - -**Directory:** `src/cli/` - -**Command:** -```bash -loct plan src/cli --script > reorganize-cli.sh -./reorganize-cli.sh --dry -``` - -**Output (excerpt):** -```bash -phase_1 () { - echo -e "${GREEN}=== Phase 1: LOW Risk ===${NC}" - echo "Moving 10 files..." - - run mkdir -p "src/cli/infra" - run git mv "src/cli/helpers.rs" "src/cli/infra/helpers.rs" - run git mv "src/cli/utils.rs" "src/cli/infra/utils.rs" - # ... -} -``` - -### Example 3: CI Integration - -**GitHub Actions:** -```yaml -- name: Architectural Review - run: | - loct plan --json > plan.json - FILES_TO_MOVE=$(jq '.stats.files_to_move' plan.json) - if [ "$FILES_TO_MOVE" -gt 0 ]; then - echo "::warning::$FILES_TO_MOVE files may need reorganization" - jq '.stats' plan.json - fi -``` - ---- - -## Integration with Other Commands - -### Before Planning - -```bash -# Understand current state -loct health # Quick health check -loct focus # Directory context -loct hotspots # Find hub files -``` - -### During Execution - -```bash -# Verify each move -loct impact # What breaks? -loct cycles # Check for new cycles -``` - -### After Migration - -```bash -# Validate results -loct health # Re-check health -loct audit # Full audit -loct report --html # Visual report -``` - ---- - -## Related Commands - -| Command | Purpose | -|---------|---------| -| `loct impact ` | Analyze what breaks if a file is changed | -| `loct focus ` | Extract directory context (deps + consumers) | -| `loct cycles` | Detect and classify circular imports | -| `loct audit` | Full codebase audit (dead + cycles + twins) | -| `loct health` | Quick health summary | - ---- - -## Architecture - -The Refactor Strategist uses these loctree building blocks: - -1. **HolographicFocus** - Extracts files in target directory with their dependencies -2. **ImpactAnalysis** - Calculates direct and transitive consumers for risk scoring -3. **Tarjan SCC** - Detects cyclic dependency groups -4. **LayerDetection** - Classifies files by architectural layer via path heuristics -5. **ShimGeneration** - Creates re-export code for backward compatibility - -**Performance:** <3s for 500-file directories (uses cached snapshot, no re-scanning) - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/rmcp-memex/01_security.md b/docs/rmcp-memex/01_security.md deleted file mode 100644 index eba9e58b..00000000 --- a/docs/rmcp-memex/01_security.md +++ /dev/null @@ -1,337 +0,0 @@ -# Security - Namespace Access Control - -## Problem - -W środowisku multi-agent, gdzie wiele AI agentów może korzystać z tego samego serwera rmcp-memex, potrzebna jest izolacja danych między agentami. Bez mechanizmu kontroli dostępu: -- Agent A może odczytać dane Agenta B -- Brak możliwości ochrony wrażliwych namespace'ów -- Trudność w audycie dostępu do danych - -Dodatkowo, ograniczenie dostępu do plików tylko do `$HOME` i `cwd` było zbyt restrykcyjne - blokowało legitymowe użycie zewnętrznych wolumenów (np. `/Volumes/ExternalDrive`). - -## Rozwiązanie - -Zaimplementowano dwupoziomowy system bezpieczeństwa: - -### 1. Konfigurowalna Whitelist Ścieżek - -Zamiast hardcoded ograniczenia do `$HOME` i `cwd`, wprowadzono konfigurowalną listę dozwolonych ścieżek. - -```toml -# ~/.rmcp_servers/config/rmcp-memex.toml -allowed_paths = [ - "~", # Home directory - "/Volumes/LibraxisShare/data", # External volume - "/opt/shared/documents" # Shared directory -] -``` - -**Zachowanie:** -- Jeśli `allowed_paths` jest puste → domyślnie `$HOME` + `cwd` (backward compatible) -- Jeśli `allowed_paths` jest ustawione → tylko te ścieżki są dozwolone -- Wspiera `~` expansion do home directory -- Walidacja przez canonicalization (rozwiązuje symlinki) - -### 2. Namespace Access Tokens - -Token-based access control dla namespace'ów. Chronione namespace'y wymagają tokena do odczytu/zapisu. - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Namespace Security │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ Public Namespace Protected Namespace │ -│ ┌─────────────┐ ┌─────────────────────┐ │ -│ │ "default" │ │ "pamietnik" │ │ -│ │ │ │ │ │ -│ │ No token │ │ Token: rmx_7f3a9b │ │ -│ │ required │ │ required │ │ -│ └─────────────┘ └─────────────────────┘ │ -│ │ -│ Agent A: ✓ access Agent A: ✗ no token │ -│ Agent B: ✓ access Agent B: ✓ has token │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - -## Użycie - -### Włączenie Security - -```bash -# CLI -rmcp_memex serve --security-enabled - -# Lub w config.toml -security_enabled = true -token_store_path = "~/.rmcp_servers/rmcp_memex/tokens.json" -``` - -### Tworzenie Tokena dla Namespace - -```json -// MCP Request -{ - "method": "tools/call", - "params": { - "name": "namespace_create_token", - "arguments": { - "namespace": "pamietnik", - "description": "Personal diary namespace" - } - } -} - -// Response -{ - "content": [{ - "type": "text", - "text": "Token created for namespace 'pamietnik': rmx_a1b2c3d4e5f6..." - }] -} -``` - -**WAŻNE:** Token jest zwracany tylko raz przy tworzeniu. Zapisz go w bezpiecznym miejscu! - -### Dostęp do Chronionego Namespace - -```json -// Bez tokena - BŁĄD -{ - "method": "tools/call", - "params": { - "name": "memory_search", - "arguments": { - "namespace": "pamietnik", - "query": "moje wspomnienia" - } - } -} -// Error: "Access denied: namespace 'pamietnik' requires a valid token" - -// Z tokenem - OK -{ - "method": "tools/call", - "params": { - "name": "memory_search", - "arguments": { - "namespace": "pamietnik", - "query": "moje wspomnienia", - "token": "rmx_a1b2c3d4e5f6..." - } - } -} -// Success: returns search results -``` - -### Odwołanie Tokena - -```json -{ - "method": "tools/call", - "params": { - "name": "namespace_revoke_token", - "arguments": { - "namespace": "pamietnik" - } - } -} -``` - -Po odwołaniu tokena, namespace staje się ponownie publiczny. - -### Lista Chronionych Namespace'ów - -```json -{ - "method": "tools/call", - "params": { - "name": "namespace_list_protected", - "arguments": {} - } -} - -// Response -{ - "content": [{ - "type": "text", - "text": "[\"pamietnik\", \"projekty\", \"finanse\"]" - }] -} -``` - -### Status Security - -```json -{ - "method": "tools/call", - "params": { - "name": "namespace_security_status", - "arguments": {} - } -} - -// Response (enabled) -{ - "content": [{ - "type": "text", - "text": "{\"enabled\":true,\"token_store_path\":\"~/.rmcp_servers/rmcp_memex/tokens.json\"}" - }] -} - -// Response (disabled) -{ - "content": [{ - "type": "text", - "text": "{\"enabled\":false,\"message\":\"Namespace security is disabled. All namespaces are publicly accessible.\"}" - }] -} -``` - -## Format Tokena - -Tokeny mają format: `rmx_<32 znaki hex>` - -``` -rmx_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 -│ └─────────────────────────────────┘ -│ 32 znaki hex (128 bit) -└── prefix "rmx_" (rmcp-memex) -``` - -Tokeny są generowane kryptograficznie bezpiecznie (`rand::thread_rng()`). - -## Token Store - -Tokeny są przechowywane w pliku JSON: - -```json -// ~/.rmcp_servers/rmcp_memex/tokens.json -{ - "pamietnik": { - "token_hash": "5e884898da28047d...", - "created_at": "2024-12-22T10:30:00Z", - "description": "Personal diary namespace" - }, - "projekty": { - "token_hash": "d033e22ae348aeb5...", - "created_at": "2024-12-22T11:00:00Z", - "description": null - } -} -``` - -**Bezpieczeństwo:** -- Przechowywany jest tylko **hash** tokena (SHA-256), nie sam token -- Token plaintext jest zwracany tylko raz przy tworzeniu -- Weryfikacja przez porównanie hashy - -## Path Validation - -Funkcja `validate_path()` chroni przed path traversal attacks: - -```rust -// Blokowane wzorce -"../../../etc/asdpasswd" // Path traversal -sd"/etc/passwd" // Outside allowed paths -"~/../../root/.ssh" // Traversal after expansion - -// Dozwolone (jeśli w allowed_paths) -"~/Documents/notes.md" // Under home -"/Volumes/Data/file.txt" // Configured external volume -``` - -**Walidacja:** -1. Sprawdzenie czy ścieżka nie jest pusta -2. Expansion `~` do home directory -3. Sprawdzenie wzorca `..` (path traversal) -4. Canonicalization (rozwiązanie symlinków) -5. Sprawdzenie czy canonical path jest pod dozwoloną ścieżką - -## Implementacja - -### Pliki źródłowe - -| Plik | Opis | -|------|------| -| `rmcp-memex/src/security/mod.rs` | `NamespaceAccessManager`, `TokenStore`, token generation/verification | -| `rmcp-memex/src/handlers/mod.rs` | `validate_path()`, integration z access manager | -| `rmcp-memex/src/lib.rs` | `NamespaceSecurityConfig`, re-exports | -| `rmcp-memex/src/bin/rmcp_memex.rs` | CLI flags `--security-enabled`, `--token-store-path` | - -### Kluczowe struktury - -```rust -/// Konfiguracja security -pub struct NamespaceSecurityConfig { - pub enabled: bool, - pub token_store_path: Option, -} - -/// Manager dostępu do namespace'ów -pub struct NamespaceAccessManager { - enabled: bool, - store: Option>>, -} - -/// Przechowywanie tokenów -pub struct TokenStore { - path: PathBuf, - tokens: HashMap, -} - -/// Wpis tokena -pub struct TokenEntry { - pub token_hash: String, - pub created_at: DateTime, - pub description: Option, -} -``` - -### Testy - -```bash -cd rmcp-memex && cargo test security -``` - -Testy pokrywają: -- `test_token_generation` - generowanie tokenów w poprawnym formacie -- `test_access_manager_disabled` - zachowanie gdy security wyłączone -- `test_token_store_create_and_verify` - tworzenie i weryfikacja tokenów -- `test_access_manager_enabled` - pełny flow z włączonym security - -## Best Practices - -### Dla administratorów - -1. **Włącz security w produkcji** - `--security-enabled` -2. **Ogranicz allowed_paths** - tylko niezbędne ścieżki -3. **Backup token store** - tokeny są nieodwracalne -4. **Rotacja tokenów** - okresowo revoke + create nowe - -### Dla agentów AI - -1. **Przechowuj tokeny bezpiecznie** - env vars lub secure storage -2. **Nie loguj tokenów** - unikaj wyświetlania w logach -3. **Używaj dedykowanych namespace'ów** - izolacja danych -4. **Sprawdzaj security_status** - upewnij się że security jest włączone - -## Przyszłe rozszerzenia - -### Faza 3: Szyfrowanie Namespace'ów (planowane) - -```toml -# Przyszła konfiguracja -[namespaces.pamietnik] -encrypted = true -key_derivation = "argon2id" -``` - -- Dane w LanceDB szyfrowane kluczem namespace'u -- Bez klucza = dane bezużyteczne -- Dla naprawdę wrażliwych danych - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/rmcp-memex/02_configuration.md b/docs/rmcp-memex/02_configuration.md deleted file mode 100644 index 2ba11c81..00000000 --- a/docs/rmcp-memex/02_configuration.md +++ /dev/null @@ -1,299 +0,0 @@ -# Configuration Guide - -## Przegląd - -rmcp-memex można skonfigurować na trzy sposoby (w kolejności priorytetu): -1. **Flagi CLI** - najwyższy priorytet -2. **Plik konfiguracyjny TOML** - średni priorytet -3. **Wartości domyślne** - najniższy priorytet - -## Opcje CLI - -```bash -rmcp_memex [OPTIONS] [COMMAND] -``` - -### Komendy - -| Komenda | Opis | -|---------|------| -| `serve` | Uruchom serwer MCP (domyślna) | -| `wizard` | Interaktywny kreator konfiguracji | -| `index` | Batch indexing dokumentów | - -### Globalne Opcje - -| Flaga | Opis | Domyślnie | -|-------|------|-----------| -| `--config ` | Ścieżka do pliku konfiguracyjnego TOML | brak | -| `--mode ` | Tryb serwera: `memory` lub `full` | `full` | -| `--features ` | Lista funkcji (comma-separated) | `filesystem,memory,search` | -| `--cache-mb ` | Rozmiar cache w MB | `4096` | -| `--db-path ` | Ścieżka do LanceDB | `~/.rmcp_servers/rmcp_memex/lancedb` | -| `--max-request-bytes ` | Max rozmiar requestu | `5242880` (5MB) | -| `--log-level ` | Poziom logowania | `info` | -| `--allowed-paths ` | Dozwolone ścieżki (można powtórzyć) | `$HOME`, `cwd` | -| `--security-enabled` | Włącz namespace security | `false` | -| `--token-store-path ` | Ścieżka do token store | `~/.rmcp_servers/rmcp_memex/tokens.json` | - -### Przykłady CLI - -```bash -# Podstawowe uruchomienie -rmcp_memex serve - -# Tryb memory-only (bez dostępu do filesystem) -rmcp_memex serve --mode memory - -# Z własną konfiguracją -rmcp_memex serve --config ~/.rmcp_servers/config/rmcp-memex.toml - -# Z security i custom paths -rmcp_memex serve \ - --security-enabled \ - --allowed-paths ~ \ - --allowed-paths /Volumes/Data \ - --log-level debug - -# Batch indexing -rmcp_memex index ./documents --namespace docs --recursive --glob "*.md" -``` - -## Plik Konfiguracyjny (TOML) - -### Lokalizacja - -Domyślna lokalizacja: `~/.rmcp_servers/config/rmcp-memex.toml` - -### Pełny Przykład - -```toml -# Tryb serwera: "memory" lub "full" -mode = "full" - -# Lista włączonych funkcji -features = "filesystem,memory,search" - -# Rozmiar cache w MB -cache_mb = 4096 - -# Ścieżka do LanceDB vector store -db_path = "~/.rmcp_servers/rmcp_memex/lancedb" - -# Maksymalny rozmiar requestu JSON-RPC (bytes) -max_request_bytes = 5242880 - -# Poziom logowania: trace, debug, info, warn, error -log_level = "info" - -# Whitelist dozwolonych ścieżek dla operacji na plikach -# Jeśli puste, domyślnie $HOME i current working directory -allowed_paths = [ - "~", - "/Volumes/LibraxisShare/Klaudiusz", - "/opt/shared/documents" -] - -# Włącz namespace token-based access control -security_enabled = true - -# Ścieżka do pliku z tokenami namespace'ów -token_store_path = "~/.rmcp_servers/rmcp_memex/tokens.json" -``` - -### Minimalna Konfiguracja - -```toml -# Tylko niezbędne ustawienia -db_path = "~/.rmcp_servers/rmcp_memex/lancedb" -security_enabled = true -``` - -## Tryby Serwera - -### Full Mode (domyślny) - -Wszystkie funkcje włączone: -- RAG indexing z plików -- Memory operations -- Semantic search - -```bash -rmcp_memex serve --mode full -# lub -rmcp_memex serve # domyślnie full -``` - -### Memory Mode - -Tylko operacje pamięciowe, bez dostępu do filesystem: -- Memory upsert/get/search/delete -- Semantic search -- Brak rag_index (tylko rag_index_text) - -```bash -rmcp_memex serve --mode memory -``` - -Użyj tego trybu gdy: -- Serwer nie powinien mieć dostępu do plików -- Tylko vector memory jest potrzebne -- Zwiększone bezpieczeństwo - -## Zmienne Środowiskowe - -| Zmienna | Opis | -|---------|------| -| `HOME` / `USERPROFILE` | Home directory (dla ~ expansion) | -| `LANCEDB_PATH` | Override ścieżki LanceDB | -| `SLED_PATH` | Override ścieżki sled K/V store | -| `FASTEMBED_CACHE_PATH` | Cache dla modeli FastEmbed | -| `HF_HUB_CACHE` | Cache dla modeli HuggingFace | - -## Konfiguracja dla Claude/MCP - -### ~/.claude.json - -```json -{ - "mcpServers": { - "rmcp-memex": { - "command": "rmcp_memex", - "args": ["serve", "--config", "~/.rmcp_servers/config/rmcp-memex.toml"] - } - } -} -``` - -### Z security enabled - -```json -{ - "mcpServers": { - "rmcp-memex": { - "command": "rmcp_memex", - "args": [ - "serve", - "--security-enabled", - "--allowed-paths", "~", - "--allowed-paths", "/Volumes/Data" - ] - } - } -} -``` - -## Batch Indexing - -Komenda `index` pozwala na masowe indeksowanie dokumentów. - -### Składnia - -```bash -rmcp_memex index [OPTIONS] -``` - -### Opcje - -| Flaga | Opis | -|-------|------| -| `-n, --namespace ` | Namespace dla dokumentów (domyślnie: `rag`) | -| `-r, --recursive` | Rekursywnie przeglądaj podkatalogi | -| `-g, --glob ` | Filtruj pliki wzorcem glob | -| `--max-depth ` | Maksymalna głębokość (0 = bez limitu) | - -### Przykłady - -```bash -# Indeksuj pojedynczy plik -rmcp_memex index ./README.md - -# Indeksuj folder rekursywnie -rmcp_memex index ./docs --recursive --namespace documentation - -# Tylko pliki markdown -rmcp_memex index ./notes --recursive --glob "*.md" --namespace notes - -# Z limitem głębokości -rmcp_memex index ./project --recursive --max-depth 3 -``` - -## Wizard (Kreator Konfiguracji) - -Interaktywny kreator do generowania konfiguracji. - -```bash -rmcp_memex wizard - -# Dry run - pokaż zmiany bez zapisywania -rmcp_memex wizard --dry-run -``` - -Wizard pomoże skonfigurować: -- Ścieżkę do LanceDB -- Dozwolone ścieżki -- Security settings -- Integrację z Claude - -## Priorytet Konfiguracji - -Gdy ta sama opcja jest ustawiona w wielu miejscach: - -``` -CLI flag > Config file > Default value -``` - -Przykład: -```bash -# Config file: log_level = "info" -# CLI: --log-level debug -# Wynik: debug (CLI wygrywa) -rmcp_memex serve --config config.toml --log-level debug -``` - -## Walidacja Konfiguracji - -Serwer waliduje konfigurację przy starcie: - -1. **Ścieżki** - sprawdza czy istnieją i są dostępne -2. **Allowed paths** - rozwiązuje ~ i sprawdza uprawnienia -3. **Token store** - tworzy plik jeśli nie istnieje (gdy security enabled) -4. **LanceDB** - inicjalizuje bazę jeśli nie istnieje - -Błędy konfiguracji są raportowane przy starcie z jasnym komunikatem. - -## Troubleshooting - -### "Access denied: path outside allowed directories" - -Dodaj ścieżkę do `allowed_paths`: -```toml -allowed_paths = [ - "~", - "/path/to/your/directory" -] -``` - -### "Cannot resolve config path" - -Sprawdź czy plik konfiguracyjny istnieje: -```bash -ls -la ~/.rmcp_servers/config/rmcp-memex.toml -``` - -### "Token store not found" - -Przy pierwszym uruchomieniu z `--security-enabled`, token store jest tworzony automatycznie. Upewnij się że katalog nadrzędny istnieje: -```bash -mkdir -p ~/.rmcp_servers/rmcp_memex -``` - -### Logi debugowania - -```bash -rmcp_memex serve --log-level trace -``` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/rmcp-memex/README.md b/docs/rmcp-memex/README.md deleted file mode 100644 index d5ee8ae7..00000000 --- a/docs/rmcp-memex/README.md +++ /dev/null @@ -1,239 +0,0 @@ -# rmcp-memex - -RAG/Memory MCP Server with LanceDB vector storage for AI agents. - -## Overview - -`rmcp-memex` is an MCP (Model Context Protocol) server providing: -- **RAG (Retrieval-Augmented Generation)** - document indexing and semantic search -- **Vector Memory** - semantic storage and retrieval of text chunks -- **Namespace Isolation** - data isolation in namespaces -- **Security** - token-based access control for protected namespaces -- **Onion Slice Architecture** - hierarchical embeddings (OUTER→MIDDLE→INNER→CORE) -- **Preprocessing** - automatic noise filtering from conversation exports (~36-40% reduction) -- **Exact-Match Deduplication** - SHA256-based dedup for overlapping exports - -## Architecture - -``` -┌─────────────────────────────────────────────────────────────┐ -│ rmcp-memex │ -├─────────────────────────────────────────────────────────────┤ -│ MCP Server (JSON-RPC over stdio) │ -│ ├── handlers/mod.rs - Request routing & validation │ -│ ├── security/mod.rs - Namespace access control │ -│ └── rag/mod.rs - RAG pipeline │ -├─────────────────────────────────────────────────────────────┤ -│ Storage Layer │ -│ ├── LanceDB - Vector embeddings │ -│ ├── sled - Key-value store │ -│ └── moka - In-memory cache │ -├─────────────────────────────────────────────────────────────┤ -│ Embeddings (External Providers) │ -│ ├── Ollama - Local models (recommended) │ -│ ├── MLX Bridge - Apple Silicon acceleration │ -│ └── OpenAI-compatible - Any compatible endpoint │ -└─────────────────────────────────────────────────────────────┘ -``` - -## Features - -### RAG Tools -| Tool | Description | -|------|-------------| -| `rag_index` | Index document from file | -| `rag_index_text` | Index raw text | -| `rag_search` | Search documents semantically | - -### Memory Tools -| Tool | Description | -|------|-------------| -| `memory_upsert` | Add/update chunk in namespace | -| `memory_get` | Get chunk by ID | -| `memory_search` | Search semantically in namespace | -| `memory_delete` | Delete chunk | -| `memory_purge_namespace` | Delete all chunks in namespace | - -### Security Tools -| Tool | Description | -|------|-------------| -| `namespace_create_token` | Create access token for namespace | -| `namespace_revoke_token` | Revoke token (namespace becomes public) | -| `namespace_list_protected` | List protected namespaces | -| `namespace_security_status` | Security system status | - -## Quick Start - -### Installation - -```bash -cd loctree-suite -cargo install --path rmcp-memex -``` - -### Running - -```bash -# Default mode (all features) -rmcp_memex serve - -# Memory-only mode (no filesystem access) -rmcp_memex serve --mode memory - -# With security enabled -rmcp_memex serve --security-enabled -``` - -### Configuration (TOML) - -```toml -# ~/.rmcp_servers/config/rmcp-memex.toml - -mode = "full" -db_path = "~/.rmcp_servers/rmcp_memex/lancedb" -cache_mb = 4096 -log_level = "info" - -# Whitelist of allowed paths -allowed_paths = [ - "~", - "/Volumes/ExternalDrive/data" -] - -# Security -security_enabled = true -token_store_path = "~/.rmcp_servers/rmcp_memex/tokens.json" -``` - -## Documentation - -- [01_security.md](./01_security.md) - Security system (namespace tokens) -- [02_configuration.md](./02_configuration.md) - Configuration and CLI options - -## Onion Slice Architecture - -Instead of traditional flat chunking, rmcp-memex offers hierarchical "onion slices": - -``` -┌─────────────────────────────────────────┐ -│ OUTER (~100 chars) │ ← Minimum context, maximum navigation -│ Keywords + ultra-compression │ -├─────────────────────────────────────────┤ -│ MIDDLE (~300 chars) │ ← Key sentences + context -├─────────────────────────────────────────┤ -│ INNER (~600 chars) │ ← Expanded content -├─────────────────────────────────────────┤ -│ CORE (full text) │ ← Complete document -└─────────────────────────────────────────┘ -``` - -**Philosophy:** "Minimum info → Maximum navigation paths" - -### CLI Commands - -```bash -# Index with onion slicing (default) -rmcp_memex index -n memories /path/to/data/ --slice-mode onion - -# Index with flat chunking (backward compatible) -rmcp_memex index -n memories /path/to/data/ --slice-mode flat - -# Search in namespace -rmcp_memex search -n memories -q "best moments" --limit 10 - -# Search only in specific layer -rmcp_memex search -n memories -q "query" --layer outer - -# Drill down in hierarchy (expand children) -rmcp_memex expand -n memories -i "slice_id_here" - -# Get chunk by ID -rmcp_memex get -n memories -i "chunk_abc123" - -# RAG search (cross-namespace) -rmcp_memex rag-search -q "search term" --limit 5 - -# List namespaces with stats -rmcp_memex namespaces --stats - -# Export namespace to JSON -rmcp_memex export -n memories -o backup.json --include-embeddings -``` - -### Preprocessing (Noise Filtering) - -Automatic removal of ~36-40% noise from conversation exports: -- MCP tool artifacts (``, ``, etc.) -- CLI output (git status, cargo build, npm install) -- Metadata (UUIDs, timestamps → placeholders) -- Empty/boilerplate content - -```bash -# Index with preprocessing -rmcp_memex index -n memories /path/to/export.json --preprocess -``` - -### Exact-Match Deduplication - -SHA256-based dedup for overlapping exports (e.g., quarterly exports containing 6 months of data): - -```bash -# Dedup enabled (default) -rmcp_memex index -n memories /path/to/data/ - -# Disable dedup -rmcp_memex index -n memories /path/to/data/ --no-dedup -``` - -**Output with statistics:** -``` -Indexing complete: - New chunks: 234 - Files indexed: 67 - Skipped (duplicate): 33 - Deduplication: enabled -``` - -## Code Structure - -``` -rmcp-memex/ -├── src/ -│ ├── lib.rs # Public API & ServerConfig -│ ├── bin/ -│ │ └── rmcp_memex.rs # CLI binary (serve, index, search, get, expand, etc.) -│ ├── handlers/ -│ │ └── mod.rs # MCP request handlers -│ ├── security/ -│ │ └── mod.rs # Namespace access control -│ ├── rag/ -│ │ └── mod.rs # RAG pipeline + OnionSlice architecture -│ ├── preprocessing/ -│ │ └── mod.rs # Noise filtering for conversation exports -│ ├── storage/ -│ │ └── mod.rs # LanceDB + sled (schema v3 with content_hash) -│ ├── embeddings/ -│ │ └── mod.rs # MLX/FastEmbed bridge -│ └── tui/ -│ └── mod.rs # Configuration wizard -└── Cargo.toml -``` - -## Claude/MCP Integration - -Add to `~/.claude.json`: - -```json -{ - "mcpServers": { - "rmcp-memex": { - "command": "rmcp_memex", - "args": ["serve", "--security-enabled"] - } - } -} -``` - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/search-tools-comparison.md b/docs/search-tools-comparison.md deleted file mode 100644 index 334cc086..00000000 --- a/docs/search-tools-comparison.md +++ /dev/null @@ -1,300 +0,0 @@ -# Search Tools Comparison Map - -## Tools Analyzed - -| Tool | Type | Scope | Speed | -|------|------|-------|-------| -| `rg` (ripgrep) | Exact text | Respects `.gitignore` | Fast | -| `grep -rn` | Exact text | All files (incl. .venv) | Medium | -| `loct find` | Symbol + Semantic | Indexed codebase | Fast | -| `loct query` | Graph traversal | Dependency graph | Fast | -| `loct` commands | Static analysis | Full codebase | Varies | -| Claude `Grep` tool | Exact text (rg) | Respects `.gitignore` | Fast | - ---- - -## Quick Reference: When to Use What - -| Szukam... | Użyj | Dlaczego | -|-----------|------|----------| -| Dokładnego stringa | `rg` | Exact match, fast | -| Stringa w dependencies | `grep -rn` lub `rg --no-ignore` | Searches .venv | -| Eksportowanego symbolu | `loct find` lub `loct query where-symbol` | Symbol + semantic | -| Czegoś z literówką | `loct find` | Semantic recovery | -| Lokalnych zmiennych | `rg` | loct nie indeksuje locals | -| Komentarzy/docstringów | `rg` | Text search | -| Kto importuje plik? | `loct query who-imports` | Reverse deps | -| Co się zepsuje jak zmienię? | `loct impact` | Transitive analysis | -| Wszystkie FastAPI routes | `loct routes` | Framework-aware | -| Circular imports | `loct cycles` | Graph analysis | -| Unused code | `loct dead` / `loct zombie` | Static analysis | -| Duplicate symbols | `loct twins` | Cross-file detection | -| Directory overview | `loct focus` | LOC + deps tree | -| Health check | `loct health` / `loct audit` | Full report | - ---- - -## Loct Command Reference - -### Instant Commands (<100ms) - -| Command | Description | JSON? | Use Case | -|---------|-------------|-------|----------| -| `loct find ` | Symbol + params + semantic search | ✅ | Find functions, classes, parameters by name | -| `loct query who-imports ` | Reverse dependencies | ✅ | "What files import this?" | -| `loct query where-symbol ` | Symbol definition + re-exports | ✅ | "Where is X defined?" | -| `loct query component-of ` | Module ownership | ✅ | "What module owns this file?" | -| `loct slice ` | File dependencies + LOC | ✅ | "What does this file depend on?" | -| `loct impact ` | Transitive consumers | ✅ | "What breaks if I change this?" | -| `loct focus ` | Directory context | ✅ | "Overview of this module" | -| `loct hotspots` | Import frequency heatmap | ✅ | "What are the core files?" | -| `loct health` | Quick health summary | ✅ | "Any obvious issues?" | - -> **Note (v0.8.4)**: All commands now support `--json` output. `loct find` also searches function parameters! - -### Analysis Commands - -| Command | Description | JSON? | Use Case | -|---------|-------------|-------|----------| -| `loct dead` | Unused exports | ✅ | Find dead code | -| `loct cycles` | Circular imports | ✅ | Detect import cycles | -| `loct twins` | Duplicate symbol names | ✅ | Find naming conflicts | -| `loct zombie` | Dead + orphan + shadows | ✅ | Combined cleanup report | -| `loct coverage` | Test gaps (structural) | ✅ | "What's not tested?" | -| `loct audit` | Full codebase report | ❌ | Markdown health report | -| `loct sniff` | Code smells aggregate | ❌ | twins + dead + crowds | -| `loct crowd ` | Functional clustering | ❌ | "Files related to X" | -| `loct tagmap ` | Unified search | ❌ | files + crowd + dead | - -### Framework-Specific - -| Command | Description | JSON? | Use Case | -|---------|-------------|-------|----------| -| `loct routes` | FastAPI/Flask routes | ✅ | List all API endpoints | -| `loct commands` | Tauri FE↔BE handlers | ❌ | Frontend-backend bridges | -| `loct events` | Event emit/listen flow | ❌ | Event analysis | - -### JQ Queries (on snapshot.json; artifacts cached by default) - -```bash -loct '.metadata' # Scan metadata -loct '.files | length' # Count files -loct '.dead_parrots[]' # List dead exports -loct '.cycles[]' # List circular imports -``` - ---- - -## Test Results - -### 1. Exported Symbol: `ResponsesAdapter` - -| Tool | Result | -|------|--------| -| **rg** | ✅ 3 files, exact matches (usage count) | -| **loct find** | ✅ Symbol match + 19 semantic matches | -| **loct query where-symbol** | ✅ Exact definition + line number | - -**Verdict**: OVERLAP - all find it, loct adds semantic context - ---- - -### 2. Typo: `streeming` (meant: streaming) - -| Tool | Result | -|------|--------| -| **rg** | ❌ No results | -| **loct find** | ⚠️ Semantic recovery: StreamOptions (0.46) | - -**Verdict**: AUGMENT - loct recovers from typos, rg cannot - ---- - -### 3. Local Variable: `request_model` - -| Tool | Result | -|------|--------| -| **rg** | ✅ 14 hits in adapter.py | -| **loct find** | ⚠️ No symbol match (not exported) | -| **loct query where-symbol** | ❌ Not found | - -**Verdict**: AUGMENT - rg finds locals, loct only indexes exports - ---- - -### 4. Reverse Dependencies - -| Tool | Result | -|------|--------| -| **rg** | ❌ Cannot do reverse deps | -| **loct query who-imports** | ✅ Full list with import type | - -``` -who-imports 'src/mlx_omni_server/responses/store.py': - src/mlx_omni_server/responses/__init__.py - imports via import - src/mlx_omni_server/responses/context_builder.py - imports via import - src/mlx_omni_server/responses/router.py - imports via import -``` - -**Verdict**: UNIQUE to loct - graph traversal - ---- - -### 5. Impact Analysis - -| Tool | Result | -|------|--------| -| **rg** | ❌ Cannot analyze | -| **loct impact** | ✅ Direct + transitive consumers with depth | - -``` -Impact analysis for: src/mlx_omni_server/responses/schema.py - Direct consumers (4 files) - Transitive impact (13 files) - [!] Removing would affect 17 files (max depth: 4) -``` - -**Verdict**: UNIQUE to loct - refactoring blast radius - ---- - -### 6. API Routes Discovery - -| Tool | Result | -|------|--------| -| **rg '@router'** | ⚠️ Raw decorators, needs parsing | -| **loct routes** | ✅ Parsed: method, path, handler, file, line | - -```json -{ - "method": "POST", - "path": "/v1/responses", - "handler": "create_response", - "file": "src/mlx_omni_server/responses/router.py", - "line": 59 -} -``` - -**Verdict**: AUGMENT - loct parses, rg just finds text - ---- - -## Known Limitations - -### Loct False Positives - -1. ~~**Monkey-patching patterns**: compat.py exports symbols injected into `sys.modules` - loct sees them as dead~~ **FIXED in v0.8.4!** sys.modules injection now detected -2. **Aliased imports**: `from x import y as _y` with noqa may not be tracked -3. **Dynamic imports**: `importlib.import_module()` not detected - -### Loct Requires Exact Names - -```bash -loct query where-symbol BatchCoordinator # ❌ Not found -loct query where-symbol BatchRequestCoordinator # ✅ Found -``` - -Use `loct find` for fuzzy matching, `loct query` for exact. - ---- - -## Overlap vs Augment Diagram - -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ SEARCH SPACE │ -│ │ -│ ┌────────────────────┐ │ -│ │ rg / grep │ ← Exact text, comments, locals, strings │ -│ │ │ │ -│ │ ┌─────────────────┼─────────────────┐ │ -│ │ │ OVERLAP │ │ │ -│ │ │ (exported │ loct find │ ← Semantic search, │ -│ │ │ symbols) │ │ typo recovery, │ -│ │ └─────────────────┼─────────────────┘ related symbols │ -│ │ │ │ -│ └────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────────────────────────────────┐ │ -│ │ loct (UNIQUE) │ │ -│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │ │ -│ │ │ who- │ │ impact │ │ routes │ │ cycles/dead/ │ │ │ -│ │ │ imports │ │ analysis │ │ parsing │ │ twins/zombie │ │ │ -│ │ └──────────┘ └──────────┘ └──────────┘ └──────────────────┘ │ │ -│ └──────────────────────────────────────────────────────────────┘ │ -│ │ -│ GAP: Abstract concepts, natural language queries, runtime behavior │ -└─────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Recommended Workflows - -### 1. Finding a Symbol -```bash -loct find MyClass # Semantic + exact -rg 'class MyClass' # If loct misses (local class) -``` - -### 2. Before Refactoring -```bash -loct impact src/module/file.py # What breaks? -loct slice src/module/file.py # What does it depend on? -loct query who-imports src/module/file.py # Direct consumers -``` - -### 3. Code Cleanup -```bash -loct health # Quick overview -loct dead # Unused exports -loct twins # Duplicate names -loct zombie # Combined report -``` - -### 4. Understanding a Directory -```bash -loct focus src/responses/ # Overview with LOC + deps -loct hotspots # Core files in project -``` - -### 5. API Discovery -```bash -loct routes # All endpoints -loct routes --json | jq '.routes[] | select(.method=="POST")' -``` - ---- - -## AI Integration (Claude Code Hooks) - -### Hook Augmentation (v10) - -Claude Code's Grep tool is automatically augmented with loctree context via PostToolUse hooks: - -```bash -# ~/.claude/hooks/loct-grep-augment.sh -# Every grep gets semantic context from loct find -``` - -**What Claude receives for each grep:** -- `symbol_matches`: Exact symbol definitions with file + line -- `param_matches`: Function parameters matching the pattern (NEW in 0.8.4) -- `semantic_matches`: Similar symbols with similarity scores -- `dead_status`: Whether the symbol is exported and/or dead - -**Example:** Grep for `template` → Hook augments with: -- Symbol: `extract_vue_template`, `parse_svelte_template_usages`, `DynamicExecTemplate` -- Params: `template: &str` in `parse_vue_template_usages()` -- Semantic: Related symbols - -### Best Practices for AI - -1. **Use grep + hook augmentation** for exploratory searches -2. **Use `loct find` directly** when you need semantic matching (typo recovery) -3. **Use `loct impact`** before refactoring to know blast radius -4. **Use `loct slice`** to understand a file's dependencies - ---- - -𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team diff --git a/docs/tutorials/01_ai_agents_manual.md b/docs/tutorials/01_ai_agents_manual.md deleted file mode 100644 index 0ba0c22f..00000000 --- a/docs/tutorials/01_ai_agents_manual.md +++ /dev/null @@ -1,931 +0,0 @@ -# AI Agent's Manual for Loctree - -> Complete guide for AI agents working with codebases using loctree. -> For quick reference, see [AI_README.md](../../AI_README.md). - -## Table of Contents - -1. [Why Loctree?](#why-loctree) -2. [Installation](#installation) -3. [Core Concepts](#core-concepts) -4. [Command Reference](#command-reference) -5. [Agent Bundle for CI](#agent-bundle-for-ci) -6. [Workflows](#workflows) -7. [Language-Specific Features](#language-specific-features) -8. [Integration Patterns](#integration-patterns) -9. [Troubleshooting](#troubleshooting) - ---- - -## Why Loctree? - -Loctree is a static analysis tool designed for AI agents. It solves the fundamental problem of **context** - knowing what code exists, how it connects, and what's actually used. - -### Problems Loctree Solves - -| Problem | Without Loctree | With Loctree | -|---------|-----------------|--------------| -| Finding existing code | Grep/search, hope for the best | `loct find Button` | -| Understanding dependencies | Read imports manually | `loct slice src/Component.tsx --consumers` (deps included) | -| Knowing what uses a file | Search for import statements | `loct slice src/utils.ts --consumers` | -| Dead code detection | Guesswork | `loct dead --confidence high` or `loct doctor` | -| Circular import detection | Runtime errors | `loct cycles` or `loct doctor` | -| Tauri FE↔BE coverage | Manual audit | `loct commands --missing` | - -### Key Philosophy - -1. **Scan once, slice many** - Initial scan builds a snapshot; subsequent queries are instant -2. **Know why it works** - Graph-based analysis over assumptions -3. **Reduce false positives** - Alias-aware, barrel-aware dead code detection -4. **Holographic slices** - Extract exactly the context needed for a task - ---- - -## Installation - -```bash -# Install from crates.io -cargo install --locked loctree loctree-mcp - -# Verify installation -loct --version -``` - -### Requirements - -- Rust toolchain (for installation) -- Git repository (optional, enables git-aware features) - ---- - -## Core Concepts - -### Snapshot - -A snapshot is a cached representation of your codebase's structure: - -``` -.loctree/ -├── snapshot.json # Code graph (files, imports, exports) -├── findings.json # All issues: dead_parrots, cycles, twins, shadows, orphans -├── manifest.json # Index for tooling integration -├── agent.json # AI-ready bundle (replaces --for-ai file) -├── report.html # Human-readable HTML report -└── report.sarif # SARIF 2.1.0 for IDE/CI integration -``` - -**Creating a snapshot:** -```bash -loct # Auto-detect stack, write snapshot.json (fast) -loct --full-scan # Force rescan (ignore cached mtime) -``` - -> **Note (0.7.0+):** The `-A` flag is deprecated. Use `loct doctor` for interactive diagnostics instead. - -### Slicing - -Slicing extracts relevant context for a specific file or task: - -```bash -# Get file's dependencies (what it imports) -loct slice src/api/client.ts - -# Get file's consumers (what imports it) -loct slice src/utils/format.ts --consumers - -# Full context (deps + consumers + file analysis) -loct slice src/Component.tsx --consumers --json -``` - -### Graph - -The import graph maps relationships between files: - -``` -src/App.tsx - └─imports→ src/components/Header.tsx - └─imports→ src/components/Footer.tsx - └─imports→ src/hooks/useAuth.ts - └─imports→ src/api/auth.ts -``` - ---- - -## Command Reference - -### Short Aliases (v0.7.0+) - -Save keystrokes with these built-in aliases: - -| Alias | Command | Description | -|-------|---------|-------------| -| `s` | `slice` | File context extraction | -| `f` | `find` | Symbol/file search | -| `d` | `dead` | Dead export detection | -| `t` | `twins` | Semantic duplicate analysis | -| `h` | `health` | Quick health check | -| `i` | `impact` | Change impact analysis | -| `c` | `cycles` | Circular import detection | -| `q` | `query` | Quick graph queries | - -**Examples:** -```bash -loct h # Quick health check -loct d --confidence high # Dead exports -loct s src/App.tsx --consumers # Slice with consumers -loct f Button # Find Button symbol -loct t --dead-only # Dead parrots only -``` - -### `loct` (default scan) - -Scans the project and generates all artifacts. - -```bash -loct # Scan from current directory -loct src src-tauri # Scan specific roots -loct --full-scan # Force rescan -loct --scan-all # Include node_modules, .venv, target -``` - -**Output:** Creates `.loctree/` with snapshot and all analysis artifacts. - -### `loct slice` - -Extract context for a file. - -```bash -loct slice [options] - -Options: - --consumers Include consumers (files that import this) – deps included by default - --json Output as JSON (for piping to AI) - --depth N Limit dependency depth (default: 3) -``` - -**Examples:** -```bash -# Context for AI task -loct slice src/ChatPanel.tsx --consumers --json | claude - -# Just the imports (deps are default) -loct slice src/utils.ts - -# What depends on this? -loct slice src/api/types.ts --consumers -``` - -### `loct find` - -Search for code patterns and relationships. - -```bash -loct find # Find symbol definitions and uses -loct find # Fuzzy find similar names (avoid duplicates) -loct impact # Show blast radius of changes -``` - -**Examples:** -```bash -# Before creating Button, check if it exists -loct find Button - -# Find all uses of useAuth hook -loct find useAuth - -# What breaks if I change api.ts? -loct impact src/utils/api.ts -``` - -### `loct dead` - -Detect unused exports (dead code). - -```bash -loct dead # All dead exports -loct dead --confidence high # Only high-confidence (no test files) -loct dead --json # JSON output -``` - -**Confidence levels:** -- `high` - Export not imported anywhere in production code -- `medium` - Export only used in tests -- `low` - Complex re-export patterns, may be false positive - -### `loct cycles` - -Detect circular imports. - -```bash -loct cycles # List all cycles -loct cycles --json # JSON output with full paths -``` - -**Output example:** -``` -Circular import detected: - src/a.ts → src/b.ts → src/c.ts → src/a.ts -``` - -### `loct health` - -Quick health check summary — combines cycles + dead exports + twins in one command. - -```bash -loct health # Quick summary -loct health --json # JSON output for CI -loct health src/ # Analyze specific directory -``` - -**Output example:** -``` -Health Check Summary - -Cycles: 3 total (2 hard, 1 structural) -Dead: 6 high confidence, 24 low -Twins: 2 duplicate symbol groups - -Run `loct cycles`, `loct dead`, `loct twins` for details. -``` - -Use this for quick sanity checks before commits or in CI pipelines. - -### `loct audit` - -Full codebase audit — combines ALL structural analyses into one actionable report. Perfect for getting a complete picture of codebase health on day one. - -```bash -loct audit # Full audit of current directory -loct audit --json # JSON output for CI -loct audit src/ # Audit specific directory -``` - -**What it includes:** -- **Cycles** — Circular imports (hard + structural) -- **Dead exports** — Unused code with 0 imports -- **Twins** — Same symbol exported from multiple files -- **Orphan files** — Files with 0 importers (not entry points) -- **Shadow exports** — Consolidation candidates -- **Crowds** — Files with similar dependency patterns - -**Output example:** -``` -🔍 Full Codebase Audit - -CYCLES (3 total) - 2 hard cycles (breaking) - 1 structural cycle - -DEAD EXPORTS (12 total) - 6 high confidence - 6 low confidence - -TWINS (2 groups) - useAuth exported from 2 files - formatDate exported from 3 files - -ORPHAN FILES (4 files, 1,200 LOC) - src/legacy/old-utils.ts (450 LOC) - ... - -SHADOW EXPORTS (1) - store exported by 2 files, 1 dead - -CROWDS (2 clusters) - API handlers: 5 similar files - Form components: 3 similar files - -───────────────────────────────── -Total: 22 findings to review -``` - -Use `loct audit` when onboarding to a new codebase or for comprehensive CI checks. Use `loct health` for quick daily checks. - -### `loct doctor` (v0.7.0+) - -Interactive diagnostics with actionable recommendations. This is the successor to `loct audit` with intelligent categorization and auto-fix suggestions. - -```bash -loct doctor # Full diagnostics -loct doctor --apply-suppressions # Auto-add patterns to .loctignore -``` - -**Categories findings into:** -- **Auto-fixable**: High confidence, safe to remove -- **Needs review**: Low confidence, verify manually -- **Suggested suppressions**: Patterns for `.loctignore` - -**Example output:** -``` -=== Doctor Diagnostics === - -Found 65 issues: 60 auto-fixable, 5 need review - -Dead Exports (12 total): - 10 high confidence (safe to remove) - 2 low confidence (needs review) - -Cycles (3 total): - 2 hard cycles (breaking) - 1 structural cycle - -Twins (8 groups): - Button exported from 2 files - formatDate exported from 3 files - -Suggested .loctignore entries: - **/index.* - **/*test* - -Next steps: - 1. Review high-confidence dead exports and remove if safe - 2. Run tests after each removal - 3. Break hard cycles (structural cycles are often harmless) -``` - -**Workflow:** -```bash -# 1. Run diagnostics -loct doctor - -# 2. Apply suppressions for known false positives -loct doctor --apply-suppressions - -# 3. Fix high-confidence issues one by one -# 4. Verify with tests after each fix -# 5. Re-run doctor to track progress -``` - -### `loct twins` - -Semantic duplicate analysis — finds dead parrots, exact twins, and barrel chaos. - -```bash -loct twins # Full analysis: dead parrots + exact twins + barrel chaos -loct twins --dead-only # Only exports with 0 imports -loct twins --path src/ # Analyze specific path -``` - -**What it detects:** - -1. **Dead Parrots** — exports with zero imports (Monty Python reference: code that's "just resting") - ``` - DEAD PARROTS (75 symbols with 0 imports) - ├─ ChatPanelTabs (reexport:6) - 0 imports - ├─ update_profile (reexport:0) - 0 imports - └─ ... - ``` - -2. **Exact Twins** — same symbol name exported from multiple files - ``` - EXACT TWINS (150 duplicates) - ├─ "Button" exported from: - │ src/components/Button.tsx - │ src/ui/Button.tsx - └─ ... - ``` - -3. **Barrel Chaos** — barrel file issues - - Missing `index.ts` in directories with many external imports - - Deep re-export chains (A → B → C → D) - - Inconsistent import paths (same symbol imported via different paths) - -### `loct commands` - -Tauri FE↔BE command coverage. - -```bash -loct commands --missing # FE invokes without BE handlers -loct commands --unused # BE handlers without FE invokes -loct commands --json # Full command mapping -``` - -### `loct events` - -Tauri event coverage (emit/listen pairs). - -```bash -loct events # Summary -loct events --json # Full event mapping -loct events --ghosts # Emits without listeners -loct events --orphans # Listeners without emitters -``` - -### `loct lint` - -CI-friendly linting with policy enforcement. - -```bash -loct lint --fail # Exit 1 if issues found -loct lint --sarif > results.sarif # SARIF output for IDE -loct lint --max-dead 0 # Fail if any dead exports -loct lint --max-cycles 0 # Fail if any circular imports -``` - -### `loct git` - -Git-aware analysis. - -```bash -loct git compare HEAD~5..HEAD # Semantic diff between commits -loct git blame src/lib.rs # Symbol-level blame (Rust) -loct git history --symbol foo # Track symbol evolution -``` - -### `loct diff` - -Compare snapshots to see what changed. - -```bash -loct diff --since # Compare current vs old snapshot -loct diff --since main # Compare against main branch snapshot -``` - -### jq-style queries - -Query snapshot data directly using jq syntax (powered by jaq, a Rust-native jq implementation). - -```bash -loct '' # Query current snapshot -loct '' --snapshot # Query specific snapshot -``` - -**Flags:** -- `-r` — Raw output (no JSON quotes) -- `-c` — Compact output (single line) -- `-e` — Exit code based on empty result -- `--arg NAME VALUE` — Pass string variable -- `--argjson NAME JSON` — Pass JSON variable - -**Examples:** -```bash -# Metadata -loct '.metadata' - -# Count files -loct '.files | length' - -# Find large files (>500 LOC) -loct '.files[] | select(.loc > 500)' -c - -# Filter edges by pattern -loct '.edges[] | select(.from | contains("api"))' - -# List Tauri commands -loct '.command_bridges | map(.name)' - -# Find top export duplicates -loct '.export_index | to_entries | map(select(.value | length > 1)) | sort_by(.value | length) | reverse | .[0:5]' - -# Query findings (0.7.0+) -loct '.dead_parrots' # Dead exports from findings -loct '.cycles' # Circular imports -loct '.twins[:5]' # First 5 twin groups -loct '.orphans' # Orphan files -loct '.shadows' # Shadow exports -``` - -**Use cases:** -- Quick codebase statistics -- Custom filtering and aggregation -- Integration with shell pipelines -- Extracting specific data for analysis - -**Output includes:** -- Files added, removed, modified -- New/resolved circular imports -- New/removed dead exports -- Changed graph edges - -### `loct dist` - -Bundle distribution analysis — verify tree-shaking by comparing source exports against production bundles using source maps. - -```bash -loct dist dist/bundle.js.map src/ # Analyze bundle vs source -``` - -**Output:** -``` -✓ Found 4 dead export(s) (67%) -Bundle Analysis: - Source exports: 6 - Bundled exports: 2 - Dead exports: 4 - Reduction: 67% - Analysis level: symbol - -Dead Exports (not in bundle): - deadFunction (function) in index.ts:5 - DEAD_CONST (var) in index.ts:10 -``` - -**Features:** -- Symbol-level detection via VLQ Base64 decoding of source map mappings -- File-level fallback when source maps lack `names` array -- Verifies bundler (Vite/Webpack/esbuild) actually eliminated dead code - -### `loct query` - -Quick graph queries without full analysis. - -```bash -loct query who-imports # Files that import target -loct query where-symbol # Where symbol is defined/used -loct query component-of # Graph component containing file -``` - -**Examples:** -```bash -# What imports my utils? -loct query who-imports src/utils/helpers.ts - -# Where is useAuth defined? -loct query where-symbol useAuth - -# Is this file isolated or connected? -loct query component-of src/orphan.ts -``` - -### jq-style Queries (v0.6.15+) - -Query snapshot data directly using jq syntax. Uses jaq (Rust-native jq implementation) for zero external dependencies. - -```bash -loct '' [options] -``` - -**Basic Usage:** -```bash -loct '.metadata' # Extract snapshot metadata -loct '.files | length' # Count files in codebase -loct '.edges | length' # Count import edges -loct '.command_bridges | length' # Count Tauri commands -``` - -**Filtering:** -```bash -# Find all edges from api/ directory -loct '.edges[] | select(.from | contains("api"))' - -# Find large files (>500 LOC) -loct '.files[] | select(.loc > 500)' - -# Get all file paths -loct '.files[].path' -r - -# List Tauri command names -loct '.command_bridges | map(.name)' -``` - -**Options:** -| Flag | Description | -|------|-------------| -| `-r`, `--raw` | Raw output (no JSON quotes for strings) | -| `-c`, `--compact` | Compact output (one line per result) | -| `-e`, `--exit-status` | Exit 1 if result is false/null | -| `--arg ` | Bind string variable | -| `--argjson ` | Bind JSON variable | -| `--snapshot ` | Use specific snapshot file | - -**Variable Binding:** -```bash -# Find edges from specific file -loct '.edges[] | select(.from == $file)' --arg file 'src/api.ts' - -# Files with LOC above threshold -loct '.files[] | select(.loc > $min)' --argjson min 300 -``` - -**Important:** Filter must come before flags: -```bash -# ✅ Correct -loct '.edges[]' --arg file 'foo.ts' - -# ❌ Won't work -loct --arg file 'foo.ts' '.edges[]' -``` - -**Snapshot Discovery:** -- Auto-discovers newest `.loctree/*/snapshot.json` by modification time -- Use `--snapshot path/to/snapshot.json` to specify explicitly - ---- - -## Agent Bundle for CI - -The agent bundle is a complete analysis package for CI pipelines: - -``` -.loctree/ -├── snapshot.json # Code graph (files, imports, exports) -├── findings.json # All issues: dead_parrots, cycles, twins, shadows, orphans -├── manifest.json # Index for tooling integration -├── agent.json # AI-ready bundle (replaces --for-ai file) -├── report.sarif # SARIF 2.1.0 for GitHub/GitLab -├── report.html # Human review -└── py_races.json # Python concurrency (if applicable) -``` - -### CI Integration - -**GitHub Actions:** -```yaml -- name: Run loctree analysis - run: | - cargo install --locked loctree - loct - -- name: Upload SARIF - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: .loctree/report.sarif -``` - -**Policy enforcement:** -```yaml -- name: Check code quality - run: | - loct lint --max-dead 0 --max-cycles 0 --fail -``` - -**Using findings.json in CI:** -```yaml -- name: Check for issues - run: | - loct - dead_count=$(loct '.dead_parrots | length') - cycle_count=$(loct '.cycles | length') - echo "Dead exports: $dead_count" - echo "Cycles: $cycle_count" - if [ "$dead_count" -gt 0 ] || [ "$cycle_count" -gt 0 ]; then - exit 1 - fi -``` - -### SARIF Contents - -The `report.sarif` includes: -- `duplicate-export` - Same symbol exported from multiple files -- `missing-handler` - Frontend command without backend handler -- `unused-handler` - Backend handler without frontend usage -- `dead-export` - Export never imported -- `circular-import` - Circular dependency chain -- `ghost-event` - Event emitted but never listened -- `orphan-listener` - Listener for non-existent event - -### IDE Integration URLs - -SARIF results include `loctree://open?f=&l=` URLs in `properties.openUrl` for direct IDE navigation. Compatible with: -- VS Code (via URL handler extension) -- JetBrains IDEs (built-in URL handling) -- Custom editor integrations - ---- - -## Workflows - -### Starting a New Task - -```bash -# 1. Scan the project (or use cached snapshot) -loct - -# 2. Find relevant context -loct find FeatureName # Check for existing code -loct slice src/related.ts --consumers --json - -# 3. Understand impact -loct impact src/file-to-modify.ts -``` - -### Before Creating a New Component - -```bash -# Check if similar exists -loct find Button -loct find ButtonComponent -loct find useButton - -# If creating, check where to place it -loct slice src/components/index.ts --consumers -``` - -### Debugging Import Issues - -```bash -# Find circular imports -loct cycles - -# Check what imports what -loct slice problematic-file.ts --consumers -``` - -### Cleaning Up Dead Code - -```bash -# Use doctor for interactive diagnostics (0.7.0+) -loct doctor - -# Or find candidates manually -loct dead --confidence high --json - -# Verify each before deletion -loct find suspectedDead -loct slice file-with-dead-code.ts --consumers -``` - -### Tauri Development - -```bash -# Check FE↔BE contract -loct commands --missing # What's called but not implemented? -loct commands --unused # What's implemented but never called? - -# Event flow -loct events --json # Full emit/listen mapping -loct events --ghosts # Emits going nowhere -``` - ---- - -## Language-Specific Features - -### TypeScript/JavaScript - -- **Path aliases** - Respects `tsconfig.json` `paths` and `baseUrl` -- **Barrel files** - Understands `index.ts` re-exports -- **Dynamic imports** - Tracks `import()` expressions -- **JSX/TSX** - Full support -- **Flow types** - Flow annotation support (v0.6.x) -- **WeakMap/WeakSet patterns** - Registry pattern detection (v0.6.x) -- **.d.ts re-exports** - Proper type-only re-export tracking (v0.6.x) - -### SvelteKit - -- **Virtual modules** - Resolves `$app/navigation`, `$app/stores`, `$app/environment`, `$app/paths` -- **`$lib` alias** - Maps `$lib/*` to configured library path -- **Runtime modules** - Correctly resolves SvelteKit internal runtime paths -- **Server/client split** - Understands `.server.ts` and `+page.server.ts` patterns -- **.d.ts re-exports** - Tracks Svelte component type exports (v0.6.x) - -### Python - -- **Namespace packages** - PEP 420 support (no `__init__.py` required) -- **Typed packages** - PEP 561 `py.typed` marker detection -- **Test detection** - Distinguishes test files from production -- **Concurrency patterns** - Detects threading/asyncio/multiprocessing -- **`__all__` tracking** - Respects public API declarations (v0.6.x) -- **Library mode** - Auto-detects Python stdlib (Lib/ directory) (v0.6.x) - -### Rust - -- **Crate structure** - Understands `mod` declarations and module hierarchy -- **Crate-internal imports** - Resolves `use crate::foo::Bar`, `use super::Bar`, `use self::foo::Bar` -- **Same-file usage** - Detects when exported symbols are used locally (e.g., `BUFFER_SIZE` in generics like `fn foo::()`) -- **Nested brace imports** - Handles complex imports like `use crate::{foo::{A, B}, bar::C}` -- **Tauri integration** - `#[tauri::command]` detection -- **Symbol-level blame** - Git blame for fn/struct/enum/impl - -### Go - -- **Package structure** - Understands Go package imports -- **Cross-package references** - Accurate dead code detection across packages -- **Standard library** - Stdlib imports tracked correctly - -### Dart/Flutter (v0.6.x) - -- **Package imports** - Resolves `package:` imports -- **Auto-detection** - Recognizes `pubspec.yaml`, ignores `.dart_tool/`, `build/` -- **Full language support** - Imports, exports, dead code detection - -### Vue - -- **Single File Components (SFC)** - ` - - - -{chatInput?.focusInput()} -``` - -### Version History - -| Version | FP Rate | Status | -|---------|---------|--------| -| 0.5.16 | 40-50% | Default imports broken | -| 0.5.17 | 8.4% | Major improvement | -| 0.6.1-dev | 0% | PERFECT | -| 0.6.2-dev | 25-33% | REGRESSION | - -## Commands Used - -```bash -cd GitButler -loct # Create snapshot -loct dead --confidence high # Dead code analysis -loct twins # Duplicate detection -``` - -## Verdict - -**REGRESSION** - Svelte component method refs need fixing. - -## Key Insights - -1. **Svelte Components**: Method refs via `bind:this` not tracked -2. **Rust Analysis**: Works well -3. **Tauri Integration**: Command bridges functional - -## Workaround - -Until fixed, manually verify Svelte component exports: -```bash -loct dead --confidence high | grep ".svelte" | while read line; do - symbol=$(echo "$line" | awk -F: '{print $NF}') - rg "\\.$symbol\\(" . --type svelte -done -``` - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/14_golang.md b/docs/use-cases/14_golang.md deleted file mode 100644 index 3cd6529b..00000000 --- a/docs/use-cases/14_golang.md +++ /dev/null @@ -1,59 +0,0 @@ -# Use Case: golang/go - The Go Standard Library - -**Repository**: https://github.com/golang/go -**Stack**: Go -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on THE Go standard library - 17,000+ files of pure Go code. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Go Files** | 17,182 | -| **Analysis Time** | 107 seconds | -| **Throughput** | 160 files/sec | - -## Findings - -### Dead Code Detection -- **High Confidence**: 1 finding -- **False Positive Rate**: ~0% - -The single finding is a Python GDB helper edge case (`ChanTypePrinter` used in tuple literals) - acceptable edge case for cross-language tooling. - -### Version History - -| Version | FP Rate | Status | -|---------|---------|--------| -| 0.5.16 | 0% | PERFECT | -| 0.6.1-dev | 100% | REGRESSION | -| 0.6.2-dev | ~0% | FIXED | - -## Commands Used - -```bash -cd GoLang -loct # Create snapshot (107s) -loct dead --confidence high # Dead code analysis -loct twins # Duplicate detection -``` - -## Verdict - -**PERFECT** - Go analysis is production-ready. The 0.6.1 regression was fixed in 0.6.2. - -## Key Insights - -1. **Scalability**: 17K files in under 2 minutes -2. **Accuracy**: Near-zero false positives -3. **Regression Fixed**: Cross-package reference tracking restored - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/15_typescript.md b/docs/use-cases/15_typescript.md deleted file mode 100644 index aa3bbb5e..00000000 --- a/docs/use-cases/15_typescript.md +++ /dev/null @@ -1,77 +0,0 @@ -# Use Case: microsoft/TypeScript - The TypeScript Compiler - -**Repository**: https://github.com/microsoft/TypeScript -**Stack**: TypeScript -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on THE TypeScript compiler - the ultimate TypeScript analysis test. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Total Files** | 75,496 | -| **Source Files** | `/src` with 21 subdirectories | -| **Test Fixtures** | `/tests/cases/` (thousands) | - -## Known Issue - -**UTF-8 Error on Full Repository**: -``` -Error: stream did not contain valid UTF-8 -``` - -**Cause**: TypeScript's test suite contains intentionally malformed files to test compiler edge cases: -- Non-UTF-8 encodings -- BOM markers -- Invalid byte sequences -- Unicode edge cases - -**This is NOT a loctree bug** - it's a valid limitation exposed by compiler test fixtures. - -## Recommendations - -### Option 1: Scan `/src` Only -```bash -cd TypeScript/src -loct # Only production code -loct dead --confidence high -``` - -### Option 2: Use `.loctreeignore` -``` -# .loctreeignore -tests/ -``` - -### Option 3: Alternative Test Targets -Real-world TypeScript projects work fine: -- VSCode -- Playwright -- Angular -- NestJS - -## Future Improvements Needed - -1. **`--skip-invalid-utf8`** flag for graceful degradation -2. **`.loctreeignore`** support for file exclusion -3. **Better error context** showing which file failed - -## Verdict - -**BLOCKED** - Test fixtures with intentional encoding violations prevent full scan. Production TypeScript codebases work fine. - -## Key Insights - -1. **Edge Case**: Compiler test suites are extreme edge cases -2. **Production Safe**: Real TS projects are properly UTF-8 encoded -3. **Feature Request**: Graceful UTF-8 error handling - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/16_nodejs.md b/docs/use-cases/16_nodejs.md deleted file mode 100644 index 7179ead7..00000000 --- a/docs/use-cases/16_nodejs.md +++ /dev/null @@ -1,73 +0,0 @@ -# Use Case: nodejs/node - The Node.js Runtime - -**Repository**: https://github.com/nodejs/node -**Stack**: JavaScript + C++ -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on THE Node.js runtime - massive hybrid codebase. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Total Files** | ~20,400 JS files | -| **lib/ Only** | 348 files | -| **Analysis Time** | 0.13s (lib/ only) | - -## Known Issue - -**UTF-8 Error on Full Repository**: -``` -Error: stream did not contain valid UTF-8 -``` - -**Cause**: Binary ICU Unicode data files (`icudt77l.dat.bz2`) - -**Workaround**: Test `lib/` directory only. - -## Findings (lib/ Directory) - -### Dead Code Detection -- **High Confidence**: 1 finding -- **False Positive Rate**: 0% - -The single finding (`eslint.config_partial.mjs` default export) is a true positive within the isolated scope. - -### Architecture -- **Circular Imports**: 0 (perfect architecture!) -- Node.js core lib has excellent module structure - -## Commands Used - -```bash -cd nodejs/lib -loct # Create snapshot (0.13s!) -loct dead --confidence high # Dead code analysis -loct cycles # Circular dependencies -``` - -## Verdict - -**INCONCLUSIVE** - Binary file handling needs improvement. - -## Key Insights - -1. **Performance**: Lightning fast on pure JS (0.13s for 348 files) -2. **Accuracy**: 0% FP within scope -3. **Blocker**: Binary file detection needed - -## Recommendations - -For Node.js-style repos: -1. Add `.loctreeignore` for binary directories -2. Implement graceful UTF-8 error recovery -3. Auto-detect and skip binary files - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/17_cpython.md b/docs/use-cases/17_cpython.md deleted file mode 100644 index 173f0a01..00000000 --- a/docs/use-cases/17_cpython.md +++ /dev/null @@ -1,81 +0,0 @@ -# Use Case: python/cpython - The Python Interpreter - -**Repository**: https://github.com/python/cpython -**Stack**: Python (+ C) -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on THE Python interpreter source - the reference implementation of Python. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Python Files** | 842 (stdlib) | -| **Analysis Time** | 25.09 seconds | -| **Throughput** | 33 files/sec | - -## Findings - -### Dead Code Detection -- **High Confidence**: 278 candidates (v0.6.1) -- **False Positive Rate**: 100% without library mode -- **With `--library-mode`**: Auto-detects stdlib, excludes `__all__` exports - -### Why Library Mode Matters (v0.6.x) - -Without library mode, all flagged exports are **public API** for external use: -- `calendar.APRIL` - Public API constant -- `csv.DictWriter` - Core utility class -- `ftplib.all_errors` - Used by urllib, socket, asyncio -- `typing.override` - Used across stdlib - -**v0.6.x improvements**: -- Auto-detects `Lib/` directory as stdlib -- Respects `__all__` declarations in modules -- Use `--library-mode` for proper stdlib analysis - -### Additional Findings -- **Dead Parrots**: 172 classes/functions -- **Circular Dependencies**: 2 lazy cycles (both safe) - -## Known Issue - -**Unicode Bug Found**: Devanagari numerals (like `६`) in test files caused panic at `py.rs:224:32`. Test directory excluded to complete scan. - -**Status**: Fixed in subsequent patch using `bytes_match_keyword`. - -## Commands Used - -```bash -cd cpython -loct # Create snapshot -loct dead --confidence high # Dead code analysis -loct cycles # Circular dependencies -``` - -## Verdict - -**LIBRARY MODE REQUIRED** - Use `--library-mode` for proper stdlib analysis (v0.6.x). - -## Key Insights - -1. **Performance**: Fast and stable (33 files/sec) -2. **Accuracy**: Requires library mode for public API analysis -3. **v0.6.x**: Auto-detection of stdlib, `__all__` tracking implemented - -## Recommendations - -For Python stdlib/library analysis: -- Use `--library-mode` flag for automatic `__all__` exclusion -- Auto-detects `Lib/` directory as Python stdlib -- `pyproject.toml` parsing for public API hints -- Focus on internal modules (`_internal/`, `_impl/`) for application code - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/18_rust.md b/docs/use-cases/18_rust.md deleted file mode 100644 index e90894d8..00000000 --- a/docs/use-cases/18_rust.md +++ /dev/null @@ -1,112 +0,0 @@ -# Use Case: rust-lang/rust - The Rust Compiler - -**Repository**: https://github.com/rust-lang/rust -**Stack**: Rust -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -The ultimate stress test for Rust analysis - analyzing THE Rust compiler source code itself. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Rust Files** | 35,387 | -| **Total Symbols** | 79,891 | -| **Repository Size** | 558 MB | -| **Snapshot Size** | 149 MB | - -## Performance - -| Metric | Value | -|--------|-------| -| **Scan Time** | ~45 seconds | -| **Throughput** | 787 files/sec | -| **Dead Analysis** | < 1 second | -| **Cycles Analysis** | < 1 second | - -## Findings - -### Dead Code Detection -- **High Confidence**: 1 finding (test fixture - intentional) -- **False Positive Rate**: 0% - -### Circular Dependencies - Architectural Analysis -``` -✓ Found 91 circular import cycles (intra-crate) -``` - -**Notable cycles detected**: - -1. **Core Library** (78-hop chain): - ``` - core/src/alloc/layout.rs → error.rs → fmt/mod.rs → - cell.rs → cmp.rs → ... (78 intermediate) ... → fmt/builders.rs - ``` - -2. **Type System** (48-hop chain): - ``` - rustc_middle/src/mir/mono.rs → dep_graph/mod.rs → ty/mod.rs → - ... (48 intermediate) ... → ty/diagnostics.rs - ``` - -3. **AST Module**: - ``` - rustc_ast/src/ast.rs → format.rs → token.rs → - tokenstream.rs → ast_traits.rs → util/parser.rs → visit.rs - ``` - -**Manual Verification Result**: These are **NOT bugs** - they are normal Rust architecture: -- All cycles are **intra-crate** (`crate::` imports within same library) -- Rust allows modules within the same crate to mutually import each other -- Compiler resolves via lazy name resolution + type checking post-resolution -- This is fundamentally different from JavaScript/Python circular imports -- **No upstream issue warranted** - this is standard Rust module organization - -### Twins Analysis -- **Exact Duplicates**: 7,918 (mostly test `main()` functions) -- **False Positive Rate**: 0% - expected pattern for test suite - -## Commands Used - -```bash -cd rust-lang -loct # Create snapshot (45s) -loct dead --confidence high # Dead code analysis -loct cycles # Circular dependencies -loct twins # Duplicate detection -``` - -## Verdict - -**EXCEPTIONAL** - If loctree handles rust-lang/rust, it handles ANY Rust project. - -## Key Insights - -1. **Scalability Proven**: 35K files in 45 seconds -2. **Accuracy Validated**: 0% FP on dead code -3. **Cycle Detection**: Found 91 real architectural cycles (intra-crate, by design) -4. **Zero Crashes**: Complete analysis on 558 MB codebase - -## Note on Intra-Crate Cycles - -Unlike JavaScript/Python where circular imports can cause `undefined`/`None` at runtime, Rust's module system handles intra-crate cycles gracefully: - -```rust -// This is VALID Rust - fmt imports cell, cell imports fmt -// crate::fmt::mod.rs -use crate::cell::Cell; - -// crate::cell.rs -use crate::fmt::{Debug, Display}; -``` - -Loctree correctly detects these architectural patterns but they should be interpreted as "module interdependencies" rather than "problematic cycles." - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/19_sveltekit.md b/docs/use-cases/19_sveltekit.md deleted file mode 100644 index 11ced179..00000000 --- a/docs/use-cases/19_sveltekit.md +++ /dev/null @@ -1,75 +0,0 @@ -# Use Case: sveltejs/kit - The SvelteKit Framework - -**Repository**: https://github.com/sveltejs/kit -**Stack**: TypeScript + Svelte -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on SvelteKit - validating virtual module resolution (`$app/*`, `$lib/*`). - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Files Scanned** | 1,117 | -| **Analysis Time** | 26.92 seconds | -| **Throughput** | 41 files/sec | - -## Findings - -### Dead Code Detection -- **High Confidence**: 0 -- **False Positive Rate**: ~0% - -### Virtual Module Resolution - MAJOR FIX -```typescript -// Previously flagged as dead (WRONG): -export function enhance() { } // in packages/kit/src/runtime/app/forms.js - -// Used via virtual module: -import { enhance } from '$app/forms'; // NOW CORRECTLY RESOLVED! -``` - -### Version History - -| Version | FP Rate | Status | -|---------|---------|--------| -| 0.5.16 | 83% | Virtual modules broken | -| 0.5.17 | 67% | Slightly better | -| 0.6.1-dev | ~100% | REGRESSION | -| 0.6.2-dev | ~0% | FIXED! | - -## Commands Used - -```bash -cd SvelteKit -loct # Create snapshot -loct dead --confidence high # Dead code analysis -loct twins # Duplicate detection -``` - -## Verdict - -**EXCELLENT** - Virtual module resolution is production-ready. - -## Key Insights - -1. **Virtual Modules**: `$app/forms`, `$lib/*` correctly resolved -2. **Framework Magic**: `load()`, `prerender` exports recognized -3. **Major Improvement**: From 100% FP to ~0% FP - -## SvelteKit-Specific Features - -Loctree now handles: -- `$app/forms`, `$app/navigation`, `$app/stores` -- `$lib/*` path aliases -- `+page.server.ts` magic exports -- `export const prerender = true` patterns - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/20_svelte.md b/docs/use-cases/20_svelte.md deleted file mode 100644 index b5cff650..00000000 --- a/docs/use-cases/20_svelte.md +++ /dev/null @@ -1,72 +0,0 @@ -# Use Case: sveltejs/svelte - The Svelte Compiler - -**Repository**: https://github.com/sveltejs/svelte -**Stack**: TypeScript/JavaScript -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on THE Svelte compiler source - the core that powers the Svelte framework. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Files Scanned** | 405 | -| **Analysis Time** | ~30 seconds | -| **Throughput** | 13.5 files/sec | - -## Findings - -### Dead Code Detection -- **High Confidence**: 47 candidates -- **False Positive Rate**: 70% -- **True Positives**: 3-4 genuinely dead internal functions - -### Confirmed Dead Code -- `ELEMENTS_WITHOUT_TEXT` -- `log_reactions` -- `not_equal` -- `bind_props` - -### False Positive Categories -1. **TypeScript .d.ts re-exports** (60% of FPs) - easing functions, SSR functions -2. **Compiler-generated usage** (30% of FPs) - functions used by compiled `.svelte` output -3. **Dynamic references** (10% of FPs) - runtime lookups, reflection patterns - -### Additional Findings -- **Dead Parrots**: 3,942 (TypeScript definition duplicates) -- **Circular Dependencies**: 15 (6 architectural, 9 test fixtures) - -## Commands Used - -```bash -cd svelte-core -loct # Create snapshot -loct dead --confidence high # Dead code analysis -loct cycles # Circular dependencies -loct twins # Duplicate detection -``` - -## Verdict - -**PASSED with caveats** - Excellent for internal dead code, needs `--library-mode` for public API. - -## Key Insights - -1. **Internal dead code**: 100% accurate (3/3 true positives) -2. **Public API exports**: 70% FP (expected for library codebases) -3. **Value delivered**: Identified 3-4 genuinely dead functions for cleanup - -## Recommendations - -- Use `--library-mode` flag when analyzing framework/library source -- Focus on internal modules, not public API barrel exports -- Cross-reference with `package.json` exports field - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/21_tauri.md b/docs/use-cases/21_tauri.md deleted file mode 100644 index 8ad2d54c..00000000 --- a/docs/use-cases/21_tauri.md +++ /dev/null @@ -1,69 +0,0 @@ -# Use Case: tauri-apps/tauri - The Tauri Framework - -**Repository**: https://github.com/tauri-apps/tauri -**Stack**: Rust + TypeScript -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on THE Tauri framework itself - the ultimate test for Tauri command bridge analysis. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Files Scanned** | 385 | -| **Analysis Time** | 9.35 seconds | -| **Throughput** | 41 files/sec | - -## Findings - -### Dead Code Detection -- **High Confidence**: 0 -- **False Positive Rate**: 0% - -### Tauri Command Bridges -``` -loct commands --missing # 157 (plugin architecture - expected) -loct commands --unused # 9 (~22% - HTML usage not detected) -``` - -The "missing" commands are expected - Tauri's plugin system registers handlers dynamically. - -### Additional Findings -- **Dead Parrots**: 44 (legitimate unused re-exports) -- **Twins**: 532 duplicates (standard Rust patterns) - -## Commands Used - -```bash -cd Tauri -loct # Create snapshot -loct dead --confidence high # Dead code analysis -loct commands --missing # Missing FE→BE handlers -loct commands --unused # Unused BE handlers -``` - -## Verdict - -**PERFECT** - 0% false positives. Tauri command tracking works flawlessly. - -## Key Insights - -1. **Command Bridge**: Perfect FE↔BE tracking -2. **Plugin Awareness**: Understands dynamic registration -3. **Production Ready**: Zero FP on framework itself - -## Special Feature: `loct commands` - -Loctree's Tauri-specific commands are validated on Tauri's own codebase: -- Detects handler registration patterns -- Tracks invoke() calls from frontend -- Identifies orphaned handlers - ---- - -*Tested by M&K ⓒ 2025-2026 The Loctree Team* diff --git a/docs/use-cases/22_vue.md b/docs/use-cases/22_vue.md deleted file mode 100644 index 1c54182a..00000000 --- a/docs/use-cases/22_vue.md +++ /dev/null @@ -1,72 +0,0 @@ -# Use Case: vuejs/core - The Vue.js Framework - -**Repository**: https://github.com/vuejs/core -**Stack**: TypeScript + Vue SFC -**Test Date**: 2025-12-08 -**Loctree Version**: 0.6.2-dev - ---- - -## Overview - -Testing loctree on Vue.js core - validating Vue Single File Component (SFC) parsing. - -## Repository Scale - -| Metric | Value | -|--------|-------| -| **Files Scanned** | ~500 | -| **Vue Files** | 11 | -| **Analysis Time** | ~10 seconds | - -## Findings - -### Dead Code Detection -- **High Confidence**: 0 -- **False Positive Rate**: 0% - -### Vue SFC Support -- **11/11 Vue files parsed correctly** -- Import extraction: Perfect -- Component imports: Recognized -- Type imports: Handled - -### Version History - -| Version | FP Rate | Status | -|---------|---------|--------| -| 0.5.16 | 86% | NO Vue SFC parser | -| 0.5.17 | 100% | WORSE | -| 0.6.1-dev | 0% | HUGE WIN | -| 0.6.2-dev | 0% | MAINTAINED | - -## Commands Used - -```bash -cd VueCore -loct # Create snapshot -loct dead --confidence high # Dead code analysis -loct twins # Duplicate detection -``` - -## Verdict - -**EXCELLENT** - Vue SFC parsing is production-ready. - -## Key Insights - -1. **SFC Parsing**: ` + + +"#; + + let analysis = analyze_js_file_ast( + content, + Path::new("src/Counter.svelte"), + Path::new("src"), + None, + None, + "Counter.svelte".to_string(), + &CommandDetectionConfig::default(), + ); + + assert!( + analysis + .exports + .iter() + .any(|e| e.name == "clicks" && e.kind == "rune_state") + ); + assert!( + analysis + .exports + .iter() + .any(|e| e.name == "doubled" && e.kind == "rune_derived") + ); + assert!( + analysis + .exports + .iter() + .any(|e| e.name == "title" && e.kind == "rune_props") + ); + assert!( + analysis + .exports + .iter() + .any(|e| e.name == "count" && e.kind == "rune_props") + ); + assert!( + analysis + .exports + .iter() + .any(|e| e.name == "label" && e.kind == "rune_bindable") + ); + } + + #[test] + fn test_svelte5_runes_in_svelte_ts_module_surface_as_exports() { + let content = r#" +export const storeName = "counter"; +let count = $state(0); +export function increment() { + count += 1; +} +"#; + + let analysis = analyze_js_file_ast( + content, + Path::new("src/lib/store.svelte.ts"), + Path::new("src"), + None, + None, + "lib/store.svelte.ts".to_string(), + &CommandDetectionConfig::default(), + ); + + assert!(analysis.exports.iter().any(|e| e.name == "storeName")); + assert!(analysis.exports.iter().any(|e| e.name == "increment")); + assert!( + analysis + .exports + .iter() + .any(|e| e.name == "count" && e.kind == "rune_state") + ); + } + + #[test] + fn test_svelte5_script_module_and_snippet_exports() { + let content = r#" + + + + +{#snippet item(label)} + {label} +{/snippet} +"#; + + let analysis = analyze_js_file_ast( + content, + Path::new("src/routes/+page.svelte"), + Path::new("src"), + None, + None, + "routes/+page.svelte".to_string(), + &CommandDetectionConfig::default(), + ); + + assert!(analysis.exports.iter().any(|e| e.name == "prerender")); + assert!( + analysis + .exports + .iter() + .any(|e| e.name == "count" && e.kind == "rune_state") + ); + assert!(analysis.exports.iter().any(|e| { + e.name == "item" + && e.kind == "snippet" + && e.export_type == "svelte_template" + && e.params.iter().any(|param| param.name == "label") + })); + } + #[test] fn test_vue_file_full_analysis() { let content = r#" @@ -792,4 +1075,181 @@ export default defineComponent({ "MyComponent usage should be tracked" ); } + + #[test] + fn test_sfc_default_export_synthesized_for_svelte() { + // Svelte component without explicit `export default` — file IS the component. + // Synthetic default export should land with name = file_stem so + // `find(name="HeroSectionV2", mode="who-imports")` can resolve it. + let content = r#" + + + +"#; + let analysis = analyze_js_file_ast( + content, + Path::new("src/components/HeroSectionV2.svelte"), + Path::new("src"), + None, + None, + "components/HeroSectionV2.svelte".to_string(), + &CommandDetectionConfig::default(), + ); + + let default_match = analysis + .exports + .iter() + .find(|e| e.name == "HeroSectionV2" && e.kind == "default"); + assert!( + default_match.is_some(), + "Svelte file should synthesize a default export named after its stem; got exports = {:?}", + analysis + .exports + .iter() + .map(|e| (&e.name, &e.kind)) + .collect::>() + ); + assert_eq!(default_match.unwrap().export_type, "sfc_component"); + } + + #[test] + fn test_sfc_default_export_synthesized_for_astro() { + let content = r#"--- +import Card from "../components/Card.astro"; +const title = "Hello"; +--- + +"#; + let analysis = analyze_js_file_ast( + content, + Path::new("src/pages/HomePage.astro"), + Path::new("src"), + None, + None, + "pages/HomePage.astro".to_string(), + &CommandDetectionConfig::default(), + ); + + assert!( + analysis.exports.iter().any(|e| e.name == "HomePage" + && e.kind == "default" + && e.export_type == "sfc_component"), + "Astro file should synthesize a default export named after its stem; got exports = {:?}", + analysis + .exports + .iter() + .map(|e| (&e.name, &e.kind)) + .collect::>() + ); + } + + #[test] + fn test_sfc_default_export_synthesized_for_vue() { + // Vue SFC without classic `export default` (e.g. ` + + +"#; + let analysis = analyze_js_file_ast( + content, + Path::new("src/widgets/Counter.vue"), + Path::new("src"), + None, + None, + "widgets/Counter.vue".to_string(), + &CommandDetectionConfig::default(), + ); + + assert!( + analysis.exports.iter().any(|e| e.name == "Counter" + && e.kind == "default" + && e.export_type == "sfc_component"), + "Vue file should synthesize a default export named after its stem; got exports = {:?}", + analysis + .exports + .iter() + .map(|e| (&e.name, &e.kind)) + .collect::>() + ); + } + + #[test] + fn test_sfc_synthetic_export_does_not_clobber_explicit() { + // Vue file already has `export default class HeroSection {}` from + // the AST visitor → ExportSymbol { name: "default", kind: "default" }. + // The synthetic helper pushes a DIFFERENT name (file stem), so both + // entries coexist. `name: "default"` is the JS-side default-import + // anchor; the file-stem entry is the symbol-search anchor. + let content = r#" + +"#; + let analysis = analyze_js_file_ast( + content, + Path::new("src/HeroSection.vue"), + Path::new("src"), + None, + None, + "HeroSection.vue".to_string(), + &CommandDetectionConfig::default(), + ); + + let default_anchor = analysis + .exports + .iter() + .filter(|e| e.name == "default" && e.kind == "default") + .count(); + let stem_anchor = analysis + .exports + .iter() + .filter(|e| e.name == "HeroSection" && e.kind == "default") + .count(); + assert_eq!( + default_anchor, 1, + "Original `name: \"default\"` export should remain untouched" + ); + assert_eq!( + stem_anchor, 1, + "Synthetic stem-named export should be pushed exactly once" + ); + } + + #[test] + fn test_sfc_synthetic_export_not_emitted_for_rune_module() { + // `.svelte.ts` rune modules are TypeScript files using the svelte + // co-located convention — they are NOT component files. No synthetic + // default export should be added (the file stem would be + // "Counter.svelte" which would mis-resolve as a component name). + let content = r#" +let count = $state(0); +export function getCount() { return count; } +"#; + let analysis = analyze_js_file_ast( + content, + Path::new("src/Counter.svelte.ts"), + Path::new("src"), + None, + None, + "Counter.svelte.ts".to_string(), + &CommandDetectionConfig::default(), + ); + + assert!( + !analysis + .exports + .iter() + .any(|e| e.export_type == "sfc_component"), + "Rune modules (.svelte.ts) must not get a synthetic sfc_component export" + ); + } } diff --git a/loctree-rs/src/analyzer/ast_js/sfc.rs b/loctree-rs/src/analyzer/ast_js/sfc.rs new file mode 100644 index 00000000..a191ed04 --- /dev/null +++ b/loctree-rs/src/analyzer/ast_js/sfc.rs @@ -0,0 +1,523 @@ +//! Single File Component (SFC) script and template extraction. +//! +//! This module handles extraction of script and template content from +//! Svelte (.svelte), Vue (.vue), and Astro (.astro) Single File Components. +//! +//! 𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents ⓒ 2025-2026 Loctree Team + +use regex::Regex; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(super) enum RuneKind { + State, + Derived, + Props, + Bindable, + Effect, + Inspect, + Host, +} + +impl RuneKind { + pub(super) fn export_kind(&self) -> &'static str { + match self { + Self::State => "rune_state", + Self::Derived => "rune_derived", + Self::Props => "rune_props", + Self::Bindable => "rune_bindable", + Self::Effect => "rune_effect", + Self::Inspect => "rune_inspect_debug", + Self::Host => "rune_host", + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(super) struct RuneDeclaration { + pub(super) name: String, + pub(super) kind: RuneKind, + pub(super) line: usize, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(super) struct SnippetDeclaration { + pub(super) name: String, + pub(super) line: usize, + pub(super) params: Vec, +} + +/// Extract script content from a Svelte file. +/// +/// Handles both `"#).ok(); + + if let Some(re) = script_regex { + let mut scripts = Vec::new(); + for caps in re.captures_iter(content) { + if let Some(script_content) = caps.get(1) { + scripts.push(script_content.as_str().to_string()); + } + } + scripts.join("\n") + } else { + String::new() + } +} + +fn find_astro_frontmatter_bounds(content: &str) -> Option<(usize, usize, usize)> { + let mut offset = 0; + let mut lines = content.split_inclusive('\n'); + let first = lines.next()?; + if first.trim_end_matches(['\r', '\n']) != "---" { + return None; + } + + let frontmatter_start = first.len(); + offset += first.len(); + + for line in lines { + let trimmed = line.trim_end_matches(['\r', '\n']); + if trimmed == "---" { + return Some((frontmatter_start, offset, offset + line.len())); + } + offset += line.len(); + } + + None +} + +fn extract_tag_blocks(content: &str, tag: &str) -> String { + let pattern = format!(r#"<{tag}[^>]*>([\s\S]*?)"#); + let Ok(re) = Regex::new(&pattern) else { + return String::new(); + }; + + re.captures_iter(content) + .filter_map(|caps| caps.get(1).map(|m| m.as_str().to_string())) + .collect::>() + .join("\n") +} + +/// Extract template content from a Svelte file (everything outside "#) { + result = script_re.replace_all(&result, "").to_string(); + } + if let Ok(style_re) = Regex::new(r#"]*>[\s\S]*?"#) { + result = style_re.replace_all(&result, "").to_string(); + } + result +} + +/// Extract template content from a Vue file (everything inside "#).ok(); + + if let Some(re) = template_regex { + let mut templates = Vec::new(); + for caps in re.captures_iter(content) { + if let Some(template_content) = caps.get(1) { + templates.push(template_content.as_str().to_string()); + } + } + templates.join("\n") + } else { + String::new() + } +} + +pub(super) fn extract_svelte5_runes(script_content: &str) -> Vec { + let mut declarations = Vec::new(); + + if let Ok(re) = Regex::new( + r#"(?m)\b(?:export\s+)?(?:let|const|var)\s+([A-Za-z_$][\w$]*)\s*=\s*\$(state|derived|bindable)(?:\.(raw|snapshot|by))?\s*\("#, + ) { + for caps in re.captures_iter(script_content) { + let Some(name) = caps.get(1) else { + continue; + }; + let Some(kind_match) = caps.get(2) else { + continue; + }; + let kind = match kind_match.as_str() { + "state" => RuneKind::State, + "derived" => RuneKind::Derived, + "bindable" => RuneKind::Bindable, + _ => continue, + }; + declarations.push(RuneDeclaration { + name: name.as_str().to_string(), + kind, + line: line_for_offset(script_content, name.start()), + }); + } + } + + if let Ok(re) = Regex::new( + r#"(?m)\b(?:export\s+)?(?:let|const|var)\s+([A-Za-z_$][\w$]*)\s*=\s*\$props(?:\.\w+)?\s*\("#, + ) { + for caps in re.captures_iter(script_content) { + if let Some(name) = caps.get(1) { + declarations.push(RuneDeclaration { + name: name.as_str().to_string(), + kind: RuneKind::Props, + line: line_for_offset(script_content, name.start()), + }); + } + } + } + + if let Ok(re) = Regex::new( + r#"(?m)\b(?:export\s+)?(?:let|const|var)\s*\{([^}]*)\}\s*=\s*\$props(?:\.\w+)?\s*\("#, + ) { + for caps in re.captures_iter(script_content) { + let Some(bindings) = caps.get(1) else { + continue; + }; + let line = line_for_offset(script_content, bindings.start()); + for name in extract_destructured_names(bindings.as_str()) { + declarations.push(RuneDeclaration { + name, + kind: RuneKind::Props, + line, + }); + } + } + } + + for (rune, kind) in [ + ("effect", RuneKind::Effect), + ("inspect", RuneKind::Inspect), + ("host", RuneKind::Host), + ] { + let pattern = format!(r#"(?m)\${rune}(?:\.\w+)?\s*\("#); + let Ok(re) = Regex::new(&pattern) else { + continue; + }; + for mat in re.find_iter(script_content) { + declarations.push(RuneDeclaration { + name: format!("${rune}"), + kind: kind.clone(), + line: line_for_offset(script_content, mat.start()), + }); + } + } + + declarations +} + +pub(super) fn extract_svelte_snippets(template: &str) -> Vec { + let Ok(re) = Regex::new(r#"\{#snippet\s+([A-Za-z_$][\w$]*)\s*\(([^)]*)\)\}"#) else { + return Vec::new(); + }; + + re.captures_iter(template) + .filter_map(|caps| { + let name = caps.get(1)?; + let params = caps + .get(2) + .map(|m| { + m.as_str() + .split(',') + .filter_map(|param| { + let name = param + .trim() + .split([':', '=', ' ']) + .next() + .unwrap_or("") + .trim(); + if name.is_empty() { + None + } else { + Some(name.to_string()) + } + }) + .collect() + }) + .unwrap_or_default(); + + Some(SnippetDeclaration { + name: name.as_str().to_string(), + line: line_for_offset(template, name.start()), + params, + }) + }) + .collect() +} + +fn extract_destructured_names(bindings: &str) -> Vec { + bindings + .split(',') + .filter_map(|part| { + let mut raw = part.trim(); + if raw.is_empty() { + return None; + } + raw = raw.trim_start_matches("..."); + let raw = raw.split('=').next().unwrap_or(raw).trim(); + let name = raw.rsplit(':').next().unwrap_or(raw).trim(); + let name = name.trim_start_matches("..."); + if is_identifier(name) { + Some(name.to_string()) + } else { + None + } + }) + .collect() +} + +fn is_identifier(name: &str) -> bool { + let mut chars = name.chars(); + matches!(chars.next(), Some(c) if c.is_ascii_alphabetic() || c == '_' || c == '$') + && chars.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '$') +} + +fn line_for_offset(content: &str, offset: usize) -> usize { + content[..offset].bytes().filter(|b| *b == b'\n').count() + 1 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_vue_script_extraction_basic() { + let vue_content = r#" + + + + "#; + + let extracted = extract_vue_script(vue_content); + assert!(extracted.contains("const message = 'Hello'")); + assert!(extracted.contains("export const greeting")); + assert!(!extracted.contains("